Gemini CLI 实践指南:用 Plan Mode 加 Model Steering 实时驾驭复杂任务的规划过程
复杂任务的方案设计往往不是一次就能做对的:代理可能找错目录、漏掉关键依赖,或者在你还没看到方案时就选定了不合适的架构。Gemini CLI 提供了两个可以组合使用的机制——Plan Mode(只读的规划环境)与 Model Steering(执行中的实时提示注入)。本文以官方教程 plan-mode-steering.md 为主线,完整还原「启动任务 → 纠正调研 → 中途改设计 → 批准实现」的四步工作流,并结合仓库源码拆解一条 steering hint 从输入框到模型上下文的实际流转路径,帮助你掌握在规划阶段实时纠偏的实战方案。
需要说明的是:Model Steering 是实验性功能(experimental),默认关闭,且当前处于活跃开发中,可能需要通过 /settings 手动开启;Plan Mode 本身默认启用。
为什么要把 Plan Mode 和 Model Steering 组合使用
Plan Mode 是一个只读的设计环境:代理在其中研究代码库、评估权衡、起草实施计划,全程不改动任何代码。它的典型流程是线性的——调研、提出、起草(research, propose, draft)。线性的代价是:一旦代理在调研阶段走偏,你只能等它把这一轮完整跑完才能干预。
加入 Model Steering 后,这条线性路径变成了可实时干预的循环,带来三个直接收益:
- 引导调研方向:代理正在看错目录或漏掉关键依赖时,立刻纠正它;
- 起草中途迭代:代理还在写计划时,就提出更换架构模式的建议;
- 加速反馈循环:不必等一整轮调研结束再提供关键上下文。
这个组合在长时间运行的子代理(subagent)执行、复杂的规划工作流中尤其有用——这正是 model-steering.md 文档中明确指出的两个典型场景。
前置条件与开启方式
前置条件
- Gemini CLI 已安装并完成认证;
- Plan Mode 已在设置中启用(默认即为启用,可通过
/settings管理); - Model Steering 已在设置中启用(默认关闭,见下文)。
开启 Model Steering
Model Steering 属于实验性功能,配置项为 experimental.modelSteering。两种开启方式:
- 在 Gemini CLI 中输入
/settings,搜索 Model Steering,将值设为 true; - 在
settings.json中直接配置:
{
"experimental": {
"modelSteering": true
}
}
这个配置项在仓库中有完整的定义链,可以确认它的行为语义:
- 配置 Schema 定义在 settingsSchema.ts:类型为布尔值,标签 Model Steering,归类于 Experimental,默认
false,requiresRestart为false(即无需重启会话即可生效),描述为「Enable model steering (user hints) to guide the model during tool execution」(启用模型转向/用户提示,在工具执行期间引导模型); - CLI 配置层在 config.ts 中把
settings.experimental?.modelSteering读入核心配置; - 核心层 packages/core/src/config/config.ts 暴露
isModelSteeringEnabled()方法作为全局唯一的开关查询入口,UI 层的所有 steering 逻辑都依赖它。
Plan Mode 的进入方式
教程的第一步是进入 Plan Mode。按 plan-mode.md 文档,有三种进入方式:
- 启动参数:
gemini --approval-mode=plan一次性以 Plan Mode 启动; - 快捷键:按
Shift+Tab在审批模式间循环切换(Default→Auto-Edit→Plan); - 斜杠命令:在输入框输入
/plan [目标],例如/plan implement authentication,会切换模式并立即把提示词提交给模型。
四步实战:在规划中实时转向
以下完整还原教程中的场景:为代码库实现一个基于 Redis 的新通知服务。
Step 1:启动一个需要调研的复杂任务
进入 Plan Mode 并启动任务:
/plan I want to implement a new notification service using Redis.
Gemini CLI 进入 Plan Mode,开始研究现有代码库,确定新服务应该放在哪里。此时你会看到它陆续调用 list_directory、grep_search 等只读工具。
Step 2:纠正调研阶段的方向
观察代理的工具调用时,你发现它遗漏了关键上下文。操作:在 spinner 仍在转动(代理工作中)时,直接输入你的提示:
Don't forget to check packages/common/queues for the existing Redis config.
结果:Gemini CLI 会先确认收到你的提示(用一小段快速生成的应答消息),随即把它纳入调研。你会看到它在接下来的下一轮中就开始探索你指定的目录。
从源码看,「工作中输入不会打断会话,而是被识别为 hint」这一行为发生在 UI 层的提交入口处:AppContainer.tsx 中,当 isModelSteeringEnabled() 为真、代理正在运行(流式响应中或有工具在执行)且输入不是斜杠命令时,提交走的是 handleHintSubmit 路径而不是普通的 submitQuery。同时 AppContainer.tsx 会在工具执行期间把输入组件切到 hintMode,输入框进入专门的 hint 缓冲状态——这就是「看到 spinner 就打字」这个交互在实现上的对应物。
Step 3:起草中途修正设计
调研结束后,代理开始起草实施计划。如果你发现它提出的设计与目标不符(比如它打算用简单队列而不是 Pub/Sub),立即纠正:
Actually, let's use a Publisher/Subscriber pattern instead of a simple queue for this service.
结果:代理会停止起草当前版本,基于你的反馈重新评估设计,然后开始一份使用 Pub/Sub 模式的新草案。这正是 Model Steering 文档描述的「分类更新」能力——内部注入的指令会要求模型把新提示分类为「新任务」或「补充上下文」,并对受影响的计划做最小差异(minimal-diff)修改。
Step 4:批准并进入实现
当代理用你的多条提示打磨出满意的计划后,审阅最终的 .md 计划文件(默认存放在 ~/.gemini/tmp/<project>/<session-id>/plans/ 目录,可用 Ctrl+X 在外部编辑器中打开查看或修改)。操作:
Looks perfect. Let's start the implementation.
Gemini CLI 退出 Plan Mode,转入实现阶段。由于计划已经过实时反馈打磨,代理执行每一步的置信度更高、出错更少。
补充一点:如果使用的是 auto 模型,Plan Mode 还会自动做模型路由——规划阶段路由到高推理能力的 Pro 模型,计划批准后自动切换到高速 Flash 模型执行实现,可通过 general.plan.modelRouting: false 关闭。
Hint 的底层流转:从输入框到模型上下文
教程描述的行为(确认收到 → 注入下一轮 → 模型重新评估)在源码中有一条清晰的实现链,值得了解以建立对功能边界的准确预期:
- 提交判定:AppContainer.tsx 中先判断输入是否为斜杠命令(斜杠命令不走 hint 路径,除非是支持并发执行的 safe 命令),再判断 steering 是否开启且代理是否正在运行,满足条件则调用
handleHintSubmit并返回,不进入常规查询队列。 - 注入时机:pending hint 不会凭空插入正在进行的流式响应,而是在合适的边界消费。AppContainer.tsx 中的效果会在配置就绪、steering 开启、流式状态回到 Idle 且 MCP 就绪时,通过
consumePendingHints()取出待处理提示,并用buildUserSteeringHintPrompt(pendingHint)包装后以submitQuery提交。 - 流式中的注入:工具执行间隙(useGeminiStream.ts 中同样出现
buildUserSteeringHintPrompt(hintText)),hint 也能在工具调用轮次之间送达,实现「调研下一轮立刻生效」的效果。 - 包装逻辑:
buildUserSteeringHintPrompt会在你的原文前追加一段内部指令,要求主代理重新评估当前计划、把更新分类(新任务 / 额外上下文)、对受影响任务做最小差异修改——这与 model-steering.md 文档「How it works」一节的三步描述(即时确认、上下文注入、下一轮实时更新)一一对应。 - 确认消息:文档说明确认由一个小的快速模型生成一句话应答;UI 侧的提示呈现则由
HintMessage组件(HintMessage.tsx)渲染。
由于 hint 最终是作为用户侧输入进入模型上下文的,它受与正常输入相同的策略与安全约束;steering 本身不提供绕过 Plan Mode 只读限制的能力。
编写有效 Hint 的要点
教程给出的三条原则,结合 model-steering.md 中的通用用例,可以整理成一份速查表:
| 原则 / 用例 | 反例 | 正例 |
|---|---|---|
| 具体明确(Be specific) | "do it differently" | "use the existing Logger class in src/utils" |
| 纠正路径(Correcting a path) | — | "Actually, the utilities are in src/common/utils." |
| 跳过步骤(Skipping a step) | — | "Skip the unit tests for now and just focus on the implementation." |
| 补充上下文(Adding context) | — | "The User type is defined in packages/core/types.ts." |
| 重定向努力(Redirecting the effort) | — | "Stop searching the codebase and start drafting the plan now." |
| 处理歧义(Handling ambiguity) | — | "Use the existing Logger class instead of creating a new one." |
| 尽早转向(Steer early) | 等最终计划完成再反馈 | 在调研阶段就给出提示,效率更高 |
| 传递代码外知识(Use for context) | — | "We are planning to deprecate this module next month"(这类信息读代码读不出来) |
核心思想:steering hint 的价值在于把「代码里读不出来的知识」和「你比代理更早看到的问题」以最低延迟送入规划循环,越早转向,废弃的无效调研越少。
行为验证:测试与评估如何覆盖这条链路
如果你想知道这些行为是否被自动化测试锁定,可以在仓库中查看:
- 集成测试 modelSteering.test.tsx 以
configOverrides: { modelSteering: true }启动 App 级测试,验证开启 steering 后的交互行为; - 行为评估 model_steering.eval.ts 对 steering 能力做端到端评估,覆盖提示注入后模型是否按提示调整行为;
- UI 侧 AppRig.test.tsx 中同样以
modelSteering: true构造测试环境,验证 hint 交互的组件级表现; - Plan Mode 侧则有 plan-mode.test.ts 覆盖模式的进入、计划生成与退出流程。
小结与后续探索
把本文的实践路径压缩成一句话:开启 experimental.modelSteering,用 /plan <目标> 进入只读规划环境,在 spinner 转动时把具体、简短的提示直接打进输入框,让模型在下一轮就重新评估计划,最后审阅并批准打磨过的计划文件进入实现。 这样得到的实施计划是「设计阶段即对齐」的,而不是「事后返工」的。
后续可以继续深入:
- Plan Mode 完整文档:工具白名单、自定义策略(policy engine 的
plan.toml)、自定义计划目录、hooks 归档等; - Model Steering 参考文档:常见用例与内部机制细节;
- Agent Skills:为规划轮次注入领域专业知识,与 steering 互补——skills 解决「代理不知道怎么做」,steering 解决「代理此刻走偏了」。
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 StartedRust0622
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