Whale
· 指南 · 约 8 分钟阅读

Whale 动态工作流:终端内的多 Agent 编排

用 JavaScript 脚本编排多个 AI Agent——扇出研究、多角度审查、流水线处理、对抗验证。 兼容 Claude Code,无需修改即可运行。

W

Whale 团队

Engineering

Whale 的 动态工作流 让你超越单轮 Agent 对话的限制。 不再由模型决定下一步做什么——编写一个 JavaScript 脚本来控制流程: 循环、扇出、屏障、流水线,而每个 agent() 调用负责实际的 LLM 工作。 结果是确定性的、可重复的、可扩展的多 Agent 编排,一切都在你的终端中完成。

什么是动态工作流?

动态工作流是一个 JavaScript 文件,使用 Whale 的运行时全局变量——agent()parallel()pipeline()phase()log()budget——来协调多个 AI Agent。脚本在隔离的 QuickJS 沙箱中运行, 与你的对话上下文分离,仅通过 agent() 叶子节点与外界通信。

✅ 兼容 Claude Code — Whale 的工作流脚本格式与 Claude Code raw scripts 完全兼容。 为 Claude Code 编写的工作流文件可直接复制到 .whale/workflows/ 使用,无需修改。

Chat vs Workflow:何时使用?

维度 Chat Workflow
谁决定下一步 模型逐轮决定 脚本控制
中间结果存放 对话上下文 脚本变量
可重复性 每次临时处理 编排被代码化
规模 每轮几次调用 每次数十到数百个 Agent
中断恢复 丢失上下文,重新开始 同一会话内可恢复

工作流的典型应用场景:

  • 扇出研究 — 并行搜索多个角度,交叉验证发现
  • 多角度审查 — 从多个视角审查代码或设计,然后综合
  • 流水线处理 — 分阶段处理(提取 → 转换 → 加载)
  • 对抗验证 — 生成独立的反方 Agent 来反驳每个发现
  • 循环直到干净 — 持续查找,直到连续多轮无新发现

工作流的运行机制

  • 隔离执行 — 脚本在 QuickJS 沙箱中运行,与对话上下文隔离
  • 可恢复 — 同一会话内,已完成的 agent() 调用返回缓存结果;仅变更或新增的调用重新执行
  • 无主机 API — 脚本不能直接访问文件系统、网络或 require();所有 I/O 通过 agent() 叶子节点进行
  • 并发 — 默认最多 3 个并发 Agent,可配置上限
  • Token 预算 — 可选的总 completion token 上限

编写你的第一个自定义工作流

每个工作流脚本都以 meta 导出开始,定义其标识和阶段, 然后是包含编排逻辑的默认导出。

基本结构

export const meta = {
  name: "my-workflow",
  description: "这个工作流的简短描述",
  phases: [
    { title: "收集", detail: "收集信息" },
    { title: "分析", detail: "分析结果并生成报告" },
  ],
};

export default async function main(args) {
  const input = args || "默认输入";

  phase("收集");
  const data = await agent(`收集关于 ${input} 的信息`, {
    label: "collector",
    schema: {
      type: "object",
      required: ["findings"],
      properties: {
        findings: { type: "array", items: { type: "string" } },
      },
    },
  });

  phase("分析");
  const report = await agent(
    `基于以下发现生成报告:${data.findings.join("、")}`,
    { label: "analyst" },
  );

  return report;
}

保存工作流的位置

位置 范围 共享方式
.whale/workflows/<名称>.js 项目级 版本控制,团队共享
~/.whale/workflows/<名称>.js 用户全局 跨项目可用
从 Claude Code 迁移:.claude/workflows/<名称>.js 复制到 .whale/workflows/<名称>.js 即可。所有 API 完全匹配。

实战示例:扇出研究

// .whale/workflows/research.js
export const meta = {
  name: "research",
  description: "多角度扇出搜索,然后综合",
  phases: [
    { title: "搜索", detail: "多角度并行搜索" },
    { title: "综合", detail: "合并发现为一份报告" },
  ],
};

export default async function main(args) {
  const topic = args || "默认主题";

  phase("搜索");
  const results = await parallel([
    () => agent(`搜索 ${topic} 的最佳实践`),
    () => agent(`找出 ${topic} 的常见错误`),
    () => agent(`查找 ${topic} 的工具和框架`),
  ]);

  phase("综合");
  return await agent(
    `将以下发现综合成一份简洁指南:\n\n${results.join("\n\n")}`,
    { label: "synthesizer" },
  );
}

实战示例:循环直到干净的死代码扫描

const DRY_STREAK = 2
const MAX_ROUNDS = 5
const found = []
let emptyRounds = 0
let round = 0

while (emptyRounds < DRY_STREAK && round < MAX_ROUNDS) {
  round++
  phase("查找")
  const { items } = await agent(
    `第 ${round} 轮。扫描未引用符号。忽略已发现的:` +
    `${found.map(r => r.symbol).join("、") || "暂无"}.`,
    { label: `find:round-${round}`, phase: "查找", schema: DEAD },
  )

  if (items.length === 0) {
    emptyRounds++
    continue
  }

  emptyRounds = 0
  found.push(...items)
}

return { rounds: round, candidates: found }

实战示例:带屏障的并行摘要

phase("加载")
const { items } = await agent("读取反馈 CSV", { schema: ITEMS })

// 屏障:需要所有摘要才能聚类
const summaries = await parallel(items.map(it => () =>
  agent(`摘要:${it.text}`, { label: `summarize:${it.id}` }),
))

phase("聚类")
const { themes } = await agent(
  `将 ${summaries.length} 个项目聚类为排名主题:\n\n` +
  summaries.map(s => `- ${s}`).join("\n"),
  { label: "cluster", schema: THEMES },
)

return { themes }

内置工作流:deep-research

Whale 内置了 deep-research 工作流,执行多阶段深度研究: 界定问题范围、多角度搜索、获取来源、对抗验证、综合引用报告。

阶段:范围界定 → 搜索 → 获取 → 验证 → 综合

管理工作流运行

在 TUI 中使用 /workflows 打开工作流面板:

  • ↑ / ↓ — 选择阶段或 Agent
  • Enter / → — 深入查看提示、工具调用和结果
  • Esc — 返回上一级
  • j / k — 在 Agent 详情中滚动
  • p — 暂停/恢复
  • x — 停止运行中的 Agent 或整个工作流

API 参考

API 用途
agent(prompt, opts?) 运行子 Agent,返回完整响应文本
parallel(thunks) 并发运行多个 agent thunk,返回结果数组
pipeline(stages) 按顺序运行阶段,每个接收前一个输出
phase(name, detail?) 声明命名阶段,用于进度追踪
log(...args) 记录工作流输出,在面板中可见
budget 只读,剩余 token 预算
args 只读,传递给工作流的参数

故障排除

问题 原因 修复
"script must begin with export const meta" 脚本头部错误 第一个非注释行必须是 export const meta = { ... }
"invalid workflow filename" 不是 kebab-case 使用 my-workflow.js
"filename must match meta.name" 文件名不匹配 my-workflow.jsname: "my-workflow"
"agent call limit exceeded" 超出 Agent 调用限制 增加预算或减少 Agent
"workflow() cannot be called from within" 嵌套工作流 仅主工作流可调子工作流

开始构建

动态工作流是 Whale 最强大的功能之一。无论你是构建研究流水线、 代码审查框架还是对抗验证器,JavaScript API 都为你提供了对多 Agent 编排的完全控制—— 一切都在你的终端中完成。

要开始使用,在你的项目中创建 .whale/workflows/ 目录, 编写你的第一个工作流脚本,然后向 Whale 描述它。 工作流面板(/workflows)让你实时查看每个阶段和 Agent 调用。

准备好创建你的工作流了吗?