你是否遇到过这样的情况:让 AI 智能体执行一项复杂的多步骤任务,结果它中途跳过了某个关键步骤。
研究表明,大语言模型普遍存在 “中间丢失” 问题 —— 在长上下文里会忘记埋在中间的任务。当你的智能体同时处理文件修改、测试执行、文档更新等工作时,重要步骤可能会无声无息地消失。受 Claude Code 启发,一种解决方案是:借助专用的 TodoWrite 工具,让规划变得显式且可观测。最终效果:智能体永远不会跳过步骤,工作流可实时观测。
TodoWriteTool 如何为 Spring AI 智能体带来结构化任务管理。
什么是 TodoWriteTool ?
TodoWriteTool 是 Spring AI 的一款工具,让大语言模型能够在执行过程中创建、跟踪和更新任务清单。它的设计灵感来自 Claude Code 的 TodoWrite 能力,将隐式规划转变为显式、可跟踪的工作流。完整实现可在 GitHub 查看(TodoWriteTool.java)。
当智能体收到复杂任务(例如 “为设置页面添加深色模式开关并运行测试”)时,它会在执行前使用 TodoWriteTool 进行拆解:

大语言模型会在需要更新计划时随时调用该工具 —— 无论是创建初始任务、标记进度,还是添加新发现的工作。
该工具接收一组待办事项,每个事项包含 id、content(需要做什么)和 status。每个待办事项遵循简单的生命周期:

该工具强制一项重要约束:同一时间只能有一个任务处于 “进行中”(in_progress)。这迫使智能体按顺序、专注地执行,而不是散乱地尝试并行工作。
以下是执行过程中的实时进度展示:
|
1 2 3 4 5 |
进度:2/4 任务已完成(50%) [✓] 找出汤姆·汉克斯排名前10的电影 [✓] 将电影两两分组 [→] 打印反转后的标题 [ ] 最终总结 |
大语言模型如何知道何时使用它
工具描述会指导大语言模型在合适的场景下开启任务跟踪:
“当任务需要 3 个或更多不同步骤或操作时使用此工具。如果只是单一、简单的任务,可在 3 个以内简易步骤完成,则无需使用。”
这种自管理行为意味着智能体会根据复杂度自主决定是否创建任务清单。
提示: 为达到最佳效果,建议使用包含详细任务管理指令的系统提示词。MAIN_AGENT_SYSTEM_PROMPT_V2 提供了一个受 Claude Code 启发的示例。
重要: TodoWrite 模式依赖 对话记忆(Chat Memory) 来保存待办清单更新,并将其传递给大语言模型。此外,启用 ToolCallAdvisor 会替换内置的 ChatModel 工具调用,确保所有工具消息都记录在对话记忆中。完整的顾问配置见下文 “快速上手” 部分。
快速开始
1. 添加依赖
|
1 2 3 4 5 |
<dependency> <groupId>org.springaicommunity</groupId> <artifactId>spring-ai-agent-utils</artifactId> <version>0.4.0</version> </dependency> |
注意: 需要 Spring AI 版本 2.0.0-SNAPSHOT 或正式发布的 2.0.0-M2。
2. 配置智能体
|
1 2 3 4 5 6 7 8 9 10 11 12 |
ChatClient chatClient = chatClientBuilder .defaultTools(TodoWriteTool.builder().build()) .defaultAdvisors( ToolCallAdvisor.builder().conversationHistoryEnabled(false).build(), MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build() ) .build(); String response = chatClient.prompt() .user("找出汤姆·汉克斯排名前10的电影,两两分组,并将每个标题反转打印。使用 TodoWrite 组织任务。") .call() .content(); |
重要: 设置 conversationHistoryEnabled(false) 是为了关闭内置的工具调用历史,转而使用 MessageChatMemoryAdvisor。
如需包含系统提示词和更多工具的完整示例,可查看 todo-demo 项目。
3. (可选)事件驱动的进度更新
该工具会发布事件,应用可以利用这些事件实时更新界面。例如,定义专用的应用事件与监听器:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class TodoUpdateEvent extends ApplicationEvent { private final List<TodoItem> todos; public TodoUpdateEvent(Object source, List<TodoItem> todos) { super(source); this.todos = todos; } public List<TodoItem> getTodos() { return todos; } } @Component public class TodoProgressListener { @EventListener public void onTodoUpdate(TodoUpdateEvent event) { int completed = (int) event.getTodos().stream().filter(t -> t.status() == Todos.Status.completed).count(); int total = event.getTodos().size(); System.out.printf("\n进度:%d/%d 任务已完成(%.0f%%)\n", completed, total, (completed * 100.0 / total)); } } |
然后在 todoEventHandler 中添加事件发布器:
|
1 2 3 4 5 6 7 8 9 10 11 |
@Autowired ApplicationEventPublisher applicationEventPublisher; ChatClient chatClient = chatClientBuilder .defaultTools(TodoWriteTool.builder() // 发布待办事项更新事件 .todoEventHandler(event -> applicationEventPublisher.publishEvent(new TodoUpdateEvent(this, event.todos()))) .build()) // ... .build(); |
总结
TodoWriteTool 为 Spring AI 智能体带来结构化任务管理,将隐式规划转变为显式的、可观测的工作流。通过让智能体的计划可见、可跟踪,用户将获得更可靠的执行、更好的用户体验以及更轻松的调试。
核心结论: 如果你的智能体在复杂任务中总漏掉步骤,加入 TodoWriteTool 即可解决。它带来的开销极小,由大语言模型根据任务复杂度自主决定是否需要跟踪。
结合用于领域知识的智能体技能和用于交互式澄清的AskUserQuestionTool,TodoWriteTool 为构建可靠的 AI 智能体补齐了最后一块基础。