# 第二阶段 · 模块二 · 第七节:Task 任务系统
什么是 Task 系统?Claude Code 如何创建和管理任务?任务输出如何管理?任务间如何处理依赖关系?
Claude Code 全局架构
┌─────────────────────────────────────────────────────────────────────┐
│ 工具层(tools/) │
│ │
│ Task 系统 ← 本节 │
│ ├── TaskCreateTool │
│ ├── 任务追踪 │
│ └── 输出管理 │
└─────────────────────────────────────────────────────────────────────┘
源码位置:`src/tools/TaskCreateTool/`
Task 是 Claude Code 中用于追踪长时间运行任务的机制,提供任务创建、追踪、输出管理和依赖处理。
┌─────────────────────────────────────────────────────────────────────┐
│ Task 系统架构 │
│ │
│ TaskCreate ──► TaskRunner ──► TaskOutput │
│ │ │ │ │
│ 创建任务 执行任务 管理输出 │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ Task vs Subagent │
│ │
│ Task: │
│ - 后台长时间运行 │
│ - 输出持久化 │
│ - 可追踪、可管理 │
│ - 支持依赖关系 │
│ │
│ Subagent: │
│ - 主代理启动 │
│ - 共享上下文 │
│ - 简单通信 │
└─────────────────────────────────────────────────────────────────────┘
问 1:Task 和子代理有什么区别?
// 子代理:
// - 独立会话
// - 适合复杂推理
// - 与主代理通信
// Task:
// - 后台任务
// - 适合长时间运行
// - 输出持久化
源码位置:`src/tools/TaskCreateTool/TaskCreateTool.ts`
export const TaskCreateTool = buildTool({
name: TASK_CREATE_TOOL_NAME,
searchHint: 'create a task in the task list',
maxResultSizeChars: 100_000,
shouldDefer: true,
isConcurrencySafe() {
return true
},
inputSchema: z.strictObject({
subject: z.string().describe('A brief title for the task'),
description: z.string().describe('What needs to be done'),
activeForm: z.string().optional().describe(
'Present continuous form shown in spinner when in_progress (e.g., "Running tests")'
),
metadata: z.record(z.string(), z.unknown()).optional().describe(
'Arbitrary metadata to attach to the task'
),
}),
outputSchema: z.object({
task: z.object({
id: z.string(),
subject: z.string(),
}),
}),
})
// 创建任务
async function createTask(input: TaskInput): Promise<TaskId> {
// 1. 验证输入
const validated = inputSchema.parse(input)
// 2. 生成任务 ID
const taskId = generateTaskId()
// 3. 初始化任务状态
await initTaskState(taskId, {
subject: validated.subject,
description: validated.description,
activeForm: validated.activeForm,
status: 'pending',
createdAt: Date.now()
})
// 4. 返回任务 ID
return taskId
}
// 任务元数据支持任意键值对
interface TaskMetadata {
// 自定义元数据
priority?: 'low' | 'medium' | 'high'
tags?: string[]
assignee?: string
dueDate?: string
// ... 任意自定义字段
}
const task = await TaskCreateTool.call({
subject: 'Review PR #123',
description: 'Review the pull request changes',
metadata: {
prNumber: 123,
author: 'john',
priority: 'high'
}
})
源码位置:`src/tasks/TaskState.ts`
// 任务状态
interface TaskState {
taskId: string
description: string
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'
createdAt: number
startedAt?: number
completedAt?: number
agentId?: string
output?: TaskOutput
error?: string
}
┌─────────────────────────────────────────────────────────────────────┐
│ 任务状态流转 │
│ │
│ pending ──► running ──► completed │
│ │ │ │
│ │ ▼ │
│ └──────► failed │
│ │ │
│ ▼ │
│ cancelled │
└─────────────────────────────────────────────────────────────────────┘
// 更新任务状态
async function updateTaskStatus(
taskId: string,
status: TaskState['status'],
updates?: Partial<TaskState>
): Promise<void> {
// 1. 读取当前状态
const current = await getTaskState(taskId)
// 2. 验证转换
if (!isValidTransition(current.status, status)) {
throw new Error(`Invalid transition: ${current.status} -> ${status}`)
}
// 3. 更新状态
await saveTaskState(taskId, {
...current,
status,
...updates
})
}
源码位置:`src/utils/task/diskOutput.ts`
// 任务输出存储
interface TaskOutput {
taskId: string
stdout: string
stderr: string
exitCode: number
files?: string[] // 生成的文件列表
}
// 存储位置
const TASK_OUTPUT_DIR = '~/.claude/tasks/'
function getOutputPath(taskId: string): string {
return `${TASK_OUTPUT_DIR}/${taskId}/output.txt`
}
// 处理任务输出流
async function handleTaskOutput(
taskId: string,
chunk: string
): Promise<void> {
// 1. 追加到输出文件
await appendToFile(getOutputPath(taskId), chunk)
// 2. 更新内存状态
await updateTaskOutput(taskId, chunk)
// 3. 触发回调(如有)
notifyOutputListeners(taskId, chunk)
}
问 1:任务输出会丢失吗?
// 可靠性保证:
// 1. 实时写入磁盘
// - 每块输出立即写入
// - 不在内存中缓存
// 2. 原子操作
// - 使用临时文件
// - 完成后移动
// 3. 定期检查点
// - 保存中间状态
// - 支持断点续传
// 任务依赖
interface TaskDependency {
taskId: string
type: 'blocking' | 'notify'
}
interface TaskWithDeps {
taskId: string
dependencies: TaskDependency[]
}
// 处理任务依赖
async function executeWithDeps(task: TaskWithDeps): Promise<void> {
// 1. 检查依赖
const pendingDeps = task.dependencies.filter(
dep => getTaskStatus(dep.taskId) !== 'completed'
)
if (pendingDeps.length > 0) {
// 2. 等待依赖完成
await Promise.all(
pendingDeps.map(dep => waitForTask(dep.taskId))
)
}
// 3. 执行任务
await executeTask(task.taskId)
}
# 列出所有任务
/tasks
# 查看任务详情
/tasks show <task-id>
# 取消任务
/tasks cancel <task-id>
# 清理已完成任务
/tasks clean
// 任务列表格式
Tasks:
├─ task-001 [running] 分析代码库
├─ task-002 [pending] 生成文档
└─ task-003 [completed] 运行测试
// 创建后台分析任务
const analysisTask = await createTask({
description: '分析代码库结构',
prompt: '分析这个代码库的结构,生成架构文档',
cwd: '/path/to/project'
})
// 继续其他工作
await doOtherWork()
// 稍后检查结果
const result = await getTaskResult(analysisTask)
// 创建任务依赖链
const task1 = await createTask({
description: '数据采集',
prompt: '采集数据...'
})
const task2 = await createTask({
description: '数据处理',
prompt: '处理数据...',
dependencies: [{ taskId: task1, type: 'blocking' }]
})
const task3 = await createTask({
description: '生成报告',
prompt: '生成报告...',
dependencies: [{ taskId: task2, type: 'blocking' }]
})
答案:
// 限制:
// 1. 资源限制
// - 同时运行的任务数有限
// - 避免资源耗尽
// 2. 超时限制
// - 长时间任务可能超时
// - 需要续期
// 3. 清理
// - 任务结果需要手动清理
// - 占用磁盘空间
答案:
// 调试方法:
// 1. 查看任务状态
// /tasks show <task-id>
// 2. 查看输出
// cat ~/.claude/tasks/<task-id>/output.txt
// 3. 查看日志
// ~/.claude/logs/tasks/<task-id>.log
答案:
// 死锁处理:
// 1. 检测循环依赖
function detectCycle(tasks: Task[]): Task[] | null {
const visited = new Set()
const path = []
for (const task of tasks) {
if (dfs(task, visited, path)) {
return path // 返回环
}
}
return null
}
// 2. 打破循环
// - 优先级高的任务优先
// - 超时自动跳过
// 3. 预防策略
// - 按字母顺序破环
// - 设置最大等待时间
答案:
// 持久化策略:
// 1. 实时写入
// - 每块输出立即写入磁盘
// - 使用追加模式
// 2. 原子操作
// - 先写临时文件
// - 完成后移动
// 3. 输出结构
interface TaskOutput {
taskId: string
stdout: string
stderr: string
exitCode: number
timestamp: number
}
// 4. 清理策略
// - 定期清理旧输出
// - 保留最近 N 个
| 资源 | 说明 |
| `src/tools/TaskCreateTool/TaskCreateTool.ts` | 任务创建工具 |
| `src/utils/task/diskOutput.ts` | 输出管理 |
| `src/tasks/TaskState.ts` | 状态管理 |