本教程深入讲解 Claude Code 的 Dynamic Workflow(动态工作流)系统——一种用 JavaScript 脚本编排多达 1000 个子 Agent 的多 Agent 编排引擎。适合已经掌握 Claude Code 基础操作、希望利用并行 Agent 完成大规模代码审计、跨文件迁移、深度调研等任务的进阶开发者。学完本教程,你将能够独立编写 Workflow 脚本,熟练使用 pipeline、parallel、phase 等核心编排原语,并掌握对抗性验证、预算控制、断点续跑等高级模式。
适用人群:有 3 个月以上 Claude Code 使用经验的开发者,熟悉 JavaScript 基础语法。
前置条件: - Claude Code v2.1.154+(Dynamic Workflow 在此版本正式发布) - Pro / Max / Team / Enterprise 订阅计划(Workflow 功能需要付费计划) - JavaScript 基础知识(变量、函数、async/await、数组方法) - 了解 Claude Code 的 Agent 和 Subagent 概念
在日常开发中,单个 Claude Code 会话可以很好地处理"修复这个 Bug"、"重构这个函数"等任务。但当你面对以下场景时,单 Agent 会遇到明显瓶颈:
单个 Agent 受限于上下文窗口和串行执行速度,处理这类任务要么超出上下文限制,要么耗时过长。
Dynamic Workflow 的核心思想是:Claude 自动编写一个 JavaScript 编排脚本,这个脚本协调多个子 Agent 并行工作。每个子 Agent 拥有独立的上下文窗口,专注于一个子任务,最终由编排脚本汇总结果。
graph TB
subgraph "Dynamic Workflow 架构"
A[主会话 Claude] --> B[编写 Workflow 脚本]
B --> C{脚本引擎执行}
C --> D[子 Agent 1: 安全审计]
C --> E[子 Agent 2: 性能审计]
C --> F[子 Agent 3: 可维护性审计]
D --> G[结果汇总]
E --> G
F --> G
G --> H[结构化输出]
end
style A fill:#f9f,stroke:#333
style C fill:#bbf,stroke:#333
style G fill:#bfb,stroke:#333
关键数据: - 单个 Workflow 最多可调度 1000 个子 Agent - 并发上限为 min(16, CPU核心数-2) - 脚本可持久化、版本化、断点续跑
| 原语 | 作用 | 是否阻塞 | 典型场景 |
|---|---|---|---|
agent() |
启动一个子 Agent | 异步 | 任何需要 AI 处理的子任务 |
pipeline() |
流水线处理 | 非阻塞 | 逐项走多阶段(扫描→验证→修复) |
parallel() |
并行执行屏障 | 阻塞 | 需要所有结果到齐后再处理 |
phase() |
阶段标记 | 无 | UI 进度分组显示 |
log() |
进度日志 | 无 | 向用户报告进度 |
workflow() |
嵌套子工作流 | 异步 | 复用已有 Workflow |
Workflow 脚本是纯 JavaScript(非 TypeScript),运行在异步上下文中:
// 脚本必须以 meta 声明开始
export const meta = {
name: 'my-workflow',
description: '描述这个 Workflow 做什么',
phases: [
{ title: '扫描', detail: '扫描代码库' },
{ title: '验证', detail: '对抗性验证' }
]
}
// 脚本主体
phase('扫描')
const results = await parallel([
() => agent('审计安全性', { label: '安全', phase: '扫描' }),
() => agent('审计性能', { label: '性能', phase: '扫描' })
])
重要约束:
- 脚本中不可使用 Date.now()、Math.random()、无参数 new Date()
- 无文件系统或 Node.js API 访问
- 类型注解(TypeScript)不可用
- 需要时间戳时,通过 args 传入
每次调用 Workflow 工具时,脚本会自动持久化到会话目录下:
.claude/
├── workflows/ # 持久化 Workflow 脚本
│ ├── my-audit-workflow.js # 自定义脚本
│ └── saved-workflows/ # 可通过 name 调用的已保存 Workflow
└── sessions/
└── <session-id>/
└── workflow-*.js # 自动保存的脚本副本
在 Claude Code 会话中,直接用自然语言描述你的需求,并包含关键词 "workflow" 或 "use a workflow":
> Use a workflow to review my codebase for security issues,
performance problems, and code quality
或者使用 Ultracode 模式(自动触发 Workflow):
> /ultracode Do a comprehensive code review of this repo
Claude 会自动生成类似以下的脚本:
export const meta = {
name: 'code-review',
description: 'Comprehensive code review across multiple dimensions',
phases: [
{ title: 'Review', detail: 'Review code across dimensions' },
{ title: 'Verify', detail: 'Adversarially verify findings' }
]
}
const DIMENSIONS = [
{ key: 'security', prompt: 'Review codebase for security vulnerabilities...' },
{ key: 'perf', prompt: 'Review codebase for performance issues...' },
{ key: 'quality', prompt: 'Review codebase for code quality issues...' }
]
const results = await pipeline(
DIMENSIONS,
d => agent(d.prompt, {
label: `review:${d.key}`,
phase: 'Review',
schema: {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
title: { type: 'string' },
file: { type: 'string' },
severity: { type: 'string' },
description: { type: 'string' }
}
}
}
}
}
}),
review => parallel(
review.findings.map(f => () =>
agent(`Verify this finding: ${f.title} in ${f.file}`, {
label: `verify:${f.file}`,
phase: 'Verify'
})
)
)
)
const confirmed = results.flat().filter(Boolean)
.filter(r => r.verdict?.isReal)
return { confirmed }
执行时你会看到进度树形结构:
▸ Code Review Workflow
▸ Review (3 agents)
● review:security — running...
● review:perf — running...
● review:quality — running...
▸ Verify (pending)
Q: Workflow 触发条件是什么?
A: 必须满足以下条件之一:
1. 用户在提示词中包含 "workflow"、"use a workflow"、"ultracode" 等关键词
2. 用户调用 /ultracode 命令(需开启 Ultracode)
3. 用户调用已保存的 Workflow 名称
Q: 为什么 Claude 没有自动生成 Workflow?
A: 检查以下几点: - 确认 Claude Code 版本 ≥ v2.1.154 - 确认订阅计划为 Pro/Max/Team/Enterprise - 在提示词中显式提到 "use a workflow"
agent() — 子 Agent 调用agent() 是最基本的构建块,启动一个子 Agent 执行任务。
// 基础用法 — 返回文本
const result = await agent('分析 src/auth.ts 的安全性')
// 带结构化输出 — 返回 JSON 对象
const findings = await agent('分析 src/auth.ts 的安全性', {
schema: {
type: 'object',
properties: {
vulnerabilities: {
type: 'array',
items: { type: 'string' }
},
riskLevel: { type: 'string' }
}
}
})
// 完整参数
const result = await agent('你的提示词', {
label: 'auth-review', // 显示标签
phase: 'Security', // 所属阶段
schema: { /* JSON Schema */ }, // 强制结构化输出
model: 'sonnet', // 模型覆盖(慎用)
isolation: 'worktree', // 在独立 git worktree 中运行
agentType: 'Explore' // 使用特定 Agent 类型
})
关键参数详解:
| 参数 | 说明 | 建议用法 |
|---|---|---|
schema |
强制 Agent 调用结构化输出工具 | 需要机器可解析的结果时必用 |
label |
进度面板显示名称 | 建议用 类型:目标 格式 |
phase |
分配到哪个阶段 | 与 meta.phases 中的 title 匹配 |
isolation |
独立 git worktree | Agent 需要修改文件时使用 |
model |
覆盖模型 | 通常省略,继承主循环模型 |
agentType |
使用特定 Agent 类型 | 如 Explore 用于搜索型任务 |
pipeline() — 流水线编排pipeline() 是默认推荐的编排模式。它让每个项目依次通过多个阶段,但项目之间可以并行——项目 A 可以在阶段 3,同时项目 B 还在阶段 1。
const FILES = ['auth.ts', 'user.ts', 'payment.ts']
const results = await pipeline(
FILES,
// 阶段 1:扫描
(file, originalItem, index) => agent(`扫描 ${file} 的安全问题`, {
label: `scan:${file}`,
phase: 'Scan'
}),
// 阶段 2:验证
(scanResult, originalItem, index) => agent(
`验证发现:${scanResult.summary}`,
{ label: `verify:${originalItem}`, phase: 'Verify' }
),
// 阶段 3:生成修复建议
(verifyResult, originalItem, index) => agent(
`为 ${originalItem} 生成修复方案`,
{ label: `fix:${originalItem}`, phase: 'Fix' }
)
)
gantt
title Pipeline 执行时间线(非阻塞)
dateFormat X
axisFormat %s秒
section auth.ts
扫描 :a1, 0, 5
验证 :a2, 5, 8
修复 :a3, 8, 12
section user.ts
扫描 :b1, 1, 6
验证 :b2, 6, 9
修复 :b3, 9, 13
section payment.ts
扫描 :c1, 2, 7
验证 :c2, 7, 10
修复 :c3, 10, 14
Wall-clock 时间 = 最慢单项链的总耗时,而非所有阶段的最慢之和。这是 pipeline 相比串行的巨大优势。
阶段回调签名:(previousResult, originalItem, index)
- previousResult:上一阶段的返回值
- originalItem:原始输入项(便于在任何阶段引用原始数据)
- index:项目索引(便于生成唯一标签)
parallel() — 并行屏障parallel() 会等待所有任务完成后才返回。这是一个同步屏障。
// 场景:需要所有维度审计结果后才能去重
const allFindings = await parallel([
() => agent('审计安全性', { schema: FINDINGS_SCHEMA }),
() => agent('审计性能', { schema: FINDINGS_SCHEMA }),
() => agent('审计可维护性', { schema: FINDINGS_SCHEMA })
])
// 去重(需要所有结果到齐)
const deduped = deduplicate(
allFindings.filter(Boolean).flatMap(r => r.findings)
)
// 然后再验证
const verified = await parallel(
deduped.map(f => () => agent(`验证: ${f.title}`, { schema: VERDICT_SCHEMA }))
)
何时用 parallel 而非 pipeline?
| 场景 | 选择 | 原因 |
|---|---|---|
| 跨项目去重 | parallel |
需要所有结果才能去重 |
| 阶段间无依赖 | pipeline |
无需等待,更快 |
| 需要汇总统计 | parallel |
需要全部数据 |
| 每项独立处理 | pipeline |
项目间无交互 |
| 早退出(0 结果跳过) | parallel |
需要先看到总数 |
phase() 和 log()phase('扫描') // 后续 agent() 调用归入此阶段
log(`已扫描 ${scanned}/${total} 个文件`) // 进度消息
phase('验证')
log(`发现 ${findings.length} 个待验证问题`)
phase('修复')
log(`已确认 ${confirmed.length} 个真实问题`)
phase() 和 meta.phases 中的 title 字段必须精确匹配,否则会创建新的进度分组。
对每个发现,启动 N 个独立"怀疑者"Agent,每个都被提示去反驳该发现。如果多数怀疑者无法反驳,则判定为真实。
export const meta = {
name: 'adversarial-code-review',
description: 'Adversarially verified code review',
phases: [
{ title: 'Find' },
{ title: 'Verify' }
]
}
const FINDINGS_SCHEMA = {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
title: { type: 'string' },
file: { type: 'string' },
line: { type: 'number' },
description: { type: 'string' }
}
}
}
}
}
const VERDICT_SCHEMA = {
type: 'object',
properties: {
refuted: { type: 'boolean' },
reason: { type: 'string' }
}
}
phase('Find')
const result = await agent(
'Find all security vulnerabilities in the codebase',
{ schema: FINDINGS_SCHEMA }
)
phase('Verify')
const verified = await parallel(
result.findings.map(f => () =>
parallel([1, 2, 3].map(i => () =>
agent(
`Try to REFUTE this finding: "${f.title}" at ${f.file}:${f.line}. ` +
`Description: ${f.description}. ` +
`Default to refuted=true if uncertain.`,
{ label: `judge:${f.file}:${i}`, phase: 'Verify', schema: VERDICT_SCHEMA }
)
))
.then(votes => ({
...f,
survived: votes.filter(Boolean).filter(v => !v.refuted).length >= 2
}))
)
)
const confirmed = verified.filter(v => v.survived)
log(`${confirmed.length}/${result.findings.length} findings survived adversarial verification`)
return { confirmed }
核心设计原则:怀疑者 Agent 的提示词要求它"尝试反驳",且"不确定时默认反驳"——这防止了验证 Agent 倾向于"同意"的偏见。
从不同角度独立生成方案,然后由评审团打分,最终综合胜出方案的优点。
export const meta = {
name: 'architecture-design',
description: 'Multi-perspective architecture design with judge panel',
phases: [
{ title: 'Design' },
{ title: 'Judge' },
{ title: 'Synthesize' }
]
}
const APPROACHES = [
{ lens: 'MVP-first', prompt: 'Design the simplest architecture that works...' },
{ lens: 'Scalability-first', prompt: 'Design for 100x scale from day one...' },
{ lens: 'Developer-experience', prompt: 'Design for maximum developer productivity...' }
]
phase('Design')
const designs = await parallel(
APPROACHES.map(a => () =>
agent(a.prompt, { label: `design:${a.lens}`, phase: 'Design' })
)
)
phase('Judge')
const scores = await parallel(
designs.map((d, i) => () =>
agent(`Score this architecture design (1-10) on: scalability, simplicity,
maintainability, cost. Design:\n${d}`, {
label: `judge:${APPROACHES[i].lens}`,
phase: 'Judge',
schema: {
type: 'object',
properties: {
total: { type: 'number' },
scalability: { type: 'number' },
simplicity: { type: 'number' },
maintainability: { type: 'number' },
cost: { type: 'number' },
strengths: { type: 'array', items: { type: 'string' } },
weaknesses: { type: 'array', items: { type: 'string' } }
}
}
})
)
)
phase('Synthesize')
const winnerIdx = scores
.filter(Boolean)
.reduce((best, s, i) => s.total > scores[best].total ? i : best, 0)
const synthesis = await agent(
`The winning approach is "${APPROACHES[winnerIdx].lens}" with score ${scores[winnerIdx].total}.
Here are all designs:\n${designs.join('\n---\n')}
Here are all scores:\n${JSON.stringify(scores)}
Synthesize the final architecture: take the winning design as the base,
but graft in the best ideas from the other approaches.`,
{ label: 'synthesize', phase: 'Synthesize' }
)
return { winner: APPROACHES[winnerIdx].lens, synthesis }
持续发现新问题,直到连续 K 轮没有新发现。
export const meta = {
name: 'exhaustive-bug-finder',
description: 'Find bugs until the well runs dry',
phases: [
{ title: 'Find' },
{ title: 'Verify' }
]
}
const seen = new Set()
const confirmed = []
let dry = 0
const MAX_DRY = 2 // 连续 2 轮无新发现则停止
while (dry < MAX_DRY) {
phase('Find')
const found = (await parallel([
() => agent('Find correctness bugs', { phase: 'Find', schema: BUGS_SCHEMA }),
() => agent('Find security bugs', { phase: 'Find', schema: BUGS_SCHEMA }),
() => agent('Find edge case failures', { phase: 'Find', schema: BUGS_SCHEMA })
])).filter(Boolean).flatMap(r => r.bugs)
const fresh = found.filter(b => !seen.has(`${b.file}:${b.line}:${b.title}`))
if (!fresh.length) {
dry++
log(`No new findings (dry ${dry}/${MAX_DRY})`)
continue
}
dry = 0
fresh.forEach(b => seen.add(`${b.file}:${b.line}:${b.title}`))
log(`${fresh.length} new findings (total seen: ${seen.size})`)
phase('Verify')
const judged = await parallel(
fresh.map(b => () =>
agent(`Is this a real, reproducible bug? "${b.title}" at ${b.file}:${b.line}`, {
label: `verify:${b.file}`,
phase: 'Verify',
schema: { type: 'object', properties: { real: { type: 'boolean' }, reason: { type: 'string' } } }
})
)
)
confirmed.push(...judged.filter(Boolean).filter(v => v.real))
log(`${confirmed.length} confirmed bugs so far`)
}
log(`Done! ${confirmed.length} confirmed bugs from ${seen.size} total findings`)
return { confirmed, totalSeen: seen.size }
关键细节:去重用 seen(全部发现),而非 confirmed(仅确认的)。否则被拒绝的发现在下一轮会再次出现,循环永远不收敛。
根据用户设定的 Token 预算(如 +500k),动态控制循环次数。
export const meta = {
name: 'budget-bounded-audit',
description: 'Audit within token budget',
phases: [{ title: 'Audit' }, { title: 'Verify' }]
}
const bugs = []
while (budget.total && budget.remaining() > 50000) {
phase('Audit')
const result = await agent('Find bugs in this codebase', {
schema: BUGS_SCHEMA,
phase: 'Audit'
})
bugs.push(...result.bugs)
log(`${bugs.length} bugs found, ${Math.round(budget.remaining() / 1000)}k tokens remaining`)
if (bugs.length >= 50) break // 上限保护
}
return { bugs, tokensUsed: budget.spent() }
budget 对象的三个方法:
- budget.total:用户设定的总预算(如 500000),未设定则为 null
- budget.spent():当前已消耗的 Token 数
- budget.remaining():剩余 Token 数(未设定预算时返回 Infinity)
从不同搜索角度并行扫描,每个 Agent "看不到"其他 Agent 发现了什么。
export const meta = {
name: 'multi-modal-sweep',
description: 'Sweep codebase from multiple angles',
phases: [{ title: 'Sweep' }, { title: 'Merge' }]
}
phase('Sweep')
const sweeps = await parallel([
() => agent('Find all API endpoints that lack authentication checks', { phase: 'Sweep' }),
() => agent('Find all database queries vulnerable to SQL injection', { phase: 'Sweep' }),
() => agent('Find all user inputs that are not properly sanitized', { phase: 'Sweep' }),
() => agent('Find all places where secrets might be logged or exposed', { phase: 'Sweep' })
])
phase('Merge')
const allFindings = sweeps.filter(Boolean).flatMap(r => {
try { return JSON.parse(r).findings || [] } catch { return [] }
})
// ... 后续去重和验证
在所有工作完成后,启动一个"挑剔"Agent 检查是否有遗漏。
// ... 前面的发现和验证逻辑 ...
phase('Completeness Check')
const critic = await agent(
`You are a completeness critic. We just did a ${meta.name} workflow.
We found ${confirmed.length} issues across these dimensions: ${DIMENSIONS.map(d => d.key).join(', ')}.
What did we MISS? Consider:
1. Dimensions we didn't check
2. Files we might have skipped
3. Claim types we didn't verify
4. Edge cases unique to this codebase
Be specific and actionable.`,
{ label: 'completeness-critic', phase: 'Completeness Check' }
)
return { confirmed, gaps: critic }
以下是一个完整的、可直接使用的 Workflow,对一个全栈应用进行多维度的对抗性代码审计:
export const meta = {
name: 'fullstack-adversarial-audit',
description: 'Adversarial multi-dimensional code audit for full-stack applications',
phases: [
{ title: 'Scan', detail: 'Scan codebase across 5 dimensions' },
{ title: 'Dedup', detail: 'Deduplicate findings across dimensions' },
{ title: 'Verify', detail: '3-judge adversarial verification' },
{ title: 'Report', detail: 'Generate final report' }
]
}
// Schema 定义
const FINDINGS = {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string' },
title: { type: 'string' },
file: { type: 'string' },
line: { type: 'number' },
severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
category: { type: 'string' },
description: { type: 'string' },
recommendation: { type: 'string' }
},
required: ['id', 'title', 'file', 'severity', 'description']
}
}
}
}
const VERDICT = {
type: 'object',
properties: {
isReal: { type: 'boolean' },
confidence: { type: 'number' },
reason: { type: 'string' }
}
}
// 阶段 1:5 维度扫描
phase('Scan')
const dimensions = [
{ key: 'security', prompt: 'Scan for security vulnerabilities: injection, XSS, CSRF, auth bypass, secrets in code, insecure dependencies' },
{ key: 'performance', prompt: 'Scan for performance issues: N+1 queries, memory leaks, unoptimized loops, missing indexes, large bundle size' },
{ key: 'reliability', prompt: 'Scan for reliability issues: unhandled errors, race conditions, missing retries, data loss scenarios' },
{ key: 'accessibility', prompt: 'Scan for accessibility issues: missing ARIA labels, keyboard navigation, color contrast, screen reader support' },
{ key: 'maintainability', prompt: 'Scan for maintainability issues: code duplication, high coupling, missing tests, unclear naming' }
]
const scanResults = await parallel(
dimensions.map(d => () =>
agent(d.prompt, {
label: `scan:${d.key}`,
phase: 'Scan',
schema: FINDINGS
})
)
)
// 阶段 2:跨维度去重
phase('Dedup')
const allFindings = scanResults
.filter(Boolean)
.flatMap(r => r.findings)
log(`Total raw findings: ${allFindings.length}`)
// 基于文件+行号+类别的简单去重
const seen = new Set()
const deduped = allFindings.filter(f => {
const key = `${f.file}:${f.line}:${f.category}`
if (seen.has(key)) return false
seen.add(key)
return true
})
log(`After dedup: ${deduped.length} unique findings`)
// 阶段 3:对抗性验证(每个发现 3 个评委)
phase('Verify')
const verified = await pipeline(
deduped,
// 每个发现被 3 个独立评委审查
finding => parallel([1, 2, 3].map(i => () =>
agent(
`You are judge #${i}. Try to REFUTE this finding:
Title: ${finding.title}
File: ${finding.file}:${finding.line}
Severity: ${finding.severity}
Description: ${finding.description}
Is this a REAL issue? Default to isReal=false if uncertain.
Consider: Is the file path correct? Is the severity justified? Is this a false positive?`,
{
label: `judge:${finding.id}:${i}`,
phase: 'Verify',
schema: VERDICT
}
)
)).then(votes => ({
...finding,
votes: votes.filter(Boolean),
confirmed: votes.filter(Boolean).filter(v => v.isReal).length >= 2
}))
)
const confirmed = verified.filter(v => v.confirmed)
const rejected = verified.filter(v => !v.confirmed)
log(`Confirmed: ${confirmed.length}, Rejected: ${rejected.length}`)
// 阶段 4:生成报告
phase('Report')
const criticalCount = confirmed.filter(f => f.severity === 'critical').length
const highCount = confirmed.filter(f => f.severity === 'high').length
log(`🔴 Critical: ${criticalCount} | 🟠 High: ${highCount} | Total: ${confirmed.length}`)
return {
summary: {
total: confirmed.length,
critical: criticalCount,
high: highCount,
medium: confirmed.filter(f => f.severity === 'medium').length,
low: confirmed.filter(f => f.severity === 'low').length
},
findings: confirmed,
rejected: rejected.length,
rawTotal: allFindings.length
}
在 Claude Code 中输入:
> Use a workflow to run a full adversarial code audit
across security, performance, reliability, accessibility,
and maintainability dimensions
或者使用 /ultracode(如果已开启):
> /ultracode Run the fullstack-adversarial-audit workflow
▸ fullstack-adversarial-audit
▸ Scan (5 agents) ✓
● scan:security — 23 findings
● scan:performance — 15 findings
● scan:reliability — 12 findings
● scan:accessibility — 8 findings
● scan:maintainability — 19 findings
▸ Dedup ✓ — 77 raw → 62 unique
▸ Verify (62 findings × 3 judges) ✓
● Confirmed: 41 | Rejected: 21
▸ Report ✓
🔴 Critical: 3 | 🟠 High: 8 | Total: 41
Workflow 支持从中断处继续执行。当你修改了脚本或需要恢复中断的运行时:
// 方法 1:通过返回的 runId 恢复
const { runId } = await Workflow({ script: myScript })
// 如果中途中断,使用 runId 恢复
await Workflow({
scriptPath: savedScriptPath,
resumeFromRunId: runId
})
恢复逻辑:
- 未修改的 agent() 调用会直接返回缓存结果
- 第一个被修改或新增的调用会重新执行
- 后续所有调用也会重新执行
schema 参数强制子 Agent 使用 StructuredOutput 工具,返回经过 JSON Schema 验证的对象。这比解析自由文本可靠得多。
// ✅ 好的 schema:字段清晰,有约束
const GOOD_SCHEMA = {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
title: { type: 'string' },
severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
file: { type: 'string' }
},
required: ['title', 'severity', 'file']
}
},
summary: { type: 'string' }
},
required: ['findings']
}
// ❌ 差的 schema:过于宽泛
const BAD_SCHEMA = {
type: 'object',
properties: {
data: { type: 'string' } // 一个大字符串,失去了结构化优势
}
}
当多个 Agent 需要修改文件时,使用 isolation: 'worktree' 防止冲突:
const results = await parallel(
files.map(f => () =>
agent(`Refactor ${f} to use the new API`, {
isolation: 'worktree',
label: `migrate:${f}`
})
)
)
注意:每个 worktree 需要约 200-500ms 的设置时间加磁盘开销,仅在 Agent 确实需要修改文件时使用。
使用 workflow() 在脚本中调用已保存的 Workflow:
// 调用已保存的 Workflow
const auditResult = await workflow('security-audit')
// 或通过脚本路径调用
const report = await workflow({
scriptPath: './.claude/workflows/generate-report.js'
}, { findings: auditResult.findings })
// 根据预算动态调整 Agent 数量
const FLEET = budget.total ? Math.floor(budget.total / 100000) : 5
const results = await parallel(
Array.from({ length: FLEET }, (_, i) => () =>
agent(`Find bugs in section ${i + 1} of the codebase`, {
schema: BUGS_SCHEMA
})
)
)
Ultracode 是一种自动触发 Workflow 的模式。开启后,Claude 会对每个"实质性任务"自动使用 Workflow 编排。
> /ultracode on
flowchart LR
A[用户输入任务] --> B{Ultracode 开启?}
B -->|是| C[自动生成 Workflow 脚本]
B -->|否| D[单 Agent 处理]
C --> E[多阶段并行执行]
E --> F[对抗性验证]
F --> G[综合输出]
D --> G
style B fill:#ff9,stroke:#333
style C fill:#bbf,stroke:#333
style F fill:#bfb,stroke:#333
Ultracode 的隐性成本:每个实质性任务都会启动多个 Agent,Token 消耗是单 Agent 的 3-10 倍。适合需要"极致正确性"的场景(代码审计、安全审查、深度调研),不适合简单问答或单文件修改。
| 错误 | 原因 | 解决方案 |
|---|---|---|
Date.now() is not available |
脚本中使用了时间函数 | 通过 args 传入时间戳 |
Type annotations are not supported |
使用了 TypeScript 语法 | 移除类型注解,使用纯 JS |
Agent limit reached (1000) |
单个 Workflow 启动超过 1000 个 Agent | 减少并行度或分批处理 |
Schema validation failed |
Agent 返回不匹配 Schema | 简化 Schema,减少 required 字段 |
Worktree creation failed |
不在 git 仓库中 | 确保在 git 仓库内运行 |
pipeline:只在确实需要同步屏障时用 parallelisolation: 'worktree':只读任务不需要隔离schema:过于严格的 Schema 会导致 Agent 反复重试label 便于调试:格式建议 动作:目标parallel,放进 pipeline 的阶段中# 在另一个终端查看运行中的 Workflow
/workflows
# 查看特定 Agent 的详细日志
/tasks
graph TB
subgraph "Claude Code Workflow 系统"
User[用户提示词] --> Trigger{触发判断}
Trigger -->|关键词/ultracode| ScriptGen[Claude 生成 JS 脚本]
Trigger -->|常规任务| SingleAgent[单 Agent 处理]
ScriptGen --> Engine[脚本引擎]
Engine --> Pipeline[pipeline 流水线]
Engine --> Barrier[parallel 屏障]
Engine --> Loop[loop-until-dry]
Pipeline --> SA1[子 Agent 1]
Pipeline --> SA2[子 Agent 2]
Pipeline --> SA3[子 Agent 3]
Barrier --> SB1[子 Agent A]
Barrier --> SB2[子 Agent B]
Barrier --> SB3[子 Agent C]
SA1 & SA2 & SA3 --> Merge[结果汇总]
SB1 & SB2 & SB3 --> Merge
Merge --> Output[结构化输出]
Budget[Budget 控制器] -.-> Engine
Cache[结果缓存] -.-> Engine
Resume[断点续跑] -.-> Engine
end
style Trigger fill:#ff9,stroke:#333
style Engine fill:#bbf,stroke:#333
style Merge fill:#bfb,stroke:#333
style Output fill:#f9f,stroke:#333
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | AI 开发者进阶营、DevOps 自动化营、代码质量工程营 |
| 教学时长 | 4-6 小时(含实操) |
| 前置要求 | Claude Code 基础使用经验、JavaScript 基础 |
| 实操占比 | 60%(建议学员带自己的代码库做实战) |
| 难度等级 | ⭐⭐⭐⭐ (高级) |
| 推荐分组 | 2-3 人一组,每组负责一种编排模式 |
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
