TodoWrite 详细执行流程分析文章目录TodoWrite 详细执行流程分析一、核心概念二、系统架构三、详细执行步骤第0阶段初始化第1阶段用户输入第2阶段LLM首次处理第3阶段Todo工具调用与状态管理第4阶段构建工具结果并返回LLM第5阶段LLM接收todo状态并继续执行第6阶段执行实际任务第7阶段任务完成并更新todo状态第8阶段迭代执行剩余任务第9阶段nag reminder机制四、完整流程图五、关键机制详解1. TodoManager的状态管理2. rounds_since_todo计数器3. 进度可见性六、与传统方法的对比传统脚本式代理TodoWrite智能代理七、核心洞察八、适用场景九、总结一、核心概念TodoWrite是一个让LLM自我跟踪进度的智能代理系统通过TodoManager来管理任务状态并使用nag reminder机制确保LLM不会忘记更新todo状态。二、系统架构用户输入 ↓ LLM处理 系统提示 ↓ 工具调用决策 ↓ 工具执行包括Todo工具 ↓ TodoManager状态更新 ↓ 结果返回LLM ↓ 循环直到任务完成三、详细执行步骤第0阶段初始化创建TodoManager实例TODO TodoManager()初始化空的items列表self.items []定义工具处理器TOOL_HANDLERS{bash:lambda**kw:run_bash(kw[command]),read_file:lambda**kw:run_read(kw[path],kw.get(limit)),write_file:lambda**kw:run_write(kw[path],kw[content]),edit_file:lambda**kw:run_edit(kw[path],kw[old_text],kw[new_text]),todo:lambda**kw:TODO.update(kw[items]),}设置系统提示词SYSTEMfYou are a coding agent at{WORKDIR}. Use the todo tool to plan multi-step tasks. Mark in_progress before starting, completed when done. Prefer tools over prose.第1阶段用户输入用户输入: 帮我创建一个Python脚本包含三个函数然后运行它 ↓ history.append({role: user, content: query})第2阶段LLM首次处理调用LLM APIresponseclient.messages.create(modelMODEL,systemSYSTEM,messagesmessages,toolsTOOLS,max_tokens8000,)LLM响应内容{content:[{type:tool_use,id:toolu_01,name:todo,input:{items:[{id:1,text:创建Python脚本文件,status:pending},{id:2,text:编写第一个函数,status:pending},{id:3,text:编写第二个函数,status:pending},{id:4,text:编写第三个函数,status:pending},{id:5,text:运行脚本,status:pending}]}}]}第3阶段Todo工具调用与状态管理关键步骤检测到todo工具调用ifblock.nametodo:used_todoTrue调用TodoManager.update()outputhandler(**block.input)# 即 TODO.update(kw[items])TodoManager内部验证和处理defupdate(self,items:list)-str:# 验证项目数量最多20个iflen(items)20:raiseValueError(Max 20 todos allowed)# 逐个验证每个todo项目validated[]in_progress_count0fori,iteminenumerate(items):# 提取并验证字段textstr(item.get(text,)).strip()statusstr(item.get(status,pending)).lower()item_idstr(item.get(id,str(i1)))# 验证必填字段ifnottext:raiseValueError(fItem{item_id}: text required)# 验证状态值ifstatusnotin(pending,in_progress,completed):raiseValueError(fItem{item_id}: invalid status {status})# 统计进行中的任务ifstatusin_progress:in_progress_count1validated.append({id:item_id,text:text,status:status})# 确保同时只有一个任务在进行中ifin_progress_count1:raiseValueError(Only one task can be in_progress at a time)# 更新内部状态self.itemsvalidated# 渲染并返回状态字符串returnself.render()渲染todo状态defrender(self)-str:ifnotself.items:returnNo todos.lines[]foriteminself.items:marker{pending:[ ],in_progress:[],completed:[x]}[item[status]]lines.append(f{marker}#{item[id]}:{item[text]})donesum(1fortinself.itemsift[status]completed)lines.append(f\n({done}/{len(self.items)}completed))return\n.join(lines)返回的todo状态字符串[ ] #1: 创建Python脚本文件 [ ] #2: 编写第一个函数 [ ] #3: 编写第二个函数 [ ] #4: 编写第三个函数 [ ] #5: 运行脚本 (0/5 completed)第4阶段构建工具结果并返回LLM构建结果列表results[]forblockinresponse.content:ifblock.typetool_use:handlerTOOL_HANDLERS.get(block.name)try:outputhandler(**block.input)exceptExceptionase:outputfError:{e}print(f{block.name}:)print(str(output)[:200])results.append({type:tool_result,tool_use_id:block.id,content:str(output)})ifblock.nametodo:used_todoTrue更新轮次计数器rounds_since_todo0ifused_todoelserounds_since_todo1注入nag reminder如果需要ifrounds_since_todo3:results.append({type:text,text:reminderUpdate your todos./reminder})添加到消息历史messages.append({role:user,content:results})第5阶段LLM接收todo状态并继续执行LLM接收到的上下文{role:user,content:[{type:tool_result,tool_use_id:toolu_01,content:[ ] #1: 创建Python脚本文件\n[ ] #2: 编写第一个函数\n[ ] #3: 编写第二次函数\n[ ] #4: 编写第三个函数\n[ ] #5: 运行脚本\n\n(0/5 completed)}]}LLM处理并决定下一步{content:[{type:tool_use,id:toolu_02,name:todo,input:{items:[{id:1,text:创建Python脚本文件,status:in_progress},{id:2,text:编写第一个函数,status:pending},{id:3,text:编写第二个函数,status:pending},{id:4,text:编写第三个函数,status:pending},{id:5,text:运行脚本,status:pending}]}}]}注意LLM将第一个任务的状态从pending改为in_progress同时保持其他任务不变。第6阶段执行实际任务Todo状态更新后[] #1: 创建Python脚本文件 [ ] #2: 编写第一个函数 [ ] #3: 编写第二个函数 [ ] #4: 编写第三个函数 [ ] #5: 运行脚本 (0/5 completed)LLM继续执行write_file工具{content:[{type:tool_use,id:toolu_03,name:write_file,input:{path:script.py,content:def function1():\n pass\n\ndef function2():\n pass\n\ndef function3():\n pass\n}}]}其他工具的执行# write_file工具的执行defrun_write(path:str,content:str)-str:try:fpsafe_path(path)fp.parent.mkdir(parentsTrue,exist_okTrue)fp.write_text(content)returnfWrote{len(content)}bytesexceptExceptionase:returnfError:{e}第7阶段任务完成并更新todo状态LLM完成第一个任务后更新todo{content:[{type:tool_use,id:toolu_04,name:todo,input:{items:[{id:1,text:创建Python脚本文件,status:completed},{id:2,text:编写第一个函数,status:pending},{id:3,text:编写第二个函数,status:pending},{id:4,text:编写第三个函数,status:pending},{id:5,text:运行脚本,status:pending}]}}]}更新后的todo状态[x] #1: 创建Python脚本文件 [ ] #2: 编写第一个函数 [ ] #3: 编写第二个函数 [ ] #4: 编写第三个函数 [ ] #5: 运行脚本 (1/5 completed)第8阶段迭代执行剩余任务重复第5-7阶段直到所有任务完成轮次3: 开始任务2 [] #2: 编写第一个函数 (1/5 completed) 轮次4: 完成任务2开始任务3 [x] #2: 编写第一个函数 [] #3: 编写第二个函数 (2/5 completed) 轮次5: 完成任务3开始任务4 [x] #3: 编写第二个函数 [] #4: 编写第三个函数 (3/5 completed) 轮次6: 完成任务4开始任务5 [x] #4: 编写第三个函数 [] #5: 运行脚本 (4/5 completed) 轮次7: 完成任务5 [x] #5: 运行脚本 (5/5 completed)第9阶段nag reminder机制如果LLM忘记更新todo状态# 假设LLM连续3轮没有调用todo工具rounds_since_todo0# 第1轮调用了todorounds_since_todo1# 第2轮没有调用todorounds_since_todo2# 第3轮没有调用todorounds_since_todo3# 第4轮没有调用todo# 触发nag reminderifrounds_since_todo3:results.append({type:text,text:reminderUpdate your todos./reminder})LLM收到提醒后的反应{role:user,content:[{type:tool_result,tool_use_id:toolu_10,content:Script executed successfully},{type:text,text:reminderUpdate your todos./reminder}]}LLM被提醒后会立即更新todo状态。四、完整流程图┌─────────────────────────────────────────────────────────────────┐ │ 初始化阶段 │ │ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │ │ │TodoManager │ │Tool Handlers │ │ System Prompt │ │ │ │ .items[] │ │ (5 tools) │ │ Use todo tool │ │ │ └─────────────┘ └──────────────┘ └─────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第1轮用户输入 │ │ User: 帮我创建一个Python脚本包含三个函数然后运行它 │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ LLM处理并调用todo工具 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ todo tool call: │ │ │ │ [ ] │ │ │ │ 1. 创建Python脚本文件 │ │ │ │ 2. 编写第一个函数 │ │ │ │ 3. 编写第二个函数 │ │ │ │ 4. 编写第三个函数 │ │ │ │ 5. 运行脚本 │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ TodoManager处理并返回状态标签 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Validation: ✓ (5 items, all valid) │ │ │ │ State Update: ✓ │ │ │ │ Rendered Output: │ │ │ │ [ ] #1: 创建Python脚本文件 │ │ │ │ [ ] #2: 编写第一个函数 │ │ │ │ [ ] #3: 编写第二个函数 │ │ │ │ [ ] #4: 编写第三个函数 │ │ │ │ [ ] #5: 运行脚本 │ │ │ │ (0/5 completed) │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ LLM接收状态标签并规划下一步 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ LLM思考我需要开始第一个任务 │ │ │ │ Action: 更新todo标记任务1为in_progress │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第2轮更新todo状态 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ [] #1: 创建Python脚本文件 ← 进行中 │ │ │ │ [ ] #2: 编写第一个函数 │ │ │ │ [ ] #3: 编写第二个函数 │ │ │ │ [ ] #4: 编写第三个函数 │ │ │ │ [ ] #5: 运行脚本 │ │ │ │ (0/5 completed) │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第3轮执行实际任务write_file │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ write_file(script.py, content) │ │ │ │ Output: Wrote 123 bytes │ │ │ │ rounds_since_todo 1 (没有调用todo) │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第4轮LLM完成任务1更新todo状态 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ [x] #1: 创建Python脚本文件 ← 完成 │ │ │ │ [] #2: 编写第一个函数 ← 开始下一个 │ │ │ │ [ ] #3: 编写第二个函数 │ │ │ │ [ ] #4: 编写第三个函数 │ │ │ │ [ ] #5: 运行脚本 │ │ │ │ (1/5 completed) ← 进度更新 │ │ │ │ rounds_since_todo 0 (重置计数器) │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第5-7轮迭代执行剩余任务 │ │ 重复类似过程每次 │ │ 1. LLM标记当前任务为in_progress │ │ 2. 执行相应的工具操作 │ │ 3. 完成后标记为completed │ │ 4. 开始下一个任务 │ │ 5. rounds_since_todo计数器管理 │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 第8轮所有任务完成 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ [x] #1: 创建Python脚本文件 │ │ │ │ [x] #2: 编写第一个函数 │ │ │ │ [x] #3: 编写第二个函数 │ │ │ │ [x] #4: 编写第三个函数 │ │ │ │ [x] #5: 运行脚本 │ │ │ │ (5/5 completed) ← 全部完成 │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Nag Reminder机制可选 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 如果LLM连续3轮没有调用todo │ │ │ │ rounds_since_todo 3 │ │ │ │ → 注入: reminderUpdate your todos./reminder │ │ │ │ → LLM收到提醒后立即更新todo状态 │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 任务完成返回结果 │ │ LLM: 我已经完成了所有任务创建了脚本编写了三个函数并运行了 │ │ 脚本。所有任务都已完成 (5/5)。 │ └─────────────────────────────────────────────────────────────────┘五、关键机制详解1. TodoManager的状态管理三态系统pending: [ ] 待处理in_progress: [] 进行中同时只能有一个completed: [x] 已完成约束条件最多20个todo项目同时只能有一个任务处于in_progress状态每个项目必须有id、text、status字段2. rounds_since_todo计数器作用跟踪LLM连续多少轮没有调用todo工具防止LLM忘记更新任务状态逻辑# 调用了todo工具 → 重置计数器rounds_since_todo0ifused_todoelserounds_since_todo1# 超过阈值 → 注入提醒ifrounds_since_todo3:results.append({type:text,text:reminderUpdate your todos./reminder})3. 进度可见性实时反馈(x/y completed) ← 进度百分比 [] 当前任务 ← 视觉指示器 [x] 已完成任务 ← 完成标记 [ ] 待处理任务 ← 待办标记双重可见性LLM内部可见: 通过工具返回的结果看到当前状态外部观察者可见: 通过打印输出看到实时进度六、与传统方法的对比传统脚本式代理# 预定义的固定步骤step1()step2()step3()step4()step5()TodoWrite智能代理# LLM自主规划和跟踪LLM决定:我需要5个步骤LLM执行:每步完成后更新状态 LLM适应:可根据实际情况调整计划七、核心洞察“The agent can track its own progress – and I can see it.”这个设计的精髓在于自我跟踪: LLM通过todo工具主动管理自己的进度外部可见: 整个过程对观察者完全透明轻量提醒: 使用nag reminder而非强制脚本灵活性: LLM可以自主调整计划不被固定步骤束缚八、适用场景✅适合TodoWrite的场景多步骤复杂任务需要进度跟踪的任务灵活性和适应性要求高的任务调试和观察LLM推理过程❌不适合TodoWrite的场景简单单步任务需要严格固定执行顺序的任务对性能要求极高的实时系统九、总结TodoWrite通过简单的todo工具和TodoManager实现了让LLM自我跟踪进度的能力。关键在于状态标签: 每次todo调用都返回当前状态标签LLM自主决策: LLM根据状态标签决定下一步行动迭代执行: 逐步完成任务并更新状态轻量监督: nag reminder确保LLM不会忘记更新状态完全可见: 整个过程对观察者透明这种设计既保持了LLM的自主性又提供了必要的结构化约束是软约束设计的典型例子。以下是您提供的相关文章的链接可直接点击阅读【claude code agent 实践1】Agent Loop 永动机与工具扩展机制详解[S02]【claude code agent 实践2】TodoWrite 详细执行流程分析:从S02到S03的演进【claude code agent 实践3】Subagent子智能体机制深度解析从S02到S04的演进【claude code agent 实践4】Skill技能加载机制深度解析从S02到S05的演进【claude code agent 实践5】Claude Code 上下文压缩机制深度解析: 从S02到S06的演进如需进一步扩展相关内容可参考上述文章的实践案例或技术细节。