欢迎光临
我们一直在努力

Workflow 基础:用代码调度多个 Agent

Workflow 基础:用代码调度多个 Agent

系列第 3 篇 · 前置:第 1 篇 → 第 2 篇


前两篇讲的是单个 Agent 怎么定义、Prompt 怎么写。这篇开始讲怎么把多个 Agent 串起来干活。

Shell 脚本也能串(claude -p 一个接一个),但数据靠文件传,并行写起来麻烦。

Workflow 解决的就是这个:用一段 JS 代码决定什么时候派谁、数据传给谁,你只需要说一句"开始"。

别怕,不需要会 JS。这篇看完你就知道,写 Workflow 只需要四样东西。


一、先看效果:一个完整的 Workflow 长什么样

这是我实际用过的自动写文章流程:三源并行搜索 → 汇总列大纲 → 写初稿。

export const meta = {
name: 'auto-article',
description: '三源并行搜索 → 汇总大纲 → 写初稿',
phases: [
{ title: '搜集资料' },
{ title: '列大纲' },
{ title: '写初稿' },
],
}

const TOPIC = args.topic || 'Claude Code Agent 编排'

// 阶段 1:三个 Agent 同时搜(搜资料用 haiku,便宜)
phase('搜集资料')
const [chinese, english, github] = await parallel([
() => agent(`搜索「${TOPIC}」的中文资料,找 3 个最有价值的来源`, { label: '搜中文', model: 'haiku' }),
() => agent(`Search for "${TOPIC}" in English, find 3 sources`, { label: '搜英文', model: 'haiku' }),
() => agent(`搜索「${TOPIC}」相关的开源项目和官方文档`, { label: '搜开源', model: 'haiku' }),
])

// 阶段 2:汇总资料,列大纲
phase('列大纲')
const allMaterials = [chinese, english, github].join('\\n—\\n')
const outline = await agent(
`基于以下资料列出文章大纲:\\n${allMaterials}`,
{ phase: '列大纲' }
)

// 阶段 3:写初稿
phase('写初稿')
const draft = await agent(
`根据大纲写一篇 1200 字初稿:\\n${outline}`,
{ phase: '写初稿' }
)

return draft

这段代码做的事:

你说"开始" → 三个 Agent 同时搜三个源
→ 结果拼在一起,派一个 Agent 列大纲
→ 大纲喂给另一个 Agent 写初稿
→ 返回文章


二、你只需要会四样 JS

写 Workflow 不需要学完整的 JS,简单总结了一下:这四样基本就够了:

1. await agent():派活,等结果

const result = await agent('帮我搜一下 Claude Code Workflow 的用法')

读作:派一个子 Agent 去做引号里的事,等它干完,把结果(一段文字)存进 result 变量。

await 就是"等它回来再往下走"。没有它,代码不会等 Agent 干完就直接执行下一行了。

2. 反引号和 ${}:拼字符串

const topic = 'Claude Code'
const prompt = `帮我搜一下${topic}的用法`
// prompt 的实际内容是:帮我搜一下Claude Code的用法

反引号 ` 就是键盘左上角和 ~ 在一起的那个键。它和普通引号的区别是:可以跨行,可以用 ${变量名} 把变量插进去。

你在 Prompt 里塞资料、塞上一步结果,全靠这个。

3. parallel([]):同时派多个

const [a, b, c] = await parallel([
() => agent('搜中文'),
() => agent('搜英文'),
() => agent('搜开源'),
])

两个要点:

  • 每个 agent() 外面包一层 () =>,意思是"先别跑,等 parallel 发令"。不包的话写的时候就执行了,变成串行。
  • const [a, b, c] 叫解构赋值,就是把三个结果分别放进三个变量。顺序和数组里的顺序对应。

parallel 会等所有 Agent 都回来才往下走。

4. return:交结果

return draft

最后把最终产物返回。你在对话里看到的输出就是它。

没了。变量声明用 const,字符串拼接用 + 或 ${},条件判断偶尔用个 ||(给默认值),其他 JS 特性一概不需要。


三、逐行拆解

回头看开头那段代码,一行行说。

meta 头

export const meta = {
name: 'auto-article',
description: '三源并行搜索 → 汇总大纲 → 写初稿',
phases: [
{ title: '搜集资料' },
{ title: '列大纲' },
{ title: '写初稿' },
],
}

告诉系统这个 Workflow 叫什么、分几个阶段。phases 只影响进度面板的显示,不写也能跑,写了能看到跑到哪一步。

phases 只影响进度面板的显示,不写也能跑,写了能看到跑到哪一步。想让某个阶段用便宜模型,在 agent() 调用里传 { model: 'haiku' }。

注意:meta 必须是纯字面量,不能在里面写变量或函数调用。

接参数

const TOPIC = args.topic || 'Claude Code Agent 编排'

args 是系统给的全局变量。你运行时说"主题是 Remotion",args.topic 就是 "Remotion"。|| 后面是默认值,不传就用它。

阶段切换和日志

phase('搜集资料')

切换当前阶段,后面的 Agent 会归到这个阶段下显示。和 meta 里的 title 对应。

三个 Agent 并行搜索

const [chinese, english, github] = await parallel([
() => agent(`搜索「${TOPIC}」的中文资料,找 3 个最有价值的来源`, { label: '搜中文' }),
() => agent(`Search for "${TOPIC}" in English, find 3 sources`, { label: '搜英文' }),
() => agent(`搜索「${TOPIC}」相关的开源项目和官方文档`, { label: '搜开源' }),
])

三个 Agent 同时启动,各搜各的。{ label: '搜中文' } 只影响进度面板上显示的名字。

三个都回来后,结果按顺序进 chinese、english、github 三个变量。

拼资料

const allMaterials = [chinese, english, github].join('\\n—\\n')

把三个搜索结果用分隔线拼成一个大字符串。等价于 chinese + '\\n—\\n' + english + '\\n—\\n' + github,但更好读。

列大纲和写初稿

phase('列大纲')
const outline = await agent(
`基于以下资料列出文章大纲:\\n${allMaterials}`,
{ phase: '列大纲' }
)

phase('写初稿')
const draft = await agent(
`根据大纲写一篇 1200 字初稿:\\n${outline}`,
{ phase: '写初稿' }
)

return draft

串行的两步:大纲 Agent 拿到全部资料,产出大纲;初稿 Agent 拿到大纲,产出文章。每一步的输出是下一步的输入,数据在变量之间传递,不写临时文件。


四、怎么运行

在 Claude Code 对话里直接说:

运行 workflows/auto-article.js,主题是 Remotion 视频渲染优化

系统会读这个文件,把 { topic: 'Remotion 视频渲染优化' } 传给 args,然后执行。会看到进度面板实时显示三个阶段的状态。

不传主题就用默认值:

运行 workflows/auto-article.js


五、Shell vs Workflow:什么时候用哪个

你可能已经在用 Shell 脚本调 claude -p 串流程了。两者不是替代关系,是场景不同。

维度Shell claude -pWorkflow agent()
运行条件 终端能跑就行,Claude Code 不用开着 必须在 Claude Code 会话里
定时任务 能,cron/launchd 直接调 不能
并行 for 循环串行,写并行麻烦 parallel() 原生支持
数据传递 写临时文件再读 JS 变量直接传
中间产物 每步落盘,可审计 只在内存里
进度显示 看终端输出 进度面板分阶段显示
一个 Agent 挂了 整条链路断 返回 null,其他继续

我的判断标准很简单:

人不在电脑前(定时跑、无人值守) → Shell
人在电脑前,需要并行 → Workflow
人在电脑前,串行简单任务 → 随便,哪个顺手用哪个
需要中途看一眼再决定下一步 → 别写脚本,在对话里手动来

比如我那个每天自动生成视频的流水线,用 Shell(launchd 定时触发)。但我在电脑前要快速出一篇文章,用 Workflow(并行快)。


六、常见坑

1. 忘了 () =>,变成串行

// 错:写的时候就执行了,parallel 拿到的是结果不是任务
await parallel([
agent('搜中文'),
agent('搜英文'),
])

// 对:包成函数,parallel 内部统一发射
await parallel([
() => agent('搜中文'),
() => agent('搜英文'),
])

2. 忘了 await

// 错:result 不是结果,是一个"还没干完的凭据"
const result = agent('搜一下')

// 对:等它干完
const result = await agent('搜一下')

3. meta 里写变量

meta 必须是纯字面量。想根据参数改阶段名做不到,阶段名是固定的。

4. 给 Agent 的 Prompt 里忘塞资料

// 错:Agent 不知道你要它分析什么
const outline = await agent('列个大纲')

// 对:把资料拼进去
const outline = await agent(`基于以下资料列大纲:\\n${allMaterials}`)

子 Agent 看不到主对话和其他变量,它只拿到你写在 Prompt 里的东西。


小结

Workflow = 一段 JS 代码,决定什么时候派谁、数据传给谁

四样 JS 走天下:
await agent('任务') 派活等结果
`文字${变量}` 拼字符串
parallel([() => agent(), …]) 同时派多个
return 结果 交差

和 Shell 的区别:
定时无人值守 → Shell
在电脑前要并行 → Workflow
要中途人工判断 → 手动对话

赞(0)
未经允许不得转载:171主机测评 » Workflow 基础:用代码调度多个 Agent
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址