跳轉到主要內容
待辦事項追蹤提供了一種結構化的方式來管理任務並向用戶顯示進度。Claude Agent SDK 包含內置的待辦事項功能,可幫助組織複雜的工作流程並讓用戶了解任務進度。
自 TypeScript Agent SDK 0.3.142 和 Claude Code v2.1.142 起,會話使用結構化的 Task 工具 TaskCreateTaskUpdateTaskGetTaskList,而不是 TodoWrite。請參閱遷移到 Task 工具以了解監控代碼如何變更。此頁面上的範例設置 CLAUDE_CODE_ENABLE_TASKS=0 以繼續為尚未遷移的會話顯示 TodoWrite

待辦事項生命週期

待辦事項遵循可預測的生命週期:
  1. 建立pending 當任務被識別時
  2. 啟動in_progress 當工作開始時
  3. 完成當任務成功完成時
  4. 移除當群組中的所有任務都完成時

何時使用待辦事項

SDK 會自動為以下情況建立待辦事項:
  • 複雜的多步驟任務需要 3 個或更多不同的操作
  • 用戶提供的任務清單當提及多個項目時
  • 非平凡的操作受益於進度追蹤
  • 明確的請求當用戶要求待辦事項組織時

範例

監控待辦事項變更

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Optimize my React app performance and track progress with todos",
  // Re-enable TodoWrite, which this example monitors. Without it, the SDK uses
  // Task tools instead and these tool_use blocks never appear.
  options: { maxTurns: 15, env: { ...process.env, CLAUDE_CODE_ENABLE_TASKS: "0" } }
})) {
  // Todo updates are reflected in the message stream
  if (message.type === "assistant") {
    for (const block of message.message.content) {
      if (block.type === "tool_use" && block.name === "TodoWrite") {
        const todos = block.input.todos;

        console.log("Todo Status Update:");
        todos.forEach((todo, index) => {
          const status =
            todo.status === "completed" ? "✅" : todo.status === "in_progress" ? "🔧" : "❌";
          console.log(`${index + 1}. ${status} ${todo.content}`);
        });
      }
    }
  }
}

實時進度顯示

import { query } from "@anthropic-ai/claude-agent-sdk";

class TodoTracker {
  private todos: any[] = [];

  displayProgress() {
    if (this.todos.length === 0) return;

    const completed = this.todos.filter((t) => t.status === "completed").length;
    const inProgress = this.todos.filter((t) => t.status === "in_progress").length;
    const total = this.todos.length;

    console.log(`\nProgress: ${completed}/${total} completed`);
    console.log(`Currently working on: ${inProgress} task(s)\n`);

    this.todos.forEach((todo, index) => {
      const icon =
        todo.status === "completed" ? "✅" : todo.status === "in_progress" ? "🔧" : "❌";
      const text = todo.status === "in_progress" ? todo.activeForm : todo.content;
      console.log(`${index + 1}. ${icon} ${text}`);
    });
  }

  async trackQuery(prompt: string) {
    for await (const message of query({
      prompt,
      // Re-enable TodoWrite, which this tracker watches for.
      options: { maxTurns: 20, env: { ...process.env, CLAUDE_CODE_ENABLE_TASKS: "0" } }
    })) {
      if (message.type === "assistant") {
        for (const block of message.message.content) {
          if (block.type === "tool_use" && block.name === "TodoWrite") {
            this.todos = block.input.todos;
            this.displayProgress();
          }
        }
      }
    }
  }
}

// Usage
const tracker = new TodoTracker();
await tracker.trackQuery("Build a complete authentication system with todos");

遷移到 Task 工具

Task 工具將單個 TodoWrite 呼叫分割為每個新項目的 TaskCreate 和每個狀態變更的 TaskUpdate,並提供 TaskListTaskGet 供模型讀回當前清單。您的監控代碼仍然檢查助手流中的 tool_use 區塊,但維護一個由任務 ID 鍵入的映射,而不是在每次呼叫時替換整個清單。Task 工具是 TypeScript Agent SDK 0.3.142 和 Claude Code v2.1.142 起的預設值,因此不需要 options.env 變更。
使用 TodoWrite使用 Task 工具
一個工具呼叫重寫完整的 todos 陣列TaskCreate 新增一個項目,TaskUpdatetaskId 修補一個項目
匹配 block.name === "TodoWrite"匹配 block.name === "TaskCreate""TaskUpdate"
項目形狀:{ content, status, activeForm }TaskCreate 輸入:{ subject, description, activeForm?, metadata? }TaskUpdate 輸入:{ taskId, status?, subject?, description?, activeForm?, addBlocks?, addBlockedBy?, owner?, metadata? }status"pending""in_progress""completed";設置 status: "deleted" 以刪除
直接呈現 block.input.todos跨呼叫累積項目,或從 TaskList 工具結果讀取快照
指派的任務 ID 不在 TaskCreate 輸入中。它在匹配的 tool_result 中作為 { task: { id, subject } } 返回,因此從結果區塊捕獲它以鍵入您的映射。以下範例顯示了對監控待辦事項變更迴圈的最小變更。要呈現完整清單,請在流中監視 TaskList 工具結果或將 TaskCreate 結果和 TaskUpdate 輸入累積到映射中:
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Optimize my React app performance",
})) {
  if (message.type !== "assistant") continue;
  for (const block of message.message.content) {
    if (block.type !== "tool_use") continue;
    if (block.name === "TaskCreate") {
      const input = block.input as { subject: string };
      console.log(`+ ${input.subject}`);
    } else if (block.name === "TaskUpdate") {
      const input = block.input as { taskId: string; status?: string };
      if (input.status) console.log(`  ${input.taskId} -> ${input.status}`);
    }
  }
}

相關文檔