Skip to content

plan / act-Modus: Zwei Rollen in derselben Architektur

源码版本v4.0.10

Verantwortung

Cline trennt «mit dem Benutzer sprechen» und «wirklich Dateien ändern» in zwei Modi (mode): plan und act, explizit gekennzeichnet durch den Typ Mode = "plan" | "act" (Mode type:14). Eine Task-Instanz gehört zu genau einem Modus; der Moduswechsel baut den Task neu auf, daher bleibt der Modus innerhalb einer einzelnen Aufgabe unverändert. Dieser mode-Parameter wird von buildApiHandler bis zum ApiHandler und von attemptApiRequest bis in den context von getSystemPrompt durchgereicht.

Seine zwei zentralen Wirkungen: Erstens beeinflusst er die Auswahl des ApiHandler — buildApiHandler wählt anhand des Modus den Provider aus planModeApiProvider oder actModeApiProvider (mode provider:520); plan und act können unterschiedliche Modelle und unterschiedliche thinkingBudget haben. Zweitens beeinflusst er den Inhalt der ACT_VS_PLAN-Komponente im Systemprompt sowie die Verfügbarkeits-Hinweise bestimmter Werkzeuge (act_vs_plan template:5).

Entwurfsmotivation

  • plan / act mit zwei ApiConfiguration-Sätzen: planModeApiProvider / actModeApiProvider sind zwei unabhängige Felder, beide haben den Default DEFAULT_API_PROVIDER (planModeApiProvider:243); der Benutzer kann für plan ein billiges Modell für schnelle Diskussionen und für act ein stärkeres Modell für echte Codeänderungen nutzen.
  • mode reicht bis zur Handler-Konstruktion: createHandlerForProvider erhält mode und holt aus gepaarten Feldern wie planModeApiModelId / actModeApiModelId, planModeReasoningEffort / actModeReasoningEffort, planModeThinkingBudgetTokens / actModeThinkingBudgetTokens den passenden Teil (mode-aware options:94); alle «Thinking-Budgets», «reasoning effort», «model id» sind pro mode isoliert.
  • plan_mode_respond-Werkzeug exklusiv für plan: Die description von plan_mode_respond sagt explizit This tool is only available in PLAN MODE; act-Modus hat zwar keine Laufzeit-Blockade für dieses Werkzeug, aber der ACT_VS_PLAN-Abschnitt im Systemprompt teilt dem Modell mit, dass «ACT MODE plan_mode_respond nicht verwenden darf» (ACT MODE exclusion:9).
  • ACT MODE Hauptwerkzeugsatz: Von den 18 Werkzeugen, die die generic variant deklariert, ist nur PLAN_MODE = "plan_mode_respond" exklusiv für plan; die anderen execute_command / read_file / write_to_file / replace_in_file / search_files / list_files / attempt_completion etc. sind in beiden Modi verfügbar (generic tools:58); act-Modus nutzt diese, um Dateien zu ändern, Befehle auszuführen und am Ende mit attempt_completion abzuschließen.
  • yoloMode beeinflusst plan-Prompt: In getActVsPlanModeTemplateText wird context.yoloModeToggled !== true geprüft; nur im Nicht-yolo-Modus wird der plan-Beschreibung ein Satz hinzugefügt: «du kannst ask_followup_question für Klärungsfragen nutzen» (yolo guard:18); yolo-Modus fragt standardmäßig nicht proaktiv.
  • needs_more_exploration-Parameter: plan_mode_respond hat einen optionalen boolean-Parameter needs_more_exploration (needs_more_exploration:38); das Modell kann nach dem Schreiben der Antwort noch sagen: «Ich muss noch ein paar Dateien lesen», um nicht durch den anfänglichen Plan festgelegt zu sein.

Schlüsseldateien

  • Mode type:14type Mode = "plan" | "act", nur diese zwei Werte.
  • buildApiHandler:517 — Einstieg, wählt aus planModeApiProvider / actModeApiProvider den Provider und reicht mode an createHandlerForProvider weiter.
  • anthropic case mode-aware:94case "anthropic" holt pro mode aus gepaarten Feldern apiModelId / reasoningEffort / thinkingBudgetTokens.
  • mode provider pick:520const apiProvider = mode === "plan" ? planModeApiProvider : actModeApiProvider.
  • planModeApiProvider default:243 — beide Felder haben den Default DEFAULT_API_PROVIDER; wenn der Benutzer nicht explizit konfiguriert, nutzen plan/act denselben Provider.
  • act_vs_plan template:5 — Vorlage für den ACT_VS_PLAN-Abschnitt im Systemprompt; definiert die jeweilige Werkzeugverfügbarkeit und Verhaltenenserwartung beider Modi.
  • ACT MODE description:9 — ACT MODE kann alle Werkzeuge außer plan_mode_respond nutzen und schließt mit attempt_completion ab.
  • PLAN MODE description:11 — PLAN MODE kann nur mit plan_mode_respond antworten; Ziel ist, erst Informationen zu sammeln und dann einen Plan vorzulegen.
  • yolo mode guard:18 — im yolo-Modus wird der Hinweis «Klärungsfragen stellen» entfernt.
  • plan_mode_respond generic:25 — Spezifikation des plan-exklusiven Werkzeugs, mit den drei Parametern response / needs_more_exploration / task_progress.
  • PLAN MODE only constraint:7 — description enthält This tool is only available in PLAN MODE; das Modell folgt dieser Selbstbeschränkung über den Prompt.
  • act_mode_respond description:29 — act-exklusives Werkzeug, um Fortschritt zu melden, ohne den Ausführungsfluss zu unterbrechen; kann nicht aufeinanderfolgend aufgerufen werden.
  • generic tools list:58 — 18 Werkzeug-IDs, die die generic variant deklariert, decken sowohl plan- als auch act-Werkzeuge ab.
  • Task mode field:585 — Task nutzt beim Konstruieren den mode-Parameter für buildApiHandler; dieser mode stammt aus TaskParams.

Datenfluss

Die Weitergabe von mode ist unidirektional und gradlinig: Task erhält beim Konstruieren einen mode, der entscheidet, welchen Zweig buildApiHandler nimmt; dann reicht attemptApiRequest denselben mode über SystemPromptContext.providerInfo.mode an die Systemprompt-Schicht:

typescript
// 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

	// ... thinkingBudget limits ...
	return createHandlerForProvider(apiProvider, options, mode)
}

Jeder case in createHandlerForProvider wählt pro mode ein Feld; der Anthropic-Zweig ist typisch:

typescript
// 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,
	})

Die Prüfung mode === "plan" wiederholt sich in über 30 cases; sie wirkt weitschweifig, hat aber den Vorteil, dass jeder Zweig dem Leser explizit sagt: «Hier gibt es zwei Sätze plan/act-Konfiguration», ohne sich Feldnamen-Konventionen merken zu müssen. Der ACT_VS_PLAN-Abschnitt der Systemprompt-Schicht wird anhand von context gerendert:

typescript
// 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.
 // ...`

Beachte, dass hier nicht pro mode eine unterschiedliche Vorlage gerendert wird; stattdessen werden die Regeln beider Modi in denselben Prompt-Abschnitt geschrieben, und das Modell entscheidet selbst anhand des Feldes environment_details.mode, welchen Weg es geht (environment_details mode:7). Die eigentliche «Werkzeugauswahl pro mode» wird von ClineToolSet.getEnabledTools durch Filtern der Werkzeugliste anhand von context.providerInfo.mode umgesetzt (ApiProviderInfo.mode:75).

Grenzen und Fehler

  • plan nutzt act-exklusives Werkzeug ohne harte Blockade: getEnabledTools filtert nach der variant.tools-Liste; zur Laufzeit wird nicht separat mode geprüft, um plan_mode_respond auszuschließen (getEnabledTools:87); die generic variant deklariert gleichzeitig PLAN_MODE und ATTEMPT, das Modell wird primär durch den Systemprompt beschränkt.
  • mode-Wechsel baut Task neu auf: Task speichert mode beim Konstruieren; ein Wechsel zur Laufzeit löst einen neuen Task-Konstruktion aus, anstatt nur ein Feld zu ändern; buildApiHandler wird nur einmal beim Task-Konstruieren aufgerufen (buildApiHandler call:585).
  • Default von planModeApiProvider: DEFAULT_API_PROVIDER ist der gemeinsame Default für plan/act (planModeApiProvider default:243); daher nutzen plan und act bei Erststart von Cline für neue Benutzer denselben Provider, das Verhalten ist konsistent.
  • thinkingBudget pro plan / act getrennt begrenzt: In buildApiHandler wird mode === "plan" ? planModeThinkingBudgetTokens : actModeThinkingBudgetTokens separat für maxLimits begrenzt (mode budget:525); das Budget von plan beeinflusst act nicht und umgekehrt.
  • yoloMode und plan im Konflikt: Bei yoloModeToggled === true entfernt der plan-Abschnitt den Hinweis «ask_followup_question stellen» (yolo guard:18); yolo-Modus bedeutet aber im Wesentlichen, dass Benutzerbestätigungen übersprungen und automatisch ausgeführt werden, was im Spannungsverhältnis zu plans «erst diskutieren, dann ausführen» steht; in der Praxis nutzen yolo-Benutzer plan kaum.
  • act_mode_respond aufeinanderfolgende Aufrufe blockiert: Die description des Werkzeugs act_mode_respond sagt explizit «kann nicht aufeinanderfolgend aufgerufen werden, sonst schlägt es fehl» (CRITICAL CONSTRAINT:43), erzwungen durch Laufzeit-Blockade.
  • needs_more_exploration Selbstkorrektur: plan_mode_respond kann nach dem Schreiben des plans noch sagen: «brauche mehr Erkundung»; über needs_more_exploration=true geht die nächste Runde in Erkundungs-Werkzeuge über, statt abzuschließen (needs_more_exploration:38), was dem Modell einen Selbstkorrektur-Ausweg bietet.

Zusammenfassung

Der plan / act-Modus ist die Linie, die Cline zwischen «Plan diskutieren» und «Code ändern» zieht; technisch gesehen ist es ein Mode = "plan" | "act"-Typ plus ein Satz gepaarter Konfigurationsfelder. Der Design-Kompromiss ist: mode wird nicht zur Laufzeit dynamisch gewechselt, sondern jeder Wechsel baut den Task neu auf; im Gegenzug werden Handler / Prompts / Werkzeugsatz pro mode vollständig neu aufgebaut, sodass der Zustand sauber isoliert ist. Das Modell wird primär durch den ACT_VS_PLAN-Abschnitt im Systemprompt selbst beschränkt, welches Werkzeug es nutzt; Laufzeit-Blockaden sind minimal.

  • Wie der Werkzeugsatz nach context filtert: /prompts/toolset
  • Wie der Systemprompt zusammengebaut wird: /prompts/prompt-builder
  • Wie mode die Handler-Auswahl beeinflusst: /providers/api-handler

Siehe offizielle Dokumentation: Cline-Dokumentation · README