ClaudeCode: 怎么规划任务

在claude code源码当中,当用户下达任务后,会由plan agent进行任务拆解,但是当任务复杂并且拆解的任务数量过多时,模型非常容易忘记后续的任务,因此一个行之有效的方法就是设置一个TodoManager,强制让AI大模型将任务转化为todo list,然后再调用大模型进行下一步的规划。

核心思想

  1. LLM绑定工具,包括文件读写,执行命令,编辑文件,以及任务更新等
  2. 使用TodoManager让模型自己管理任务状态(待办/进行中/完成)
  3. 模型连续3轮不更新任务-> 自动注入提醒
  4. 全程不写四执行步骤,模型自主规划,自主推进

核心创新点

模型自己追踪进度,而不是程序硬编码流程

nag reminder提醒机制,3轮不更新todo就强制提醒

同一时间只能有一个任务进行,防止模型发生混乱

流程分析

下面我们来分析一下流程:

  1. 如果超过三次没有调用todo工具,则直接在messages中插入一条提醒消息, 并计数归零
python 复制代码
if rounds_since_todo >= 3:
    # 将提醒作为一条独立的 user 消息注入
    messages.append({
        "role": "user",
        "content": "<reminder>Update your todos.</reminder>"
    })
    # 注意:注入提醒后,计数器重置为 0 或保持?原逻辑没有重置,这里保持原样:
    # 提醒只是附加消息,不影响计数,但为避免无限提醒,可以重置 rounds_since_todo = 0
    # 建议根据需求调整,以下重置为 0 更合理:
    rounds_since_todo = 0
  1. 当大模型接受到这条最新的消息后,则会调用todo工具,其中todo工具的distpatch map是这么定义的:
python 复制代码
{
    "name": "todo", 
     "description": "Update task list. Track progress on multi-step tasks.",
     "input_schema": {
         "type": "object", 
         "properties": {
             "items": {
                 "type": "array", 
                 "items": {
                     "type": "object", 
                     "properties": {"id": {"type": "string"}, "text": {"type": "string"}, "status": {"type": "string", "enum": ["pending", "in_progress", "completed"]}}, "required": ["id", "text", "status"]}}}, "required": ["items"]}},

从代码中我们可以看出,大模型会返回一个items列表,该任务列表中会详细列举任务的id, text, 状态

然后我们看一下当大模型返回todo列表后,程序会遍历items, 检查是否所有的to do list是否合法,以及当前输入in_progress的任务是否只有一个,如果都符合要求,则进行render。 将render后的字符串组转成消息,发送给大模型,进行下一轮的任务。

这里提一下render的规则:

如果是pending任务: 渲染成: #item_id #itemtext

如果是in_progress任务: 渲染成: \> #item_id #itemtext

如果是completed任务: 渲染成: x #item_id #itemtext

python 复制代码
def update(self, items: list) -> str:
    if len(items) > 20:
        raise ValueError("Max 20 todos allowed")
    validated = []
    in_progress_count = 0
    for i, item in enumerate(items):
        text = str(item.get("text", "")).strip()
        status = str(item.get("status", "pending")).lower()
        item_id = str(item.get("id", str(i + 1)))
        if not text:
            raise ValueError(f"Item {item_id}: text required")
        if status not in ("pending", "in_progress", "completed"):
            raise ValueError(f"Item {item_id}: invalid status '{status}'")
        if status == "in_progress":
            in_progress_count += 1
        validated.append({"id": item_id, "text": text, "status": status})
    if in_progress_count > 1:
        raise ValueError("Only one task can be in_progress at a time")
    self.items = validated
    return self.render()

// reader函数 
def render(self) -> str:
    if not self.items:
        return "No todos."
    lines = []
    for item in self.items:
        marker = {"pending": "[ ]", "in_progress": "[>]", "completed": "[x]"}[item["status"]]
        lines.append(f"{marker} #{item['id']}: {item['text']}")
    done = sum(1 for t in self.items if t["status"] == "completed")
    lines.append(f"\n({done}/{len(self.items)} completed)")
    return "\n".join(lines)
相关推荐
SeaDhdhdhdhdh19 小时前
MCP Server 搭建与使用指南
java·ai·agent·mcp
李姆斯19 小时前
为啥Agent在coding表现这么好,但是在别的领域就是差的不少?
前端·agent·ai编程
nix.gnehc19 小时前
工具表之外 -- 派生、注入与两条原语
agent
uncle_ll20 小时前
大模型量化落地全解:原理、实操、效果对比与评估调优指南
大模型·llm·模型评估·量化·ptq
HIT_Weston1 天前
181、【Agent】【OpenCode】TuiThreadCmd(类型增长)(编译&运行时)
人工智能·agent·opencode
爱炼丹的James1 天前
从技术名词堆积到知识图谱:如何建立自己的大模型技术体系
人工智能·llm·知识图谱
DeepAgent1 天前
AI Agent 工程实践(31):Agent 如何部署
agent
苏灿烤鱼1 天前
官方终端 Agent 空降登顶,为什么最新版还是 alpha?
agent
nix.gnehc1 天前
工具表是怎么装满的 -- 函数、协议与聚合
agent