平台工程视角下的 LLMOps:指标、契约、灰度与复盘的整合实践

zhichao Lv3

大模型上线不等于“答案正确”。这是一套从痛点出发、以业务为锚的评测与对齐方法论:让模型在你的场景中稳定、可解释、可量化。


引言

每次模型升级,我们都会被一串漂亮的离线分数诱惑:BLEU +3、Exact Match +2、BERTScore 也亮了绿灯。可一上生产,投诉与回滚照样来得迅猛。为什么“看起来变好”的模型,在线却“不够好”?

我的核心论点是:面向业务的 LLM 评测与对齐,核心不是追逐单一分数,而是为“人-模型-系统”三者设计一套降低认知负荷的开发者契约。就像一座城市的基础设施——它不决定你盖什么房子,但会规范道路、供水、电力与紧急通道,确保任何建筑都能安全运行、可持续迭代。

本文将结合平台工程的严谨与一线落地的经验,展示我如何从“分数崇拜”转向“契约驱动”,搭建一条能支撑持续交付的评测与对齐流水线。


为什么这件事很难:复杂性的三重根源

综合 Martin Fowler 对“架构即约束”的洞见、Jeff Atwood 对开发者体验的敏锐,以及 Dan Abramov 在演化式设计上的节制,我把难点归纳为三层:

  • 语义不封闭:开放领域的问答没有唯一正确答案,“看起来对”的语言可能与事实相悖。
  • 反馈不连续:离线指标与在线体验相关性不稳定,数据分布、知识时效与用户心智都在漂移。
  • 系统性缺席:评测常被做成一次性活动,缺少数据版本、指标契约、灰度与回归的工程化串联。

因此,评测与对齐必须走出“分数表”,回到业务目标与系统边界上来:我们要评估“系统在约束内完成任务的可靠性”,而不是“模型在某个样本集上说得像人”。


我的故事:从“刷分失败”到“契约驱动”的转身

背景:我们要做一个覆盖客服、运营与销售的知识问答助手。起初,我们用公开数据与少量标注集,围绕 BLEU/ROUGE/EM 搭了离线评测。指标一路走高,大家兴奋地上了 30% 灰度。

崩盘来得很快:

  • 事实幻觉:模型会“自信”补全过期政策;
  • 证据漂移:检索到的材料版本不一致,答案偶尔正确却无法复现;
  • 用户挫败:满意度波动大,客服把它当“聪明的自动完成功能”,不敢信任。

我们复盘时把问题拆成两类:评价“错在什么”与系统“该允许什么”。这催生了后续的契约驱动方案。

核心转折:定义“开发者契约”

我们写下了第一版契约(片段):

1
2
3
4
5
6
7
8
9
10
11
12
13
contract:
intents:
- name: policy_lookup
must_ground_on: latest_official_documents # 必须基于“官方最新文档”
allow_tools: [vector_search, sql_query]
disallow: [speculation, cross_department_policy_merge]
response:
must_include: [citations, version]
max_tokens: 300
style: crisp
safety:
on_uncertainty: ask_for_clarification # 不确定时先澄清
pii: redact

这里的关键不在 YAML,而是心智转换:

  • 不追求“一句完美答案”,而是规定“可用答案的边界与证据”。
  • 让评测围绕契约展开:如果答案没引证、超出证据域,即为失败。

评测与对齐流水线

我们把评测做成一条可持续交付的流水线,像 CI/CD 一样有“门槛与回滚”。

1
2
3
4
5
6
7
8
9
10
11
flowchart LR
A[真实日志采样] --> B[标注黄金样本/失败样本池]
B --> C[契约化提示与工具配置]
C --> D[离线评测: 事实一致性/可追溯/安全]
D --> E{达标?}
E -- 否 --> B
E -- 是 --> F[灰度发布 10%/30%/全量]
F --> G[在线监测: 采样标注/满意度/故障率]
G --> H{回归达标?}
H -- 否 --> B
H -- 是 --> I[版本固化与知识快照]

实施细节与结果

  • 数据:从真实对话采样 1,200 条,拆成 600 条黄金集、300 条难例集、300 条探索集;每次升级回放全部黄金集+抽样难例。
  • 工具对齐:把计算/查库交给工具,模型只负责编排。证据外回答直接拒绝或澄清。
  • 证据绑定:回答必须附带来源与版本;日志里保存向量检索 Top-k 与最终引用。
  • 指标体系:离线看“事实一致性(反事实惩罚)/证据覆盖率/拒答适当率/敏感过滤”,在线看“满意度/重复提问率/人工接入率/首次解决率”。

上线三周后的可衡量变化:

  • 幻觉相关工单下降 62%;
  • 首次解决率提升 18%;
  • 新政策上线的误答比例从 14% 降到 3%(得益于知识快照与版本标注);
  • 我们把“评测—对齐—灰度—回归”做成了日常动作,团队可以放心地每两周升级一次模型或提示。

评测不是分数表:构建“契约驱动”的指标框架

为了避免指标被“游戏化”,我们用一张“场景 x 指标”矩阵,约束每类任务该看什么分数:

  • 检索问答:事实一致性、证据覆盖率、引用质量(可人工抽检打分)。
  • 决策/流程:结果正确率、工具调用成功率、旁路校验通过率(例如总金额=各项之和)。
  • 文案生成:风格一致性、禁词命中率、差评率(在线采样)。
  • 安全与合规:拒答适当率、敏感话术过滤率、PII 脱敏正确率。

同时我们明确“成功标准”的三件事:

  1. 合法答:遵守契约(证据域/风格/长度/安全)。
  2. 有据答:引用充分(覆盖、质量、可复现)。
  3. 有用答:满足任务目标(闭环率/满意度)。

一个最小可用的评测仓库结构

1
2
3
4
5
6
7
./datasets/              # 标注数据(gold, hard, exploratory)
./contracts/ # 业务契约(YAML)
./prompts/ # 提示模板(含反例与澄清策略)
./evaluators/ # 评测脚本(faithfulness, grounding, safety)
./tools/ # 工具封装(search/sql/calc)
./runner.py # 批量运行与日志
./reports/ # HTML/CSV 报告与趋势

runner.py(简化):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from typing import Dict, Any
from evaluators import faithfulness, grounding, safety
from contracts import load_contract
from llm import call_model

def run_case(case: Dict[str, Any], contract):
rsp, trace = call_model(case["query"], tools=contract.tools)
return {
"q": case["query"],
"a": rsp,
"trace": trace, # 检索/工具调用/温度/版本
"citations": trace.get("citations", [])
}

def evaluate(cases, contract):
logs = [run_case(c, contract) for c in cases]
return {
"faith": faithfulness(logs),
"ground": grounding(logs),
"safety": safety(logs)
}

if __name__ == "__main__":
contract = load_contract("./contracts/policy.yaml")
metrics = evaluate(load_dataset("gold"), contract)
print(metrics)

对齐策略:把“聪明”关进规则里

对齐不是“把模型训到听话”,而是“让系统在约束内可靠完成任务”。我用“三把锁”来做对齐:

  1. 提示与反例锁:把业务规则写成“判定表 + 反例”,例如“遇到跨部门政策冲突必须拒绝”。
  2. 证据锁:答案只允许来自指定证据集,未命中则澄清或拒答。
  3. 工具锁:把可验证的计算、查询交给工具,模型只负责编排与解释。

必要时再加一把“流水线锁”:

  • 每个意图一个评测门(gold/hard 集),不达标不放量。
  • 回归失败自动触发“降级/回滚”,并把失败样本加入“修复池”。

行动手册:从明天开始你可以这样做

  1. 写下你的第一份契约:列出 3 个高频意图,定义“必须基于什么证据、允许哪些工具、遇到不确定如何处理”。
  2. 准备 200–500 条黄金样本:从真实日志采样;挑 50 条“难例”。
  3. 建一个最小评测仓库:datasets/contracts/evaluators/runner.py。
  4. 先做 10% 灰度:接入在线采样标注,把“重复提问率/首次解决率/人工接入率”拉到面板上。
  5. 每周一次回归:回放 golden + hard;失败样本进“修复池”。
  6. 版本固化:每次发布冻结“提示/工具/知识快照/模型版本”,保证可复现。
  7. 复盘仪式:用 30 分钟看 5 个失败样本,问三个问题:哪些契约含糊?哪些工具该前置?哪些证据需要分层?

权衡与局限:诚实面对不可避免的取舍

  • 过拟合评测集:门槛一旦固化,团队可能“为过门槛而优化”。对策:定期置换 10–20% 样本,引入在线采样。
  • 成本与时延:证据绑定、工具编排会增大延迟。对策:对频繁问题做缓存,对长流程做“延迟确认”。
  • 知识时效:政策与价格变化快。对策:知识快照 + 生效时间 + 过期提醒,把“时效”显式化。
  • 多语言与风格:指标跨语言不稳定。对策:把评测问题转成“结构化判定”,减少纯文本比较。
  • 标注偏差:不同标注者标准不一。对策:给“裁判”写规则,三评仲裁,记录分歧样本。

结语与展望

评测的价值不在“分数更高”,而在“知道为什么错、如何稳定变好”。当我们用契约把系统的“能与不能”写清楚,用流水线把“评测—对齐—灰度—回归”串起来,模型的能力被“关”在可控的边界内,团队的心智与协作成本也随之下降。

向前看,LLMOps 会更像平台工程:

  • 数据与提示的版本化像代码一样可回滚;
  • 评测门像单元测试一样普及;
  • 证据与工具的可观察性成为 SLO 的一部分;
  • 生成 + 检索 + 工具的组合将由策略引擎编排,评测将转向“策略层”的对齐。

我相信,一套好的评测与对齐系统,就像一座城市的基础设施:不规定你要建什么房子,但道路、供水和救火通道必须时刻在线。把这件事做好,AI 才能真正变成你的生产力,而不是你的另一个负债。

  • Title: 平台工程视角下的 LLMOps:指标、契约、灰度与复盘的整合实践
  • Author: zhichao
  • Created at : 2024-05-18 21:00:00
  • Updated at : 2025-10-07 23:25:40
  • Link: https://chozzc.me/2024/05/18/2024-05-tech-css-architecture/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments