Conductor 如何构建可治理的自适应图(Durable Adaptive Graph)?
【免费下载链接】conductorConductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents项目地址: https://gitcode.com/GitHub_Trending/co/conductor
如果你要构建一个在运行时自己决定下一步的 AI 工作流,直接让模型自由发挥会带来两个问题:选择过程不可追溯,副作用不受控。Conductor 的 Durable Adaptive Graph 模式对此的解法是:让 agent 只从一组预先批准的选项中选择路径,每次选择都被校验并持久化,写入动作前必须经过人工审批。官方文档用一个完整示例演示该模式——受治理的 GitHub PR 审查器:先做四轮持久化的证据收集,再由人工批准,最后才发布一条 PR 评论。
本文按这个示例走一遍完整的构建与运行路径:准备前置条件、注册并启动工作流、在审批门处放行或驳回,最后核对输出。
图结构与内置任务
文档对该模式的定义:adaptive agent 可以在运行时选择一条已批准的下一路径;durable graph 让这个选择变成持久化、可检查、可治理的执行状态,而不是一段留在单个进程内的临时控制流。
示例图的整体流程(摘自文档):
该图只使用 Conductor 内置任务:LIST_MCP_TOOLS、CALL_MCP_TOOL、LLM_CHAT_COMPLETE、JSON_JQ_TRANSFORM、FORK_JOIN_DYNAMIC、JOIN、HUMAN、SWITCH、SET_VARIABLE、DO_WHILE。没有SIMPLE任务,因此不需要注册任何自定义 worker。
治理机制与任务原语的对应关系(来自文档的 agent concern 映射表):
| 治理需求 | 使用的原语 |
|---|---|
| 运行时选择已批准的工具 | SWITCH+ 受保护的CALL_MCP_TOOL |
| 有界并行扇出 | FORK_JOIN_DYNAMIC |
| 跨迭代记忆 | SET_VARIABLE+ workflow variables |
| 人工审批门 | HUMAN(durable pause,跨重启存活) |
| 迭代上限 | DO_WHILE的loopCondition |
| 失败补偿 | failureWorkflow |
运行前提
- Conductor 服务器与 CLI。用
npm install -g @conductor-oss/conductor-cli安装 CLI,conductor --version验证;本地开发可用conductor server start启动服务器。CLI 默认指向本地 OSS 服务器(详见 CLI 文档)。 - GitHub MCP 端点:一个 HTTP 可访问、已完成认证的端点,且暴露
pull_request_read和add_issue_comment两个工具。pull_request_read可用方法包括get、get_files、get_check_runs、get_diff、get_reviews、get_review_comments。 - 一个自己拥有的 fixture PR用于测试,文档明确要求对 owned fixture PR 运行。
- 凭据放在服务器侧:示例把
workflow.env.GH_TOKEN写入 MCP 的Authorization头。使用默认 environment-backed 配置时,在 Conductor server 进程启动前设置CONDUCTOR_ENV_GH_TOKEN(或配置等效的服务器端环境 provider)。不要把 token 放进workflow.input.githubToken——workflow input 会随执行记录一起留存。需要更强隔离时使用 credential-injecting MCP gateway 或服务器端 secrets provider;注意workflow.env的解析是 eager 的,发生在任务调度时。
注册并启动工作流
完整可运行的定义在 ai/examples/35-governed-adaptive-agent.json,工作流名governed_github_pr_reviewer,版本 1,工作流级超时timeoutSeconds: 1200(即文档所说的 20 分钟上限),超时策略TIME_OUT_WF。
在仓库根目录注册定义:
conductor workflow create ai/examples/35-governed-adaptive-agent.json启动时输入以下参数。其中mcpServerUrl替换为你自己已认证的 GitHub MCP 端点,owner/repo/pullNumber替换为你的 fixture PR,llmProvider/model替换为你实际使用的 LLM 配置(文档示例值为openai+gpt-4o-mini):
conductor workflow start -w governed_github_pr_reviewer -i '{ "mcpServerUrl": "https://your-authenticated-github-mcp.example/mcp", "owner": "your-org", "repo": "pr-review-fixture", "pullNumber": 42, "llmProvider": "openai", "model": "gpt-4o-mini" }'四轮证据收集:前三轮固定,第四轮自适应
DO_WHILE循环固定跑 4 轮(loopCondition为$.review_loop['iteration'] < 4),每轮通过SWITCH按迭代号分派:
- Pass 1:
pull_request_read的get读取 PR 上下文; - Pass 2:
get_files(perPage: 50)读取变更文件面; - Pass 3:
get_check_runs读取 CI 检查; - Pass 4(自适应):LLM 只允许从固定的深读集合
get_diff/get_reviews/get_review_comments中选一个或两个条目;随后 JQ 守卫(JSON_JQ_TRANSFORM)对选择做校验、去重并截断到最多 2 项,没有给出有效选择时回退到get_reviews;FORK_JOIN_DYNAMIC再用这份受控输入扇出CALL_MCP_TOOL任务做有界并行。
前三轮是文档特意设为不可跳过的:这让每次执行可比对,也保证示例可见地完成四次迭代。每轮产出一个紧凑、经过校验的 assessment 写入 workflow 变量,并追加到持久化证据账本evidence_ledger;最终评论从这份 durable ledger 合成,而不是来自无界的聊天历史。文档还强调:PR 文本、评论和 diff 在每个 LLM prompt 中都是不可信证据,绝不当作指令。
人工审批门
运行在第四轮之后停在HUMAN审批任务(taskReferenceName为approve_pr_comment)。这个暂停是持久的,跨服务器重启和部署存活。
先检查拟发布的评论和 durable ledger,然后在 OSS Conductor 上完成该任务。<workflow-id>替换为你启动执行后得到的 workflow id:
conductor task update-execution \ --workflow-id <workflow-id> \ --task-ref-name approve_pr_comment \ --status COMPLETED \ --output '{"approved":true,"reviewer":"operator@example.com","feedback":"Approved after review"}'驳回则发送{"approved":false,"reviewer":"operator@example.com","feedback":"Needs manual follow-up"}。驳回会以一个持久化的决策记录完成工作流,并且不会调用 GitHub。
验证结果
工作流的outputParameters暴露以下字段(定义见 35-governed-adaptive-agent.json):
passesCompleted:循环完成的轮数;evidenceLedger:持久化证据账本;riskLevel与review:最终草稿的风险等级与完整评审结果;approval:审批决策;publication:发布状态。
按审批路径,图会先读取 PR 现有评论并检查标记<!-- conductor-pr-review:<workflowId> -->:若标记已存在,publication记为already_published,不再重复发布;否则通过add_issue_comment发布评论,状态为published。驳回路径下状态为not_published,原因字段为 "Human approval was not granted."。
治理边界(文档给出的防护设计)
| 关注点 | 示例中的防护 |
|---|---|
| 缺少能力 | 循环开始前,工具发现步骤先验证两个必需的 GitHub MCP 工具,缺失则以TERMINATE失败退出 |
| 失控 agent | DO_WHILE固定 4 次迭代;深读扇出上限 2 次调用;工作流 20 分钟超时 |
| 上下文过大 | 每个 MCP 结果虽持久保存,但先裁剪为有界证据摘录再交给 LLM 评估 |
| 模型输出非法 | 非法 JSON 在 LLM 任务上失败并重试;可解析但不符合契约的 assessment 通过 JQ 守卫变成显式的 unknown 结果;非法的最终草稿在审批前 fail-close |
| 外部写入 | HUMAN任务必须返回approved: true,add_issue_comment才可能执行 |
| 重复评论 | 生成的评论携带 workflow-ID 标记;发布前检查 PR 现有评论中的该标记 |
| 写入结果不明 | 评论创建没有幂等键,因此重试次数为 0;对模糊失败按标记搜索对账,不要盲目重试写入 |
| 取消 | 在批准写入之前终止不会产生评论;写入进行中被取消时同样需要按标记对账 |
文档还特别提醒:这个 reviewer 刻意保留全部 4 轮迭代,不要为它设置keepLastN——keepLastN会移除较早的循环输出和任务历史,对短审计轨迹是错误取舍;仅在可接受丢失历史时才对长循环使用它。
恢复与运维
- 基础设施恢复和普通任务级重试会保留已完成的下游任务;失败的读取和 LLM 调用有有界重试策略(各读取任务
retryCount: 2,指数或线性退避,详见 task 定义文档 同级的 taskdef 配置说明)。 - 重试一个失败的
DO_WHILE是另一回事:它会重启该循环的迭代历史。设计更长的循环时,应依赖已记录的证据账本和幂等的外部接口。 - 可以从 UI 或 CLI 对执行做 pause、resume、inspect、terminate 操作。
下一步
- Production Agent Architecture:把这张受治理的图带入评估、部署、恢复与运维的完整参考架构,含重试、内存、等待与补偿的展开说明。
- Failure Semantics:任务重试、at-least-once 投递、等待与循环失败行为的准确契约。
- MCP Guide:从工作流配置和调用 MCP 工具。
- JSON + Code Native Workflow Orchestration:快照、版本化与安全的运行时生成定义。
【免费下载链接】conductorConductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents项目地址: https://gitcode.com/GitHub_Trending/co/conductor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考