Skip to content

Plan Mode 与 TodoList 实现说明

Plan Mode是DeerFlow提供的任务规划与进度跟踪功能,通过TodoList中间件实现,允许Agent将复杂任务拆分为多步执行,并实时跟踪进度,为用户提供透明的工作流程可见性。


组件位置职责
Todo中间件packages/harness/deerflow/agents/middlewares/todo_middleware.py扩展LangChain内置TodoListMiddleware,添加上下文丢失检测和提醒注入功能
ThreadState定义packages/harness/deerflow/agents/thread_state.py定义todos字段存储任务列表状态
中间件注册packages/harness/deerflow/agents/lead_agent/agent.py动态根据Plan Mode开关决定是否加载Todo中间件
write_todos工具LangChain内置,由TodoListMiddleware自动提供任务列表管理工具,支持创建、更新、完成任务

Plan Mode通过runtime配置参数动态控制,无需修改静态配置:

  • 在调用Agent时,通过config.configurable.is_plan_mode = True开启Plan Mode
  • 开启后,_build_middlewares函数会自动创建并加载TodoMiddleware
  • 关闭时,Todo中间件不会被加载,Agent也不会拥有write_todos工具权限

TodoMiddleware继承自LangChain的TodoListMiddleware,扩展了上下文丢失保护机制:

前置钩子(before_model/abefore_model

Section titled “前置钩子(before_model/abefore_model)”

在每次调用LLM之前执行:

  1. 检查当前状态中是否存在todos任务列表
  2. 检查最近的消息历史中是否包含write_todos工具调用(即任务列表是否还在上下文窗口中)
  3. 检查是否已经注入过todo提醒消息,避免重复
  4. 如果任务列表存在但已经不在上下文窗口中,自动注入系统提醒消息,包含当前所有任务的状态
<system_reminder>
Your todo list from earlier is no longer visible in the current context window,
but it is still active. Here is the current state:
- [pending] 任务1
- [in_progress] 任务2
- [completed] 任务3
Continue tracking and updating this todo list as you work.
Call `write_todos` whenever the status of any item changes.
</system_reminder>
  • 任务列表存储在ThreadStatetodos字段中,类型为list[Todo]
  • 每个Todo对象包含:
    • content: 任务描述
    • status: 任务状态(pending/in_progress/completed
    • activeForm: 任务进行时的描述(可选)

DeerFlow对内置的TodoListMiddleware进行了定制,添加了严格的使用规则和最佳实践提示:

  • 必须立即标记完成:完成任务后立即更新状态,不要批量更新
  • 单任务进行中:同一时间只能有一个任务处于in_progress状态(可并行任务除外)
  • 实时更新:工作过程中实时更新任务列表,给用户提供可见性
  • 避免滥用:少于3步的简单任务不要使用Todo功能,直接完成即可
  • 复杂多步骤任务(≥3步)
  • 需要仔细规划的非平凡任务
  • 用户明确要求使用任务列表
  • 用户提供多个任务(编号或逗号分隔列表)
  • 需要根据中间结果动态调整计划的任务

当对话历史被截断(例如被SummarizationMiddleware summarization)导致原始write_todos调用被移出上下文窗口时,中间件会自动注入提醒消息,确保Agent不会忘记当前的任务列表。

内置规则确保任务管理的规范性:

  • 只有完全完成的任务才能标记为completed
  • 遇到阻塞时保持任务为in_progress,并新增解决阻塞的任务
  • 自动提醒实时更新状态,避免进度跟踪滞后

Plan Mode完全通过runtime参数控制,无需修改静态配置文件,可按需为每个会话独立开启或关闭。

同时实现了同步before_model和异步abefore_model钩子,兼容同步和异步两种Agent运行模式。

基于LangChain官方TodoListMiddleware扩展,保持了与LangGraph生态的兼容性,同时添加了适合生产环境的增强功能。


在创建Agent运行时传入配置:

config = {
"configurable": {
"is_plan_mode": True,
# 其他配置...
}
}

Agent会根据任务复杂度自动决定是否调用write_todos工具,示例调用:

{
"name": "write_todos",
"parameters": {
"todos": [
{
"content": "分析子Agent委派实现",
"status": "in_progress",
"activeForm": "分析子Agent委派实现中"
},
{
"content": "撰写实现文档",
"status": "pending",
"activeForm": "撰写实现文档中"
},
{
"content": "复核文档正确性",
"status": "pending",
"activeForm": "复核文档正确性中"
}
]
}
}

Agent在完成任务或切换任务时自动调用write_todos更新状态:

{
"name": "write_todos",
"parameters": {
"todos": [
{
"content": "分析子Agent委派实现",
"status": "completed",
"activeForm": "分析子Agent委派实现中"
},
{
"content": "撰写实现文档",
"status": "in_progress",
"activeForm": "撰写实现文档中"
},
{
"content": "复核文档正确性",
"status": "pending",
"activeForm": "复核文档正确性中"
}
]
}
}

组件交互方式
SummarizationMiddlewareTodo中间件在summarization之后执行,检测summarization是否导致任务列表被移出上下文窗口
ClarificationMiddlewareTodo中间件在ClarificationMiddleware之前执行,确保Agent可以在需要澄清问题时仍然能够管理任务列表
前端UI任务状态变化会通过SSE事件推送到前端,实时展示进度
子Agent系统Plan Mode下的任务可以委派给子Agent执行,状态更新会同步回主任务列表

  1. Plan Mode默认是关闭的,需要显式开启
  2. 任务列表存储在会话状态中,会话结束后不会持久化
  3. 中间件自动处理上下文丢失问题,无需人工干预
  4. 严格遵守内置规则可以有效提升任务执行的透明度和可追溯性