Gemini CLI Plan Mode 详解:只读规划、策略引擎工具白名单与 Pro/Flash 自动模型路由
本文基于 Gemini CLI 官方文档 Plan Mode 及其对应源码,系统讲解 Plan Mode 的完整工作流:如何进入与退出规划模式、四步"目标-讨论-审阅-批准"协作循环、由策略引擎(policy engine)强制执行的只读工具白名单、自定义策略与计划目录的配置方法,以及基于 Pro/Flash 模型的自动路由机制。读完本文,你可以在终端中以安全只读的方式让 Gemini CLI 先"研究-设计-计划"再实施,并通过 TOML 策略、hooks 与扩展构建适合自己团队的规划工作流。
一、Plan Mode 是什么
Plan Mode 是 Gemini CLI 提供的只读规划环境:在执行任何代码修改之前,先在不受污染的状态下架构化地设计方案。它支持三类核心活动:
- Research(研究):以只读状态探索项目,防止意外改动;
- Design(设计):理解问题、评估取舍、选择方案;
- Plan(计划):在任何代码被修改前,先就执行策略达成一致。
Plan Mode 默认启用。你可以使用 /settings 命令管理该设置——对应 配置模式定义 中的 general.plan.enabled(默认 true,标签 "Enable Plan Mode",需要重启生效)。
二、如何进入 Plan Mode
Plan Mode 与工作流无缝集成,可随时在"规划"与"执行"之间切换。入口共有四类:
1. 默认以 Plan Mode 启动
- 使用
/settings命令; - 将 Default Approval Mode 设为
Plan。
2. 单次以 Plan Mode 启动
启动时使用命令行参数:
gemini --approval-mode=plan
3. 会话中手动进入
- 键盘快捷键:按
Shift+Tab循环切换审批模式(Default->Auto-Edit->Plan)。当 Gemini CLI 正在处理请求或显示确认对话框时,Plan Mode 会自动从循环中移除。 - 命令:在输入框输入
/plan [goal]。[goal]为可选参数,例如/plan implement authentication会切换到 Plan Mode 并立即把提示词提交给模型。 - 自然语言:直接对 Gemini CLI 说 "start a plan for..."。此时 CLI 会调用
enter_plan_mode工具完成模式切换。注意:YOLO 模式下该工具不可用(参见命令行参数中的 YOLO 说明)。
从源码看,模式切换由 EnterPlanModeTool 实现:执行时调用 config.setApprovalMode(ApprovalMode.PLAN),并预先创建 plans 目录(config.storage.getPlansDir()),这样在沙箱环境中该目录已存在于宿主系统,可被绑定/放行;即使创建失败也仅记录日志而不中断,后续 write_file 会再次尝试。
三、Plan Mode 的使用流程
Plan Mode 让你在 Gemini CLI 采取动作之前,先与它共同设计方案:
- 给出目标:描述你想达成的目标。若尚不在 Plan Mode,Gemini CLI 会先切换到 Plan Mode 研究任务。
- 讨论并达成一致:分析代码库时,Gemini CLI 会与你讨论发现和拟定策略;可能通过
ask_user提问或给出多种实现选项。Gemini CLI 会在起草正式计划前停下等待你的确认——你应先就方案达成非正式共识。 - 审阅计划:达成一致后,Gemini CLI 会在 plans 目录生成一份 Markdown 实施计划文件。
- 查看:直接打开该文件阅读拟议变更;
- 编辑:按
Ctrl+X在外部编辑器中直接打开计划。
- 批准或迭代:Gemini CLI 会提交终稿计划请求正式批准。
- 批准:满意即批准,立即开始实施:"Yes, automatically accept edits" 或 "Yes, manually accept edits";
- 迭代:需要调整时,在输入框给反馈,或直接编辑计划文件;Gemini CLI 会细化策略并更新计划;
- 取消:按
Esc取消当前计划。
协作式计划编辑
你可以直接修改计划或在其上留下批注,这通常比用自然语言描述复杂变更更快、更精确:
- 打开计划:Gemini CLI 展示计划供审阅时按
Ctrl+X; - 编辑或批注:计划在你配置的外部编辑器(如 VS Code 或 Vim)中打开,可以:
- 修改步骤:直接重排、删除或改写实施步骤;
- 留下批注:添加内联问题或反馈(例如"等等,这里不应该复用现有的
Logger类吗?");
- 保存并关闭编辑器;
- 审阅与精化:Gemini CLI 自动检测变更、审阅你的批注,并调整实施策略,随后展示精化后的计划供最终批准。
批准动作的底层实现
ExitPlanModeTool 实现了批准环节的关键逻辑,与文档描述一一对应:
- 先通过
validatePlanPath/validatePlanContent校验计划文件路径与内容(validatePlanPath 校验); - 交互环境下弹出
type: 'exit_plan_mode'的 "Plan Approval" 确认框,携带planPath; - 批准后调用
config.setApprovalMode(newMode)与config.setApprovedPlanPath(resolvedPlanPath),并记录遥测事件logPlanExecution,返回内容明确要求模型"严格阅读并遵循计划"; - 若用户拒绝,会把反馈文本回传给模型:"Plan rejected. User feedback: ... Revise the plan based on the feedback."。
四、如何退出 Plan Mode
随时可以退出 Plan Mode(无论计划是否定稿):
- 批准计划:当 Gemini CLI 展示定稿计划时,批准即自动退出 Plan Mode 并开始实施;
- 键盘快捷键:
Shift+Tab切换到目标模式; - 自然语言:要求 "exit plan mode" 或 "stop planning"。
五、工具限制:策略引擎强制的只读白名单
Plan Mode 通过策略引擎执行严格的安全策略,防止意外变更。这些规则内置于 plan.toml(Tier 1 默认策略)。Plan Mode 下仅允许的工具如下:
| 类别 | 工具 | 说明 |
|---|---|---|
| 文件系统(读) | read_file、list_directory、glob |
只读访问 |
| 搜索 | grep_search、google_web_search、web_fetch、get_internal_docs |
web_fetch 需要显式确认 |
| 研究子代理 | codebase_investigator、cli_help |
内置研究子代理 |
| 交互 | ask_user |
需要确认 |
| MCP 工具(读) | 只读 MCP 工具(如 github_read_issue、postgres_read_schema)及核心 MCP 资源工具(list_mcp_resources、read_mcp_resource) |
默认需确认 |
| 计划(写) | write_file、replace |
仅允许写 plans 目录下的 .md 文件或自定义计划目录 |
| 技能 | activate_skill |
以只读方式加载专门指令与资源 |
plan.toml 的策略规则细节
从 plan.toml 源码可以看到这套白名单的完整实现逻辑:
- 模式转换规则(priority 50/70):
enter_plan_mode在交互环境下ask_user、非交互环境allow;在 Plan Mode 内重复调用会被deny并提示 "You are already in Plan Mode."。exit_plan_mode仅在 Plan Mode 内有效(交互ask_user/ 非交互allow),非 Plan Mode 调用会被拒绝:"You are not currently in Plan Mode. Use enter_plan_mode first to design a plan." - 兜底拒绝(priority 40):Plan Mode 下
toolName = "*"一律deny,拒绝消息明确告知"Plan Mode 只提供只读工具,脚本执行(包括来自技能的脚本)被阻止"。 - 只读 MCP 工具(priority 50):
toolAnnotations = { readOnlyHint = true }的 MCP 工具在交互环境下ask_user。 - 子代理解锁(priority 50):通过
argsPattern匹配invoke_agent的agent_name参数,仅放行codebase_investigator与cli_help。 - 计划文件写入(priority 70):共 10 条
argsPattern规则,分别覆盖"带/不带 session ID 的绝对路径、以.gemini、./.gemini开头的相对路径、纯文件名、plans/相对路径"等形态,且注释强调这些模式是"split、防路径穿越、防 ReDoS"的深度防御设计——只允许把计划写到~/.gemini/tmp/<project>/<session-id>/plans/(或无 session 的 plans 目录)内的.md文件。 - 其他写入显式拒绝(priority 65):不匹配上述模式的
write_file/replace被拒绝,消息为 "You are in Plan Mode and cannot modify source code. You may ONLY use write_file or replace to save plans to the designated plans directory as .md files."
文件头部的注释还说明了优先级分层体系:默认策略处于 Tier 1(1 + priority/1000),低于扩展(Tier 2)、工作区(Tier 3)、用户(Tier 4)、管理端(Tier 5),保证 Admin > User > Workspace > Extension > Default 的层级始终成立。相关行为由 enter-plan-mode.test.ts 与 exit-plan-mode.test.ts 等测试用例覆盖验证。
六、自定义与最佳实践
Plan Mode 默认安全,但可按工作流定制:用 skills 定制规划方式、用策略调整安全边界、改计划存储位置、或加 hooks。
1. 用 Skills 定制规划
可用 Agent Skills 定制 Gemini CLI 对特定任务类型的规划方式。技能在 Plan Mode 中被激活时,其专门指令与流程性工作流将指导研究、设计与计划阶段。典型例子:
- "Database Migration" 技能:确保计划包含数据安全校验与回滚策略;
- "Security Audit" 技能:在代码库探索阶段提示查找特定漏洞;
- "Frontend Design" 技能:引导使用特定 UI 组件与无障碍标准。
使用时可显式要求"use the <skill-name> skill to plan...",Gemini CLI 也可能基于任务描述自主激活(对应 activate_skill 工具的放行规则)。
2. 自定义策略
全局规则 vs 模式专属规则
按策略引擎文档的说明,任何未显式指定 modes 的规则都视为"始终生效",因此同样作用于 Plan Mode。为维护 Plan Mode 作为安全研究环境的完整性,持久工具批准是上下文感知的:在 Default 或 Auto-Edit 模式授予的批准不适用于 Plan Mode(研究阶段不会自动执行你在实施阶段信任的工具);而在 Plan Mode 内授予的批准被视为有意的全局信任选择,适用于所有模式。
若想让某规则仅作用于其他模式而不作用于 Plan Mode,必须显式指定目标 modes。例如让 npm test 在 default 与 Auto-Edit 模式可用、但 Plan Mode 不可用:
[[rule]]
toolName = "run_shell_command"
commandPrefix = "npm test"
decision = "allow"
priority = 100
# 省略 "plan",该规则在 Plan Mode 下不生效。
modes = ["default", "autoEdit"]
示例:自动批准只读 MCP 工具
默认情况下,只读 MCP 工具在 Plan Mode 需要用户确认。可用 toolAnnotations 与 mcpName 通配符定制,创建 ~/.gemini/policies/mcp-read-only.toml:
[[rule]]
toolName = "*"
mcpName = "*"
toolAnnotations = { readOnlyHint = true }
decision = "allow"
priority = 100
modes = ["plan"]
示例:允许 Plan Mode 内使用 git 命令
在 Plan Mode 查看仓库状态与变更,创建 ~/.gemini/policies/git-research.toml:
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["git status", "git diff"]
decision = "allow"
priority = 100
modes = ["plan"]
示例:启用自定义子代理
内置研究子代理(codebase_investigator、cli_help)在 Plan Mode 默认开启。可通过策略启用额外的自定义子代理。创建 ~/.gemini/policies/research-subagents.toml:
[[rule]]
toolName = "my_custom_subagent"
decision = "allow"
priority = 100
modes = ["plan"]
并在提示中告诉 Gemini CLI 可以使用它,例如:"You can check ongoing changes in git."
3. 自定义计划目录与策略
默认情况下,规划产物存储在项目之外的受管临时目录:~/.gemini/tmp/<project>/<session-id>/plans/。你可以在 settings.json 中配置自定义目录,例如存到项目内 .gemini/plans:
{
"general": {
"plan": {
"directory": ".gemini/plans"
}
}
}
源码层面,该目录由 getPlansDir() 解析:用户配置的自定义目录被限制在项目根目录之内——解析后的真实路径若不在项目边界内会直接抛出错误,防止自定义路径被用来逃逸并覆盖其他敏感文件。这正是文档中"为保持 Plan Mode 安全,计划目录受限"的实现依据。
使用自定义目录还需更新策略引擎配置,允许在该位置执行 write_file 与 replace。例如允许写入项目内 .gemini/plans,创建 ~/.gemini/policies/plan-custom-directory.toml:
[[rule]]
toolName = ["write_file", "replace"]
decision = "allow"
priority = 100
modes = ["plan"]
# 按自定义目录调整 pattern。
# 此示例匹配项目内 .gemini/plans 目录下的任意 .md 文件。
argsPattern = "\"file_path\":\"[^\"]+[\\\\/]+\\.gemini[\\\\/]+plans[\\\\/]+[\\w-]+\\.md\""
4. 结合 Hooks 使用 Plan Mode
可用 hook 系统 自动化规划工作流的环节,或在进出 Plan Mode 时强制额外检查:BeforeTool / AfterTool 可拦截 enter_plan_mode 与 exit_plan_mode 的工具调用。
注意:当 hooks 由工具执行触发时,如果你用
/plan命令或Shift+Tab快捷键手动切换 Plan Mode,hooks 不会运行。若需要 hooks 在模式变化时执行,须确保切换由 agent 发起(例如请求"start a plan for...")。
示例:把已批准的计划归档到 GCS(AfterTool)
如果组织策略要求保存所有执行计划记录,可用 AfterTool hook 在 Gemini CLI 退出 Plan Mode 开始实施时,将计划文件安全复制到 Google Cloud Storage。
.gemini/hooks/archive-plan.sh:
#!/usr/bin/env bash
# 从工具输入 JSON 中提取计划文件名
plan_filename=$(jq -r '.tool_input.plan_filename // empty')
# 利用 GEMINI_PLANS_DIR 环境变量构造绝对路径
plan_path="$GEMINI_PLANS_DIR/$plan_filename"
if [ -f "$plan_path" ]; then
# 用时间戳生成唯一文件名
filename="$(date +%s)_$(basename "$plan_path")"
# 后台上传到 GCS,避免阻塞 CLI
gsutil cp "$plan_path" "gs://my-audit-bucket/gemini-plans/$filename" > /dev/null 2>&1 &
fi
# AfterTool hooks 一般应放行流程
echo '{"decision": "allow"}'
在 settings.json 中注册该 AfterTool hook:
{
"hooks": {
"AfterTool": [
{
"matcher": "exit_plan_mode",
"hooks": [
{
"name": "archive-plan",
"type": "command",
"command": "~/.gemini/hooks/archive-plan.sh"
}
]
}
]
}
}
七、相关命令
/plan copy:把当前已批准的计划复制到剪贴板。
八、规划工作流(Planning Workflows)
Plan Mode 提供结构化研究与设计的"积木",这些积木以 extensions 的形式实现,组合核心规划工具 enter_plan_mode、exit_plan_mode 与 ask_user。
内置规划工作流
内置规划器采用自适应工作流:分析项目、通过 ask_user 与你讨论取舍、起草计划供你批准。
第三方规划工作流:Conductor
Conductor 是为 spec-driven development(规格驱动开发) 设计的规划工作流扩展,把工作组织为"tracks",并把持久化产物存放在项目的 conductor/ 目录:
- 自动化转换:通过
enter_plan_mode切换到只读模式; - 简化决策:用
ask_user做架构选择; - 维护项目上下文:利用自定义计划目录与策略把产物存放在项目目录;
- 交接执行:通过
exit_plan_mode转入实施阶段。
自建规划工作流
由于 Plan Mode 基于模块化积木构建,你可以把自定义规划工作流开发为 extension:
建议:自建规划工作流时可参考 Conductor 的实现方式。
以 Plan Mode 作为执行环境,你的自定义方法论可以在设计阶段强制只读安全,同时受益于高推理模型的自动路由。
九、自动模型路由(Automatic Model Routing)
使用 auto 模型 时,Gemini CLI 会根据任务当前阶段自动优化模型路由:
- 规划阶段:处于 Plan Mode 时,请求被路由到高推理 Pro 模型,确保稳健的架构决策与高质量计划;
- 实施阶段:计划被批准并退出 Plan Mode 后,CLI 检测到已批准计划的存在,自动切换到高速 Flash 模型,在按计划实施时获得更快、更响应的体验。
若高推理模型不可用或你无权访问,Gemini CLI 会自动静默回退到更快的模型,保证工作流不中断。该行为默认开启,可在设置中关闭(对应 settingsSchema 中的 modelRouting 项,默认 true):
{
"general": {
"plan": {
"modelRouting": false
}
}
}
十、清理(Cleanup)
默认情况下,Gemini CLI 会自动清理旧的会话数据,包括所有关联的计划文件与任务追踪器:
- 默认行为:会话(及其计划)保留 30 天;
- 配置:可通过
/settings命令(搜索 Enable Session Cleanup 或 Keep chat history)或settings.json文件定制,详见会话保留。
手动删除会一并移除所有关联产物:
- 命令行:
gemini --delete-session <index|id>; - 会话浏览器:按
/resume,定位到目标会话,按x。
注意:若使用了自定义计划目录,其中的文件不会被自动删除,需要自行管理。
十一、非交互执行
在非交互环境(headless 脚本或 CI/CD 流水线)中,Plan Mode 针对自动化工作流做了优化:
- 自动转换:策略引擎自动批准
enter_plan_mode与exit_plan_mode工具,无需用户确认(对应 plan.toml 中interactive = false的allow规则); - 自动化实施:退出 Plan Mode 执行计划时,Gemini CLI 会自动切换到 YOLO 模式而非标准 Default 模式,使 CLI 能自动执行实施步骤,而不会卡在交互式工具确认上。源码依据是 getAllowApprovalMode():非交互环境下策略放行
exit_plan_mode时,目标模式取ApprovalMode.YOLO;交互环境下则取ApprovalMode.DEFAULT。
示例:
gemini --approval-mode plan -p "Analyze telemetry and suggest improvements"
小结
Plan Mode 是 Gemini CLI 中"先规划、后执行"的安全边界:它以策略引擎(plan.toml 中的 40/50/65/70 优先级规则)强制只读白名单,以 enter/exit-plan-mode 工具 为转换枢纽,以 plans 目录下的 Markdown 文件为协作载体,再叠加 skills、自定义策略、hooks 与扩展机制实现深度定制;配合 Pro/Flash 自动模型路由,在质量与速度之间取得平衡。掌握 Shift+Tab、/plan [goal]、Ctrl+X、/plan copy 与 ~/.gemini/policies/*.toml 这几类手段,即可把规划阶段完整纳入个人与团队的工程工作流。
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