Spring AI 智能体模式(第三部分):为什么你的 AI 智能体会遗忘任务(以及如何修复)

预估阅读时长:7分钟

Spring AI 智能体模式(第三部分):为什么你的 AI 智能体会遗忘任务(以及如何修复)

你可曾让 AI 智能体执行复杂的多步骤任务,却发现它半途跳过关键步骤?并非只有你遇到这种情况。

研究表明,大语言模型(LLM)会出现”迷失在中间”的失败——遗忘埋藏在长上下文中的任务。当智能体同时应付文件编辑、测试执行与文档更新时,重要步骤可能悄然消失。一个受 Claude Code 启发的解决方案是,借助专用的 TodoWrite 工具让规划显式且可观测。结果便是:智能体永不跳过步骤,工作流实时可见。

这是 Spring AI 智能体模式系列的第三部分。我们已介绍过面向模块化能力的 Agent Skills 和面向交互式工作流的 AskUserQuestionTool。现在,我们将探索 TodoWriteTool 如何为 Spring AI 智能体带来结构化的任务管理。

准备好深入了解了吗?跳到 快速开始 部分。

什么是 TodoWriteTool?

TodoWriteTool 是一个 Spring AI 工具,它让 LLM 能够在执行过程中创建、跟踪和更新任务列表。受 Claude Code 的 TodoWrite 启发,它将隐式规划转变为显式、可追踪的工作流。完整实现见 GitHub:TodoWriteTool.java

当智能体收到诸如”在设置页添加深色模式开关并运行测试”这类复杂任务时,它会在执行前使用 TodoWriteTool 分解任务:

LLM 会在需要更新计划时调用该工具——无论是创建初始任务、标记进展,还是添加新发现的工作。

该工具接受一组待办项,每项包含 idcontent(待做事项)和 status。每个待办项遵循简单的生命周期:

该工具强制实施一项重要约束:同一时间只能有一个任务处于 in_progress 状态。这迫使顺序、专注的执行,而非分散地尝试并行工作。

以下是执行过程中实时进度的样子:

进度:已完成 2/4 个任务(50%)
[✓] 找出前 10 部汤姆·汉克斯的电影
[✓] 将电影两两分组
[→] 打印反转后的片名
[ ] 最终总结

LLM 如何知道何时使用它

工具描述会指示 LLM 何时适合跟踪任务:

“当任务需要 3 个或更多不同步骤或操作时使用此工具。若只有单一、直接的任务且可在少于 3 个简单步骤内完成,则跳过。”

这种自我管理行为意味着智能体会根据复杂度自主决定是否创建任务列表。

💡 提示:此外,为获得最佳效果,请使用包含详细任务管理指令的系统提示。MAIN_AGENT_SYSTEM_PROMPT_V2 提供了一个受 Claude Code 启发的示例。

⚠️ 重要提示:Todo-Write 模式依赖聊天记忆来保留待办列表更新并将其传递给 LLM。此外,启用 ToolCallAdvisor 会替换内置的 ChatModel 工具调用,并确保所有工具消息都记录在聊天记忆中。请参阅下方”快速开始”中的完整 advisor 配置。


快速开始

1. 添加依赖

<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. 配置你的智能体

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("Find the top 10 Tom Hanks movies, group them in pairs, " +
          "and print each title reversed. Use TodoWrite to organize your tasks.")
    .call()
    .content();

⚠️ 重要提示:将 conversationHistoryEnabled(false) 设为 false 会禁用内置的工具调用历史,转而采用 MessageChatMemoryAdvisor

有关带系统提示和其他工具的完整示例,请参阅 todo-demo 项目。

3. (可选)事件驱动的进度更新

该工具会发布事件,你的应用可利用这些事件实时更新 UI。例如,定义专用的 ApplicationEvent 和事件监听器:

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("\nProgress: %d/%d tasks completed (%.0f%%)\n", completed, total,
                (completed * 100.0 / total));
    }
}

然后在你的 todoEventHandler 中添加事件发布器:

@Autowired
ApplicationEventPublisher applicationEventPublisher;

ChatClient chatClient = chatClientBuilder
    .defaultTools(TodoWriteTool.builder()
        // Publish todo update events
        .todoEventHandler(event ->
            applicationEventPublisher.publishEvent(new TodoUpdateEvent(this, event.todos())))
        .build())
    // ...
    .build();

总结

TodoWriteTool 为 Spring AI 智能体带来结构化的任务管理,将隐式规划转化为显式、可观测的工作流。让智能体的计划可见且可追踪,你就能获得更可靠的执行、更好的用户体验和更轻松的调试。

关键要点:如果你的智能体在复杂任务上遗漏步骤,请加入 TodoWriteTool。开销极小,且 LLM 会根据任务复杂度决定何时需要跟踪。

结合用于领域知识的 Agent Skills 和用于交互式澄清的 AskUserQuestionTool,TodoWriteTool 补全了构建可靠 AI 智能体的基础。

接下来:在第四部分,我们将探索使用 TaskTool 的子智能体编排;第五部分将介绍 A2A 集成,使用 Agent2Agent 协议构建可互操作的智能体。


资源

相关资源

系列链接

相关 Spring AI 博客


【注】本文译自:Spring AI Agentic Patterns (Part 3): Why Your AI Agent Forgets Tasks (And How to Fix It)