☰
Kimi Code 的 EnterPlanMode 工具:进入 Plan 模式的时机判断与底层实现
2026/9/28 2:35:35 网站建设 项目流程
  • AI Agent
  • 代码智能体
  • 人工智能
  • 大模型
  • CLI

【免费下载链接】kimi-code

Kimi Code CLI — The Starting Point for Next-Gen Agents

项目地址:https://gitcode.com/gh_mirrors/ki/kimi-code
点击查看免费下载

导读

在 Kimi Code(agent-core-v2包)的 Agent 体系中,EnterPlanMode是一个由模型主动调用的工具(tool),用于在开始非平凡(non-trivial)实现任务前先进入"计划模式"(Plan Mode),让用户先行确认实现思路,从而避免盲目写代码造成返工。本文以 enter-plan-mode.md 为骨架,完整讲解它的适用条件、反例场景、与权限模式(manual / auto / yolo)的交互,以及从EnterPlanModeTool到AgentPlanService、计划文件落盘和只读守卫的源码级实现原理。读完你可以准确掌握:什么时候该触发计划模式、进入后 Agent 被强制约束为只读、以及它与ExitPlanMode如何构成完整的工作流闭环。

一、工具定位:写代码前的"方案确认闸门"

EnterPlanMode是agent-core-v2中plan功能域(Feature)注册的两个工具之一,与 ExitPlanMode 成对出现。注册逻辑位于 planFeature.ts:

export class PlanFeature extends Feature { static override readonly name = 'plan'; constructor() { super(); this.contributeAgentService(IAgentPlanService, AgentPlanService); this.contributeTool(IEnterPlanModeTool, EnterPlanModeTool, { name: 'EnterPlanMode', domain: 'plan', }); this.contributeTool(IExitPlanModeTool, ExitPlanModeTool, { name: 'ExitPlanMode', domain: 'plan', }); } }

从工具契约看,EnterPlanMode是一个零参数工具:其输入 schema 定义为z.object({}).strict()(见 enter-plan-mode.ts),也就是说模型调用它时不需要携带任何参数,进入计划模式本身即是全部意图。它的英文描述直接内嵌为工具描述(import DESCRIPTION from './enter-plan-mode.md?raw'),这正是本文所依托文档的原始用途——这段 Markdown 就是 Agent 的 system prompt 中该工具的说明文本。

二、何时应该调用 EnterPlanMode(完整条件清单)

原文档明确了七类应当主动使用EnterPlanMode的场景,全部属于"开始非平凡实现任务"的范畴:

  1. 新功能实现(New Feature Implementation):例如"为 API 增加缓存层",涉及新增逻辑与数据流,先确认方案价值高。
  2. 存在多种可行方案(Multiple Valid Approaches):例如"优化数据库查询"至少存在加索引、重写查询、引入缓存三条路线,先让用户拍板可以避免选错方向。
  3. 代码修改(Code Modifications):例如"重构 auth 模块以支持 OAuth",改动面广、影响既有行为。
  4. 架构决策(Architectural Decisions):例如"为服务增加 WebSocket 支持",属于结构级变更,牵一发动全身。
  5. 多文件改动(Multi-File Changes):涉及超过 2~3 个文件的改动,单凭直觉推进很容易顾此失彼。
  6. 需求不明确(Unclear Requirements):需要先探索(exploration)才能弄清范围的任务,先进入只读探索环境是安全的选择。
  7. 用户偏好影响方案(User Preferences Matter):如果用户的输入会实质性地改变实现方式,应使用EnterPlanMode把决策结构化,而不是边写边猜。

同时原文档也划定了不应该使用的反例:

  • 单行或几行的修复(拼写错误、显而易见的 bug、小调整);
  • 用户已给出非常具体、详尽的指令;
  • 纯研究 / 探索类任务(searching files、reading code、理解代码库时不要调用计划工具,这一点在 exit-plan-mode.md 中也有同样强调)。

一句话概括判断标准:只要"先想清楚再做"带来的收益大于进入计划模式的开销,就应该用EnterPlanMode;反之,改动足够小、方向足够明确时直接动手。

三、与权限模式的交互规则

原文档给出了三条与权限模式(permission mode)相关的关键说明。权限模式本身由defaultPermissionMode配置项控制,可选值为manual、auto、yolo(见 configSection.ts):

  • 进入不受审批:在所有权限模式下,EnterPlanMode都会自动进入计划模式,不会弹出审批提示。这一点可以从 enterPlanModeTool.ts 看到:resolveExecution直接调用planMode.enter(),没有任何审批流程,并记录plan_enter_resolved / outcome: 'auto_approved'遥测事件。
  • 退出仍要审批:在yolo和manual模式下,ExitPlanMode依然会把计划呈现给用户审批;auto模式下ExitPlanMode则直接退出计划模式、不询问用户。对应实现见 exitPlanModeTool.ts:当permissionMode.mode === 'auto'时输出auto-approved结果并附带"用户尚未显式批准"的提醒,否则走正常审批分支。
  • auto 模式下的取舍:在auto模式下不要用AskUserQuestion询问,而是根据已有上下文做出最佳决策。
  • 仅当规划本身有价值时才使用:EnterPlanMode不是每次任务都要走的仪式,规划本身也要"算账"。

四、进入计划模式后的完整工作流

4.1 计划文件与只读约束

一旦进入计划模式,Agent 就处于只读状态。核心约束由 AgentPlanService 中的guardToolExecution(planService.ts)强制执行,它在每个工具执行前挂钩(hook)检查:

  • Write/Edit:只允许写当前计划文件(writesOnlyPlanFile判断所有写访问是否都指向计划文件路径),否则直接否决(veto)并返回"Plan mode is active. You may only write to the current plan file..."的拒绝消息;
  • TaskStop:计划模式下不可用,必须先ExitPlanMode;
  • CronCreate/CronDelete:同样被否决,因为它们会变更计划退出后仍要运行的后台任务。

计划文件保存在会话目录下的固定路径中:{sessionDir}/agents/{agentId}/plans/{id}.md(见 planService.ts),id由generateHeroSlug(randomUUID(), ...)生成(planService.ts)。

4.2 工作流五步法

原文档及进入计划模式后的返回消息共同勾勒出标准流程:

  1. 理解(Understand):使用Read、Grep、Glob等只读工具探索代码库;仅在必要时使用Bash(且Bash仍遵循正常权限模式规则)。
  2. 设计(Design):收敛出最佳方案,权衡取舍但尽量给出单一推荐;若存在 2~3 个真正有意义的备选方案,则把它们作为options参数传给ExitPlanMode,让用户在审批时选择。
  3. 复核(Review):重读关键文件验证理解正确。
  4. 写计划(Write Plan):用Write(计划文件尚不存在时)或Edit修改计划文件。计划应列出具体、可验证、落地于真实代码的步骤(真实文件、函数、命令,按合理顺序),避免"improve performance"这类空话。
  5. 退出(Exit):调用ExitPlanMode请求用户批准。

在计划模式下,模型回合只能以AskUserQuestion(澄清需求/偏好)或ExitPlanMode(请求批准)结尾,不得以其他方式结束回合。注意:AskUserQuestion只用于澄清影响方案的需求,绝不能用来问"这个计划 OK 吗"——那是ExitPlanMode的职责;同理也不要问"我该继续吗"。

4.3 进入后的提醒注入机制

为了让模型在整个计划期间不"忘记"自己的只读身份,系统通过 PlanModeInjection 向上下文注入计划模式提醒(reminder)。该机制会按回合数动态选择提醒密度(planModeInjection.ts):

  • 首次进入且计划文件为空时,注入完整版提醒(full reminder),见 plan-mode-full-reminder.md,其中明确写道:"Plan mode is active. You MUST NOT make any edits (with the exception of the current plan file)...",并重申TaskStop、CronCreate、CronDelete被封锁;
  • 若计划文件已有内容(例如从历史会话恢复),注入 re-entry 提醒;
  • 持续处于计划模式时,按去重间隔(PLAN_MODE_DEDUP_MIN_TURNS = 2)与完整刷新间隔(PLAN_MODE_FULL_REFRESH_TURNS = 5,planModeInjection.ts)在 sparse 与 full 变体之间切换;
  • 退出计划模式后,下一次提醒注入会切换为 plan-mode-exit-reminder.md,提示模型约束已解除。

五、EnterPlanMode 的源码执行链路

EnterPlanMode的完整调用链可以从 enterPlanModeTool.ts 追踪:

  1. 幂等检查:先查询planMode.status();若当前已有活动计划(before !== null),直接返回错误"Plan mode is already active. Use ExitPlanMode when the plan is ready.",防止重复进入。
  2. 执行进入:调用planMode.enter();AgentPlanService.enter(id, createFile)(planService.ts)会确保计划目录存在、派发PlanModeEnter事件并切换到plan遥测模式;若指定createFile则写入空计划文件。若中途失败,会回滚(cancel(id))。
  3. 遥测记录:记录plan_enter_resolved / outcome: auto_approved。
  4. 返回引导消息:enteredPlanModeMessage(after?.path)(enterPlanModeTool.ts)根据是否有计划文件路径返回两种消息:有路径时提示"3. Write the plan to the plan file with Write or Edit.";无路径(宿主未提供计划文件)时提示"Wait for the host to provide a plan file path before calling ExitPlanMode",并明确Do NOT use Write or Edit。

状态管理层面,planKey状态(planOps.ts)通过PlanModeEnter/PlanModeCancel/PlanModeExit/PlanRevision四个持久化(durable)事件驱动,active标志与id一起被持久化,因此计划模式可以跨会话恢复。退出后ExitPlanMode还会调用recordRevision()(planService.ts)把计划文件内容按版本存入 BlobStore(key 形如plan/{id}/v{n}.md,同时记录 sha256 与字节数),形成可审计的修订历史。

六、测试验证与可靠性保障

agent-core-v2的测试套件覆盖了EnterPlanMode的关键行为:

  • plan.test.ts(约 950 行)系统验证了AgentPlanService的进入、退出、取消、清空、状态查询、修订记录、计划文件读写约束以及跨会话恢复(expectResumeMatches)等行为;
  • plan-tools-telemetry.test.ts 验证进入 / 退出计划模式时plan_enter_resolved、plan_submitted、plan_resolved等遥测事件的落点;
  • 权限策略相关测试(如 default-tool-approve.test.ts、permissionPolicyService.test.ts)覆盖了EnterPlanMode在不同权限模式下的审批差异;
  • loop.test.ts 与 resume.test.ts 则验证了计划模式在主循环中及会话恢复场景下的行为一致性。

七、最佳实践小结

把原文档的边界条件与源码实现结合起来,可以提炼出以下可执行的判断框架:

场景是否进入计划模式理由
新功能 / 架构决策 / 多文件改动✅ 调用EnterPlanMode方案确认收益大,避免返工
存在多种可行方案且方向未定✅ 调用EnterPlanMode用AskUserQuestion澄清后写单一推荐计划,或以options参数呈现 2~3 个备选
需求不明确、需先探索代码库✅ 调用EnterPlanMode天然处于只读环境,安全探索
单行修复 / 明显 bug / 小调整❌ 直接执行计划开销大于收益
用户已给出非常具体的指令❌ 直接执行无需再确认方向
纯研究 / 阅读代码任务❌ 直接执行不产生变更,计划无意义

进入计划模式后请记住三个"红线":只能写计划文件(其余Write/Edit会被否决);TaskStop、CronCreate、CronDelete被封锁;回合必须以AskUserQuestion或ExitPlanMode收尾。遵循这套流程,EnterPlanMode→ 只读探索 → 写计划文件 →ExitPlanMode审批,就构成了 Kimi Code Agent 中可控、可审计、可恢复的"先规划后动手"闭环。

相关文件索引

  • 工具描述文档(本文骨架):enter-plan-mode.md
  • 工具实现:enterPlanModeTool.ts / enter-plan-mode.ts
  • 配套退出工具:exit-plan-mode.md / exitPlanModeTool.ts
  • 计划服务与状态:planService.ts / planOps.ts / plan.ts
  • 提醒注入:planModeInjection.ts 与 plan-mode-full-reminder.md
  • 功能注册与配置:planFeature.ts / configSection.ts
  • 测试:plan.test.ts / plan-tools-telemetry.test.ts
  • AI Agent
  • 代码智能体
  • 人工智能
  • 大模型
  • CLI

【免费下载链接】kimi-code

Kimi Code CLI — The Starting Point for Next-Gen Agents

项目地址:https://gitcode.com/gh_mirrors/ki/kimi-code
点击查看免费下载

相关推荐

上一篇:claude-seo 图片生成提示词工程实战:6 组件推理简报、领域模式库与 Gemini 提示词优化指南
下一篇:jnv在微服务架构中的应用:API响应处理方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询