这是系列第六篇。第三篇建立数据契约,第四篇讨论故障边界,第五篇说明执行器接入。本篇将这些机制迁移到文档与模型处理。源码仍固定在公开 5cded0b 版本;流程和模型输出均为教学构造,没有调用真实模型、运行完整引擎或验证生成效果。
把视频分片换成文档片段
视频流程中的探测、分片、并行转码与合并,可以对应文档解析、分段、并行提取和汇总。假设要从一组技术说明中抽取功能、限制与引用依据,先把文件变成可定位的文本,再按片段调用模型,最后形成结构化报告。计算内容改变了,依赖与等待仍然存在。
文档 → 解析 → 分段 ┬→ 片段 A 提取与校验 ─┐
├→ 片段 B 提取与校验 ─┼→ 汇总 → 终审
└→ 片段 C 提取与校验 ─┘
图中的校验和终审是本文建议增加的业务节点,终审可以由程序规则或人工完成,并不表示引擎原生具备文档质量评估。这个区分很重要:引擎负责让节点在条件满足时执行,业务负责定义一个节点怎样才算真正完成。
可以复用的部分包括依赖表达、输入输出映射、集合展开、异步完成处理和符合条件的任务重试。每个片段进入一个子上下文,输出保留片段身份,父节点汇总后再交给下一步。第三篇讨论的空集合、缺失结果、重复身份和乱序问题,在这里仍然成立。
但文档片段不是天然独立的。跨段落的指代、表格标题和术语定义可能决定一句话的含义。分段策略应保留必要的上下文和来源定位,汇总时还要去重与处理冲突。并行结构可以加速独立工作,却不能证明拆分后的语义仍然完整;这需要通过应用样例评估。
因此,模型节点不宜直接承诺“返回一段文字就成功”。应先定义需要抽取什么、如何引用原文、什么情况下允许回答未知,再设计节点之间的数据结构。否则,原本清晰的工作流只会稳定地传递一串难以验证的自由文本。
现有模型接入实现提供了什么
固定版本已经包含 ChatGPTDispatcherExtension,它实现 DispatcherExtension,读取输入与模型参数,组织请求并调用外部接口;异步模式通过线程池执行,再使用回调地址通知引擎。它说明模型调用可以接入原有派发机制,不需要另造一套节点调度模型。
这是一份历史实现。代码中写有当时的接口地址和默认模型,并拼接提示词前缀、正文与后缀。本文讨论的是这个 commit 的接入路径,不把其中的默认模型、请求构造方式或参数摆放当作当前推荐方案。实际接入应依据服务方当期协议重新实现并验证适配器。
还应看到它做了什么、没有做什么。插件检查输入和部分必需参数,发送请求,将返回值交给后续处理;异步通知会带上完成类型及解析后的响应对象。它没有在这条路径中验证提取结论是否有文档依据,也没有建立整次业务的质量评分和调用预算账本。
与第五篇的 Java 示例相比,通知结果的具体嵌套方式也有差别:模型插件将解析后的响应放在 result 下。输出映射必须以实际适配器为准,不能拿另一份执行器示例的字段层级直接套用。协议外壳一致,并不意味着业务响应结构完全相同。
新适配器可以把供应商响应转换为稳定的应用对象,保存必要的请求标识、用量和错误分类,再把正文交给独立校验节点。这样更换模型或接口时,下游不用追着供应商字段变化。凭据应由受控配置提供,日志也应考虑文档内容的访问范围;这些属于本文提出的接入设计。
插件提供的是一次模型调用的桥梁。要把它用于文档产品,还必须补齐输入契约、输出契约和失败决策。把这些责任放在显式节点或适配层里,能让每一次质量判断都有可追查的输入与理由,而不是藏在一段难以审查的提示词中。
HTTP 成功之后,还需要哪些成功条件
可以把成功拆成四层。服务成功表示请求得到了可解释的正常响应;结构正确表示结果符合预定字段和类型;证据充分表示每条结论能回到给定材料;业务质量表示这些结论满足覆盖范围、准确性和表达要求。上一层成立,不会自动证明下一层成立。
下面是人工构造的抽取结果,用来说明校验对象,不是真实模型输出。片段标识与引文也都来自虚构教学材料:
{
"chunk_id": "doc-A:chunk-02",
"claims": [
{
"text": "服务支持异步完成通知",
"evidence": {"chunk_id": "doc-A:chunk-02", "quote": "任务完成后发送通知"}
}
]
}
结构校验可以检查 chunk_id 是否存在、claims 是否为数组、每项是否包含证据对象。它能够拦截缺字段和错误类型,却不能证明引文真的出现在输入中。因此,下一步还需要按文档版本查找引文,并确认片段标识属于本次允许使用的来源。
即使引文存在,也不代表结论被充分支持。例如,“发送通知”不一定意味着“保证通知最终送达”。证据校验应继续检查结论是否超出了原文范围;重要结论可以进入人工复核,或采用另一个受控评估步骤。评估器本身也可能出错,需要保留规则和判定依据,不能把第二次模型回答当成绝对事实。
业务质量还涉及遗漏和冲突。每一条已提取事实都有证据,仍可能漏掉整段限制条件;两个片段分别描述不同版本,汇总也可能把它们混成一个结论。验收样例应包含这些情况,并使用有明确预期的材料检查覆盖率与冲突处理,而不是只判断 JSON 能否解析。
为了便于复核,可以让校验节点输出错误类别、问题位置和可执行的修正建议。后继节点据此决定修复、补充材料、拒绝或转人工。它们是应用层结果,不应伪装成引擎任务状态枚举。流程中的成功节点,也可以输出“证据不足”这个业务判断,再通过分支决定下一步。
不同失败应该走不同处理路径
网络瞬断、临时限流、格式错误与证据不足,不适合使用同一重试策略。固定版本的任务重试提供再次执行的机制,业务仍要定义哪些失败值得再次调用、调用时是否改变输入,以及重复调用会消耗多少预算。重试能力本身不会改善一份缺少事实依据的材料。
对临时网络问题,可以在确认幂等与成本边界后退避重试。请求超时却不确定服务端是否完成时,应保留请求关联信息;如果服务支持查询,就先查询。无法确认时,需要把可能发生的重复调用纳入预算,不能默认上一次完全没有消耗。
对格式错误,可以先判断能否用确定性的转换修复,例如剔除协议允许的外层包装,再重新校验。若需要再次请求模型,应把具体字段错误和原始结果交给受限的修复步骤,并限制次数。不能为了通过校验,悄悄删除缺少证据的结论或凭空补出字段值。
对证据不足,原样重试通常不能创造缺失资料。合理分支可能是补充检索、请求用户提供材料,或输出明确的未知。对质量不达标,则要判断问题来自切分、提示词、模型能力还是验收规则。不同原因对应不同变更,统一增加重试次数只会让定位更困难。
如果部分片段通过、部分未通过,汇总策略也要明确:允许形成带缺失说明的阶段结果,还是必须等待全部有效结果。允许部分输出时,应把缺失片段与原因写进报告,不能用“父节点成功”掩盖资料不完整。严格场景则应在汇总前阻止未通过校验的结果进入。
这些策略可以用普通函数节点和条件分支组织,但需要区分两类动作:引擎对一次失败调用的重试,以及应用发起一次带新提示词或新材料的修复。后者改变了业务输入,应有新的尝试记录与版本关联,不能把所有结果都覆盖进一个看不出历史的字段。
预算、版本与人工介入放在哪里
并行调用模型后,单个节点的次数限制不足以约束整次业务消耗。十个片段各自允许修复几次,总调用量可能远大于用户预期。因此,预算应属于整次文档处理或明确的业务主体,再由每个调用申请额度。这是应用层扩展,固定插件没有替我们完成这份账本。
预算可以同时约束调用次数、Token 用量和总耗时。并发场景下,先检查余额再各自调用会发生竞争;更稳妥的设计是调用前原子预留额度,结束后按可取得的用量结算。预留与真实用量不一致时需要调整;超时导致用量暂时未知时,应保留未决记录,而不是立即释放全部预算并继续调用。
预算耗尽也应成为可解释的业务结果,例如停止新增模型请求、保存已完成片段并等待用户决定是否继续。不要把它伪装成网络异常触发无限重试。延迟返回的调用仍可能继续结算,因此停止新调用和撤销已有调用是不同能力,需要分别核对外部接口支持情况。
版本记录至少应关联文档内容、分段方式、提示词、模型配置和结果契约。否则,同一份文档再次运行得到不同结论时,很难区分输入变化与处理策略变化。保存这些信息是为了比较与审计,不代表能够靠重放一次请求获得完全相同的生成文本。
缓存与幂等也要遵循同样的版本边界。仅用文档名缓存结果,可能把新内容误认为旧输入;仅用片段文本,又可能忽略不同任务目标。结果复用键应覆盖会影响业务含义的输入和配置,并说明人工修订结果是否允许被后续运行替换。
人工介入可以由应用维护审核记录,再通过受控入口继续后续流程。审核状态属于业务域,不能直接声称引擎内置某个等待审核状态。进入审核前保存候选结果与依据,审核后保存采用、修改或拒绝的决定;恢复时还要确认输入版本没有变化,避免批准的是旧文档结果。
| 可复用机制 | 仍需补充 | 主要责任方 |
|---|---|---|
| 映射与子上下文 | 文档身份、来源与结果契约 | 应用与执行器 |
| 异步派发与完成处理 | 服务协议、通知确认与用量记录 | 模型适配层 |
| 重试与条件分支 | 错误分类、修复次数与退出规则 | 应用策略层 |
| 并行展开与汇总 | 全局预算、完整性与冲突处理 | 应用及预算存储 |
| 状态推进入口 | 审核记录、授权与版本复核 | 业务后台 |
DAG 能表达什么,开放式循环还缺什么
对数量已知或由前置节点产生的片段集合,foreach 很适合表达同一种处理的批量展开。对预先设定的分支,switch 可以根据结果选择后继。它们能覆盖很多文档流水线,但集合展开不是一个 Agent 根据中间反馈无限规划下一步的同义词。
固定版本的图校验包含对环的约束。不能仅在配置中把末尾指回前面,就宣称获得了任意动态循环。有限轮修复可以由应用预先展开为有限步骤;更开放的循环可以交给外部控制器,每一轮调用一个有边界的工作流。两者是扩展方案,需要额外实现与验证。
外部控制器至少需要记录当前轮次、剩余预算、已取得证据、待处理问题和退出原因,并决定哪一层拥有最终状态。否则,引擎认为一轮已完成,控制器仍在追加任务,用户却看见整个任务成功,多个“完成”含义会互相冲突。终止、取消和迟到结果也要沿这个边界协调。
退出条件应先于循环实现:目标满足、证据无法补足、预算耗尽、达到轮次上限或等待人工,分别对应什么结果。对工具选择开放的流程,还应限制可用工具和操作范围,并保留每轮决策依据。它们属于 Agent 应用的控制责任,不能由 DAG 拓扑或一次成功回调自动推导出来。
这六篇文章共同建立的是一种阅读方法:先确定流程与数据的责任,再检查状态、协议和故障窗口,最后讨论可以复用与需要补充的能力。对于 LLM,编排解决过程协调,质量仍需业务契约与评估来定义。前一篇是执行器接入与运行治理;回读源码可从历史模型插件、派发入口和并行展开实现开始。源码查阅日期为 2026-09-23。