多 Agent 编排
运行多个 Agent,把顺序交给 controller 决定。
有些工作的顺序无法事先写下来。设置 type: controller,声明运行结束时什么必须成立,Dagu 就让模型根据回传的结论挑选下一个要执行的 Agent 步骤。每个动作仍然是普通的工作流步骤,带有日志、重试、审批和审计记录。
# code-review.yaml
type: controller
llm:
provider: anthropic
model: claude-opus-5
system: |
Get top_n.py past both reviews. When a review fails, pass its finding
to revise, then ask that same reviewer again. A revision made for one
reviewer can break the other.
steps:
- name: review_simplicity
description: Judge simplicity. Prints PASS, or FAIL with what to change.
action: harness.run
with:
provider: opencode
prompt: Read top_n.py. Print "PASS" or "FAIL: <what to change>".
- name: review_correctness
description: Judge correctness. Prints PASS, or FAIL with the bug.
action: harness.run
with:
provider: codex
prompt: Read top_n.py. Print "PASS" or "FAIL: <the bug>".
- name: revise
description: Edit top_n.py to resolve one review finding.
action: dag.run
with: { dag: revise }
tasks:
- name: simplicity_passed
description: The latest simplicity review returned PASS on the current file.
- name: correctness_passed
description: The latest correctness review returned PASS on the current file.声明完成条件,而不是步骤顺序
每个动作都是真实的 Agent CLI: Claude、Codex、Gemini、OpenCode
任务以完成、跳过或失败三种状态收敛
等待人工回答时挂起,不留下常驻进程
At a glance
Controller 工作流与 Agent 框架
由你声明完成条件。没有任务处于 open 时运行结束。
要么模型自己判断已经做完,要么提前画出全部路径并靠人维护。
等待中的运行退出进程,并在新进程上恢复。
长时间等待通常意味着一个要保活的进程和一套要运维的状态存储。
调度、队列、重试、产物和审计记录都来自这次 DAG 运行。
每个项目重造一遍,或者交给托管的控制面。
工作流文件里的那组步骤。
工具定义允许的一切。
In depth
Where each tool fits
无法写下来的正是顺序
图可以按退出码分支,却无法按评审实际说了什么分支。Controller 工作流固定动作集合,只把排序交出去。
- 步骤变成动作目录,不再有需要维护的 depends
- tasks 声明运行结束时什么必须成立
- Controller 把一个 Agent 的结论带进下一个 Agent 的参数
模型选择的是顺序,绝不是能力
Controller 只能在你声明过的步骤中挑选。它无法凭空创造步骤、无法自己写 shell 命令、也够不到文件里没写的东西,因此影响范围就是这份工作流定义。
- 每个 Agent 可以跑在主机上,也可以跑在挂载和出网规则都写明的容器沙箱里
- 按角色分配不同的 provider 和模型,避免同一个模型给自己的产出打分
- 已经足够可信的部分移进子工作流,就不再是一个决策
生产管控来自运行本身,而不是框架
Controller 运行就是一次 DAG 运行。调度、队列、重试、产物和审计记录原样适用,限制 Agent 花费的上限也是引擎设置,而不是提示词里的叮嘱。
- ask_user 会持久挂起运行: 进程退出,worker 槽位释放
- 几小时后有人回答,运行在新进程上继续
- 触及轮次、动作重试或提问次数上限时运行失败,而不是无边界地消耗
事后可以还原任何一次运行
Controller 没有依赖边,因此运行展示为它实际做出的决策序列,而不是一张图。
- 决策时间线: 每轮一行,含尝试次数、耗时,以及每个动作产生的子运行链接
- 任务视图显示每个目标被判为完成、跳过还是失败,以及给出的理由
- 完整对话记录,包含模型看到的每一条工具结果
FAQ
Practical questions before adopting Dagu
Controller 工作流和 Agent 循环有什么区别?
裸循环把「是否结束」交给模型。Controller 保留循环,但把终止条件收回来: 你声明任务以及「完成」的含义,没有任务处于 open 时运行结束。
如果某个任务其实没必要做,会怎样?
Controller 会把它标记为跳过并记录理由,运行仍然算成功。跳过和失败是两种状态,因为「不需要做」和「做不到」在审计日志里是不同的结果。
不同步骤能用不同的模型吗?
可以。每个 Agent Harness 步骤指定自己的 provider 和模型,controller 自身的模型单独配置,因此可以用便宜的模型驱动昂贵的专家,也可以让两个 provider 互相校验。
怎样避免运行无节制地花钱?
上限由引擎强制执行。单次运行中一个动作最多执行五次,最多提五个问题,轮次上限默认五十并且可以调低。触及上限会让运行失败,并指出还有哪些任务未收敛。
什么时候仍然应该用普通的图?
画得出来就画出来。type: graph 仍是默认值,因为它更快、更便宜、可复现。只有当顺序确实取决于前面步骤产出了什么时,才动用 controller。
Next step
Start with one workflow.
Install Dagu, move one fragile script or agent task into YAML, and decide from a real run history.