多智能体总会“听话”吗?拆解忠实性与依据性,找到可靠性的真正边界
“给人确定性。不轻易承诺,一旦承诺,就必须负责到底。”
多智能体总会“听话”吗?拆解忠实性与依据性,找到可靠性的真正边界
在系统开始自主推理的时刻,传统的确定性可靠性全线崩溃;唯有在概率的宇宙中铸造确定性的外骨骼,才能守住工程交付的硬底线。
在很多技术团队的架构方案汇报中,最容易让全场陷入狂欢的,莫过于画出一张张“多智能体协同(Multi-Agent System, MAS)”的拓扑图:规划者(Planner)、执行者(Worker)、代码编写者(Coder)、审计者(Critic)各司其职,彼此通过自然语言消息交织成网。方案听起来宛如一个全自动运转的高科技数字化虚拟公司,但真正把这套东西推向严监管、高并发生产环境(例如核心金融与保单理赔核算平台)的一线工程师心里都清楚:默认答案永远是不该用;多 agent 是一笔要付的成本,得有具体理由才值。
本文将深入工业级生产系统深水区,彻底拆解多智能体架构的成立边界、确定性失效的信号、传统可靠性范式的彻底崩塌,以及如何在非确定性模型之上构建“确定性外骨骼”;同时剖析依据性(Groundedness)与忠实性(Faithfulness)的微观区别,并奉上涵盖四层观测信号、代理指标监控、告警军规与金丝雀审计的完备工程防线。
真正成立的理由
当你坐在架构决策席上,面对将单一 Agent 拆解为多个协同 Agent 的提案时,你必须审视前提假设。在严肃工程实践中,唯有以下四个场景才真正值得付出多智能体的高昂代价:
-
上下文隔离(最主要的一个)
主 Agent 的 Context 是极其宝贵的稀缺资源。一个要翻 40 份文档才能得出一句结论的子任务,应该在它自己的窗口里烧完 Token,只把那句结论交回来。这不是为了所谓的“组织分工”,纯粹是为了防止主线被噪音污染。把海量原始检索段落灌入主窗口,不仅浪费算力,还会导致注意力弥散,让核心决策迷失在上下文中。 -
并行化换延迟
这项收益只在“读多写少”的任务上成立——例如同时查五个互不相干的数据源,然后汇总提炼。一旦子任务之间涉及协调写入或事务修改,并行就从性能优势瞬间蜕变为灾难性的分布式一致性泥潭。 -
权限边界
这条在金融与保险场景里最硬:能读客户个人隐私(PII)的那个 Agent,绝对不应该同时拥有外部网络调用权限。把权限在物理层面切开,每个 Agent 严格遵守最小权限原则,这是基础设施与架构级的防御,绝不是靠在 Prompt 里写两句弱约束能替代的。 -
独立演进与独立评估
每个 Agent 拥有自己的 Prompt 版本、自己的评估黄金集(Golden Set)以及自己的回归测试套件。不同业务团队可以分别独立认领和维护。这是组织扩展的理由,不是纯技术理由——但它在企业实际研发落地中,往往才是最真实、最具说服力的动因。
要付的代价(能主动讲出来才显得做过)
任何未经压力测试的多智能体狂热,都会在生产环境遭到现实的冷酷惩罚。在架构设计之初,就必须主动向管理层与团队算清以下五笔隐形代价:
- 错误复合:单步 95% 的可靠性,串联五个 Agent 之后,整体成功率会迅速跌落至:
\(0.95^5 \approx 77.38\%\)
系统的整体脆弱性随着链条长度呈指数级恶化。 - 交接有损:子 Agent 不知道主 Agent 知道的事,节点交接全靠一段摘要或 JSON 结构体,信息必然在压缩与跨上下文传递中丢失,细微语义偏差会被逐级放大。
- Token 成本:通信协议开销、多轮握手与系统角色引导,普遍会导致 Token 消耗飙升至单 Agent 的十几倍。
- 可观测性复杂度:调用链路的 Trace 从一条直线变成一棵分支繁复的非对称拓扑树,排障定位难度直接上升一个量级。
- 评估难度:非确定性叠加非确定性,导致系统陷入黑盒归因困境——当最终输出错误时,究竟是提取器的锅、校验器的错,还是最终聚合节点的偏见?
┌─────────────────┐
│ User Query │
└────────┬────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Orchestrator: Can it be a Workflow? │
└──────┬────────────────────────────────┬──────┘
│ YES │ NO
▼ ▼
┌────────────────────┐ ┌───────────────────────┐
│ Deterministic DAG │ │ Runtime Branching │
│ (State Machine) │ │ (True Agent Needed) │
└────────────────────┘ └───────────┬───────────┘
│
┌─────────────────┴─────────────────┐
▼ ▼
Single Agent Multi-Agent
(Shared State) (Strict Isolation)
│ │
[Default Choice] [Only if: Context / Perms /]
[Parallel-Read / Independent Eval]
我用的判定标准
面对一个拆分需求,我有一套极其直接的工程检验红线:
📌 判定标准:子任务能不能用一段话描述清楚,结果能不能用一段话交回来? 不能,就说明交接会丢太多东西,必须留在单 Agent 里;读多写少适合拆;需要协调写入,绝对不要拆。
什么时候明确不该拆
在以下四类场景中,拆分多智能体非但不能带来收益,反而是纯粹的技术自嗨:
- 任务其实是固定流程:如果业务步骤是固定的 A 到 B 再到 C,那是状态机工作流(Workflow),必须用代码强制编排,绝不是 Agent,更不是多 Agent。
- 子任务之间要频繁来回对齐:当两个节点需要多轮双向协商才能收敛,通信与重试成本会瞬间吃掉全部收益。
- 延迟预算紧的同步场景:业务 SLA 严格限制在毫秒级或 1 至 2 秒内,多次 LLM 串行调用的网络开销与推理时延完全无法承受。
- 还没把单 Agent 的 Eval 做好:没有评估体系就上多 Agent,等于在看不见的地方制造复杂度。 这句话把所有狂热拉回到工程严谨性本身。
确定性失效的四个信号
在很多团队的架构评审中,常有一种将所有逻辑交由 Agent 接管的冲动。但工业级的共识是:绝大多数情况下就该用确定性编排。Agent 只在一种情况下才挣得到位置——控制流本身无法在设计时枚举。
确定性编排失效并真正需要 Agent 介入的四个信号如下:
- 分支不可枚举:输入空间高度开放,长尾情况无限。如果你写到了第 40 个
if还在加,说明你正在用机械代码吃力地模拟认知判断。 - 步数依赖中间结果:要检索几轮、要不要换个查询词重来,完全取决于上一轮读到了什么。DAG 图在编译期画不出来,因为边的存在与否只有在运行时才能知晓。
- 失败后需要换策略而不是重试:确定性重试是针对瞬态网络波动的“再做一次同样的事”;而在语义解析受阻时,系统需要的是“这条路走不通,主动换个查询策略重来”。
- 维护成本翻转:每新增一类业务场景就要大幅修改编排代码并重新发布,规则库的代码增长速度已经远远快过了业务价值的增长速度。
这四条如果一条都不满足,就老老实实用 Step Functions 或硬编码工作流。
确定性赢在哪(这些是真实的、不是保守)
确定性编排从来不是所谓“保守陈旧”,而是在核心生产工程指标上具备无可匹敌的绝对优势:
- 逻辑可枚举且行为完全可单测;
- 端到端延迟高度稳定可预测;
- 计算与调用成本恒定有界;
- 系统失败点定位清晰,无需复杂归因;
- 具备完全的可审计性:在合规与本地监管机构的要求下,“向审计员证明这个业务决定究竟走了哪条分支代码”是生死线。Agent 的链路虽然可以通过 Trace 记录,但其合规举证与解释成本要高出整整一个数量级。
我实际会用的形态:确定性外骨骼 + 模型内核
作为一线系统架构师,在日常工作中做系统设计最该强调这一点,因为这才是真正的工业级答案:
flowchart TD
subgraph Deterministic_Exoskeleton [确定性外骨骼架构]
A[Client Request] --> B[Input Sanity & PII Masking]
B --> C[Auth & Rate Limit Budget Gate]
C --> D{Deterministic Router}
subgraph Probabilistic_Core [模型内核]
D -->|Complex Case| E[LLM Agent Reasoning Node]
E --> F[Tool Intent Formulation]
end
F --> G[Deterministic Policy & Schema Guard]
G -->|Violated| H[Hard Block / Fallback]
G -->|Passed| I[Idempotent Action Execution]
I --> J[Structural Contract & Grounding Eval]
J --> K[Audit Log & Response Delivery]
end
- 外层确定性:死死拥有事务边界、重试与熔断机制、全局超时控制、访问权限隔离、全链路审计日志、幂等性保障以及分布式状态持久化。
- 模型只在节点内部做判断:仅负责分类、属性抽取以及这一步该调用哪个外部工具。
📌 核心心智模型:把 Agent 的自由度严格框在一个确定性的信封里——它能决定做什么,但不能决定边界在哪。 放开 Agent 在沙盒内的选择权,但一切不可逆动作与资金修改必须穿过一道确定性的物理闸门。
两个方向都要走
架构演进绝对不是一锤子买卖,而必须维持双向演化通路:
- 确定性走向 Agent:系统初期先用规则跑,埋点记录人工操作员在哪里频繁偏离了规则。等线上数据积累出充分的统计证据,证明分支确实爆炸了,再把那一段特定逻辑重构成 Agent。这样团队是拿实打实的证据做决策,而不是凭空追赶技术潮流。
- Agent 沉淀为确定性:反向的流动更加被行业低估。用 Agent 强大的灵活性去做业务路径探索;等系统在线上跑稳定了,通过日志聚类把 80% 的高频路径固化为硬编码确定性流程,Agent 仅退回到底层兜底长尾问题。这样改造后,系统的 Token 成本和 P95 延迟都会瞬间下降一个数量级。
Agent 适合用来“找”出流程,确定性编排适合用来“跑”流程。很多团队的问题是找完了还一直用 agent 在跑。
“AI-native” 的分界线
行业内很多人热衷于讨论“AI-native”,但两者的底层界限极其残酷:不是看“系统里有没有 AI”,而是看模型是否直接参与了控制流的决策。
| 维度 | AI-enabled 系统(传统叠加) | AI-native 系统(原生架构) |
|---|---|---|
| 模型所处位置 | 一个外围功能(摘要、分类、辅助推荐) | 处于中枢,决定系统下一步做什么 |
| 系统控制流 | 研发人员在设计时完全硬编码写死 | 运行时由模型动态推理产生 |
| 系统失败方式 | 显式抛出代码异常(如 500、NPE) | 看起来格式极其合理地做错事 |
| 移除模型后果 | 系统主体还能跑,只是少了个功能 | 系统直接不复存在,调度彻底瘫痪 |
架构检验试金石:把模型拿掉,还剩什么? 剩下一个少了功能的系统,就是 AI-enabled;什么都不剩,才叫 AI-native。
“reliable” 在这里意味着什么
传统软件工程历经数十年构建的可靠性公理,在 AI-native 语境下全线瓦解:
| 传统软件假设 | AI-native 的客观现实 |
|---|---|
| 同样输入必产生同样输出 | 相同输入在温度采样下输出每次不同 |
| 失败会显式抛出报错异常 | 失败往往表现为流畅、自信却致命的错误输出 |
| 静态测试能够穷举逻辑分支 | 执行轨迹与分支在运行时才动态涌现 |
| 系统正确性是布尔值(True/False) | 正确性是一个连续的统计学概率分布 |
| 升级依赖是团队自主的主动决定 | 外部模型供应商可以在我方毫无知情的情况下改变底层行为 |
最后一条在金融与保险企业特别致命:你的核心技术依赖会在你毫不知情时自己发生改变。供应商微调模型对齐策略、版本热替换、甚至安全拒答策略收紧,这些都不是你发版的,但引发的业务事故全部由你承担。
因此,在 AI 时代,系统的可靠性必须被重新定义:
在一个本质上非确定、偶尔会自信地犯错的组件之上,构造出行为可预测、后果有界、失败可发现的系统。
五个支柱(这就是企业级生产系统该有的完整架构)
要让概率组件承载起工业级关键业务,系统必须具备以下五大支撑柱:
┌────────────────────────────────────────────────────────────────────────┐
│ AI-Native Reliability Pillars │
├───────────────────┬───────────────────┬────────────────────────────────┤
│ 1. 后果有界 │ 2. 正确性是统计量 │ 3. 失败必须可见 │
│ (Bounded Blast) │ (Statistical QA) │ (Active Observability) │
│ • 事务物理隔离 │ • 告别布尔对错观 │ • 拒答率监控 │
│ • 幂等闸门拦截 │ • 置信度方差分析 │ • 路径断言异常告警 │
│ • 步数/预算硬上限 │ • 持续 Eval 度量 │ • 强制引用率监控 │
├───────────────────┴───────────────────┴────────────────────────────────┤
│ 4. 优雅降级 (Graceful Degradation) : 规则兜底 / 人工回退 / 确定性拒答 │
├────────────────────────────────────────────────────────────────────────┤
│ 5. 面对漂移的韧性 (Resilience to Drift) : 模型 Pin / 生产金丝雀集 │
└────────────────────────────────────────────────────────────────────────┘
-
后果有界
最重要的一条。可靠性从来不是奢求模型永远不犯错,而是让它犯错时也绝不造成不可逆损失。不可逆动作(如资金扣划、数据物理删除)必须穿过确定性闸门,强制执行最小权限、幂等性校验、单次调用的步数与预算硬上限。 -
正确性是统计量
在工程讨论中提问“它能工作吗”没有任何意义。有意义的工程问题是:“在这个数据分布上成功率是多少、方差有多大、失败集中在哪类输入切片上”。因此,Eval 不是上线前跑一次就扔的单测,而是生产系统实时可靠性的度量工具本身。 -
失败必须可见
传统系统宕机会直接拉响报警;AI-native 系统坏了却会继续输出漂亮得体的文字。所以必须主动在代码中造信号:置信度分流、结构化校验、引用强制、路径约束断言、与基线的持续比对。没有观测,你甚至不知道系统已经静默坏了三个月。 -
优雅降级
当模型接口不可用或生成质量不达标时,系统退到什么通道?退到固定规则、退到人工座席、还是退到确定性的“抱歉我无法回答”。一个只有满血正常路径的 AI-native 系统绝不配叫可靠系统。 -
面对漂移的韧性
坚决 Pin 住模型版本快照,拒绝使用无版本绑定的通用 Alias;Prompt 作为核心代码严格版本化纳管;保留随时回滚配置的通路;全天候常态化运行生产金丝雀基线集以捕获漂移。
保险语境下再加一层
在严监管与核心金融场景下,可靠性拥有更严苛的第二层释义:可被监管者信任。
决策证据链条必须清晰可追溯(调阅了哪些依据条款、经过了哪条逻辑分支)、人工复核专员在高风险点保留绝对的最终决定权、算法公平性完全可论证、客户个人信息与数据访问边界可随时接受现场审计。在合规风控标准下,无法白纸黑字举证的 Agent 系统,绝不允许跨入生产半步。
🩸 血泪提醒:切忌在系统内迷信任何所谓的“大模型自我反思(Self-Correction)”。缺乏确定性外部断言的纯模型内部循环,只会诱发更隐蔽、更难以察觉的自我欺骗与高阶胡说八道。
一句话工程原则版本
“AI-native 意味着控制流是模型生成的,所以可靠性不能再靠穷举分支来保证。我的做法是:把不确定性关在一个确定性的信封里——模型自由决定做什么,但边界、权限、不可逆动作和预算由确定性层管死;然后用 eval 把正确性变成可测量的分布,用 observability 让静默失败变得可见。可靠的 AI-native 系统不是不犯错的系统,是犯错也伤不到人的系统。”
一、先把失败分类——不同类型要用不同信号抓
捕获 AI 系统的失败之所以极其艰难,是因为你要检测的是一个没有任何异常抛出、没有报错堆栈、看起来完全正常的失败。必须针对不同失效类型部署针对性探针:
| 失败类型 | 典型外部表现 | 传统监控能抓吗 | 生产破坏力 |
|---|---|---|---|
| 硬失败 | 网络超时、HTTP 500、JSON 解析失败 | ✅ 能(标准 APM 覆盖) | 低(有成熟重试与熔断机制) |
| 幻觉 | 凭空捏造一条根本不存在的保单赔付条款 | ❌ 完全看不见(文本语法极其流利) | 极高(直接导致理赔纠纷) |
| 检索退化 | 向量索引损坏,但模型基于空上下文大胆发挥 | ❌ 完全看不见(依然给出体面回答) | 极高(业务逻辑彻底失真) |
| 静默降级 | 供应商调整后台策略,长尾场景成功率骤降 8% | ❌ 完全看不见(延迟状态码无异样) | 高(业务价值悄然流失) |
| 能力边界外 | 遇到从未涵盖的新案型,极度自信地瞎猜 | ❌ 完全看不见 | 高(误导用户做出错误决策) |
| 路径漂移 | 最终给出的结果看似正确,但执行步数从 4 步暴涨到 11 步 | ❌ 极其隐蔽(常被误当成网络慢) | 中(算力 Token 成本失控) |
| 拒答膨胀 | 安全护栏过度收紧,把大量合规请求强行拦截 | ❌ 更隐蔽(质量评分可能完全飘绿) | 极高(核心客户大面积流失) |
拒答膨胀极其阴险:拒答率上升在所有常规质量指标上都不掉分(因为系统没有给错答案),但实际的业务收益却在被过度敏感的风控闸门无声绞杀。
二、四层信号,按成本从低到高
要让上述隐性故障显形,必须由浅入深构建四道防线:
┌────────────────────────────────────────────────────────┐
│ 第四层: 采样审计与在线评估 (1-5% 流量, 高成本 LLM / 人工盲审) │
├────────────────────────────────────────────────────────┤
│ 第三层: 置信度多信号分流 (100% 流量, 毫秒级多特征加权评分) │
├────────────────────────────────────────────────────────┤
│ 第二层: 运行时路径断言 (100% 流量, 动态图轨迹不变量拦截) │
├────────────────────────────────────────────────────────┤
│ 第一层: 确定性契约与依据性校验 (100% 流量, 近乎零成本 CPU 正则) │
└────────────────────────────────────────────────────────┘
第一层:确定性校验(每一次请求都跑,近乎零成本)
能用代码硬逻辑判定的地方,绝不用模型打分。在出口网关处强制执行基于 Pydantic 的契约校验与业务不变量约束,这层能以微秒级耗时挡掉 30% 到 40% 的低级错误。
from decimal import Decimal
from typing import List, Dict, Any
from pydantic import BaseModel, field_validator, model_validator, ValidationInfo
class Citation(BaseModel):
doc_id: str
text_segment: str
page_number: int
class ClaimAssessment(BaseModel):
policy_number: str
covered: bool
excess_amount: Decimal
reasoning: str
citations: List[Citation] # 强制显式引用依据
@field_validator("policy_number")
def must_exist_in_context(cls, v: str, info: ValidationInfo) -> str:
# 关键:保单号必须来自检索结果,不能是模型造的
retrieved_ids = info.context.get("retrieved_policy_ids", set())
if v not in retrieved_ids:
raise ValueError(f"fabricated policy id: {v}")
return v
@model_validator(mode="after")
def excess_within_policy_bounds(self) -> "ClaimAssessment":
# 业务不变量:免赔额必须在该险种的法定区间内
legal_bounds: Dict[str, tuple[Decimal, Decimal]] = {
"HOME_COMPREHENSIVE": (Decimal("200.00"), Decimal("5000.00")),
"AUTO_PREMIUM": (Decimal("100.00"), Decimal("3000.00"))
}
bounds = legal_bounds.get(self.product_code, (Decimal("0.00"), Decimal("10000.00")))
if not (bounds[0] <= self.excess_amount <= bounds[1]):
raise ValueError(f"excess amount {self.excess_amount} out of bounds {bounds}")
return self
在此层之中,引用强制(Grounding Check) 是最值钱的手段:
import re
from dataclasses import dataclass
@dataclass
class GroundingReport:
grounding_rate: float
unsupported: list[str]
def verify_grounding(answer: str, sources: list[str]) -> GroundingReport:
claims = extract_atomic_claims(answer) # 拆成可验证的原子断言
unsupported = []
for c in claims:
# 先用便宜手段:字符串/数字必须能在 source 里找到
if c.has_numeric and not numeric_present_in(c, sources):
unsupported.append(c.text)
elif not semantic_match(c.text, sources, threshold=0.72):
unsupported.append(c.text)
return GroundingReport(
grounding_rate=round(1.0 - (len(unsupported) / max(len(claims), 1)), 4),
unsupported=unsupported,
)
grounding_rate 是我会放在看板最显眼位置的单一核心指标。它掉了,基本等于检索坏了或模型开始信口胡编。
第二层:运行时路径断言(每次请求,低成本)
把原本属于持续集成测试(CI)里的 Trajectory 轨迹断言直接搬到线上,作为不阻断请求的轻量级在线观测(涉及写操作的安全类断言除外,那些必须原地拦截):
RUNTIME_INVARIANTS = [
Invariant("no_write_before_approval",
lambda t: idx(t, "require_approval") < idx(t, "issue_payment"),
severity="BLOCK"), # 这条直接拦死,防止越权资金修改
Invariant("retrieval_before_answer",
lambda t: "search_policy" in t.tools_called,
severity="ALERT"), # 未查知识库直接下结论,记录告警
Invariant("step_budget",
lambda t: t.step_count <= 8,
severity="ALERT"), # 超过8步即判定为轨迹震荡
Invariant("no_repeated_identical_call",
lambda t: max(t.call_counts.values()) <= 3,
severity="ALERT"), # 单个工具连续调用超3次,判定为死循环
]
这层能精准抓到“输出结果看似正确,但执行过程已经严重损坏”——而这通常是生产事故的前兆信号,往往比大规模崩溃早出现整整几天。
第三层:置信度分流(每次请求,低成本)
关键是绝对不要只依赖模型吐出的 Logprob 单一信号,必须将多个互补的弱信号加权合成:
def confidence(ctx) -> Confidence:
signals = {
"retrieval_top_score": ctx.retrieval.scores[0], # 向量检索首位得分
"retrieval_margin": ctx.retrieval.scores[0] - ctx.retrieval.scores[1], # 区分裕度
"grounding_rate": ctx.grounding.rate, # 结构化依据率
"self_consistency": ctx.n_sample_agreement, # 采样3次的一致率(高风险跑)
"ood_distance": distance_to_training_dist(ctx.input_embedding), # 偏离基线向量距离
"step_anomaly": ctx.step_count / BASELINE_STEPS, # 步数异常比率
}
score = weighted_average(signals)
return Confidence(score, signals) # 信号要全部完整留在 trace 里,不只留合成分
低置信度,直接路由给人工。这把“模型可能错了”从一个飘忽不定的技术质量隐患,彻底转化成了一个可观测、可计数的业务事件:低置信度分流率本身就是系统最坚挺的健康指标之一。
第四层:采样审计与在线评估(抽样,高成本)
- LLM-as-a-judge 抽样:仅对 1% 到 5% 的流量运行昂贵的裁判模型,绝不是全量盲跑;
- 人工审计:每天固定抽查 20 到 50 条 Case,重点抽调处于低置信度区间以及高赔付金额的类别;
- 生产金丝雀集(Canary Suite):一组固定的复杂合成用例,每小时在真实生产 API 环境中完整跑一遍。这是检测供应商侧静默变更的最直接手段——线上流量天天在变,但这组输入永远不变;只要它的得分掉了,就断定一定是系统内部发生退化或外部供应商改了模型。
三、线上没有 ground truth 怎么办——代理指标
这是在架构评审中技术主管最常提问的一点。答案极其笃定:用人的行为当标注。
| 代理指标 | 说明 | 保险场景业务含义 |
|---|---|---|
| 人工推翻率 | 复核员改了 agent 的结论 | 最强的信号,直接近似线上真实错误率 |
| 编辑距离 | 人工对 agent 生成的草稿改了多少 | 质量的连续度量,比布尔值更加敏感细腻 |
| 升级率 | 会话主动转人工处理的比例 | 上升即代表系统能力边界在急剧收缩 |
| 客户二次联系率 | 同一客户或 case 7 天内再次进线 | 第一次交互未解决问题的最直接铁证 |
| 放弃率 | 用户在交互中途直接关闭跳出 | 流程卡顿或体验崩盘的直接体现 |
| 返工率 | 已归档的 case 被重新开启调查 | 存在隐藏逻辑疏漏或虚假赔付结论 |
| 拒答率 | 模型输出安全拒答或无法处理的比例 | 抓取外部 guardrail 是否过度收紧 |
人工推翻率 + 编辑距离 这一对是黄金组合,因为它们完全免费、连续产生、并且天然带有高质量标注——把被推翻的 Case 自动收集脱敏,便构成了你下一代 Eval 流水线的回归用例源头。这种正向循环流在工程持续迭代中至关重要。
四、告警怎么设才不会被无视
绝对不要对单次请求告警。 大模型系统单次波动是纯粹的噪音。
alerts:
- name: grounding_rate_drop
metric: p50(grounding_rate)
window: 1h
condition: "< baseline_7d - 0.08" # 相对过去7天基线,拒绝死板绝对值
min_volume: 200 # 样本不足200绝不触发误报
severity: page
- name: override_rate_spike
metric: human_override_rate
window: 24h
condition: "> baseline_14d * 1.5"
severity: page
- name: canary_degradation
metric: canary_task_success
window: 3 consecutive runs # 连续三次低于基线才告警,严格防抖
condition: "< baseline - 0.05"
severity: page # 这条最可能意味着供应商改了底层模型
- name: refusal_rate_spike # 容易被遗忘的关键防御方向
metric: refusal_rate
condition: "> baseline_7d * 1.4"
severity: ticket
三大军规牢记于心:相对基线、要求最小样本量、按时间窗口聚合。再加一条严格的分层机制——分为 Page(半夜呼叫)、Ticket(工单跟踪)、Dashboard(看板观察)三级,只有真正需要工程师立刻起床救火的硬性崩溃才允许触发 Page。
五、挑战问题与回答
Q: “线上没有标注,你凭什么说准确率掉了?”
分三路相互印证。一是代理指标——人工推翻率和客户二次联系率,这两个不需要人工打标且天然带有业务终局含义。二是生产金丝雀集,一组固定输入每小时跑一遍,它和线上流量的区别是输入永恒不变,得分变化只能来自系统内部。三是抽样审计,每天几十条由专家过目。三路互锁验证:如果只有线上代理指标下跌而金丝雀集平稳,那大概率是输入分布变了;若金丝雀集跌落,则是模型或底层检索发生退化。
Q: “怎么区分模型变差了,还是用户问的东西变了?”
这正是金丝雀集存在的理由。再加上输入分布监控:对输入做 Embedding,监控它相对历史基准分布的漂移(PSI 或分布距离),同时按意图类别拆分统计成功率。如果成功率的下降仅仅集中在某个新出现的特定类别上,那是输入分布漂移,需扩充语料;如果是全类别均匀下降,那一定是模型或检索出现故障。
Q: “你的 guardrail 自己也是个模型,它错了怎么办?”
承认这是个真问题。三条应对:第一,Guardrail 优先采用确定性手段,凡能用 Schema、数值区间、ID 存在性校验的绝不用模型。第二,Guardrail 必须有自己的 Eval 集,单独度量它的漏报率和误报率——漏报让风险穿透,误报让拒答率飙升,两端必须平衡。第三,不可逆动作不依赖 Guardrail 的判断,而是靠确定性的物理权限与审批闸门,Guardrail 只是外围的一道辅助打标层。
Q: “LLM-as-judge 全量跑成本太高。”
所以分层执行。确定性契约校验跑 100%,路径断言跑 100%(二者都是微秒级 CPU 计算,近乎零成本);LLM Judge 只针对 1% 到 5% 的抽样流量跑,人工复核跑千分之几。抽样绝非均匀随机,而是按业务风险分层抽样:高涉案金额、低置信度、新客户、新案型的抽样权重拉高。另外 Judge 使用专用小模型即可,它做的是判别而不是复杂长链推理。
Q: “告警太多团队就不看了,你怎么防?”
这是我最在意的工程组织失败模式,因为它会让前面所有防御机制形同虚设。做法:只对聚合指标告警,绝不对单次低分告警;阈值严格锚定在相对动态基线上;强制设置最小样本量;划分三级报警严重度;每个月定期审计告警的真阳性率,低于特定比例的告警规则必须直接降级或删除。宁可少报几条,也绝不能让研发团队在麻木中学会忽略告警。
Q: “trace 里全是客户 PII,怎么办?”
在客户端 SDK 层做,绝对不能推到中心化后端再治理。写入 Span 缓冲前,本地 SDK 对 Input/Output 执行确定性脱敏与哈希,链路中只保留结构化元数据(Token 长度、引用 ID、置信度多维信号)与脱敏文本。若因排障必须查阅原文,走专门的双人审批短 TTL 存储。默认不存原文,在严监管标准下这是不可触碰的红线。
Q: “你说‘坏了三个月才发现’,具体怎么避免?”
故障能静默三个月不被发现,唯一原因在于系统指标全是输出侧的——只看延迟、HTTP 错误率、吞吐,那些在模型胡说八道时确实毫无异常。要彻底杜绝,就必须建立独立于线上流量的客观参照系(固定金丝雀集)与独立于模型自评的业务参照系(人工推翻率与编辑距离)。只要这两个参照物在跑,静默故障就不可能存活。
架构结论:生产级可靠性从来不是奢求系统永不出现故障,而是确保系统对故障的平均发现时间(MTTD)被严格压制在不可逆灾难发生之前。我会把 MTTD 当成一个和成功率并列的一等指标,并且定期做注入演练去验证它——故意降级检索质量或切换低参数测试模型,检验系统能否在 24 小时内全自动捕获报警。
概念明辨:RAG 的三大境界与依据性 vs 忠实性
在日常架构对话与技术演进中,团队对基础概念的理解精度决定了系统最终的高度。
RAG 认知的三个层级
- 普通工程师:“我有使用 LangChain 开发 RAG 系统的经验。”(停留在拼装现成库代码)
- Senior 工程师:“我基于特定业务场景构建了 RAG,调优了分块策略,利用混合检索优化了召回准确率。”(聚焦于技术实现细节与局部优化)
- Lead 架构师:“在决定采用 RAG 架构之前,我首先在业务链路上明确检索是否真正必不可少;接着在第一行代码编写前,定义出可度量的质量、P95 延迟、Token 成本以及安全合规硬指标。围绕这些目标设计召回策略、Agent 编排与工具权限边界,并在投产前把端到端的可观测性与 Eval 基础设施构建就绪。”(从商业价值、系统边界、成本与风险全局统领)
RAG Architecture
│
┌─────────────────┴─────────────────┐
▼ ▼
Groundedness Faithfulness
(Has support in context?) (Free of distortion/extrapolation?)
│ │
Is the claim anchored in the Does it preserve the modality
retrieved text? and constraints of the source?
│ │
"Does evidence exist?" "Is the logic twisted?"
依据性(Groundedness)与 忠实性(Faithfulness)的微观辨析
- 依据性(Groundedness):核心检验生成的回答在检索到的证据文本中能否找到支撑材料。它回答的是:“输出内容是否有出处?”
- 忠实性(Faithfulness):核心检验生成的回答是否完全忠实于上下文证据,绝不引入自作主张的逻辑扭曲、条件删除或无事实根据的断言。它回答的是:“逻辑是否变形?是否把可能性说成了必然性?”
典型反例解析
例如保单条款原文写道:
“Coverage may apply subject to the conditions listed below.”(理赔可能适用,但严格受限于下述条件。)
而 Agent 在输出中作答:
“Your claim is definitely covered.”(您的理赔申请在此条款下必定获得全额赔偿。)
此时进行评估:即使 Agent 准确引用了该条款原文,其依据性(Groundedness)得分看似合格,但忠实性(Faithfulness)已经彻底崩溃! 它把原本极具法律约束力的或然条件语态(may apply subject to),擅自夸大为确定性承诺(definitely covered)。在金融与合规生产场景中,此类忠实性崩塌会直接给企业带来巨额赔偿诉讼。
生产级动态模型路由策略(Routing of Models)
没有任何单一模型能够同时满足最高的推理质量、极低的延迟与微薄的 Token 成本。构建工业级系统的核心能力之一,在于打造基于规则、模型轻量分类与质量级联驱动的多级混合路由体系:
Incoming Client Request
│
▼
Deterministic Path Checking
(Schema, Cache, Simple Regex)
│
┌───────────────┴───────────────┐
▼ Matches ▼ Misses
Direct Execution Lightweight SLM Classifier
(Zero LLM Cost) (Task, Intent, Risk Scoring)
│
┌─────────────────────┼─────────────────────┐
▼ Low Risk ▼ Complex Task ▼ High Risk Claim
Fast Small SLM Advanced Reasoning Deterministic
(e.g., 8B Class) (e.g., Frontier LLM) Controls + Human Gate
│ │ │
▼ Output Validation Fail │ │
└──────────────► Cascading Escalation ──────────────┘
落地方法论
- 能用代码解决的确定性场景绝不用大模型:能走正则、匹配、缓存或查表的,在系统最外层直接处理并返回,Token 成本严格保持为零;
- 轻量分类器前置甄别(Lightweight Classifier):对于需要 LLM 的请求,由延迟极低的轻量分类器评估意图、复杂度与潜在合规风险,分发至满足质量阈值且最具性价比的模型;
- 级联升级策略(Cascading Approach):在输出能够被验证的场景,流量先由低成本小模型处理;一旦后置契约或依据性校验失败,请求无缝级联升级至大模型重试;
- 核心高风险场景强制确定性控制:涉及重大财产判定的流程,绝不单凭模型打分决定,强制要求确定性控制闸门和人工专家复核;
- 路由策略的多维离线评估:在黄金数据集上持续压测路由策略,严格度量:任务成功率、单请求成本、P95 延迟、级联升级率以及安全违规率。
模型路由的目标从来不是盲目追求让小模型处理 90% 的请求,而是在绝对满足既定业务质量、延迟 SLA 与安全合规红线的前提下,实现端到端总拥有成本的全局最小化。
升维定律:确定性外骨骼与概率内核的分离定律
从一个具体的金融理赔系统,拉升到现代自适应软件工程的全局视角,我们可以抽象出一条可迁移的核心架构法则:
确定性外骨骼与概率内核的分离定律(The Law of Deterministic Exoskeleton Separation)
- 核心机制:在一切由概率驱动的现代软件系统中,业务正确性的最终防线绝对不能寄托于概率模型自身的内部对齐;系统的可靠性必须由包裹在其外部的、具备完全确定性状态机的物理外骨骼来严格承载。 概率内核负责在发散的语义空间中进行认知理解与局部判断,确定性外骨骼负责掌控事务边界、计算资源预算、不可逆动作闸门与终审合规。任何试图在概率内核内部寻找确定性的架构方案,都会在复杂度突破阈值后遭遇数学上的必然崩溃。
- 适用边界:适用于所有对对外商业承诺、法定义务合规、资金流动安全有严格要求的严肃工程系统。在纯娱乐对话、自由发散的灵感头脑风暴等不产生实际权责后果的场景中,该定律的约束厚度可适当放宽。
举一反三:审视你当前负责的系统——如果明天底层大模型突然产生了一次不可理喻的严重幻觉,你的系统架构是否能确保在最坏情况下,这个错误也能被外部确定性代码牢牢拦截在内网中,绝不会给客户造成任何实际损失或引发监管风暴?
结语:留下一个未合拢的切口
在系统控制流逐渐向 Agent 移交的今天,我们必须保持冷静的工程克制:系统不会因为打上了“多智能体”的标签就天然具备高可靠性。在概率的海洋里,一线工程师最高阶的手艺,依然是为系统注入不容妥协的确定性。
你的生产环境里,现在是否也有一个看似每天输出着体面文本、但实际上早已在长尾业务上静默降级了两个月的 Agent?你打算在明天的发布窗口里,部署哪一个固定输入的金丝雀探针,去第一次敲醒它的幻觉?