AGENTUPDATE 技术博客

Claude Code Dynamic Workflow 上手指南:多 Agent 编排

Claude Code Dynamic Workflow 上手指南:多 Agent 编排
目录

基于真实实践总结,面向初学者的完整教学指南


目录


1. 什么是 Dynamic Workflow

Dynamic Workflow 是 Claude Code v2.1.154+ 引入的多 agent 编排引擎。你写一段 JavaScript 脚本,它按你的逻辑自动 spawn 多个子 agent,并行或串行执行任务,最终汇总结果。

一句话:用代码控制多个 AI agent 协作干活。

适用场景

场景 示例
批量处理 8道数学题并行解
流水线 解题 → 验证 → 打分
大规模审查 100个文件并行 review
多视角分析 同一问题从安全/性能/可读性角度分别评估

2. 核心概念速览

概念 说明
meta 脚本头部声明,定义名称、描述、阶段
agent() spawn 一个子 agent,返回结果
pipeline() 串行流水线:每项数据依次通过多个阶段
parallel() 并行执行:多个任务同时跑
phase() 声明当前阶段(用于 UI 进度展示)
log() 输出日志到用户界面
args 外部传入的参数
budget 当前 turn 的 token 预算控制

执行模型

graph TD
    A[用户触发 Workflow] --> B[解析 meta]
    B --> C{编排逻辑}
    C -->|串行| D[pipeline: item → stage1 → stage2 → stage3]
    C -->|并行| E[parallel: task1 | task2 | task3 同时跑]
    C -->|混合| F[parallel + pipeline 嵌套]
    D --> G[汇总返回结果]
    E --> G
    F --> G

3. 目录结构

.claude/
├── workflows/              # Workflow 脚本存放目录
│   └── math-problems.js    # 一个 workflow = 一个 .js 文件
├── agents/                 # 自定义 agent 定义(⚠️ workflow 无法引用)
│   ├── math-solver.md      # 仅用于主会话自动路由
│   └── math-verifier.md
└── settings.json           # 项目配置

Workflow 文件结构

每个 .js 文件固定格式:

export const meta = {
  name: 'my-workflow',           // 必填:唯一标识
  description: '一句话描述',      // 必填:说明用途
  phases: [                      // 可选:定义阶段(UI 展示用)
    { title: 'Analyze' },
    { title: 'Execute' },
  ],
}

// ... 你的编排逻辑
// 用 agent() / pipeline() / parallel() 编排
// 最后 return 结果

4. 第一个 Workflow:Hello World

最简版本

export const meta = {
  name: 'hello',
  description: '最简单的 workflow',
  phases: [{ title: 'Greet' }],
}

const result = await agent('说一句 hello world', { phase: 'Greet' })
return result

带参数版本

export const meta = {
  name: 'hello-name',
  description: '打招呼',
}

// args 由外部传入
const name = (args && args.name) || 'World'
const result = await agent(`对 ${name} 说你好,介绍自己`)
return result

⚠️ 重要: 通过 name 引用 workflow 时 args 可能不传递!建议总是提供默认值,或使用内联 script 调用。


5. 内置 API 详解

5.1 agent() — 生成子 agent

// 基础用法
const result = await agent('你的提示词')

// 完整参数
const result = await agent('你的提示词', {
  label: '显示名称',           // UI 中显示的标签
  phase: 'Solve',             // 归属阶段
  schema: {                   // 强制结构化输出(JSON Schema)
    type: 'object',
    properties: {
      answer: { type: 'string' },
      confidence: { type: 'number' }
    }
  },
  model: 'sonnet',            // 可选模型覆盖
  agentType: 'Explore',       // ⚠️ 仅支持内置类型,不支持自定义
})

5.2 pipeline() — 串行流水线

数据依次通过每个阶段,前一个阶段的输出是下一个阶段的输入:

graph LR
    A[数据项] -->|stage1| B[中间结果1]
    B -->|stage2| C[中间结果2]
    C -->|stage3| D[最终结果]

    style A fill:#e1f5fe
    style D fill:#c8e6c9
const results = await pipeline(
  ['题1', '题2', '题3'],         // 数据数组
  (item) => agent(`处理: ${item}`),     // stage 1
  (prev, item) => agent(`审核: ${prev}`), // stage 2
)

// results[0] = stage2(题1) 的结果
// results[1] = stage2(题2) 的结果
// 每个数据项独立走完整个 pipeline,不同项之间并行

关键特性: pipeline 内部每项数据独立流转,item A 在 stage 3 时 item B 可能还在 stage 1。总耗时 = 最慢的单项链路,而非所有阶段之和。

5.3 parallel() — 并行屏障

所有任务同时开始,全部完成后才返回:

graph TD
    A[parallel 启动] --> B[Task 1]
    A --> C[Task 2]
    A --> D[Task 3]
    B --> E[汇总结果]
    C --> E
    D --> E

    style A fill:#fff9c4
    style E fill:#c8e6c9
const results = await parallel([
  () => agent('分析前端代码'),
  () => agent('分析后端代码'),
  () => agent('分析数据库'),
])

// results = [前端分析, 后端分析, 数据库分析]
// 任一失败返回 null,用 .filter(Boolean) 过滤

5.4 phase() 和 log()

phase('Review')          // 切换到 Review 阶段(UI 进度条分组)
log('已处理 3/10 个文件')  // 输出进度信息

6. 实战:数学题 Pipeline

设计原则:题目直接写在 prompt 里。 每组题目作为一个整体,通过 prompt 模板传入 agent,初学者一眼就能看清分组结构和数据流转。

架构图

graph TD
    subgraph "题目分组(直接写在 prompt)"
        G1["第一组(基础计算)
12×15, √144+3², 2^10, ..."] G2["第二组(进阶题目)
100!末尾0, sin30°×cos60°, ..."] end subgraph "Pipeline 流水线(每组整体处理)" S1["🧮 Solve
整组题目写在 prompt"] V1["✅ Verify
题目+解答写在 prompt"] SC1["📊 Score
题目+验证结果写在 prompt"] S1 --> V1 --> SC1 end G1 -->|"prompt 含组1题目"| S1 G2 -->|"prompt 含组2题目"| S1 SC1 --> R["按组汇总结果"] style G1 fill:#e3f2fd style G2 fill:#fce4ec style S1 fill:#bbdefb style V1 fill:#c8e6c9 style SC1 fill:#fff9c4 style R fill:#f8bbd0

数据流详解

每组的数据流(以第一组为例):

┌─────────────────────────────────────────────────┐
│ Stage 1: Solver                                 │
│ prompt = SOLVER_PROMPT + 组1全部题目             │
│ output = 5道题的详细解答                         │
└──────────────────────┬──────────────────────────┘
                       │ solution (上一阶段输出)
┌──────────────────────▼──────────────────────────┐
│ Stage 2: Verifier                               │
│ prompt = VERIFIER_PROMPT + 组1题目 + solution   │
│ output = 逐题验证结果(✅/❌)                   │
└──────────────────────┬──────────────────────────┘
                       │ verification (上一阶段输出)
┌──────────────────────▼──────────────────────────┐
│ Stage 3: Scorer                                 │
│ prompt = SCORER_PROMPT + 组1题目 + verification │
│ output = 每道题的分数和评语                      │
└─────────────────────────────────────────────────┘

实际 Prompt 示例(模板替换后)

下面展示 .replace('{problems_block}', ...) 执行后,真正发给 agent 的完整 prompt

Stage 1 — Solver 收到的 prompt(第一组)

你是一位数学解题专家。请逐一解答以下数学题。

1. 12 × 15 = ?
2. √144 + 3² = ?
3. 2^10 = ?
4. 1 + 2 + 3 + ... + 100 = ?
5. 1/2 + 1/3 + 1/6 = ?

输出格式(每道题):
- 题目:{原题}
- 解题过程:{逐步推导}
- 答案:{最终结果}

Stage 1 — Solver 收到的 prompt(第二组)

你是一位数学解题专家。请逐一解答以下数学题。

6. 100! 末尾有多少个 0?
7. sin30° × cos60° = ?
8. log₂1024 = ?
9. 一个圆的周长是 31.4cm,求面积(π≈3.14)
10. 解方程:2x + 5 = 17

输出格式(每道题):
- 题目:{原题}
- 解题过程:{逐步推导}
- 答案:{最终结果}

Stage 2 — Verifier 收到的 prompt(第一组,含解答)

你是一位数学验证专家。独立重新解题,对比下面的解答。

1. 12 × 15 = ?
2. √144 + 3² = ?
3. 2^10 = ?
4. 1 + 2 + 3 + ... + 100 = ?
5. 1/2 + 1/3 + 1/6 = ?

=== 待验证的解答 ===
[Solver 的完整输出会插入这里]

=== 要求 ===
- 独立计算,不可信任给出的解答
- 逐步对比,标注对错
- 有错误则精确指出位置

输出格式:
- 判定:✅ 正确 / ❌ 错误
- 验证过程:{独立推导}
- 错误原因:{如有}

Stage 3 — Scorer 收到的 prompt(第一组,含验证结果)

你是数学评分专家。综合解题和验证结果打分。

1. 12 × 15 = ?
2. √144 + 3² = ?
3. 2^10 = ?
4. 1 + 2 + 3 + ... + 100 = ?
5. 1/2 + 1/3 + 1/6 = ?

=== 验证结果 ===
[Verifier 的完整输出会插入这里]

评分:10=完美 | 7-9=正确可改进 | 4-6=部分正确 | 0-3=错误

输出格式:
- 分数:{0-10}
- 评语:{一句话}

关键点: {problems_block} 在每个阶段都被同一组题目替换,{solution} / {verification} 被上一阶段的输出替换。每个 agent 都能看到完整上下文,不需要猜测题目是什么。

完整代码

export const meta = {
  name: 'math-problems',
  description: '数学题 workflow — 题目按组写入 prompt,3阶段 pipeline(解题→验证→评分)',
  phases: [
    { title: 'Solve', detail: '每组并行解题' },
    { title: 'Verify', detail: '独立验证每组解答' },
    { title: 'Score', detail: '综合评分' },
  ],
}

// ─── Prompt 模板(顶部定义,一目了然)──────────────
// {problems_block}  → 该组所有题目
// {solution}        → Solver 的输出
// {verification}    → Verifier 的输出

const SOLVER_PROMPT = `你是一位数学解题专家。请逐一解答以下数学题。

{problems_block}

输出格式(每道题):
- 题目:{原题}
- 解题过程:{逐步推导}
- 答案:{最终结果}`

const VERIFIER_PROMPT = `你是一位数学验证专家。独立重新解题,对比下面的解答。

{problems_block}

=== 待验证的解答 ===
{solution}

=== 要求 ===
- 独立计算,不可信任给出的解答
- 逐步对比,标注对错
- 有错误则精确指出位置

输出格式:
- 判定:✅ 正确 / ❌ 错误
- 验证过程:{独立推导}
- 错误原因:{如有}`

const SCORER_PROMPT = `你是数学评分专家。综合解题和验证结果打分。

{problems_block}

=== 验证结果 ===
{verification}

评分:10=完美 | 7-9=正确可改进 | 4-6=部分正确 | 0-3=错误

输出格式:
- 分数:{0-10}
- 评语:{一句话}`

// ─── 题目分组(直接写在这里,初学者直接改)──────────
const DEFAULT_GROUPS = [
  {
    name: '第一组(基础计算)',
    problems: [
      '1. 12 × 15 = ?',
      '2. √144 + 3² = ?',
      '3. 2^10 = ?',
      '4. 1 + 2 + 3 + ... + 100 = ?',
      '5. 1/2 + 1/3 + 1/6 = ?',
    ],
  },
  {
    name: '第二组(进阶题目)',
    problems: [
      '6. 100! 末尾有多少个 0?',
      '7. sin30° × cos60° = ?',
      '8. log₂1024 = ?',
      '9. 一个圆的周长是 31.4cm,求面积(π≈3.14)',
      '10. 解方程:2x + 5 = 17',
    ],
  },
]

// ─── 主流程 ─────────────────────────────────────────
const groups = (args && args.groups && args.groups.length)
  ? args.groups
  : DEFAULT_GROUPS

log(`共 ${groups.reduce((n, g) => n + g.problems.length, 0)} 道题,${groups.length} 组`)
groups.forEach((g) => log(`  ${g.name}: ${g.problems.join(', ')}`))

// 每组并行跑 pipeline,题目直接写在 prompt 里
const results = await parallel(
  groups.map((group) => () => {
    const problemsBlock = group.problems.join('\n')
    return pipeline(
      [group],  // 整组作为一个单元
      // Stage 1: 解题
      (grp) => agent(
        SOLVER_PROMPT.replace('{problems_block}', grp.problems.join('\n')),
        { label: `${grp.name}-解题`, phase: 'Solve' }
      ),
      // Stage 2: 验证
      (solution, grp) => agent(
        VERIFIER_PROMPT
          .replace('{problems_block}', grp.problems.join('\n'))
          .replace('{solution}', solution),
        { label: `${grp.name}-验证`, phase: 'Verify' }
      ),
      // Stage 3: 评分
      (verification, grp) => agent(
        SCORER_PROMPT
          .replace('{problems_block}', grp.problems.join('\n'))
          .replace('{verification}', verification),
        { label: `${grp.name}-评分`, phase: 'Score' }
      ),
    )
  })
)

// 按组返回
const output = {}
groups.forEach((g, i) => output[g.name] = results[i][0])
return output

调用方式

在 Claude Code 里直接说"跑 workflow math-problems"就行。 Claude 会调用 Workflow 工具执行。

方式1:使用默认题目(10题2组)

直接让 Claude 跑:

跑 workflow math-problems

Claude 执行:

Workflow({ name: 'math-problems' })

方式2:自定义题目分组(通过 args 传入)

告诉 Claude 具体的题目和分组:

跑 workflow math-problems,8道题分4组:
12×15, √144+3², 2^10, 100!末尾几个0,
1+2+...+100, sin30°×cos60°, log₂1024, 1/2+1/3+1/6

Claude 执行:

Workflow({
  name: 'math-problems',
  args: {
    groups: [
      { name: '组1', problems: ['1. 12×15', '2. √144+3²'] },
      { name: '组2', problems: ['3. 2^10', '4. 100!末尾几个0'] },
      { name: '组3', problems: ['5. 1+2+...+100', '6. sin30°×cos60°'] },
      { name: '组4', problems: ['7. log₂1024', '8. 1/2+1/3+1/6'] },
    ]
  }
})

方式3:自定义分组(任意题目)

跑 workflow math-problems,分2组:
几何题:求半径5的圆面积、求边长3的正方体体积
代数题:解方程 x²-4=0、求 3x+2=14 的 x

Claude 执行:

Workflow({
  name: 'math-problems',
  args: {
    groups: [
      { name: '几何题', problems: ['求半径5的圆面积', '求边长3的正方体体积'] },
      { name: '代数题', problems: ['解方程 x²-4=0', '求 3x+2=14 的 x'] },
    ]
  }
})

提示:/workflows 查看实时进度。Workflow 跑完后结果自动返回到对话中。

为什么题目写在 prompt 里?

方式 初学者体验 维护性
动态轮询分组 看不出哪道题在哪个组,需脑补分组逻辑 改题需理解 round-robin
题目写在 prompt(✅ 当前) DEFAULT_GROUPS 直接展示分组,改题即改数组 改题目、改分组直观

7. 在 Workflow 内定义 Agent

Workflow 的 agentType 不支持 .claude/agents/ 自定义 agent。解决方案:在脚本内用 Prompt 模板 定义 agent 角色。

Prompt 模板模式(推荐)

把每个 agent 的完整指令写成字符串模板,用 {占位符} 标记数据插入点:

// ─── Prompt 模板(顶部定义,一眼看清所有 agent) ──────────

const SOLVER_PROMPT = `你是一位数学解题专家。请逐一解答以下数学题。

{problems_block}

输出格式(每道题):
- 题目:{原题}
- 解题过程:{逐步推导}
- 答案:{最终结果}`

const VERIFIER_PROMPT = `你是一位数学验证专家。独立重新解题,对比下面的解答。

{problems_block}

=== 待验证的解答 ===
{solution}

=== 要求 ===
- 独立计算,不可信任给出的解答
- 逐步对比,标注对错

输出格式:
- 判定:✅ 正确 / ❌ 错误
- 错误原因:{如有}`

const SCORER_PROMPT = `你是数学评分专家。综合解题和验证结果打分。

{problems_block}

=== 验证结果 ===
{verification}

评分:10=完美 | 7-9=正确可改进 | 4-6=部分正确 | 0-3=错误

输出格式:
- 分数:{0-10}
- 评语:{一句话}`
// ─── 模板结束 ─────────────────────────────────────────

使用:`.replace()` 填充数据

// pipeline 中用 .replace() 把数据填入模板
pipeline(
  [group],  // 整组数据
  // Stage 1: 解题
  (grp) => agent(
    SOLVER_PROMPT.replace('{problems_block}', grp.problems.join('\n')),
    { label: `${grp.name}-解题`, phase: 'Solve' }
  ),
  // Stage 2: 验证(solution 是上一阶段输出)
  (solution, grp) => agent(
    VERIFIER_PROMPT
      .replace('{problems_block}', grp.problems.join('\n'))
      .replace('{solution}', solution),
    { label: `${grp.name}-验证`, phase: 'Verify' }
  ),
  // Stage 3: 评分(verification 是上一阶段输出)
  (verification, grp) => agent(
    SCORER_PROMPT
      .replace('{problems_block}', grp.problems.join('\n'))
      .replace('{verification}', verification),
    { label: `${grp.name}-评分`, phase: 'Score' }
  ),
)

三种 Agent 定义方式对比

方式 优点 缺点 适用场景
Prompt 模板(✅ 推荐) 指令和数据分离清晰,.replace() 一看就懂 多阶段时模板较长 ≥2 阶段的 pipeline
Agent 对象 + buildPrompt() 封装好,可复用 需理解 this 绑定 多处复用同一 agent
字符串内联 最简单 prompt 和逻辑混杂 单阶段、demo

建议: 初学者用 Prompt 模板模式。模板在文件顶部,一眼看清所有 agent 角色和数据流向。


8. ⚠️ 限制与踩坑

已知限制

问题 说明 解决方案
自定义 agent 不可用 agentType 只支持内置类型,.claude/agents/ 定义的被忽略 脚本内定义 Agent 对象
args 可能丢失 通过 name 引用 workflow 时 args 可能为 undefined 内联 script 或提供默认值
不支持 TypeScript 脚本是纯 JS,类型注解会报错 用纯 JS,注释代替类型
无 Date/Math.random Date.now()Math.random() 等不可用(影响缓存) 通过 args 传入时间戳
并发上限 同时运行 agent 数 ≈ min(16, CPU核心-2) 自动排队,无需处理
总量上限 单次 workflow 最多 1000 个 agent 合理分组
7天自动过期 循环任务 7 天后自动停止 需要时重新创建

agentType 支持列表(内置)

claude, claude-code-guide, Explore, general-purpose, Plan
gsd-*, glm-plan-usage:usage-query-agent, statusline-setup

❌ 不支持:.claude/agents/ 里的自定义名称


9. 架构对比

Workflow vs 直接用 Agent Tool

graph TB
    subgraph "Workflow 方式"
        W1[JS 脚本控制流] --> W2[agent]
        W1 --> W3[agent]
        W1 --> W4[agent]
        W2 --> W5[pipeline/parallel 编排]
        W3 --> W5
        W4 --> W5
        W5 --> W6[结构化返回]
    end

    subgraph "Agent Tool 方式"
        A1[主会话 prompt] --> A2[Agent subagent_type]
        A1 --> A3[Agent subagent_type]
        A2 --> A4[手动汇总]
        A3 --> A4
    end

    style W1 fill:#bbdefb
    style A1 fill:#fff9c4
维度 Workflow Agent Tool
编排方式 JS 代码控制流 Prompt 驱动
并行能力 parallel() 原生支持 需手动 spawn 多个
流水线 pipeline() 一行搞定 需手动串联
自定义 agent ❌ 仅内置类型 subagent_type 支持自定义
args 传递 ⚠️ name 引用时可能丢失 ✅ 通过 prompt 传递
适用场景 批量、多阶段、结构化 灵活、少量 agent
复杂度 需写 JS 脚本 简单 prompt

pipeline vs parallel 选择

graph LR
    Q{数据项之间
有依赖吗?} -->|是| P[用 pipeline] Q -->|否| PR[用 parallel] Q{需要所有结果
一起处理吗?} -->|是| PR Q -->|否| P style Q fill:#fff9c4
模式 何时用 类比
pipeline 每项数据要经过多个阶段,项与项独立 工厂流水线
parallel 多个任务同时跑,全部完成后汇总 并行工程师团队
pipeline + parallel 分组并行,组内流水线 多条流水线同时开工

10. 总结

核心要点

  1. Dynamic Workflow = JS 脚本编排多 agent
  2. 三大原语: agent()pipeline()parallel()
  3. 自定义 agent 要定义在脚本内,不能引用 .claude/agents/
  4. args 传参不稳定,提供默认值或用内联 script
  5. 脚本是纯 JS,不支持 TS 语法、Date.now()Math.random()

推荐模板

export const meta = {
  name: 'my-workflow',
  description: '描述',
  phases: [{ title: 'Phase1' }, { title: 'Phase2' }],
}

// 1. Prompt 模板(顶部定义,{占位符} 标记数据位置)
const AGENT_PROMPT = `你是一位专家。

{data_block}

请按要求处理以上数据。`

// 2. 数据分组(直接定义,初学者一眼看懂)
const DEFAULT_GROUPS = [
  { name: '组A', items: ['数据1', '数据2'] },
  { name: '组B', items: ['数据3', '数据4'] },
]

const groups = (args && args.groups) || DEFAULT_GROUPS

// 3. 编排:每组并行,组内 pipeline
const results = await parallel(
  groups.map(group => () => pipeline(
    [group],
    (grp) => agent(
      AGENT_PROMPT.replace('{data_block}', grp.items.join('\n')),
      { label: `${grp.name}-阶段1`, phase: 'Phase1' }
    ),
    (prev, grp) => agent(
      '基于结果进一步处理:\n' + prev,
      { label: `${grp.name}-阶段2`, phase: 'Phase2' }
    ),
  ))
)

// 4. 按组返回
const output = {}
groups.forEach((g, i) => output[g.name] = results[i][0])
return output

进一步学习

官方文档:

社区资源:


📝 本指南基于 Claude Code Dynamic Workflow 实践总结,所有代码均经过实际运行验证。官方文档参考:Dynamic Workflows

Claude Opus 4.8 发布总结
AGENT-SYS // SYNTH

Claude Opus 4.8 发布总结

Anthropic 突发发布 Claude Opus 4.8!距离上代仅41天,这次它不仅加了便宜3倍的快速模式,还推出了能自动拆解任务、自己跑几天的「动态工作流」。它变得更诚实了,遇到不会的代码不再瞎编。一文带你大白话看懂这次硬核更新!

2026年5月29日 作者: Eric w
深度体验 Antigravity CLI 总结
AGENT-SYS // SYNTH

深度体验 Antigravity CLI 总结

本文深度评测了 Antigravity CLI 的实战表现,分析其 Agent-First 设计、高性能模型支持及性价比优势,同时指出了剪贴板支持缺失和交互繁琐等待优化点。

2026年5月27日 作者: Eric w