AI 自动化工作流从零搭:断点续跑式编排指南
📖 摘要:上一篇《给 AI 接上一双真干活的手》用一次发布前巡检实证了「Dify 编排发起、Agent 真执行」的形态,这篇是它的动手篇——不重复讲为什么,讲怎么搭:Dify 社区版 + 开源 Agent + 一个自写的约百行执行服务(桥),跑通最小闭环「流程发起 → Agent 真执行 → 结果回写」。文章给环境准备清单、桥的职责与代码骨架、两个 Dify 流程的搭建要点、以及「照做就能验」的验收三件套(正常路径/三类故障注入/安全闸门)。演示级最小闭环一到两天可搭完。文中代码为骨架级展示,完整交付级资产(生产化源码与配置)随项目交付文档提供。
一、这篇写给谁,读完能搭出什么
这篇写给两类人:一是交付工程师——想把「AI 真执行」从概念变成自己手里能跑的最小闭环;二是技术负责人——想评估这套形态要投入什么(不是看我们演示,是看自己搭要几步)。
读完并照做,你会得到这样一个最小闭环:
- 在 Dify 里填一个表单提交任务(比如「执行服务器巡检」)
- 流程秒回「任务已受理」——不阻塞等待
- 后台的 Agent 真的去目标机器上执行(拆任务、跑命令、看结果)
- 执行完成后结果自动回写 Dify 流程(收口流程 B——第二个独立流程),走成功分支收口;失败也回写,走兜底分支。收口整理出的报告推送给审批人/发起人(企微/邮件)——不是回到流程 A(A 在投递时就已结束)
整个过程任务 ID 贯穿、失败不悬空、高危动作默认被拦。这个闭环不依赖任何私有组件——Dify 社区版 + 开源 Agent + 一个约百行、零依赖的自写服务。演示级跑通,一到两天。
先说清楚这篇文章的边界:它是「最小闭环」的搭建指南,不是生产系统的完整图纸。桥的核心职责与骨架代码会给出(足够你理解与自建),但交付级的完整资产——生产化的源码、全部接口字段、部署脚本——随项目交付文档提供。原因不是藏私,是这类链路的真实价值在生产化那部分(台账、鉴权、闸门演进),而最小闭环的价值在于让你一小时看懂、两天跑通。
二、为什么是「断点式」:先理解桥的位置
动手之前,先花两分钟理解架构——不理解就照着搭,遇到问题只能瞎猜。
Dify 的强项是确定性编排:流程固定、节点可调试、输出可预期。但它流程里的 AI 默认不接触真实系统——你可以在平台内接各种工具 API,但让 AI 直接操作你的服务器(跑命令、改配置、读系统状态)不是它的默认能力。
Agent(执行体)相反:它擅长自主执行——收到任务自己拆解、调工具、看中间结果、处理异常——但它的执行过程对业务方是黑盒,不可审批、不可审计、结果不保证回得来。
所以中间需要一层「桥」:它接 Dify 的确定性指令,转给 Agent 自主执行,再把结果送回确定性流程。两端都不越界,断点由桥承接——这就是「断点式编排」名字的由来。
桥的职责拆成五块:
| 职责 | 干什么 | 不干会怎样 |
|---|---|---|
| 投递接收 | 接 Dify 的任务投递,秒回任务 ID | 流程被长任务卡死 |
| 任务状态机 | 记录任务从提交到完成的状态流转 | 任务状态不可查 |
| 转交执行 | 把任务交给 Agent,盯状态、收结果 | 无人驱动执行 |
| 结果回写 | 成功/失败都回调 Dify 流程 | 失败信号回不去,任务悬空 |
| 安全闸门 | 高危任务默认拒绝,显式授权才放行 | 破坏性命令可能被自动执行 |
为什么拆成独立服务,而不是做成 Dify 插件塞进平台?三个实测过的理由:一是安全边界——执行体的权限、审批、审计独立管理,不混进编排平台;二是复用——一个桥可以同时服务多个 Dify 流程,不用每个流程各接一套工具;三是自主性——执行任务是「会拆解、会看中间结果、会处理异常」的活,独立执行体天生干这个。自研插件这条路可行(我们做过插件开发),但实测后外置方案在安全与复用上更优。
时序上,完整链路长这样:
三、环境准备清单:三件套,先都验通
搭闭环需要三样东西各就各位:
1. Dify(编排平台)——社区版 docker 部署。需要确认两件事:Console 能登录(建流程用);API 服务可达(流程节点调外部服务用)。部署完成先自己访问一遍界面和 API 健康检查,别等搭到一半才发现平台没起来。
2. Agent(执行体)——开源 Agent 框架即可(本文基于 Hermes Agent 实测)。选型三条件:自带终端与文件操作通道(否则没法真执行);支持任务级授权控制(否则闸门无从谈起);可本地部署(不依赖云服务)。部署后确认它的 API 服务可用,且默认只监听本机回环地址——不要暴露公网。
3. 桥(自写执行服务)——一个约百行、零依赖的 Python 服务。跑在哪有讲究:它既要被 Dify 的流程节点调用(HTTP 投递),又要能访问 Agent 的 API,所以部署位置要两边都能通。桥本身无第三方依赖,一个 python 文件就能跑。
「两边都能通」具体怎么实现? 两种常用部署路径,按你的环境选一个:
- 路径一:桥跑在宿主机上,Dify 容器通过宿主机网关访问它。 桥直接跑在部署 Dify 的那台机器上(python 文件启动即可,监听本机端口);Dify 的流程节点调用桥时,地址写宿主机网关(docker 环境下通常是 host.docker.internal,Linux 需在 compose 里显式开启该映射,或用宿主机在 docker 网络内的实际 IP)。桥访问 Agent 走本机网络,天然可达。
- 路径二:桥作为容器加入 Dify 所在的 docker 网络。 在 docker-compose 里给桥加一个服务,network 与 Dify 一致(挂到同一自定义网络下),Dify 流程节点用桥的容器名访问它。路径二的好处是网络内寻址稳定、不依赖宿主机映射,代价是桥要容器化(多一层配置)。
最小闭环推荐路径一:桥零依赖、一个 python 文件,跑宿主机最省事;等要上生产再容器化也不迟。无论哪条路径,动手前先做连通性验证(第三节检查清单第三项):从 Dify 容器里 curl 一下桥的地址,通了再往下搭——这一步最容易被忽略,也是「流程节点报超时」最常见的根因。
前置检查清单(照做,全部通过再往下):
| 检查项 | 怎么验 | 通过标准 |
|---|---|---|
| Dify 可达 | 浏览器开 Console + API 健康检查 | 界面能登录,API 返回正常 |
| Agent 可达 | 调 Agent API 健康端点 | 返回正常 |
| 桥的位置能双向通 | 从 Dify 容器内访问桥地址 + 桥能访问 Agent | 两边都通(这一步最容易忽略,先验) |
| 目标机授权 | 确认 Agent 有权限操作目标机 | 试跑一条只读命令成功 |
第四项特别说一句:Agent 执行发生在目标机器上,权限要提前配好——最小闭环阶段用只读权限(巡检、查状态),别一上来就给写权限。
四、桥的最小实现:五职责的代码骨架
桥是整个链路里唯一要自己写的东西。好消息是它足够小——核心逻辑就是「收任务、转交、盯状态、回写、把关」。下面按职责给骨架,每一段说明它为什么长这样。
投递接收:秒回,不阻塞。 Dify 流程是同步等待 HTTP 响应的——如果桥在处理完整个任务后才返回,流程就会被长任务卡住(实测同步等待要 8-15 秒,用户端直接超时感)。所以投递端点只做一件事:收下任务、登记状态、立即返回任务 ID。
# 骨架 1:投递接收(只登记,不执行)
@app.post("/submit")
def submit():
task = request.body # Dify 投来的任务描述或结构化任务包
run_id = start_agent(task) # 提交给 Agent 执行(异步,不等结果)
return {"task_id": run_id, "status": "submitted"} # 秒回这里有一个实测踩过的大坑:Dify 的 HTTP 请求节点在 body 模板里做变量替换时,对含 JSON 引号的字符串变量替换不可靠——任务描述里只要带引号,投递到桥的内容就可能被截断。排查时在桥侧登记原始字节长度,发现收到的内容比 Dify 声明的短——内容在传输中丢了。解法:body 里裸引用变量,让任务包 JSON 原文直发,桥侧兼容两种形态(一段文本描述,或一个完整任务包)。搭的时候直接按「裸传原文」做,能少踩一个坑。
状态机 + 转交:提交、盯状态、收结果。 桥提交任务给 Agent 后,Agent 异步执行,桥需要轮询它的运行状态,直到终态。状态机就四个状态:submitted(已提交)、running(执行中)、succeeded / failed(终态,二选一)。
# 骨架 2:状态机 + 轮询转交
def start_agent(task):
run = agent.submit(task) # 提交 run
while True:
st = agent.poll(run.id) # 轮询状态
if st in ("succeeded", "failed", "cancelled"):
return finish(run) # 终态:收结果走回写
sleep(poll_interval)轮询间隔与超时阈值按任务类型调:短任务(几秒的巡检命令)间隔短一点;长任务放宽。超时后不能干等——先主动终止孤儿 run,再走失败回写(见下)。
双态回写:成功回,失败也回。 这是「敢不敢交付」的分水岭。最初版本只回调成功结果,后来做故障注入测试才发现:Agent 失败时桥不回调,Dify 下游无感知——任务在用户眼里永远「处理中」。所以回写必须是双态的:成功回调带执行结果,失败回调带失败原因和任务 ID,Dify 流程收到失败信号后走兜底分支(生成人工处置指引,而不是让任务悬空)。
# 骨架 3:双态回写(成功/失败都回调 Dify 流程 B)
def finish(run):
ok = run.status == "succeeded"
callback_to_dify({
"task_id": run.id,
"status": "succeeded" if ok else "failed",
"result": run.output if ok else None,
"error": None if ok else run.error,
})安全闸门:高危默认拒绝,显式授权放行。 这是最后一道闸。实测发现 Agent 自己的原生审批在无人值守链路上并不拦危险命令——所以闸门要放在桥这一层:内置高危模式库(递归删除、根路径强删、关机重启、格式化、清库这类破坏性动作),任务一旦命中高危模式,默认拒绝,Agent 零接触;要放行必须由流程显式授权(授权位由审批环节置入,单次有效)。
# 骨架 4:安全闸门(高危默认拒绝)
def check_gate(task):
if matches_high_risk(task) and not task.allow_high_risk:
return reject("高危任务被闸门拦截") # Agent 根本不接触
return allow(task)骨架就这四段——完整可运行的桥,是在这个骨架上补全边界处理(重试、超时终止、日志)而已。写出来大约百行。
再次说明边界:这里给的是职责骨架,足够你理解桥长什么样、自己搭一个。生产化的桥(任务台账落盘、鉴权与多租户隔离、高危显式声明字段演进)涉及完整接口设计与部署方案,属于交付级资产——需要时随项目交付文档提供,公开文不展开。
五、Dify 侧两个流程怎么建
桥就位后,Dify 侧要建两个流程——一个发起(A)、一个收口(B)。拆成两个而不是一个,正是断点式的核心:长任务不可能在一个同步流程里等完,必须 A 提交后立即结束,任务在桥那边跑,完成后再由 B 承接收口。两个流程靠任务 ID 关联。
流程 A(发起流程):表单 → 审批 → 组装任务包 → 投递。
节点职责:
- 表单节点——收业务输入。演示场景(服务器巡检)的表单就是几个字段:目标服务器、巡检项目、备注。
- 审批节点——人确认后才投递。这是「AI 真执行」与「AI 只建议」的分水岭之一:执行要留痕,动手要有人批。演示里审批通过才往下走,驳回就结束。
- 组装任务包——把表单字段组装成一次任务投递的内容。任务包的结构建议固定(可复用、可调试、可审计),最小形态含四块:任务类型(要执行哪类活)、任务上下文(目标、参数、约束)、预期输出(要回什么形态的结果)、执行约束(超时、权限边界等)。代码节点或模板节点组装都行,输出一个 JSON。
- HTTP 请求节点——投递给桥的地址。两个要点:一是body 裸引用任务包变量(见第四节那个坑,别把任务包嵌进一层带引号的 JSON 模板里);二是接口是 POST、投递后秒回任务 ID——流程拿到 ID 就结束,把 ID 记下来(后续对账用),不要在 A 流程里等执行结果。
流程 B(收口流程):接收回调 → 解析 → 分支收口。
节点职责:
- 接收回调——桥在任务终态时回调这个流程(HTTP 接收端点)。回调内容:任务 ID、状态(成功/失败)、结果或错误信息。
- 解析节点——把回调内容拆开:成功时把执行结果转成结构化字段(实测建议让 Agent 直接回结构化 JSON,如结论、根因假设、处置步骤、风险级别——桥原样回传,B 流程解析入库,下游好消费);失败时取出失败原因和任务 ID。
- 分支收口——按状态分两条路:成功端——展示执行结果(报告/数据对账),结束;失败端——不默默结束,生成人工兜底指引:任务 ID、失败原因、建议的处置选项(重试/人工介入/查日志)。兜底指引是「失败不悬空」的最后一环——用户永远知道任务去哪了、下一步怎么办。
流程 B 的两个节点不用 Dify 自带的 HTTP 接收能力也能做:如果平台对入站回调支持有限,可以让桥在回写时主动调流程 B 的 API(用 B 流程的应用 API 发一条消息/触发一次运行)。实现路径按你平台的实际情况选,职责不变:回调必达、成功失败分路、失败有人工出口。
六、打通与验收:照做就能验的三件套
流程建完,进入验收——这是和「demo 跑通就算完」拉开差距的地方。三件套照做:
验收一:正常路径端到端。 最小用例:提交一个只读任务(让 Agent 在目标机上执行一条巡检命令,比如查服务状态、读系统信息),验证完整链路:表单提交 → 秒回任务 ID → Agent 真执行 → 结果回写流程 B → 成功端出报告。关键验证点:回写的结果和真实系统对不对得上——报告里的主机名、服务状态、版本号,去目标机上手动核实。对得上才是真执行,对不上就是编的。实测里「内存占用这类数值两次取样有浮动」反而是好现象——恰证明数据是实时读的,不是背的。
验收二:故障注入三件套。 正常路径通不代表敢交付——要故意制造故障,验证失败路径真的兜得住。三个必注入的故障:
| 故障 | 怎么注入 | 期待结果 |
|---|---|---|
| 桥停摆 | 杀掉桥进程,再提交任务 | 流程 B 收到失败回调(或投递重试后失败),走人工兜底指引 |
| 执行中断 | 任务执行到一半,主动终止 Agent 的运行 | 桥捕获中断 → 失败回调 → 兜底分支,任务不悬空 |
| 任务超时 | 把超时阈值调小(比如 5 秒),提交一个必然超时的任务 | 桥超时后主动终止孤儿 run → 失败回调 → 兜底指引 |
三类故障的共性期待:任何故障都回到确定性流程,生成人工兜底指引——没有任何一种情况让任务无声悬空。这是验收的及格线。
验收三:安全闸门验证。 提交一个高危任务(任务描述里带破坏性动作,比如删除路径下的文件),验证:默认提交被闸门拦截(返回「高危任务被闸门拦截」,Agent 根本没接触);带授权标记提交则放行、真执行。双向都验——既验「该拦的拦得住」,也验「授权后确实放行」(否则正常的高危业务场景会全被卡死)。
验收判定表(照此打勾):
| 用例 | 期待 | 实测 |
|---|---|---|
| 正常路径:只读巡检任务 | 全链路走通,回写结果与真实系统对账一致 | ☐ |
| 故障注入:桥停摆 | 失败回调 + 人工兜底指引 | ☐ |
| 故障注入:执行中断 | 失败回调 + 兜底指引,不悬空 | ☐ |
| 故障注入:任务超时 | 孤儿 run 被终止 + 失败回调 + 兜底指引 | ☐ |
| 闸门:高危任务默认提交 | 拦截,Agent 零接触 | ☐ |
| 闸门:高危任务带授权提交 | 放行并真执行成功 | ☐ |
六项全过,最小闭环才算真的「通了」——否则只是「快乐路径能跑」。
七、演示级 vs 生产化:差距清单
最小闭环能跑,但它是演示级——距离生产交付还有一段明确的差距。列成清单,每一项都是实测过程中确认的功课:
| 差距 | 演示级现状 | 生产化要做的 | 为什么 |
|---|---|---|---|
| 任务台账 | 桥的任务记录在内存,重启丢 | 落盘存储,任务全程可查 | 重启丢记录 = 出问题没法审计 |
| 鉴权与隔离 | 桥无鉴权,谁调都能投 | 加鉴权,多租户隔离 | 桥是执行入口,裸奔危险 |
| 高危闸门 | 关键词模式粗筛 | 任务包显式声明高危字段 + 审批授权置位 | 关键词会误伤正常业务描述(如任务里提「覆盖」会被拦) |
| 投递可靠性 | 基本重试 | 提交失败重试 + 幂等 | 网络抖动下任务不能丢也不能重复执行 |
| 超时策略 | 固定阈值 | 按任务类型分档 + 超时后孤儿 run 处置 | 长任务短任务阈值不能一刀切 |
演示级到生产化的差距不是「再调调就好」,是「每一行都是独立的工程决策」——这也是为什么演示级一到两天、生产化按交付流程分阶段走。但要说清楚演示级的位置:最小闭环不是「上生产的半成品」,是「验证价值的工具」——场景值不值得投入、业务流程顺不顺、用户买不买账,跑完最小闭环就有答案;值得,再在它上面做生产化加固——生产化是加固演进,不是推翻重来。
常见问题
能换别的 Agent 吗?还是必须用文里这个?
能换。桥对 Agent 的依赖只有三个接口行为:能提交任务(run)、能查状态(poll)、能取结果——任何满足这三个行为的 Agent 都能对接。选型建议三个条件:自带终端与文件操作通道(否则无法真执行)、支持任务级授权控制(闸门才有意义)、可本地部署(数据不出内网)。其他框架我们没在这条链路上做同等深度实测,不展开对比——你按这三条件筛选即可。部署层面:按所选 Agent 的官方文档装(容器或二进制皆可),关键配置两处——开启它的 API 服务(本文链路的对接入口)、把目标机的执行凭据放入它的运行环境(最小闭环用只读权限起步)。
必须用 Dify 吗?别的编排平台行不行?
行,只要平台能满足两个能力:流程节点能发起 HTTP 调用(投递任务)、有接收回调的途径(收口)。Dify 社区版是本文默认,因为它开源、可本地部署、流程可视化——但桥的职责设计不绑定任何平台。反过来,如果不用编排平台,就是「纯 Agent 直连」——那是另一种形态(轻量独立),少了审批留痕和业务方可视化,适合单点任务不适合要审计的流程。
桥的完整源码能给吗?
文章给的是职责骨架(第四节),足够理解与自建——完整可运行的桥,照骨架补边界处理大约百行,自己写不难。生产化的桥(台账落盘、鉴权隔离、显式声明闸门、投递重试幂等、超时分档——第七节差距清单那五项的实现)是交付级资产,随项目交付文档提供,公开文不贴完整实现。这不是藏私——最小闭环的价值是让你看懂并跑通,生产化的价值是稳定与安全,后者需要按你的环境定制,给一份通用源码反而误导;需要时,交付文档里的完整版包含上述五项模块的完整实现与部署方案。
搭一遍要多久?搭完就能上生产吗?
演示级最小闭环(本文场景照做)约一到两天——前提是环境就位、照第六节验收清单走完。搭完是「能演示」,不是「能生产」——第七节的差距清单每一项都是生产化功课(台账落盘、鉴权、闸门演进),按交付流程分阶段做,另计周期。建议路径:先跑通最小闭环验证场景价值,值得再投入生产化。
这样搭安全吗?Agent 拿到执行权限会不会乱来?
安全不是单点,是三层:桥的闸门层(高危默认拒绝、显式授权放行——第六节验收三专门验它);Agent 的授权层(任务级授权控制,最小权限原则);平台的审批层(流程 A 的审批节点,人确认才投递)。三层都在,破坏性动作要过「闸门放行 + 人审批 + Agent 授权」三道关。但要说实话:执行权限一旦给出,风险不是零——所以最小闭环阶段用只读权限起步,高危场景的授权流程要单独设计和验收。
相关文章:给 AI 接上一双真干活的手——Agent 工作流里的人工审批怎么编排(形态总览)|AI 执行服务怎么搭:任务调度中枢拆解(调度中枢)|AI Agent 怎么安全地碰真实系统:执行体系三支柱拆解(执行体系三支柱)
本文与《给 AI 接上一双真干活的手——Agent 工作流里的人工审批怎么编排》同属一套实测体系(Dify 1.17.0 社区版 + Hermes Agent v0.21.0)。AI 参与创作声明:本文由 AI 辅助写作,内容基于作者真实实测记录。