← 返回文章列表

从踩坑到定理(五):可验证性设计——为什么「看起来能跑」交付就翻车?

从踩坑到定理:Dify 应用工程的通用理论 · 5/7

📖 摘要:LLM 应用必须设计可观测性、可审计性、可重复验证路径,否则无法被独立验收。本文给出三层用例(功能点/节点/路径)+ 三分归因(应用/用例/环境)的完整验证体系——可靠是设计出来的,不是验收时发现的。

📌 本文要解决的核心痛点

  • 验收时「看起来能跑」,交付后边界场景连炸?
  • 客户问「你怎么证明可靠」,你只有「我点过几遍」?
  • 验收 FAIL 了,到底是应用错、用例错,还是环境错?
  • 本文讲可验证性设计:可观测、可审计、可复现——可靠是设计出来的,不是验收时发现的。

前四篇都在讲「怎么设计」,这一篇讲「怎么证明」。这是整个系列的落点:前面所有定理,最后都要回答一个问题——你怎么证明它真的可靠?

大多数 LLM 应用团队的做法是:开发完,手工点几遍「看起来能跑」,就交付了。然后用户发现问题,团队说「这是模型的问题」。这条路线我们走过,翻过车,后来彻底换了方法。

场景

交付一个 RAG 问答应用,验收阶段。第一版我们的验收方式是:把典型问题在界面上点一遍,「回答得还行」,出验收报告。

结果被客户当场打脸:人家问了三个边界问题——「手册里没写的,你怎么回答?」「两个相似故障,你答错了一个。」「换个问法,你给的依据变了。」我们无从辩驳,因为我们根本没有证据证明它可靠,只有「我点过几遍没问题」的印象。

那次之后我们立了一条铁律:验收不是流程,是设计的一部分。可验证性必须在设计期就造进应用里。

结论

定理 6(可验证性设计):LLM 应用必须设计可观测性(中间状态可查)、可审计性(输入输出可回溯)、可重复验证路径(同样的输入可复现验证),否则无法被独立验收。

推导来源:LLM 是黑盒 + 概率性 → 黑盒不可验证 → 验证能力必须在设计期造进去,而不是验收时才想。

这条定理是四个约束维度理论的应用层:它不增加新的维度,而是要求前四个维度的每条设计都「可被证明」。

推导链:为什么「看起来能跑」不算数

一个应用要能被独立验收,必须同时满足三个条件:

  1. 可观测:运行的中间状态要能查。LLM 节点的输入输出、检索节点实际检索了什么、改写节点把问题改成了什么——这些中间值必须有记录可查。没有可观测性,出了问题只能猜。

  2. 可审计:输入输出要能回溯。一次回答依据了哪几个文档段落、结论和依据对不对得上——要能回放。不能回放,就无法判断「这次答错了」是模型问题还是检索问题。

  3. 可重复验证:同样的输入要能复现验证路径。不是「点一次看看」,是「同配置、同输入、可重复执行用例」——验收的每个结论都要有可重复的执行记录支撑。

这三个条件的反面,就是「看起来能跑」:中间值看不到、回答依据说不清、验证结论无法复现。三个条件全部不满足,这个应用就是不可验收的——无论它实际质量多高。

正例实证:一套完整的验证体系长什么样

我们最终形成了一套完整的验证方法论,核心是测试分层 + 验收基线化

第一层:节点级验证(断言形状,不断言措辞)。

每个确定性节点验证输入输出契约;LLM 节点验证输出形状(字段存在、类型正确、值合法),不验证措辞——因为措辞是采样结果,逐字断言是错误预期。这一层回答「节点坏了没有」。

第二层:链路级验证(按路径枚举端到端用例)。

按业务拓扑枚举路径:主路径、分支路径、失败路径、边界路径,每条路径一个端到端用例。这一层回答「链路断了没有」。两层合起来,覆盖了「节点失效(局部)」和「链路失效(全局)」两类问题——对应定理 5。

第三层:验收基线化(断言事实,不断言措辞)。

验收用例先全部输出 → 用户确认基线化 → 执行时严格按基线跑,中途不因应用特殊性改用例。同一个问题采样多次,看结论是否一致——一致性断言的是「事实」,不是「表述」。 结论一致、表述不同 = 正常波动;结论都变了 = 工程缺陷。这一层回答「它稳定吗」。

三层合起来的执行链路:

graph TD subgraph layers["三层用例"] A["功能点级:端到端链路"] B["节点级:输入输出断言"] C["路径级:按拓扑枚举"] end A --> E["执行"] B --> E C --> E E --> F{"FAIL?"} F -->|"是"| G["三分归因"] G --> G1["应用缺陷:修应用"] G --> G2["用例缺陷:改用例"] G --> G3["环境问题:重跑"] F -->|"否"| H["基线化验收报告"]

独立验收(只报告,不修改)。

交付侧和验收侧分开:验收方只做验证和报告,不改应用。为什么?因为「改完再测」和「测完再改」混在一起,永远说不清质量是谁的。独立验收让「缺陷归因」干净——应用问题归应用,用例问题归用例,环境问题归环境,三分法明确责任。

这套体系跑下来,交付的每个应用都有完整的验证证据链:节点级断言记录、链路级用例执行记录、基线化验收报告。客户再问「你怎么证明可靠」,我们给出的是可回放的执行记录,不是「我点过几遍」。

反例实证:验收翻车的三种姿势

反例 1:手点验收。

现象:验收「看起来能跑」,交付后边界场景连炸。

根因:手点无法覆盖路径、无法复现、无法留痕——「点过几遍没问题」是印象,不是证据。

修复:路径枚举用例 + 执行记录留痕。

反例 2:验收时改应用。

现象:测试发现一个问题,当场改应用,改完「重测一下」,报告里分不清哪些是原样测的、哪些是改后测的。

根因:验证与修改混在一起,基线被污染。

修复:基线化 + 独立验收——先按基线跑完拿结果,再统一归因,再修应用。

反例 3:断言措辞。

现象:验收用例断言「回答必须一字不差」,模型措辞一变就报 FAIL。

根因:把采样结果当确定性断言——这是 LLM 应用验收最常见的自欺:把用例缺陷当应用缺陷。

修复:断言事实不断言措辞;同一问题多轮采样看结论一致性。这条经验后来独立成方法论——「如何区分 AI 幻觉与用例缺陷」:FAIL 先分清「谁错了」再动手修。

三个反例的共性:都是验证方法本身有缺陷,不是应用有缺陷。 这就是为什么说「可验证性是设计出来的」——验证方法设计错了,再好的应用也验不出来。

扩展:验证体系的落地形态——三层用例 + 三分归因

这套方法论具体落到项目上,是三层用例设计 + 三分归因的固定组合,这里把细节展开:

三层用例:功能点级、节点级、路径级。

三层合起来,把「验证」从一次性的「我点过几遍」变成了可执行的用例集。每一层都有明确的判定标准,执行结果可记录、可回放。

三分归因:应用缺陷 / 用例缺陷 / 环境问题。

验收中遇到 FAIL,第一件事不是修,是归因:

三分归因的价值在于防止一个最常见的自欺:把用例缺陷当应用缺陷修——应用本来是对的,因为用例断言错了报 FAIL,然后团队去「修应用」,越修越错。先归因再动手,是验收的第一纪律。

这套组合跑下来,每个交付项目都有一份完整的验证证据链:三层用例集 + 执行记录 + 归因记录 + 基线化验收报告。这就是「可验证性设计」在项目里的最终形态——不是一篇方法论,是一套每次交付都会执行的固定动作。

实践动作

边界与版本

版本无关:定理 6 是 LLM 应用的普遍规律——任何平台、任何框架下,黑盒概率系统的可验证性都只能靠设计期造入。版本相关的只是取证手段(节点执行记录的 API、日志格式)随平台版本变化。

边界说明:本系列的验证方法论基于文本型 RAG 应用与工作流应用实测;多模态应用的验证维度(图像输出如何断言)未在本系列实测范围内,推断待验证。

收尾

可验证性设计是四个约束维度理论的汇合点:平台约束决定你能观测什么(节点执行记录)、LLM 行为决定你该断言什么(形状与事实,不是措辞)、架构决策决定你该怎么分层(节点级 + 链路级)、数据/记忆决定你该审计什么(检索命中段与依据)。四个维度合起来,才构成「可证明的可靠」。

最后一篇,我们诚实地面对这套理论的边界:性能/成本这些我们实测还不充分的地方、平台版本演进带来的不确定性、以及理论本身的自我检验方法。

下一篇:从踩坑到定理(六):盲区与开放问题——这套理论有什么不能信的地方?

💬 讨论区:你验收过 LLM 应用吗?有没有经历过「看起来能跑、交付就翻车」?验收 FAIL 时你分得清是应用错还是用例错吗?评论区聊聊你的验收方法论。

本文基于真实项目交付经验撰写(Dify 1.16.x 环境、69 个实验与验收记录)。文中数据均来自我们自己的实测记录,理论部分以「已验证 / 推断待验证」标注边界。

联系我

15088711270

手机端点击号码可直接拨打 · 桌面端可复制

微信二维码

扫码加微信 · 备注「门户」更快通过