项目:文档处理任务编排器
用独立文档项目连接图校验、节点契约、任务快照和恢复,区分模型提取与有权限的外部操作。
验证依赖图,定义节点状态,并在版本固定的任务中恢复或核实副作用。
文档处理任务编排器让用户连接读取、提取、校验和人工审阅等操作,并看到每一步的结果。第一版可以只处理一类合成文档:读取文本、提取记录、验证字段,最后由人决定是否导出。
可视化画布只是编辑入口。真正需要设计的是图的合法性、节点输入输出、持久执行状态和副作用权限。先建立这些契约,再考虑拖拽、连接线和更多节点。
把节点限定为可检查的能力
一个节点定义包含稳定标识、类型、配置、输入字段和输出字段。类型来自程序维护的允许列表,例如读取已有材料、提取指定字段、校验记录和请求人工审阅。文档中的文字不能变成新节点或扩大工具权限。
提取节点可以使用模型,但其输出仍是待校验的数据。校验节点由程序检查字段与业务条件。导出节点产生外部效果,需要明确目的地和执行授权。把这些职责分开,失败时才能知道该修改提示、数据规则还是执行策略。
第一版选择有向无环图(DAG),拒绝自环和循环依赖。循环工作流是另一个设计题,需要终止条件、迭代状态和预算;不要因为画布能画出环,就默认执行器知道何时停止。
保存不可变的执行快照
图的编辑版本和任务运行版本应分开。开始运行时冻结图版本、节点配置、输入材料版本和需要的适配器版本。用户之后修改画布,不改变已经执行一半的任务。
任务记录总体状态,节点运行记录保存尝试次数、开始结束时间、输入引用、输出引用与错误类别。大文档或产物放在受控存储中,状态表保存引用与归属。记录恢复所需的数据,日志不默认复制整份文档。
可恢复状态不只是聊天历史。程序必须知道哪些节点已经完成、哪些结果已持久化、哪些副作用尚未确认。成功结果与完成标志尽量协调提交;若它们跨存储系统,要设计暂存、确认和对账,而不是假设存在一个全局事务。
先验证图,再安排节点
保存图时检查节点 ID 唯一、依赖存在、节点类型允许、必填配置完整和端口类型兼容。开始任务前再检查权限及资源限制,避免用户编辑后的配置绕过此前的判断。
拓扑顺序保证依赖先执行,但不代表所有节点都应同时启动。可以并行处理独立节点,同时限制活动节点数、输入大小、总运行时间与模型预算。某个依赖失败时,下游应进入阻塞或跳过状态,不能用空对象冒充成功输出。
下面的状态关系可以作为第一版约定:等待节点在依赖成功后进入运行,运行节点可完成、失败或请求人工输入;取消请求影响尚未启动节点,已经在外部运行的任务需继续核实实际结果。状态名字要对应实现行为。
用一个小图验证依赖与环路
示例反复找到依赖已完成的节点,按 ID 排序后加入执行顺序。它先拒绝不存在的依赖;若还有待处理节点却找不到可执行节点,则拒绝循环。
def order(graph):
if any(dep not in graph for deps in graph.values() for dep in deps):
raise ValueError("unknown dependency")
done = []
pending = set(graph)
while pending:
ready = sorted(node for node in pending if set(graph[node]) <= set(done))
if not ready:
raise ValueError("cycle")
done.extend(ready)
pending.difference_update(ready)
return done
assert order({"parse": [], "review": ["parse"]}) == ["parse", "review"]
try:
order({"a": ["b"], "b": ["a"]})
raise AssertionError("cycle accepted")
except ValueError:
pass
print(order({"parse": [], "review": ["parse"]}))
输出是 ['parse', 'review'],互相依赖的两个节点被拒绝。这是离线顺序检查,没有执行节点、保存任务或调用模型。代码为便于阅读反复扫描待处理集合,没有展示适用于大图的线性拓扑实现;大型执行器应另行评估算法和资源成本。
对恢复和重试分别定义条件
恢复任务先读取冻结版本与已确认结果,不能把当前画布直接接到旧任务上。复用已完成的纯计算节点,需要输入、配置和相关版本相同;依赖外部最新数据的节点还需明确新鲜度约定。
重试限制次数和总预算,区分临时错误与永久输入错误。每次尝试保留单独记录,逻辑节点仍保持一个身份。重试提取可以重新计算,但重试导出、通知或写入外部系统可能重复产生效果,应使用逻辑操作键及可核实的外部结果。
超时可能发生在外部操作已经完成之后。此时先查询或对账,不能直接把它写成“没有执行”。人工审阅同样针对冻结输出;输出被重新计算后,不能无条件沿用旧批准。
选择编排库时保留职责
LangGraph 提供状态图和持久执行等运行时能力,Dify 的 Workflow 与 Chatflow 提供各自的编排与交互方式。可以使用它们作为适配层,但节点权限、文档归属、业务校验和恢复策略仍由应用明确负责。
第一版先用代码保存一个固定图,跑通读取、校验和人工审阅。随后加入任务状态查询及恢复,再让画布编辑同一种图格式。这样能分别检查编辑器和执行器,避免把拖拽效果误当成执行可靠性。
画布显示节点状态、输出预览和可恢复动作。预览只展示当前用户有权读取的材料,错误消息不含凭据;人工确认应显示实际目标和副作用,而不是一个没有上下文的“继续”按钮。
节点输入契约还应区分必需字段与可选字段。上游输出缺少必需字段时,在调度下游前给出契约错误;不能自动填空字符串后交给模型猜测。节点升级若改变字段含义,应新增版本并提供显式转换,旧任务继续使用原契约。人工补充的数据也经过同一校验,保存操作者与修改范围,避免恢复过程绕过执行入口的限制。
练习:在每个边界中断一次
构造未知依赖、循环、字段不兼容、无权限材料和下游失败。图校验错误应在启动前返回;执行错误应留下明确的节点与尝试记录,并使依赖节点停止。
再在提取完成后、完成标志写入前和外部导出响应返回前模拟中断。验收恢复是否使用同一图版本、是否复用正确结果、是否识别可能完成的外部操作。检查取消后尚未开始的节点不会启动,同时明确已经执行的效果如何核实或补偿。
资料来源与延伸阅读
- Workflow and Chatflow
- Stateful graph orchestration
- Understanding JSON Schema
- Model Context Protocol — Tools
资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。