☰
Kimi Code 计划模式全量提醒机制解析:Plan Mode Full Reminder 注入原理与工程实现
2026/9/29 2:27:23 网站建设 项目流程
  • AI Agent
  • 代码智能体
  • 人工智能
  • 大模型
  • CLI

【免费下载链接】kimi-code

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

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

计划模式(Plan Mode)是 Kimi Code 这类 Agent 系统中最关键的“先规划、后执行”约束机制:Agent 在进入该模式后只能读取代码、撰写计划,禁止修改系统,直到用户批准计划后才恢复全部能力。本文以 agent-core-v2 中plan-mode-full-reminder.md这一提示词文档为切入点,剖析它在 Kimi Code 中如何被注入到对话上下文、何时被选择为全量(full)而非稀疏(sparse)版本,以及它背后的计划文件、工具守卫与批准流程。读完本文,你将掌握计划模式提示词的完整链路:从文档内容 → 源码注入 → 上下文拼接 → 工具拦截,并理解其 dedup 与刷新策略的工程考量。

一、Full Reminder 文档:计划模式的核心行为契约

plan-mode-full-reminder.md是一份以“助手指令”形式书写的 Markdown 提示词文档,全文共 19 行,其作用是:当 Agent 刚进入计划模式(或长时间未收到提醒时),把完整的模式约束与工作流重新注入到对话上下文中。它包含两个层面的内容:

1.1 模式禁令(最高优先级约束)

文档开篇即声明计划模式下的“不可为”清单,并以“This supersedes any other instructions you have received”强调其优先级高于任何其他指令:

  • 禁止任何编辑:除非工具请求被明确批准(exception: the current plan file),否则不得对系统做任何修改;
  • 优先使用只读工具:Read、Grep、Glob 等;
  • Bash 仅在必要时使用,且遵循正常权限模式与规则;
  • TaskStop、CronCreate、CronDelete 在计划模式下被屏蔽:需要先调用ExitPlanMode才能使用。

值得注意的是,禁令的工程实现在planService.ts的guardToolExecution中得到了硬性落实:当plan状态非空(即计划模式激活)时,Write/Edit只有在对当前计划文件本身的写入时才会被event.allow()放行,其余一律event.veto()拒绝,并返回“Plan mode is active. You may only write to the current plan file… Call ExitPlanMode to exit plan mode before editing other files.”的拒绝消息;TaskStop、CronCreate、CronDelete同样被 veto,这正是文档中禁令的代码级落地。

1.2 五步工作流(Workflow)

Full Reminder 为 Agent 明确了进入计划模式后的操作次序:

  1. Understand—— 用 Glob、Grep、Read 探索代码库;
  2. Design—— 收敛出最佳方案,权衡取舍但目标是给出单一推荐;
  3. Review—— 重读关键文件以验证理解;
  4. Write Plan—— 用 Write 或 Edit 修改计划文件(文件不存在时先用 Write 创建);
  5. Exit—— 调用ExitPlanMode请求用户批准。

其中第 4 步“写计划文件”是计划模式的核心产物,第 5 步是唯一合法的“退出通道”。

1.3 多方案处理规则(Handling multiple approaches)

文档同时约束了“计划里出现多个方案”时的行为规范:

  • 最多保留2~3 个有实质差异的方案,不要用微小变体凑数;如果某个方案明显更优,只提出那一个;
  • 当最佳方案依赖用户偏好或未知约束时,先用AskUserQuestion澄清,而不是把所有选项丢给用户;
  • 把多方案通过options参数传给ExitPlanMode,让用户在批准时直接选择要执行哪个方案;
  • 严禁在计划里罗列多个方案却不传options—— 否则用户只能看到默认批准控件而无法选择具体方案。

这条规则的底层约束同样写死在exit-plan-mode.ts:options数组限制为 1~3 项,label 必须唯一、且不得使用保留的批准标签(Approve、Reject、Reject and Exit、Revise)。

1.4 回合收尾约束

文档还规定:每一回合必须以AskUserQuestion(澄清需求)或ExitPlanMode(请求批准)结束,不得以其他方式结束回合,且不得用文本或AskUserQuestion询问“计划是否批准”——那是ExitPlanMode的职责。

二、提醒家族的完整谱系:Full 与 Sparse、Reentry、Exit 的定位

Full Reminder 并非孤立存在,它与同目录下的其他提醒文档共同构成了一套分级注入体系(见injection/目录):

提醒文档触发场景内容定位
plan-mode-full-reminder.md首次进入 / 长时间未提醒 / 用户有新输入完整禁令 + 五步工作流 + 多方案规则,全文注入
plan-mode-sparse-reminder.md已注入过 full、间隔较短精简版:只提醒“模式仍激活、优先只读工具、只可写计划文件、用 AskUserQuestion / ExitPlanMode 结束回合”
plan-mode-reentry-reminder.md会话恢复时已有旧计划文件强调“先读旧计划文件 → 评估当前请求 → 同任务则更新、不同任务则重写”
plan-mode-inline-*-reminder.md三个变体宿主未提供计划文件路径时与上述三种场景一一对应的“无计划文件路径”版本
plan-mode-exit-reminder.md计划模式刚结束提示“只读与仅计划文件的限制已解除,按已批准计划继续执行”

这些变体全部通过planModeInjection.ts以?raw方式作为原始文本导入(第 9~15 行),再由PlanModeInjection服务按场景动态挑选。

三、注入决策引擎:planModeInjection.ts 如何挑选提醒

3.1 三种提醒 + 一个退出提醒的切换逻辑

PlanModeInjection以PLAN_MODE_INJECTION_VARIANT = 'plan_mode'注册进IAgentReminderService,每个回合开始时都会执行注入回调,其核心状态机如下:

  1. 计划模式未激活(plan.status()返回 null):若planWasActive状态为 false(从未激活过),返回undefined(不注入);若此前激活过,则把状态置回 false 并注入EXIT_REMINDER(计划模式已结束,恢复常规工具权限)。
  2. 计划模式激活但planWasActive仍为 false(首次进入):置状态为 true;若计划文件已有非空内容,返回reentryReminder(有旧计划的重新进入场景);否则返回fullReminder(全新计划场景)。
  3. 计划模式已激活且此前已注入过:调用planModeReminderVariant(injectedAt, history)决定本轮注入 full、sparse 还是不注入。

3.2 频率控制:dedup 与刷新阈值

planModeReminderVariant是提醒频率的核心算法,其中定义了三个关键常量:

  • PLAN_MODE_DEDUP_MIN_TURNS = 2:距上次注入至少经过2 个助手回合后,才允许注入稀疏提醒(sparse),避免同一上下文里刷屏;
  • PLAN_MODE_FULL_REFRESH_TURNS = 5:距上次注入经过5 个及以上助手回合时,重新注入全量提醒(full),防止长会话中模型遗忘计划模式约束;
  • 用户新输入(user 消息)会直接触发 full:算法从injectedAt + 1开始扫描历史,一旦遇到 user 角色消息即返回'full'。

判定逻辑可用伪代码概括:

injectedAt == null → full (本回合首次注入) 自 injectedAt 之后: 遇到 user 消息 → full (用户发起新请求) assistant 回合数 ≥ 5 → full (长时间未刷新,重新注入完整版) assistant 回合数 ≥ 2 → sparse (短间隔,只注入精简版) 否则 → null (太频繁,本轮不注入)

这一设计体现了典型的“记忆衰减”思想:刚注入时约束最新鲜(不重复注入),随回合推移约束逐渐“褪色”(先 sparse 维持存在感),达到阈值后再用 full 完整刷新。测试用例plan.test.ts的plan mode injection cadence描述块恰好验证了这套节奏:首次注入含Plan mode is active与Plan file:的 full 提醒 → 立即再次注入不重复(上下文长度不变)→ 追加 2 个助手回合后注入含Plan mode still active的 sparse 提醒 → 退出后只注入一次 exit 提醒。

3.3 计划文件路径页脚

fullReminder/sparseReminder/reentryReminder三个函数都会调用withPlanFileFooter:当存在计划文件路径时,在提醒正文后追加一行Plan file: <path>;当计划文件路径为空(宿主未提供)时,则改用对应的PLAN_MODE_INLINE_*_REMINDER内联版本——这也解释了为什么目录里同时存在“带路径”与“inline”两套文档。

四、计划文件生命周期:从创建、写入到版本快照

4.1 计划文件路径约定

根据planService.ts的planFilePathFor,计划文件固定存放在会话目录下:

<sessionDir>/agents/<agentId>/plans/<planId>.md

planId由generateHeroSlug(randomUUID(), new Set())生成(见createPlanId),enter()时会先ensurePlanDirectory递归创建目录,createFile为 true 时还会用writeEmptyPlanFile预创建一个空文件。

4.2 EnterPlanMode / ExitPlanMode 工具

PlanFeature注册了两个工具(domain 均为plan):

  • EnterPlanMode:参数为空对象(z.object({}).strict(),见enter-plan-mode.ts),执行时若计划模式已激活则报错,否则调用planMode.enter()并返回包含工作流指引的结果消息(含计划文件路径版本与无路径版本,见enterPlanModeTool.ts)。
  • ExitPlanMode:可选参数options(1~3 个方案,label 唯一且禁用保留词),执行时从计划文件读取计划内容而非接收参数,ExitPlanModeReview在非 auto 权限模式下把计划以plan_review展示交给用户批准,批准后输出Plan mode deactivated. All tools are now available.并附上已批准计划与“Selected approach”提示(当用户选择了某个 options 方案时)。

4.3 版本快照 recordRevision

每次调用ExitPlanMode前(见exitPlanModeTool.ts),AgentPlanService.recordRevision()会把当前计划文件内容以plan/<id>/v<version>.md的 key 存入 BlobStore,并派发PlanRevision事件记录版本号、sha256 与字节数(见planService.ts)。这意味着每次提交审批的计划都留有可追溯的不可变快照。

4.4 权限模式对流程的影响

全链路中权限模式(permission mode)是关键变量:

  • EnterPlanMode在所有权限模式下都是自动进入(无需批准提示);
  • ExitPlanMode在yolo 与 manual 模式仍会向用户呈现计划等待批准;在auto 模式下则直接读取计划文件、退出计划模式而不询问用户(见exit-plan-mode.md与exitPlanModeTool.ts的 auto 分支,输出中明确标注“auto-approved without user review”)。

五、审批结果处理:ExitPlanModeReview 的分支语义

ExitPlanModeReview.approvalResult对用户的审批响应做了精细分流:

用户操作结果语义
approved(批准)plan.exit()退出计划模式;若选了 options 中的方案,输出Selected approach: <label>\nExecute ONLY the selected approach...,明确禁止执行未被选中的备选方案
cancelled(取消/关闭弹窗)不退出,输出 “Plan approval dismissed. Plan mode remains active.”
Reject and Exit退出计划模式并 stopTurn,输出 “Plan rejected by user. Plan mode deactivated.”
Revise / 附带反馈不退出,把用户反馈原样返回给模型(“User rejected the plan. Feedback: ...”),或提示 “User requested revisions. Plan mode remains active.”
Rejected(普通拒绝)不退出、stopTurn,输出 “Plan rejected by user. Plan mode remains active.”

所有分支都会记录plan_resolved遥测事件(outcome 分别为approved、dismissed、rejected_and_exited、revise、rejected),为后续的流程分析提供数据基础。

六、从文档到上下文的完整注入链路

把全链路串联起来,一次完整的“计划模式体验”可以描述为:

  1. 用户在非平凡任务(新功能、多方案、架构决策、多文件改动等,判定标准见enter-plan-mode.md)中让 Agent 调用EnterPlanMode,AgentPlanService.enter()创建计划文件目录并派发plan_mode.enter事件;
  2. 下一回合开始时,PlanModeInjection回调被触发:plan.status()返回激活状态、planWasActive为 false,于是把full reminder(附Plan file: ...页脚)以origin: { kind: 'injection', variant: 'plan_mode' }的 user 消息形式拼接到上下文(测试快照中的<plan-mode-reminder>即此消息的占位,见plan.test.ts);
  3. Agent 按五步工作流操作:只读探索 → 设计 → 写计划文件;期间guardToolExecution持续拦截 Write/Edit/TaskStop/Cron* 等违规调用;
  4. 计划就绪后调用ExitPlanMode:记录计划版本快照 → 生成plan_review展示(options 可选)→ 用户批准/拒绝/修订;
  5. 批准后plan_mode.exit事件派发、遥测模式从plan切回agent;下一回合planWasActive为 true 且plan.status()为 null,注入exit reminder告知 Agent 恢复全部工具权限,随后继续执行已批准的计划。

七、工程启示:提示词注入设计要点

从plan-mode-full-reminder.md及其配套实现中,可以提炼出几条可复用的工程经验:

  1. 提示词即契约,代码即执行:文档中的禁令(只读、只写计划文件、屏蔽定时任务工具)与planService.ts的工具守卫一一对应,模型提示与硬性拦截双保险,避免模型“忘记规则”;
  2. 分级提醒对抗上下文衰减:full / sparse / reentry / exit 四档提醒 + 2/5 回合阈值,兼顾约束可见性与 token 成本,避免每回合重复注入完整长文;
  3. 内联变体兜底无路径场景:宿主未提供计划文件路径时自动降级为 inline 版本,保证不同宿主环境下的行为一致性;
  4. 所有状态变更可追溯:plan_mode.enter/exit/cancel、plan.revision均为 durable 事件,配合 BlobStore 版本快照,让计划流程可回放、可审计。

如需深入阅读源码,可重点关注以下文件:

  • 提醒文档全集:packages/agent-core-v2/src/features/plan/injection/
  • 注入决策引擎:planModeInjection.ts
  • 计划服务与守卫:planService.ts
  • 工具定义与批准流:exitPlanModeTool.ts、exitPlanModeReview.ts
  • 频率与场景测试:test/features/plan/plan.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
点击查看免费下载

相关推荐

上一篇:vue-vben-admin 组件设计指南:5 步用原子组件 + 组合式 API 搭出业务页面
下一篇:掌握HTMX hx-vals:POST请求数据处理的终极指南 🚀

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

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

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

立即咨询