Modos plan / act: dos roles bajo una misma arquitectura
Responsabilidades
Cline separa «conversar con el usuario» y «modificar archivos de verdad» en dos modos (mode): plan y act, marcados explícitamente por el tipo Mode = "plan" | "act" (Mode type:14). Una misma instancia de Task pertenece a un único mode; cambiar de modo reconstruye el Task, de modo que dentro de una misma tarea el mode es fijo. Este parámetro se propaga desde buildApiHandler hasta ApiHandler, y desde attemptApiRequest hasta el context de getSystemPrompt, atravesando todo el stack.
Sus dos efectos centrales: primero, influye en la selección del ApiHandler —buildApiHandler elige provider según mode desde planModeApiProvider o actModeApiProvider (mode provider:520), de modo que plan y act pueden colgar distintos modelos y distintos thinkingBudget—; segundo, influye en el contenido del componente ACT_VS_PLAN del system prompt y en las notas de disponibilidad de ciertas herramientas (act_vs_plan template:5).
Motivación de diseño
- Dos ApiConfiguration para plan / act:
planModeApiProvider / actModeApiProviderson dos campos independientes; ambos tienen como valor por defectoDEFAULT_API_PROVIDER(planModeApiProvider:243). El usuario puede hacer que plan use un modelo barato para discutir enfoques con rapidez y act un modelo más capaz para cambiar código de verdad. - mode atravesando la construcción del handler:
createHandlerForProviderrecibe mode y escoge el campo correspondiente de los paresplanModeApiModelId / actModeApiModelId,planModeReasoningEffort / actModeReasoningEffort,planModeThinkingBudgetTokens / actModeThinkingBudgetTokens(mode-aware options:94). Todo «presupuesto de pensamiento», «reasoning effort» y «model id» queda aislado por mode. plan_mode_respondes exclusivo de plan: la descripción deplan_mode_responddiceThis tool is only available in PLAN MODE; act mode no tiene bloqueo en runtime para esta herramienta, pero el segmentoACT_VS_PLANdel system prompt indica al modelo «en ACT MODE no se puede usar plan_mode_respond» (ACT MODE exclusion:9).- Conjunto de herramientas principal en ACT MODE: de las 18 herramientas del variant generic, solo
PLAN_MODE = "plan_mode_respond"es exclusiva de plan; el resto (execute_command / read_file / write_to_file / replace_in_file / search_files / list_files / attempt_completion, etc.) está disponible en ambos modos (generic tools:58). Act mode se apoya en este conjunto para cambiar archivos, ejecutar comandos y cerrar conattempt_completion. - yoloMode afecta al prompt de plan:
getActVsPlanModeTemplateTextcompruebacontext.yoloModeToggled !== true; solo en modo no-yolo la descripción de plan añade «puedes usar ask_followup_question para preguntas de clarificación» (yolo guard:18); en yolo no se pregunta proactivamente. - Parámetro needs_more_exploration:
plan_mode_respondincluye el booleano opcionalneeds_more_exploration(needs_more_exploration:38), permitiendo al modelo, tras redactar su respuesta, volver atrás y decir «necesito leer más archivos», evitando quedar atrapado por su plan inicial.
Archivos clave
Mode type:14—type Mode = "plan" | "act", solo estos dos valores.buildApiHandler:517— entrada; elige provider desdeplanModeApiProvider / actModeApiProvidery propaga mode acreateHandlerForProvider.anthropic case mode-aware:94— la ramacase "anthropic"tomaapiModelId / reasoningEffort / thinkingBudgetTokenssegún mode.mode provider pick:520—const apiProvider = mode === "plan" ? planModeApiProvider : actModeApiProvider.planModeApiProvider default:243— ambos campos tienen como defaultDEFAULT_API_PROVIDER; si el usuario no configura explícitamente, plan/act usan el mismo provider.act_vs_plan template:5— plantilla del segmento ACT_VS_PLAN del system prompt; define la disponibilidad de herramientas y el comportamiento esperado en cada modo.ACT MODE description:9— ACT MODE puede usar todas las herramientas excepto plan_mode_respond y cierra con attempt_completion.PLAN MODE description:11— PLAN MODE solo puede responder con plan_mode_respond; su objetivo es primero recopilar información y luego proponer un plan.yolo mode guard:18— en modo yolo se elimina la indicación «puedes hacer preguntas de clarificación».plan_mode_respond generic:25— especificación de la herramienta exclusiva de plan, con tres parámetros:response / needs_more_exploration / task_progress.PLAN MODE only constraint:7— la descripción diceThis tool is only available in PLAN MODE; el modelo se autoconstriñe por la indicación.act_mode_respond description:29— herramienta exclusiva de act, sirve para reportar progreso sin interrumpir el flujo de ejecución y no puede llamarse de forma consecutiva.generic tools list:58— los 18 ids de herramientas declarados por el variant generic, cubriendo tanto herramientas de plan como de act.Task mode field:585— el constructor de Task llama abuildApiHandlercon el parámetromode, proveniente de TaskParams.
Flujo de datos
La propagación de mode es lineal y en un solo sentido: el constructor de Task recibe un mode, este mode decide qué rama sigue buildApiHandler, y luego attemptApiRequest propaga ese mismo mode vía SystemPromptContext.providerInfo.mode a la capa de system prompt:
// apps/vscode/src/core/api/index.ts
export function buildApiHandler(configuration: ApiConfiguration, mode: Mode): ApiHandler {
const { planModeApiProvider, actModeApiProvider, ...options } = configuration
const apiProvider = mode === "plan" ? planModeApiProvider : actModeApiProvider
// ... límite thinkingBudget ...
return createHandlerForProvider(apiProvider, options, mode)
}Cada case de createHandlerForProvider elige el campo según mode; la rama Anthropic es típica:
// apps/vscode/src/core/api/index.ts
case "anthropic":
return new AnthropicHandler({
onRetryAttempt: options.onRetryAttempt,
apiKey: options.apiKey,
anthropicBaseUrl: options.anthropicBaseUrl,
apiModelId: mode === "plan" ? options.planModeApiModelId : options.actModeApiModelId,
reasoningEffort: mode === "plan" ? options.planModeReasoningEffort : options.actModeReasoningEffort,
thinkingBudgetTokens:
mode === "plan" ? options.planModeThinkingBudgetTokens : options.actModeThinkingBudgetTokens,
})La comprobación mode === "plan" se repite en más de 30 cases; puede parecer verboso, pero la ventaja es que cada rama le deja claro al lector «aquí hay dos configuraciones, una para plan y otra para act», sin necesidad de recordar convenciones de nombres. El segmento ACT_VS_PLAN del system prompt se renderiza según el context:
// apps/vscode/src/core/prompts/system-prompt/components/act_vs_plan_mode.ts
const getActVsPlanModeTemplateText = (context: SystemPromptContext) => `ACT MODE V.S. PLAN MODE
In each user message, the environment_details will specify the current mode. There are two modes:
- ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_respond tool.
- In ACT MODE, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user.
- PLAN MODE: In this special mode, you have access to the plan_mode_respond tool.
- In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before they switch you to ACT MODE to implement the solution.
// ...`Observa que no renderiza plantillas distintas por mode, sino que escribe las reglas de ambos modos en el mismo segmento, dejando que el modelo decida el camino según el campo environment_details.mode (environment_details mode:7). La verdadera «selección de herramientas por mode» la realiza ClineToolSet.getEnabledTools filtrando la lista de herramientas según context.providerInfo.mode (ApiProviderInfo.mode:75).
Límites y fallos
- plan usando herramienta exclusiva de act sin bloqueo duro:
getEnabledToolsfiltra por la listavariant.toolsy no chequea mode en runtime para excluirplan_mode_respond(getEnabledTools:87); el variant generic declara simultáneamentePLAN_MODEyATTEMPT, de modo que el modelo se autoconstriñe principalmente por el system prompt. - Cambiar de mode reconstruye Task: el constructor de Task almacena mode; cambiar de mode durante la ejecución dispara un nuevo Task en lugar de modificar el campo, y
buildApiHandlersolo se llama una vez, al construir el Task (buildApiHandler call:585). - Valor por defecto de planModeApiProvider:
DEFAULT_API_PROVIDERes el valor común para plan y act (planModeApiProvider default:243); así, al iniciar Cline por primera vez, plan y act usan el mismo provider y el comportamiento coincide. - thinkingBudget con límite separado en plan / act:
buildApiHandlertomamode === "plan" ? planModeThinkingBudgetTokens : actModeThinkingBudgetTokensy aplica el límite maxTokens de forma independiente (mode budget:525), de modo que el budget de plan no afecta a act ni viceversa. - Conflicto entre yoloMode y plan: cuando
yoloModeToggled === true, el segmento de plan elimina la indicación «puedes usar ask_followup_question» (yolo guard:18), pero yolo consiste en saltarse la confirmación del usuario y ejecutar automáticamente, lo cual entra en tensión con la filosofía de plan de «primero discutir, luego ejecutar»; en la práctica, los usuarios yolo casi no usan plan. - Bloqueo de llamadas consecutivas a act_mode_respond: la descripción de
act_mode_respondindica explícitamente «no puede llamarse de forma consecutiva, fallará» (CRITICAL CONSTRAINT:43), respaldado por un bloqueo en runtime. - Autocorrección con needs_more_exploration:
plan_mode_respondpermite, tras redactar el plan, volver atrás y decir «necesita más exploración»; conneeds_more_exploration=truela siguiente ronda usa herramientas de exploración en lugar de cerrar (needs_more_exploration:38), ofreciendo al modelo una vía de autocorrección.
Resumen
Los modos plan / act son la línea que Cline traza entre «discutir un enfoque» y «modificar código»; en términos de ingeniería, se reduce a un tipo Mode = "plan" | "act" más un conjunto de campos de configuración por pares. Su compromiso de diseño es: no cambiar mode dinámicamente en runtime, sino reconstruir el Task en cada cambio de mode, ganando que handler / prompt / toolset se reconstruyan como un bloque según mode y dejando el estado limpiamente aislado. En la práctica, el modelo se autoconstriñe a qué herramienta usar mediante el segmento ACT_VS_PLAN del system prompt; los bloqueos en runtime son mínimos.
- Cómo se filtra el toolset por context:
/prompts/toolset - Cómo se ensambla el system prompt:
/prompts/prompt-builder - Cómo afecta mode a la selección de handler:
/providers/api-handler