AI代理:基于待办清单的任务规划
在本文中,我们将深入探讨智能体如何利用待办事项清单的功能,分析规划过程的底层组成部分,并演示如何使用 LangChain 实现它。
规划是我们每个人都会自然而然地经常做的事情。在个人生活中,我们经常会列出待办事项清单来安排假期、琐事以及其他各种事情。
在工作中,我们依靠任务跟踪器和项目计划来保持团队的步调一致。对于开发人员来说,在代码中留下 TODO 注释作为未来修改的提醒也十分常见。
不出所料,LLM 智能体也能从清晰的待办事项清单中受益,从而更好地进行规划。
待办事项清单帮助智能体更有效地规划和跟踪复杂任务,使其在需要可见进度的多工具协调和长时间运行的操作中尤为有用。
OpenAI Codex、Cline 和 Claude Code(我经常使用)等编码智能体就是这一概念的典型例子。
它们将复杂的请求分解成一系列初始步骤,将其组织成包含依赖关系的待办事项清单,并在任务完成或出现新信息时实时更新计划。

这种清晰性使智能体能够处理长序列操作,协调不同工具,并以易于理解的方式跟踪进度。
在本文中,我们将深入探讨智能体如何利用待办事项清单的功能,分析规划过程的底层组成部分,并演示如何使用 LangChain 实现它。
配套代码可在 GitHub 仓库中找到。
1、规划代理示例场景
让我们通过示例场景来展开讲解。
我们将设置一个代理来规划旅行行程并执行预订任务。该代理可以使用三个工具:
- buy_travel_insurance:为此次旅行购买旅行保险
- book_flight:根据行程预订机票
- book_hotel:根据行程预订酒店
在本示例中,这些工具是模拟的,并不执行实际的预订操作;它们仅用于演示代理的规划逻辑以及它如何使用待办事项列表。
以下是使用 LangChain 实现我们的规划代理的代码:
agent_prompt = """
You are a executive assistant who plans and executes setup of travel trips.
If any details are missing, no need to ask user, just make realistic assumptions directly.
After entire plan is completed, succinctly explain rationale for sequence of actions of the plan.
"""
agent = create_agent(
system_prompt=agent_prompt,
model="openai:gpt-5.1",
tools=[buy_travel_insurance, book_flight, book_hotel],
middleware=[TodoListMiddleware()]
)我们输入用户查询,并查看代理规划生成的待办事项列表:
user_input = "Book business trip to Singapore between 20 and 24 Sep 2025 for an AI conference"
response = agent.invoke({"messages": [HumanMessage(user_input)]})
# Show the to-do list generated by the planning agent
print(response["todos"])

通过待办事项列表进行结构化笔记,代理能够在上下文窗口之外保持持久记忆。这种策略提高了代理管理和保留相关上下文的能力。
代码设置很简单:create_agent 创建 LLM 代理实例,我们传入系统提示,选择模型(GPT-5.1),并链接工具。
值得注意的是传递给中间件参数的 TodoListMiddleware() 对象。
首先,什么是 LangChain 的中间件?
顾名思义,它是一个中间层,允许您在 LLM 调用前后运行自定义代码。
中间件可以看作是一个可编程层,它允许我们注入代码来监控、调整或扩展代理的行为。
它使我们能够在不改变代理核心逻辑的情况下控制和了解其行为。它可以用于转换提示和输出、管理重试或提前退出,以及应用安全措施(例如,防护栏、个人身份信息检查)。
TodoListMiddleware 是一个内置中间件,专门为代理提供待办事项列表管理功能。接下来,我们将探讨 TodoListMiddleware 的底层工作原理。
2、待办事项功能的关键组成部分
规划代理的待办事项列表管理功能可归结为以下四个关键组成部分:
- 待办任务项
- 待办事项列表
- 用于写入和更新待办事项列表的工具
- 待办事项系统提示更新
TodoListMiddleware 将这些元素整合在一起,从而实现代理的待办事项列表功能。
让我们仔细看看每个组件以及它们在待办事项中间件代码中的实现方式。
2. 待办任务项
待办任务项是待办事项列表中的最小单元,代表一项任务。它由两个字段表示:任务描述和当前状态。
在 LangChain 中,这被建模为一个 Todo 类型,使用 TypedDict 定义:
class Todo(TypedDict):
"""A single todo item with content and status."""
content: str
"""The content/description of the todo item."""
status: Literal["pending", "in_progress", "completed"]
"""The current status of the todo item."""content 字段表示代理接下来需要执行的任务的描述,而 status 字段则跟踪任务是尚未开始(pending)、正在进行(in_progress)还是已完成(completed)。
以下是一个待办事项示例:
{
"content": "Compare flight options from Singapore to Tokyo",
"status": "completed"
},2.2 待办事项列表
现在我们已经定义了待办事项的结构,接下来我们将探讨如何存储和跟踪一组待办事项,作为整体计划的一部分。
我们定义了一个状态对象(PlanningState)来捕获计划,该计划以待办事项列表的形式呈现,并在任务执行过程中更新:
class PlanningState(AgentState):
"""State schema for the todo middleware."""
todos: Annotated[NotRequired[list[Todo]], OmitFromInput]
"""List of todo items for tracking task progress."""todos 字段是可选的(NotRequired),这意味着在首次初始化时可能不存在(即,代理的计划中可能还没有任何任务)。
OmitFromInput 表示 todos 由中间件内部管理,不应直接作为用户输入提供。
状态是代理的短期记忆,它捕获最近的对话和关键信息,以便代理能够根据先前的上下文和信息采取适当的行动。
在这种情况下,待办事项列表会一直保留在代理的状态中,以便代理在整个会话期间可以持续地参考和更新任务。
以下是一个待办事项列表的示例:
todos: list[Todo] = [
{
"content": "Research visa requirements for Singapore passport holders visiting Japan",
"status": "completed"
},
{
"content": "Compare flight options from Singapore to Tokyo",
"status": "in_progress"
},
{
"content": "Book flights and hotels once itinerary is finalized",
"status": "pending"
}
]2.3 用于编写和更新待办事项的工具
待办事项列表的基本结构已经建立,现在我们需要一个工具供 LLM 代理在任务执行过程中管理和更新它。
以下是定义我们工具 (write_todos) 的标准方法:
@tool(description=WRITE_TODOS_TOOL_DESCRIPTION)
def write_todos(todos: list[Todo], tool_call_id: Annotated[str, InjectedToolCallId]) -> Command:
"""Create and manage a structured task list for your current work session."""
return Command(
update={
"todos": todos,
"messages": [ToolMessage(f"Updated todo list to {todos}", tool_call_id=tool_call_id)],
}
)write_todos 工具返回一个 Command,该 Command 指示代理更新其待办事项列表并附加一条记录更改的消息。
write_todos 结构很简单,关键在于工具的描述( WRITE_TODOS_TOOL_DESCRIPTION)。
当代理调用该工具时,工具描述会作为重要的附加提示,指导代理如何正确使用该工具以及需要提供哪些输入。
以下是 LangChain 对该工具的描述(相当冗长):
WRITE_TODOS_TOOL_DESCRIPTION = """Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the task directly.
## When to Use This Tool
Use this tool in these scenarios:
1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
3. User explicitly requests todo list - When the user directly asks you to use the todo list
4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
5. The plan may need future revisions or updates based on results from the first few steps
## How to Use This Tool
1. When you start working on a task - Mark it as in_progress BEFORE beginning work.
2. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation.
3. You can also update future tasks, such as deleting them if they are no longer necessary, or adding new tasks that are necessary. Don't change previously completed tasks.
4. You can make several updates to the todo list at once. For example, when you complete a task, you can mark the next task you need to start as in_progress.
## When NOT to Use This Tool
It is important to skip using this tool when:
1. There is only a single, straightforward task
2. The task is trivial and tracking it provides no benefit
3. The task can be completed in less than 3 trivial steps
4. The task is purely conversational or informational
## Task States and Management
1. **Task States**: Use these states to track progress:
- pending: Task not yet started
- in_progress: Currently working on (you can have multiple tasks in_progress at a time if they are not related to each other and can be run in parallel)
- completed: Task finished successfully
2. **Task Management**:
- Update task status in real-time as you work
- Mark tasks complete IMMEDIATELY after finishing (don't batch completions)
- Complete current tasks before starting new ones
- Remove tasks that are no longer relevant from the list entirely
- IMPORTANT: When you write this todo list, you should mark your first task (or tasks) as in_progress immediately!.
- IMPORTANT: Unless all tasks are completed, you should always have at least one task in_progress to show the user that you are working on something.
3. **Task Completion Requirements**:
- ONLY mark a task as completed when you have FULLY accomplished it
- If you encounter errors, blockers, or cannot finish, keep the task as in_progress
- When blocked, create a new task describing what needs to be resolved
- Never mark a task as completed if:
- There are unresolved issues or errors
- Work is partial or incomplete
- You encountered blockers that prevent completion
- You couldn't find necessary resources or dependencies
- Quality standards haven't been met
4. **Task Breakdown**:
- Create specific, actionable items
- Break complex tasks into smaller, manageable steps
- Use clear, descriptive task names
Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully
Remember: If you only need to make a few tool calls to complete a task, and it is clear what you need to do, it is better to just do the task directly and NOT call this tool at all."""
我们可以看到,该描述结构清晰、精确,明确定义了何时以及如何使用该工具、任务状态和管理规则。
它还提供了清晰的指南,用于跟踪复杂任务、将其分解为清晰的步骤并进行系统更新。
你可以点击此处查看 Deepagents 对待办事项工具描述的更简洁的解读。
2.4 系统提示更新
设置待办事项功能的最后一个步骤是更新代理的系统提示。
这可以通过将 WRITE_TODOS_SYSTEM_PROMPT 注入到主提示中来实现,从而明确告知代理 write_todos 工具的存在。
它指导代理何时以及为何使用该工具,为复杂的多步骤任务提供上下文,并概述维护和更新待办事项列表的最佳实践:
WRITE_TODOS_SYSTEM_PROMPT = """## `write_todos`
You have access to the `write_todos` tool to help you manage and plan complex objectives.
Use this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.
This tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.
It is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.
For simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.
Writing todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.
## Important To-Do List Usage Notes to Remember
- The `write_todos` tool should never be called multiple times in parallel.
- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant."""
WRITE_TODOS_SYSTEM_PROMPT = """## write_todos
你可以使用 write_todos 工具来管理和规划复杂的目标。
3、将其整合到中间件中
最后,所有四个关键组件都整合到一个名为 TodoListMiddleware 的类中,该类将待办事项功能打包成一个供代理使用的统一流程:
- 定义 PlanningState 以跟踪待办事项列表中的任务
- 动态创建 write_todos 工具,用于更新列表并使其可供 LLM 访问
- 注入 WRITE_TODOS_SYSTEM_PROMPT 用于指导代理的规划和推理
WRITE_TODOS_SYSTEM_PROMPT 通过中间件的 wrap_model_call(和 awrap_model_call)方法注入,该方法会将 WRITE_TODOS_SYSTEM_PROMPT 添加到代理每次模型调用的系统消息中,如下所示:
def wrap_model_call(
self,
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelCallResult:
"""Update the system message to include the todo system prompt."""
if request.system_message is not None:
new_system_content = [
*request.system_message.content_blocks,
{"type": "text", "text": f"\n\n{self.system_prompt}"},
]
else:
new_system_content = [{"type": "text", "text": self.system_prompt}]
new_system_message = SystemMessage(
content=cast("list[str | dict[str, str]]", new_system_content)
)
return handler(request.override(system_message=new_system_message))4、结束语
就像人类一样,智能体使用待办事项列表来分解复杂问题、保持条理清晰并实时调整,从而更高效、更准确地解决问题。
通过 LangChain 的中间件实现,我们还可以更深入地了解智能体如何构建、跟踪和执行计划任务。
原文链接:How Agents Plan Tasks with To-Do Lists
汇智网翻译整理,转载请标明出处