Goose CLI 计划模式实战:/plan 命令、双模型 Planner 配置与 plan.md 提示词模板
在 goose 的交互式会话中,/plan 提示补全命令会先把任务拆解为清晰的、可执行的步骤,再交给 agent 执行;配套的两个环境变量 GOOSE_PLANNER_PROVIDER / GOOSE_PLANNER_MODEL 允许你为"规划"与"执行"分别指定不同的 LLM,从而兼顾规划质量与执行成本。读完本文,你可以掌握:如何在 CLI 中进入/退出计划模式、如何为 planner 单独配置模型、澄清问答(clarifying questions)机制如何工作,以及 goose 在源码层面如何把 planner 的输出转化为执行器的新会话。
为什么要在动手之前先做计划
没有清晰计划就开工,如同盖房没有图纸:不知道该做什么、时间和精力的浪费、项目越滚越大——这三点是官方文档总结的典型后果(见 creating-plans.md)。一个好的计划能让所有参与者保持同频,也让进度可衡量。goose CLI 为此提供了 /plan 提示补全命令,把项目拆解为清晰、可管理的步骤。
需要注意一个产品形态差异:goose Desktop 端没有 plan 关键字。如果希望在 Desktop 中生成计划,需要用自然语言显式要求,例如:
"Hey goose, can you create a plan to convert my CLI project into a locally hosted web page
that gives me input fields for each CLI command I can run? Please don't start the actual work"
除非你明确要求"create a plan",Desktop 版 goose 可能会直接开始干活。而 CLI 的 plan mode 是交互式的:在生成计划前会先提出澄清问题,你能给出信息量越足的答复,生成的计划就越可落地。
基本用法:会话、/plan 与 /endplan
进入计划模式前需要有一个活跃的 goose 会话。如果打算用独立会话专门做规划,建议给它起一个名字:
~ goose session -n web-project-plan
starting session | provider: databricks model: databricks-meta-llama
session id: 20251110_5
working directory: /Users/alincoln
goose is running! Enter your instructions, or try asking what goose can do.
输入 /plan 进入计划模式,也可以把计划描述直接追加在命令后面,省去一次输入:
( O)> /plan Build a four bedroom house
CLI 的计划模式是一种特殊交互模式:goose 帮你把任务拆解为可管理的步骤。想关闭计划模式、回到当前活跃会话时,输入:
( O)> /endplan
从源码可以看到这两条命令的入口:input.rs 中的 parse_plan_command 把 /plan 及其后的文本解析为 InputResult::Plan;帮助文本(input.rs)明确写着 /plan <message_text> 会"基于当前消息创建计划,并询问用户是否要执行它;若执行,goose 模式会被置为 auto,执行完再恢复原模式",且模型选择依据 $GOOSE_PLANNER_PROVIDER 与 $GOOSE_PLANNER_MODEL,未设置时回退到默认模型。运行时层面,mod.rs 用一个 RunMode 枚举(Normal / Plan)在会话状态上标记当前是否处于计划模式。
官方 CLI 帮助还给出了一条实用建议:在使用 /plan 之前先 /mode approve 并把合适的上下文喂给 goose,相当于"预热",能让 planner 拿到更充分的背景信息。
为 planner 单独配置 provider 和 model
一些工作流里,用一个 LLM 负责规划、另一个负责执行效果更好。官方文档给出的例子是:GPT-4.1 擅长战略规划与复杂任务拆解,而 Claude Sonnet 3.5 更擅长写出干净高效的代码并精确遵循指令——让 GPT-4.1 规划、Claude 执行,可以各取所长。
goose CLI 的 plan mode 使用两个配置值:
GOOSE_PLANNER_PROVIDER:规划使用的 providerGOOSE_PLANNER_MODEL:规划使用的模型
一个典型的多模型组合思路是:把规划模式与一个不同的"默认执行模型"搭配,在成本、速度与质量之间取得平衡。
设置 planner 环境变量
可以把这两行加入 bash 的 shell 配置文件(如 .bashrc):
export GOOSE_PLANNER_PROVIDER=<my-chosen-provider>
export GOOSE_PLANNER_MODEL=<my-chosen-model>
保存后需要重启 goose 会话,变量才会生效。如果这两个变量没有设置,goose 会使用你的默认 provider 与 model 配置。默认配置通常已经足够;只有当你发现某些模型更擅长把任务拆解为清晰步骤时,才值得单独指定规划模型。
这个"优先 planner、回退默认"的行为在源码中可以直接验证。mod.rs 中的 get_reasoner 函数先尝试从全局配置读取 GOOSE_PLANNER_PROVIDER,读不到就打印 WARNING: GOOSE_PLANNER_PROVIDER not found. Using default provider... 并回退到 GOOSE_PROVIDER;GOOSE_PLANNER_MODEL 的处理逻辑完全对称,回退到 GOOSE_MODEL。
验证配置是否生效
在终端输入:
~ goose info -v
info 命令会返回当前配置与配置文件路径,例如:
goose Version:
Version: 1.0.18
goose Locations:
Config file: /Users/alincoln/.config/goose/config.yaml
Sessions dir: /Users/alincoln/.local/share/goose/sessions
Logs dir: /Users/alincoln/.local/state/goose/logs
goose Configuration:
GOOSE_PROVIDER: anthropic
GOOSE_MODEL: claude-3.5-sonnet
GOOSE_PLANNER_PROVIDER: openai
GOOSE_MODE: smart_approve
GOOSE_PLANNER_MODEL: gpt-4.1
只要 GOOSE_PLANNER_PROVIDER 或 GOOSE_PLANNER_MODEL 任一缺失,goose 就用 GOOSE_PROVIDER 与 GOOSE_MODEL 来生成计划。
plan.md:规划提示词模板及其可定制性
计划模式下 planner 的行为由 plan.md 提示词模板驱动,源码中的默认模板位于 prompts/plan.md。它的核心约束包括:
- planner 是一个"专职规划 AI",它的产出只能是二选一:一份详细的分步计划(信息足够时),或一份澄清问题清单(信息不足时);
- 模板会注入当前会话中定义的工具(名称、描述、参数),若没有工具则显式写明 "No tools are defined";
- 计划要求步骤编号、显式标注步骤间依赖(如"把 Step 3 的输出作为 Step 4 的输入")、包含条件分支逻辑;
- 由于执行器 AI 只能看到最终计划本身(作为一条新的 user 消息),看不到本次规划会话的历史,模板要求 planner 把执行计划所需的背景、指令和历史细节全部重述进计划里;
- planner 只响应一次:若产出计划,它会作为 user 消息出现在执行器的全新会话中,等效于清除了先前上下文。
模板在代码中的注册与渲染见 prompt_template.rs:TEMPLATE_REGISTRY 把 plan.md 登记为 "Prompt used when goose creates step-by-step plans. CLI only"。模板通过 minijinja 渲染(支持 code_fence 等过滤器),内置模板通过 include_dir! 编译进二进制,而 user_prompts_dir() 指向用户配置目录下的 prompts/ 子目录(prompt_template.rs)。
::: tip
你也可以自定义 goose 创建计划的方式:编辑 plan.md 提示词模板即可,具体做法参见 prompt-templates.md。
:::
规划响应的分类:plan 还是 clarifying questions?
CLI 需要区分 planner 这一次输出的是"计划"还是"澄清问题",两者的后续处理完全不同。这个判定在 mod.rs 中实现:
-
PlannerResponseType枚举只有两个变体:Plan和ClarifyingQuestions; -
classify_planner_response会发起一次额外的 LLM 调用,把 planner 的完整输出嵌入如下判定提示词中:"The text below is the output from an AI model which can either provide a plan or list of clarifying questions. Based on the text below, decide if the output is a 'plan' or 'clarifying questions'."
要求模型只回复分类标签
plan或clarifying questions,输出文本包含 "plan" 即判为Plan; -
送分类器的文本来自
planner_classification_text,即 planner 响应中 agent 可见的内容,且源码会断言其非空("Planner returned no agent-visible text to classify")。
分类之后,plan_with_reasoner_model(mod.rs)执行两条分支:
- 判为 Plan:CLI 弹出确认框
Do you want to clear message history & act on this plan?(默认 Yes)。若确认执行:- 运行模式从
Plan切回Normal,并把 goose 的批准模式临时切到auto(若当前不是 auto); - 清空会话消息历史,把计划全文作为一条 user 消息推入会话,然后立即驱动 agent 开始执行;
- 执行结束后把 goose 模式恢复为进入计划前的值。 若选择"不执行",计划文本作为 assistant 消息保留在会话中,下一轮你可以继续微调计划——这也解释了文档中"退出计划模式后可以随时恢复继续做"的用法。
- 运行模式从
- 判为 ClarifyingQuestions:把响应作为 assistant 消息追加到会话,等待你作答,然后进入下一轮规划循环。
这里还有一处值得注意的工程细节:送进 planner 的消息历史会先经过 planner_provider_messages 投影(mod.rs)——过滤掉 turn-context 事件、修复会话合法性并合并相邻消息。源码注释解释原因是 "planner 提示词中没有 turn-context 指令,这些块不应到达 planner"。也就是说计划模式下的规划请求是一个被刻意"降噪"过的精简上下文。
如何描述你的项目
goose 能处理复杂的项目描述,但在清晰、简洁的描述下效果最好:聚焦陈述项目的目的与期望结果。如果这些不清楚,goose 会持续追问,直到完全理解你的目标。
简单项目示例:造一栋四层卧室的房子
文档用一个"建房"例子展示计划模式的完整交互:
( O)> /plan
Entering plan mode. You can provide instructions to create a plan and then act on it. To exit early, type /endplan
( O)> Build a four bedroom house
◓ Measuring semantic distance...
I need to gather more information before creating a detailed house-building plan. Please provide clarification on the following:
1. What is the purpose of this plan? Are you looking for architectural designs, construction steps, or a project management timeline?
2. What is your budget range for this four-bedroom house?
...(共 8 个澄清问题:面积、地块/ zoning、建筑风格、卫浴数量、可持续性要求、工期等)
( O)> 1 construction steps and a project management timeline. 2 $600,000. 3 4,000 sq feet. ... 8 complete in six months.
答复澄清问题后,planner 生成了一份计划,涵盖:设计与规划(聘请建筑师、平面图、地块准备)、能效与太阳能(光伏阵列、储能、保温门窗、节能电器)、预算(指出 4,000 平方英尺按 $200–250/sq ft 估算会超出 $600,000 预算,需要优化)、时间线(前两个月设计报建,3–4 月地基与框架,第 5 个月水电暖与光伏,第 6 个月精装修)。随后 CLI 询问:
◇ Do you want to clear message history & act on this plan?
│ Yes
选 Yes 即"Exiting plan mode and acting on the above plan"。文档还点出一个预期管理要点:这份建房计划停留在较高层面,是因为 goose 的模型更擅长技术与软件开发而非建筑施工——所以像"构建 web 应用"这类软件项目会拿到更具体、更细致的计划。
为计划的子步骤单独再做一份计划
建房计划里"Hire an architect"这一步过于粗略。如果你审阅计划后想继续深入,可以退出计划模式后再进入,针对子步骤单独规划:
( O)> /plan hire an architect
Entering plan mode. You can provide instructions to create a plan and then act on it. To exit early, type /endplan
I need some clarifying questions to better understand your request about hiring an architect:
1. What is your location or preferred region for the architect to be based in?
2. Do you have a specific budget range for architectural services?
3. Are you looking for an architect with specific expertise (e.g., energy-efficient homes, modern design, traditional styles)?
...
收集到足够信息后,goose 会生成"聘请建筑师"的详细子计划。这份子计划会融入更大的建房项目上下文,步骤反映并支撑整体建设目标——这就是计划模式可以分层、递归式使用的价值。
开发项目示例:把 Python CLI 改造成 Web 应用
这是一个更贴近开发者日常的场景:一位开发者用 Python 写了个 CLI 脚本(search_replace_routes.py),通过 Contentful CMS 做字符串搜索替换;他希望改造成网站,以便更好用并扩展更多功能。
启动计划:
( O)> /plan
Entering plan mode. You can provide instructions to create a plan and then act on it. To exit early, type /endplan
( O)> Convert the CLI built by search_replace_routes.py into a web page
goose 会解析你的项目描述,咨询你配置的 LLM;若信息不足,就发起一轮澄清问题。CLI 转网站的场景下,问题通常围绕样式、认证、功能、技术栈等,例如:
1. Should the application support any keyboard shortcuts for common actions?
2. Would you like the application to remember user preferences (like case sensitivity setting) between sessions?
3. Should there be any form of notification when operations complete successfully?
4. How should the application handle very large text fields that might be difficult to display in the three-column layout?
5. Are there any specific CI/CD requirements for deployment to AWS?
回答澄清问题的技巧
-
可以逐条回答,也可以批量回答。批量回答示例(注意用编号与问题对应):
( O)> 1 no keyboard shortcuts. 2 do not remember preferences. 3 on success, open a dialog that says "success". 4 Truncate to 30 characters before the string to replace and then 30 characters after the string to replace. 5 no CI/CD requirements -
编号作答很重要:与其简单回答 "no",不如给出带编号的上下文式回答,如 "2. Do not store my preferences."——这帮助 goose 跟踪哪些问题已答,避免重复追问。
-
计划模式下无法直接读文件:当 goose 索要源代码等工件时,必须把内容直接粘贴进对话(前面加一句 "Here's the requested code:" 之类的说明即可);只给文件路径在计划模式下是行不通的。
-
多轮澄清是正常的:复杂项目中,每轮新问题往往源于你上一轮答案里的新信息,或某些方面仍缺细节。
-
不想再答了?直接要一份通用计划。当 goose 仍在追问关键信息(比如 Contentful 脚本的具体功能、预定义键是什么、是否要保留全部命令行选项等)时,可以输入
please provide a generic plan,让它基于标准化模板输出一份计划:I still need some critical information to create a comprehensive plan: 1. What specific functionality does your Python script perform with Contentful? ... 2. What are the 5 predefined keys/inputs you mentioned earlier? ... Without this information, I can only provide a generic plan that might not accurately capture your requirements. ( O)> please provide a generic plan
goose 会创建标准化的计划格式,但内容根据你的答案定制;它还能生成实现计划各步骤所需的代码。在输入 /endplan 并要求 goose 实施计划之前,务必审阅计划与它生成的代码。
下面是该项目的一份示例计划(文档中省略了生成的网站代码):
# Plan for Converting CLI Script to React Web Application
## Step 1: Set up the React project and dependencies
1. Create a new React application using Create React App
2. Install necessary dependencies
3. Set up project structure
src/
├── components/
│ ├── Auth/
│ ├── Layout/
│ ├── Search/
│ ├── Results/
│ └── History/
├── services/
│ ├── contentful.ts
│ ├── auth.ts
│ └── storage.ts
├── utils/
│ ├── validation.ts
│ └── helpers.ts
├── contexts/
│ └── AppContext.tsx
└── pages/
├── Home.tsx
├── Search.tsx
└── History.tsx
## Step 2: Implement authentication with Okta
1. Create an Okta application in the Okta Developer Console
2. Configure the Okta authentication settings in the application
3. Implement protected routes using Okta's React components
## Step 3: Create the layout and UI components with Material UI
1. Implement the main layout with Material UI
2. Create the search form component
3. Create the results display component with three columns
4. Implement the "Load More" pagination component
## Step 4: Implement Contentful service
1. Create a service for interacting with Contentful
## Step 5: Implement local storage service for history
1. Create a service for managing search history in localStorage
## Step 6: Implement validation utilities
1. Create utility functions for input validation
## Step 7: Implement main pages
1. Create the Search page
2. Create the History page
## Step 8: Set up routing and main application
1. Create the main App component
## Step 9: Implement error handling and loading states
1. Create error boundary components
2. Add loading indicators for API operations
3. Implement error messages display
## Step 10: Set up deployment configuration
1. Create AWS deployment configuration
## Step 11: Testing and quality assurance
1. Write unit tests for key components
2. Implement integration tests for the main workflows
3. Perform manual testing of the application
This plan provides a comprehensive framework for converting your CLI script to a React web application
with Material UI and Okta authentication. You'll need to adapt specific parts based on your exact
requirements and the functionality of your original script.
小结与延伸阅读
- 用
goose session -n <name>开一个专属规划会话,/plan进入、/endplan退出;计划确认后 goose 会清空历史、把计划作为新 user 消息并以auto模式执行(见 mod.rs)。 - 通过
GOOSE_PLANNER_PROVIDER/GOOSE_PLANNER_MODEL为规划单独指定模型,未设置时回退默认配置(见 get_reasoner),用goose info -v验证。 - 计划模式的信息传递规则值得记牢:澄清问题留在当前会话继续对话;计划则会作为独立的新会话消息交给执行器,因此计划本身必须自含全部必要上下文——这正是
plan.md模板的核心约束。 - 想调整计划风格、格式或语言,编辑 plan.md 对应的用户模板即可,模板体系说明见 prompt-templates.md。
- 关于"AI agent 什么时候该规划、怎么规划"的更完整讨论,可参考仓库内的博客文章 Does Your AI Agent Need a Plan?。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00