ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kimi Code TodoList 工具与进度追踪机制:从写入提醒到陈旧提醒的完整实现解析

Kimi Code TodoList 工具与进度追踪机制:从写入提醒到陈旧提醒的完整实现解析 AI Agent代码智能体人工智能大模型CLI【免费下载链接】kimi-codeKimi Code CLI — The Starting Point for Next-Gen Agents项目地址https://gitcode.com/gh_mirrors/ki/kimi-code点击查看免费下载本文围绕 agent-core-v2 中TodoList工具及其配套的“写入提醒write reminder”机制展开先讲清楚该工具的调用约定与三种使用模式再深入剖析写入提醒文本如何被拼装进工具输出、以及“陈旧提醒stale reminder”如何独立于工具本身在 Agent 循环中工作。读完你可以掌握一套自洽的进度追踪设计什么时候该用 TodoList、怎么写、写完后模型会被灌输什么约束、以及长期不更新时系统如何自我纠正。一、背景为什么 Agent 需要一张 TODO 列表Kimi Code 的核心是让大模型 Agent 在长链路任务中自主规划与执行。这类任务往往跨越数十次工具调用先搜索代码库、再读文件、然后连续编辑、最后跑测试验证。如果 Agent 只凭上下文记忆推进很容易在中途丢失目标、重复做已完成的步骤或者在收尾时漏掉关键检查。TodoList工具位于 todoListTool.ts正是为此设计的结构化进度跟踪设施。它由 TodoFeature 注册贡献了AgentTodoService作为 Agent 级服务并以{ name: TodoList, domain: todo }的方式向 Agent 暴露工具。与许多“一次性问答”不同TodoList 的生命周期贯穿整个会话——Agent 可以反复调用它来查询、替换或清空任务列表。在本仓库中与 TodoList 相关的文档文件有三份本文聚焦其中的核心约束文本todo-list-write-reminder.md写入提醒一行强制性的进度追踪行为约束todo-list.md工具主描述使用时机、反例与最佳实践todoListReminder.ts陈旧提醒当列表长期未更新时的主动干预逻辑。二、写入提醒TodoList 每次写操作后附带的硬约束2.1 提醒文本的原始内容todo-list-write-reminder.md 全文仅一行却承载了 Agent 进度追踪的三大纪律Ensure that you continue to use the todo list to track progress. Mark tasks done immediately after finishing them, and keep exactly one task in_progress when work is underway.可以拆解为三层要求持续使用继续用 todo list 跟踪进度不要写一次就丢下即时完成任务一做完就立刻标记为done不要攒到结尾批量更新单一进行中只要有工作在推进就恰好保持一个任务处于in_progress。这条文本的定位不是工具描述而是“写操作后的行为提醒”只在更新列表时出现避免在查询、清空等场景下重复噪音。2.2 提醒如何被注入工具输出在 todoListTool.ts 中这份 Markdown 以原始文本?raw方式导入import DESCRIPTION from ./todo-list.md?raw; import TODO_LIST_WRITE_REMINDER from ./todo-list-write-reminder.md?raw;execute逻辑里只有当替换后的列表非空时提醒才会被拼接到输出末尾const stored this.todo.get(); const output stored.length 0 ? Todo list cleared. : Todo list updated.\n${renderTodoList(stored)}\n\n${TODO_LIST_WRITE_REMINDER.trim()};也就是说更新列表 → 输出新列表 → 追加写入提醒。清空列表stored.length 0时只返回Todo list cleared.不带提醒——因为此时已无任务在推进提醒不再适用。2.3 工具输入契约与三种模式工具的参数由 todo-list.ts 中的 Zod Schema 定义const TodoItemSchema z.object({ title: z.string().min(1).describe(Short, actionable title for the todo.), status: z.enum([pending, in_progress, done]).describe(Current status of the todo.), }); export const TodoListInputSchema: z.ZodTypeTodoListInput z.object({ todos: z .array(TodoItemSchema) .optional() .describe(The updated todo list. Omit to read the current todo list without making changes. Pass an empty array to clear the list.), });由此形成三种调用模式与 todo-list.md 中的说明一一对应模式传参方式行为输出查询query省略todos参数读取当前列表不修改Current todo list: 列表项写入writetodos: [...]传入完整列表整体替换旧列表Todo list updated. 列表 写入提醒清空cleartodos: []空数组清空列表Todo list cleared.值得强调的是“整体替换”语义execute中args.todos.map(...)会把整个输入列表转换为TodoItem[]再通过this.todo.replace(next)一次写入见 todoListTool.ts。Agent 每次写操作都必须提交完整的新列表而非增量 diff——这与后续“陈旧列表应整体重写”的提醒逻辑是自洽的。resolveExecution还会根据参数形态生成面向用户的执行描述供审批/界面展示const description args.todos undefined ? Reading todo list : args.todos.length 0 ? Clearing todo list : Updating todo list;2.4 状态枚举与渲染格式状态值由 todoItem.ts 定义严格限定为三值枚举export type TodoStatus pending | in_progress | done;渲染时每个任务使用方括号标记与枚举值完全一致Current todo list: [pending] Read session-control.ts [in_progress] Add planMode flag to TurnManager [done] Fix flaky test in replay-adapter测试 todo-list.test.ts 专门断言了这一点标记必须是[done]而绝不是[completed]第 100-114 行保证模型看到的状态标签与 Schema 枚举严格对应避免别名歧义。2.5 测试对写入提醒的验证todo-list.test.ts 的第 71-98 行完整覆盖了写入模式的行为关键断言包括输出包含Todo list updated与新列表的渲染结果[pending] first、[in_progress] second输出必须包含写入提醒原文的两处关键片段Ensure that you continue to use the todo list to track progress.与exactly one task in_progress写操作对输入做了防御性拷贝测试在调用后修改原input数组input[0] { title: leaked, status: done }而存储中的列表不受影响验证了todos.map((todo) ({ ...todo }))的浅拷贝隔离。此外查询模式测试第 54-69 行确认不带todos参数时列表不被修改清空模式测试第 116-129 行确认输出为Todo list cleared.且不带提醒。三、使用纪律何时该用、何时不该用、如何避免扰动todo-list.md 是工具暴露给模型的主描述它把使用时机讲得非常具体这里结合源码逐条展开。3.1 应该使用的场景When to use跨多次工具调用的多步任务一旦任务会拆成多个工具调用就值得开始跟踪大规模代码库搜索中的调查进度检索、读文件、记录结论的推进过程在一批编辑之前规划步骤顺序先立列表再动手收到新的多步指令后立即把需求转写成 todo 条目开始被跟踪的任务前恰好标记一个条目为in_progress完成一个被跟踪的任务后立刻标记为done不要在结尾批量补标。其中“即时标记 done、禁止批量补标”正是写入提醒中Mark tasks done immediately after finishing them的呼应——工具描述与写入提醒在语义上互为强化。3.2 不应该使用的场景When NOT to use一两次工具调用就能完成的一次性回答琐碎请求跟踪本身不增加清晰度纯对话或纯信息性回复。这条边界很重要TodoList 不是“每次会话都必须调用”的仪式而是“多步工作时的脚手架”。误用反而会稀释进度信息的信号价值。3.3 避免扰动Avoid churn不要无意义重调用上次调用后没有实质进展就不要再次调用只在真实推进后更新不确定状态先查询拿不准当前列表时先用查询模式省略todos看一眼再决定如何更新卡住时如实告知如果没有可用工具能推进任何任务就向用户说明卡点而不是反复重排相同的 todo。“先查询再更新”在实现上有天然支撑查询模式走this.todo.get()只发送todo.used事件并读取状态不触发任何写存储事件见 todoService.ts因此零副作用。3.4 标题与状态的最佳实践标题保持简短、可执行例如Read session-control.ts、Add planMode flag to TurnManager而不是空泛的Do stuff随着进展持续更新状态工作中恰好保持一个in_progress只有真正完成才标记done——测试失败、实现不完整、错误未解决、或所需文件/依赖找不到时一律不得标记 done遇到阻塞时保持该任务in_progress或新增一条pending任务描述“必须先解决什么”。最后两条是防止“虚假完成”的护栏模型不得把未验证的工作标记为完成这直接保护了长任务的最终质量。四、陈旧提醒当 Agent 忘了更新时系统如何自我纠正写入提醒是“写操作附带”的约束但若 Agent 写了列表之后就再也不碰它约束就失效了。为此agent-core-v2 在工具之外实现了一个独立的**陈旧提醒stale reminder**机制实现在 todoListReminder.ts。4.1 触发条件const TODO_LIST_REMINDER_TURNS_SINCE_WRITE 10; const TODO_LIST_REMINDER_TURNS_BETWEEN_REMINDERS 10; export function todoListStaleReminder(input: TodoListReminderInput): string | undefined { if (!input.active) return undefined; const counts getTodoListReminderTurnCounts(input.history); if ( counts.turnsSinceLastWrite TODO_LIST_REMINDER_TURNS_SINCE_WRITE || counts.turnsSinceLastReminder TODO_LIST_REMINDER_TURNS_BETWEEN_REMINDERS ) { return undefined; } return renderTodoListReminder(input.todos); }两个阈值均为 10距上次写列表超过 10 轮、且距上次提醒也超过 10 轮才输出提醒。这样既不会在刚写过之后立刻烦扰模型也避免了每轮都重复提醒。4.2 如何从历史中统计轮数getTodoListReminderTurnCounts从上下文历史末尾向前扫描遇到 assistant 消息时若其中包含对TodoList工具的调用且参数里带todos数组hasTodoListWrite判定记为“上次写入”否则turnsSinceLastWrite递增遇到来源为injection、变体为todo_list_reminder的消息isTodoListReminder判定记为“上次提醒”否则turnsSinceLastReminder递增两者都找到后提前退出。这里有个值得注意的细节查询模式不带todos参数不计入写入因为hasTodoListWrite要求Array.isArray(args.todos)为真。也就是说只有真正改动列表的调用才会重置“写入时钟”。4.3 提醒文案与装配let message The TodoList tool has not been updated recently. If you are working on tasks that benefit from progress tracking, consider using TodoList to update task status. Also consider clearing or rewriting the todo list if it has become stale and no longer matches the current work. Only use it if relevant. This is a gentle reminder; ignore it if not applicable. Make sure that you NEVER mention this reminder to the user.;要点措辞是温和建议gentle reminder明确允许忽略ignore it if not applicable明确要求模型永远不要向用户提及该提醒——提醒属于系统内部自我纠正不应暴露给用户若列表非空会附上当前列表编号 [状态] 标题格式让模型知道哪些任务已陈旧“考虑清空或重写列表”与工具“整体替换”的写语义配合既然写入是整体替换那么清理陈旧列表最自然的动作就是提交一份新的完整列表。4.4 提醒的注入与激活条件提醒通过IAgentReminderService注册并受工具策略控制见 todoService.tsconst injector input.runtime.get(IAgentReminderService); const memory input.runtime.get(IAgentContextMemoryService); const toolPolicy input.runtime.get(IAgentToolPolicyService); const registration injector.register(TODO_LIST_REMINDER_VARIANT, () todoListStaleReminder({ active: toolPolicy.isToolActive(TODO_LIST_TOOL_NAME, builtin), history: memory.get(), todos: input.runtime.getState(), }), );只有满足三个条件时提醒才会真正产生当前 Agent 是主 AgentagentId MAIN_AGENT_ID见同文件第 50 行子 Agent 不触发TodoList工具在工具策略中处于 activebuiltin 域——工具被禁用时提醒自然关闭历史统计满足上面提到的双 10 轮阈值。xstate 状态机todoActorLogic管理整个生命周期beforeRestore → active → reminding。列表一旦被使用todo.used事件由get()/replace()/clear()触发就进入reminding状态启动提醒回调会话恢复时若此前已使用过used true同样直接进入reminding。4.5 状态持久化与事件溯源列表状态不是临时内存变量而是通过事件溯源持久化的。AgentTodoService使用ToolsUpdateStore见 todoOps.ts这一 durable 事件完成写入export class ToolsUpdateStore extends AgentEvent2z.infertypeof toolsUpdateStoreSchema { static override readonly type tools.update_store; static override readonly durable true; static override readonly schema toolsUpdateStoreSchema; }replace()通过this.actor.dispatch(new ToolsUpdateStore({ agentId, key: todo, value: [...] }))落盘todoService.ts并且该事件被标记为undoable——这意味着会话可以回滚/重放TodoList 状态在恢复后依然一致。onDidChange事件则让 UI 或上层组件实时感知列表变化。五、完整工作流写入提醒与陈旧提醒如何协同把上述机制串起来一个长任务中的进度追踪闭环是这样的立列表收到多步指令后模型调用TodoList带todos数组写入计划输出附上写入提醒——持续使用、即时标记 done、恰好一个 in_progress推进每完成一步模型调用TodoList整体替换列表把对应条目改为done并把当前正在做的条目设为in_progress查询不确定现状时调用无参TodoList查看当前列表零副作用遗忘检测若模型连续 10 轮以上没有写列表也没有收到过提醒系统注入陈旧提醒附上当前列表提示“考虑更新、清空或重写”纠正模型据提醒更新列表或明确判断提醒不适用而忽略收尾全部完成后调用TodoList传入todos: []清空列表输出Todo list cleared.不带写入提醒。六、给接入方与实现者的建议接入 TodoList 的工具/服务写入必须走“整体替换”语义并保留“查询零副作用、清空不带提醒”的边界避免破坏提醒时序想复用提醒机制写入提醒是todo-list-write-reminder.md的?raw导入见 todoListTool.ts可替换为自定义约束文本陈旧提醒则参考 todoListReminder.ts 的“双阈值 历史扫描”模式可调整TODO_LIST_REMINDER_TURNS_SINCE_WRITE与TODO_LIST_REMINDER_TURNS_BETWEEN_REMINDERS两个常量来改变提醒频率验证行为仓库提供了完整测试套件todo-list.test.ts 覆盖三种模式与写入提醒文本todoListReminder.test.ts 覆盖陈旧提醒的触发与文案可作为回归基准扩展阅读TodoList 的注册入口在 todoFeature.ts服务层与状态机在 todoService.ts状态枚举与渲染在 todoItem.ts。七、小结本文从一份仅一行的写入提醒文档出发还原了 Kimi Code 进度追踪机制的完整设计TodoList工具通过“整体替换 三模式调用”维护结构化任务列表每次写操作后在输出中附带写入提醒以强化“即时标记、单任务进行中”的纪律而独立于工具的陈旧提醒则用“双 10 轮阈值 历史扫描 温和文案 工具策略门控”在模型遗忘时自我纠正。两者一前一后、互为补充构成一套无需人类干预的进度追踪闭环——这也是 todo-list.md、todo-list-write-reminder.md 与 todoListReminder.ts 三份材料共同讲述的完整故事。赞分享AI Agent代码智能体人工智能大模型CLI【免费下载链接】kimi-codeKimi Code CLI — The Starting Point for Next-Gen Agents项目地址https://gitcode.com/gh_mirrors/ki/kimi-code点击查看免费下载相关推荐Kimi Code TodoList 工具深度解析多步任务进度追踪机制与 agent-core-v2 源码实现Kimi Code TodoList 工具深度解析多步任务进度追踪机制与 agent core v2 源码实现 导读 本文聚焦 Kimi Code 项目 agAI Agent代码智能体人工智能大模型CLIKimi Code 计划模式Plan Mode重新进入提醒注入机制从 reentry-reminder 到 PlanModeInjection 的完整解析Kimi Code 计划模式Plan Mode重新进入提醒注入机制从 reentry reminder 到 PlanModeInjection 的完整解析AI Agent代码智能体人工智能大模型CLIKimi Code 计划模式全量提醒机制解析Plan Mode Full Reminder 注入原理与工程实现Kimi Code 计划模式全量提醒机制解析Plan Mode Full Reminder 注入原理与工程实现 计划模式Plan Mode是 Kimi CAI Agent代码智能体人工智能大模型CLI上一篇10个步骤打造高性能MCP服务器从测试到优化的终极指南下一篇【亲测免费】 Embox 开源项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表