ByteNoteByteNote

字节笔记本

2026年8月29日

给 Gemini CLI 加一个 Plan Mode

API中转
¥120

Gemini CLI 以前一开口就可能改文件。Plan Mode 先把会话锁成只读:能读仓库、搜文档、问你确认,但不能动源码。方案对齐之后再批准执行。2026 年 1 月它还是周末原型,3 月写进官方博客,现在默认开着。

文档在 Plan Mode,仓库是 google-gemini/gemini-cli

它实际锁住了什么

Plan Mode 是一套审批策略,不是另起一个产品。进这个模式之后,模型只能用只读工具:

  • 读文件、列目录、glob、grep
  • 网页搜索;web_fetch 要你再点一次确认
  • 调研用子代理:codebase_investigatorcli_help
  • 只读 MCP(比如读 GitHub issue、看 Postgres schema)
  • ask_user:卡在分叉点时停下来问你
  • 写文件只允许落到计划目录里的 .md

write_file、改源码、跑会改状态的 shell,默认一律拦住。读类工具可以并行,调研会快一截。

怎么进去

已经装好 Gemini CLI 的话,不必再拉实验分支。当前版本默认带 Plan Mode,进法有几种:

  1. 会话里按 Shift+Tab,在 Default → Auto-Edit → Plan 之间轮换。状态栏会出现 planning 提示。CLI 正在跑工具或弹确认框时,这个快捷键会暂时从轮换里拿掉。
  2. 输入 /plan。后面可以跟目标,例如 /plan 给登录加上邮箱 OTP,会立刻切模式并把这句话交给模型。
  3. 直接说「先做个方案」或 start a plan for ...。CLI 会调 enter_plan_mode。YOLO 模式下这个工具不可用。
  4. 启动时加参数:
bash
gemini --approval-mode=plan

想每次打开都先调研,在会话里敲 /settings,把 Default Approval Mode 设成 Plan。对应配置是 general.defaultApprovalMode

json
{
  "general": {
    "defaultApprovalMode": "plan"
  }
}

不习惯这套流程,按 /settings 搜 Plan 关掉即可。关了之后 Shift+Tab 不再出现这一档,enter_plan_mode / exit_plan_mode 也不会再注册。

一次完整流程

目标说清楚就行,比如「把鉴权从 session cookie 迁到 JWT」。CLI 会先摸仓库:路由、中间件、现有测试、相关配置。摸的过程中可能用 ask_user 问你:兼容旧 cookie 多久、刷新令牌放哪、要不要顺手改文档。它会等你拍板,再写正式计划。

计划是一份 Markdown,默认落在 ~/.gemini/tmp/<session>/plans/。弹出来之后可以:

  • 直接读
  • Ctrl+X 用外部编辑器改步骤、留批注(这里用现成的 Logger,别再写一套)
  • 批准:自动接受编辑,或逐步确认
  • 在输入框里继续改需求,让它重写计划
  • Esc 取消

批注往往比再打一段自然语言准。存盘关编辑器后,CLI 会读你的改动,出一版新计划再让你批。批准即退出 Plan Mode,开始改代码。

想中途离开:再按 Shift+Tab,或说「退出 plan mode」。/plan copy 会把当前已批准的计划拷到剪贴板。

计划文件放哪

默认目录在用户目录的临时区,会话清理时一起删(默认留 30 天)。想把计划留在仓库里,方便评审或给下一个会话接着干,可以改到项目内:

json
{
  "general": {
    "plan": {
      "directory": ".gemini/plans"
    }
  }
}

自定义目录必须在项目根之内,防止写到仓库外面。换目录之后还要在 ~/.gemini/policies/ 里放一条策略,允许 Plan Mode 对这个路径做 write_file / replace,否则计划写不进去。项目内的计划不会被会话清理自动删,得自己管。

规划和落地用不同模型

开了 auto 模型时,Plan Mode 阶段会走推理更强的 Pro(文档举例是 Gemini 3.1 Pro),批准之后切到更快的 Flash 去改文件。Pro 不可用会静默回退,不会卡死。不需要这套切换:

json
{
  "general": {
    "plan": {
      "modelRouting": false
    }
  }
}

按项目改规则

默认只读策略写在内置的 plan.toml。自己的规则放 ~/.gemini/policies/,覆盖或放宽某一条。

调研时允许看 git 状态:

toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["git status", "git diff"]
decision = "allow"
priority = 100
modes = ["plan"]

只读 MCP 默认还要确认一次。团队里这些工具本来就是只读的,可以按注解放行:

toml
[[rule]]
toolName = "*"
mcpName = "*"
toolAnnotations = { readOnlyHint = true }
decision = "allow"
priority = 100
modes = ["plan"]

没写 modes 的规则会在所有模式生效,包括 Plan Mode。

只想在 Default / Auto-Edit 里允许测试命令、规划阶段继续禁 shell,就要显式写 modes。

别的模式里点过始终允许的工具,不会自动带到 Plan Mode。在 Plan Mode 里批准的,才会当成全局信任。

还可以用 Agent Skills 规定某一类任务怎么规划。对模型说用 database-migration 技能来做方案,计划里就会带上备份、回滚、数据校验这些步骤。Hooks 能挂在 enter_plan_mode / exit_plan_mode 上,比如批准之后把计划备份到对象存储。

脚本和 CI 里怎么用

无交互环境里,策略引擎会自动批准进入和退出 Plan Mode。退出去执行时会切到 YOLO,避免卡在确认框上。

gemini --approval-mode plan -p "Analyze telemetry and suggest improvements"

适合先出方案再自动落地的流水线。真要人工看计划,还是用交互会话。

这段功能是怎么来的

2026 年 1 月初,Dmitry Lyalin 用一个周末写出原型,开了 PR 15901:只读调研、Shift+Tab 切换、并行读工具、计划对话框。那份 PR 没有直接合入,作用是把交互定下来。正式实现随后推进,3 月 11 日 Google Developers Blog 宣布上线,后来改成默认开启。

更重的编排可以看 Conductor 扩展:按 track 存产物,规划阶段走只读,节点用 ask_user 确认。官方说会往内置模式收。

相关链接

先用 /plan 加一句真实任务走通调研、提问、改计划、批准。主路径稳了,再决定要不要默认进 Plan、要不要把计划目录挪进仓库。

分享: