Spring AI Agentic Patterns (Part 3): Why Your AI Agent Forgets Tasks (And How to Fix It)

Engineering | Christian Tzolov | January 20, 2026 | ...

Have you ever asked an AI agent to perform a complex multi-step task, only to find it skipped a critical step halfway through? You're not alone.

Research shows that LLMs struggle with "lost in the middle" failures—forgetting tasks buried in long contexts. When your agent juggles file edits, test execution, and documentation updates, important steps can silently disappear. One solution, inspired by Claude Code, is to make planning explicit and observable with the help of a dedicated TodoWrite tool. The result: agents that never skip steps and workflows you can observe in real-time.

This is Part 3 of our Spring AI Agentic Patterns series. We've covered Agent Skills for modular capabilities and AskUserQuestionTool for interactive workflows. Now we explore how TodoWriteTool brings structured task management to Spring AI agents.

Ready to dive in? Skip to the Getting Started section.

What Is TodoWriteTool?

TodoWriteTool is a Spring AI tool that enables LLMs to create, track, and update task lists during execution. Inspired by Claude Code's TodoWrite, it transforms implicit planning into explicit, trackable workflows. The full implementation is available on GitHub: TodoWriteTool.java

When an agent receives a complex task, such as "Add a dark mode toggle to the settings page and run tests", it uses TodoWriteTool to decompose it before execution:

The LLM calls the tool whenever it needs to update the plan—whether creating initial tasks, marking progress, or adding newly discovered work.

The tool accepts a list of todo items, each with id, content (what needs to be done), and status. Each todo item follows a simple lifecycle:

The tool enforces an important constraint: only one task can be in_progress at a time. This forces sequential, focused execution rather than scattered attempts at parallel work.

Here's what real-time progress looks like during execution:

Progress: 2/4 tasks completed (50%)
[✓] Find top 10 Tom Hanks movies
[✓] Group movies in pairs
[→] Print inverted titles
[ ] Final summary

How the LLM Knows When to Use It

The tool description instructs the LLM on when task tracking is appropriate:

"Use this tool when a task requires 3 or more distinct steps or actions. Skip when there is only a single, straightforward task that can be completed in less than 3 trivial steps."

This self-governing behavior means the agent decides autonomously whether to create a task list based on complexity.

💡 Tip: Additionally, for best results, use a system prompt with detailed task management instructions. The MAIN_AGENT_SYSTEM_PROMPT_V2 provides a Claude Code-inspired example.

⚠️ Important: The Todo-Write pattern relies on Chat Memory to retain the todo list updates and relay them to the LLM. Additionally, enabling the ToolCallAdvisor replaces the built-in ChatModel tool calling and ensures that all tool messages are logged in chat memory. See the full advisors configuration in Getting Started below.

Getting Started

1. Add the Dependency

<dependency>
    <groupId>org.springaicommunity</groupId>
    <artifactId>spring-ai-agent-utils</artifactId>
    <version>0.4.0</version>
</dependency>

ℹ️ Note: Requires Spring AI version 2.0.0-SNAPSHOT or 2.0.0-M2 when released.

2. Configure Your Agent

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();

⚠️ Important: Setting conversationHistoryEnabled(false) disables the built-in tool-call history in favor of the MessageChatMemoryAdvisor.

For a complete example with system prompts and additional tools, see the todo-demo project.

3. (Optional) Event-Driven Progress Updates

The tool publishes events that your application can use to update UIs in real-time. For example, define a dedicated ApplicationEvent and event listener:

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));
    }
}

Then add the event publisher in your 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();

Conclusion

TodoWriteTool brings structured task management to Spring AI agents, transforming implicit planning into explicit, observable workflows. By making the agent's plan visible and trackable, you get more reliable execution, better user experience, and easier debugging.

Key takeaway: If your agent is dropping steps on complex tasks, add TodoWriteTool. The overhead is minimal; the LLM decides when tracking is needed based on task complexity.

Combined with Agent Skills for domain knowledge and AskUserQuestionTool for interactive clarification, TodoWriteTool completes the foundation for building reliable AI agents.

Next up: In Part 4, we explore Subagent Orchestration with TaskTool, and in Part 5, the A2A Integration for building interoperable agents with the Agent2Agent protocol.

Resources

  • Part 1: Agent Skills - Modular, reusable capabilities
  • Part 2: AskUserQuestionTool - Interactive workflows
  • Part 3: TodoWriteTool (this blog) - Structured planning
  • Part 4: Subagent Orchestration - Hierarchical agent architectures
  • Part 5: A2A Integration - Building interoperable agents with the Agent2Agent protocol
  • Part (soon): Subagent Extension Framework (coming soon) - Protocol-agnostic agent orchestration

Get the Spring newsletter

Stay connected with the Spring newsletter

Subscribe

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all