给编码代理加可更新清单,减少漏项
文章介绍通过TodoWrite工具持续维护任务清单,缓解长上下文中代理遗漏原始要求的问题。示例基于Java与Spring生态,每次调用提交完整列表,记录任务描述、执行中表述和状态。
AI 深度解读
让 AI Agent 检查 10 个接口、逐个修复鉴权问题、运行测试,再整理变更说明。它修好 6 个,跑了部分测试,交出一份整齐的报告,剩下 4 个却没碰。没有报错,只是漏了。
作者给出的办法很朴素:给 Agent 一份持续更新的待办清单。ByteChef 把 Spring AI 的 TodoWriteTool 接进工具调用循环,让计划反复出现在上下文里。它值得了解的地方,是把「记得做完」变成了可见、可约束的工作状态;但示例距离证明任务可靠完成,还有一段距离。
为什么开头交代清楚,执行到一半还是会漏
作者把问题归因于「中间遗忘」(lost-in-the-middle):长上下文中,模型对中间部分的信息关注不足。工具调用、执行结果不断累积,最初的任务要求逐渐被挤到中间,后续行动就可能偏离原计划。
这能解释一种常见现象:Agent 的每一步看起来都合理,最终交付却缺项。局部执行顺畅,不代表它始终记得完整任务。
Spring AI 团队借鉴 Claude Code 的做法,用清单保存计划。spring-ai-agent-utils 提供的 TodoWriteTool 向模型暴露名为 TodoWrite 的工具,每次调用都提交完整列表,每项包含三个字段:
content保存任务指令,例如更新 Spring Boot 版本。activeForm保存执行中的表述,例如正在更新 Spring Boot 版本。status只能取pending、in_progress、completed。
这里最关键的机制,是每次更新都重新提交整份清单。只要工具调用循环把调用参数和结果保留在对话中,模型决定下一步时,就能看到最新的完成情况。
清单的作用,是让任务状态持续回到模型眼前。
不过,原文所说的「计划不会失去关注」有些绝对。反复写入能缓解信息被埋没的问题,不能保证模型一定遵守,也没有解决上下文被截断或压缩后的状态恢复问题。
只有一个任务进行中,约束到底有多强
TodoWriteTool 规定,同一时间最多只能有一个任务处于 in_progress。如果提交的列表里有两个进行中任务,工具会拒绝,并要求先完成当前任务。
这条规则限制了同时开工的数量。Agent 不能一边改依赖,一边把配置修改、测试迁移都标成进行中,然后留下多个半成品。
工具说明还约定:有 3 个及以上独立步骤时才使用清单;任务完全完成后才能标记 completed;测试失败或工作只做了一部分时,应保持 in_progress;遇到阻塞,就增加一项处理阻塞的任务。
需要分清两类约束。多个任务同时进行,会被工具明确拒绝;「测试确实通过」「修改确实完整」则仍需要执行证据。原文没有展示工具会读取测试结果、核对代码差异,再批准状态变更。
因此,一个合法的清单,也可能是一份内容不实的清单。completed 是 Agent 提交的状态,不能单独充当验收结果。
另外,「最多一个进行中」也没有证明任务必须按照列表顺序执行。作者希望借此让 Agent 逐项推进,但原文展示的硬性校验范围,主要是进行中任务的数量。
接入的关键,是让模型真的看见工具记录
在普通 Spring AI 项目中,开发者需要把工具接到 ChatClient,配置 MessageChatMemoryAdvisor 和 ToolCallAdvisor,确保工具消息能到达模型;如果需要后续追问,还要配置聊天记忆。
ByteChef 的 AI Agent 组件已经负责工具调用循环,并把工具消息保留在对话里。开发者将 Todo Write Tool 放入 Agent 的 Tools 插槽即可。
下面这段包装代码,把库中的工具转换成可注册的回调提供者:
TodoWriteTool todoWriteTool = TodoWriteTool.builder()
.build();
return ToolCallbackProvider.from(ToolCallbacks.from(todoWriteTool));
要留意最后一行:它完成工具暴露,清单更新、消息保留和后续调用还依赖库与 AI Agent 的运行机制。
作者用 Spring Boot 4 迁移规划器展示接入效果。模板分三步:New Chat Request 接收消息,AI Agent 使用 Anthropic 模型、Chat Memory 和 Todo Write Tool,最后由 Reply 返回回答。

系统提示词负责明确清单使用时机和更新节奏:
You are a senior Java engineer. For any request with 3 or more distinct
steps, first create a todo list with the TodoWrite tool. Keep exactly one
task in_progress at a time, mark each task completed as soon as it is done,
and update the list after every step. Finish with a short summary.
要留意 update the list after every step:如果只在开头列一次计划,后面不更新,就失去了持续刷新状态的作用。
导入模板、配置 Anthropic connection 后,作者用「将 Java 17 上的 Spring Boot 3.5 服务迁移到 Spring Boot 4」作为请求。预期清单包括升级到受支持的 Java 版本、更新 Spring Boot 和依赖 BOM、修复重命名及移除的配置属性、更新测试并运行构建、整理变更。
原文没有明确目标 Java 版本,也没有给出完整迁移差异,不能把这份规划直接当成迁移手册。

作者展示了真实测试的首次调用,确认清单中一项为 in_progress,其余为 pending。编辑器里的 Agent Playbook 还会将每次更新显示为工具调用卡片,便于观察执行过程。
我的判断
我认可它把任务状态显式化的方向。相比只在提示词里要求「不要遗漏」,完整清单能让模型和使用者共同看到哪些已经完成、哪些还没开始。它也比最终报告更早暴露误解:计划刚生成时,人就能检查拆分是否覆盖需求。
但作者没有提供使用前后的漏项率、重复测试结果,也没有与普通 Markdown 清单或其他任务状态机制做对照。「能解决大部分漏步问题」目前属于经验判断。
示例证明了工具会被调用、状态能被展示,没有证明一次真实迁移已经完成并通过构建。对于团队落地,更重要的是把完成状态关联到可检查的产物,例如修改文件、测试结果和未解决问题。
单任务进行中的规则适合依赖关系明显的工作。若任务本来可以独立并行,它就可能限制效率;清单本身也不等同于支持并行、重试和恢复的工作流引擎。应按任务复杂度选择,没必要给单个简单请求增加规划负担。
能拿来做什么
- 给前端或 Node Agent 安排多个独立步骤时,要求先用 TodoWrite 建立清单,并在每一步后提交完整状态;原文建议的启用门槛是 3 个及以上独立步骤。
- 将「修改完成」和「验证完成」写清楚。涉及测试的任务,测试失败就保持进行中,并记录阻塞原因,避免代码一改完就提前结项。
- 接入工具时检查消息链路。确认最新清单的参数和结果确实进入下一轮模型上下文,工具注册成功并不足以证明这个机制生效。
- 审阅 Agent 交付时,把清单与代码变更、构建或测试输出一起检查。优先核对仍待处理的任务,以及已经标记完成却缺少结果支撑的任务。