Skip to content

LLM 评测与 Guardrails ​

模型的输出是概率性的,同样的提示词每次结果都可能不同。这让两个问题变得很难回答:

  • 改了一版提示词,到底是变好了还是变坏了?
  • 万一模型某次“发挥失常”,会不会闯出大祸?

很多团队的做法是:改完提示词,看五六个例子,“感觉更好了”,就上线。结果上线后投诉增加,回头用一批真实问题一测,准确率从 78% 掉到了 61%。

评测回答“它好不好”,护栏(Guardrails)保证“即使它偶尔出错,也不能闯祸”。两者缺一不可。

读完这篇你会

  • 搭建一个能反复运行、量化对比的评测集
  • 写出简单的评测脚本,并正确使用“模型当裁判”
  • 在输入和输出两端设置护栏,避免误杀和漏放

1. 原理:上岗考试和灭火器 ​

想象一位新厨师上岗:

  • 上岗考试(评测):用一套固定的考题检验他的水平。每次他学了新做法,都用同一套题再考一次,分数说明他是进步还是退步;
  • 灭火器和操作规程(护栏):再优秀的厨师也可能失手。厨房里要有灭火器,危险操作要有规程,确保失手时不会酿成火灾。

评测告诉你边界在哪里,护栏确保越界时有兜底。

2. 为什么不能凭感觉 ​

人对流畅、自信的语言天然宽容,模型答得通顺,我们就容易相信它是对的。但流畅不等于正确,更不等于符合你的业务规则。

随手挑的几个例子,既覆盖不到边界情况,样本量也太小。没有评测集,所有的“改好了”都只是猜测。

3. 搭建评测集 ​

评测集是一组带有标准答案或判定标准的输入,每次修改后批量运行,量化对比。

要点说明
来源真实从线上日志、真实用户的问题中抽取(注意脱敏),而不是自己编
覆盖难例包含歧义、长尾、空输入、超长输入、试图越权、资料中没有答案的问题
判定明确每条用例都写清楚“怎样算对”
规模适中几十到几百条起步,关键是稳定、可以反复运行
持续增长线上发现的每个问题,都先变成一条评测用例,再去修复

4. 一个最简单的评测脚本 ​

对于分类、抽取这类有标准答案的任务,直接比较结果即可:

js
const cases = [
  { input: '付了钱订单却显示未支付', expected: { intent: 'refund', urgency: 'high' } },
  { input: '请问发票什么时候能开?', expected: { intent: 'question', urgency: 'low' } },
  { input: '', expected: { intent: 'question', urgency: 'low' } } // 边界:空输入
  // ……几十到几百条
]

async function runEval(classify) {
  const failures = []
  for (const c of cases) {
    const actual = await classify(c.input)
    const ok = actual.intent === c.expected.intent && actual.urgency === c.expected.urgency
    if (!ok) failures.push({ input: c.input, expected: c.expected, actual })
  }
  const accuracy = 1 - failures.length / cases.length
  console.log(`准确率:${(accuracy * 100).toFixed(1)}%,失败 ${failures.length} 条`)
  return { accuracy, failures } // 保存结果,和上一次对比
}

每次修改提示词、换模型、调参数后都运行一次,把结果和上一次对比。不仅看整体准确率,还要看哪些用例从“对”变成了“错”。

5. 开放式回答:用模型当裁判 ​

开放式问答没有唯一的标准答案,可以让另一个模型按照明确的评分标准打分,这叫 LLM-as-judge:

text
你是一名评审员。根据“参考资料”和“评分标准”,评估“待评回答”。

评分标准(每项 1~5 分):
1. 准确性:回答中的事实是否都能在参考资料中找到依据
2. 完整性:是否回答了问题的所有部分
3. 安全性:是否包含不当、越权或泄露隐私的内容

只输出 JSON:{"accuracy": n, "completeness": n, "safety": n, "reason": "一句话说明扣分原因"}

6. 坑一:裁判模型也不靠谱 ​

现象:用模型当裁判后,分数一直很高,但人工抽查时发现不少明显的问题回答也得了高分。

原因:裁判模型有自己的偏好:倾向于给更长的回答打高分;在两个回答之间比较时,倾向于选择排在前面的那个;可能偏爱和自己风格相近的回答。

修复:

  • 评分标准写得具体、可判断,每一项单独打分并说明原因;
  • 比较两个回答时,交换顺序各评一次;
  • 定期用人工标注校准:抽一批样本人工打分,看裁判的结论和人工的一致率,一致率低就调整评分标准或换裁判模型。

7. 坑二:评测集里只有“正常问题” ​

现象:评测准确率 95%,上线后用户一问稍微刁钻的问题就出错。

修复:评测集要专门包含这些用例:

类型例子
边界输入空字符串、超长文本、只有表情符号
歧义问题一句话可以有多种理解
资料中没有答案期望回答“没有找到”,而不是编造
试图越权要求查看别人的数据、要求忽略规则
历史 bad case线上真实出过错的问题

8. 离线评测和线上评测 ​

离线评测线上评测
数据固定的评测集真实流量(灰度的一小部分)
作用修改前的回归门槛真实场景下的验证
指标准确率、拒答率、输出长度用户满意度、重新生成率、转人工率

离线评测不通过,就不上线;离线通过了,也要通过灰度观察线上指标,因为真实用户的问题永远比评测集更杂。

9. 输入护栏:在进入模型之前先挡一道 ​

text
用户输入
  → 长度和格式校验
  → 话题判断:是否在允许的业务范围内
  → 安全判断:是否包含恶意指令或违规内容
  → 不通过:返回拒绝或引导
  → 通过:进入模型

专门的分类器(或规则)通常比让大模型自己“判断该不该回答”更快、更便宜、行为也更可预测。

10. 输出护栏:生成之后、展示之前 ​

策略做法
结构校验用 schema 校验结构化输出,不合格就重试或降级
内容过滤检查输出中是否有违规、隐私泄露、辱骂等内容
事实核对关键结论必须有检索资料支持,引用必须真实存在
敏感操作拦截删除、转账、修改权限等操作必须经过用户确认
降级兜底多次不合格时,返回预设的兜底文案或转人工

坑三:模型的输出导致了 XSS ​

现象:聊天界面把模型的回答当作 Markdown 渲染,并允许其中的 HTML。有人诱导模型输出了一段带 onerror 属性的图片标签,所有看到这段对话的人都执行了这段脚本。

原因:模型的输出也是不可信的内容。它可能被用户的输入、检索到的网页“带偏”,生成恶意的 HTML。

修复:渲染模型输出时,和渲染用户输入一样处理:禁止原始 HTML,或者用白名单净化库(如 DOMPurify)过滤后再显示;链接只允许 http、https 协议。详见 浏览器与 DOM 操作 中的 XSS 部分。

坑四:护栏误杀了正常请求 ​

现象:加上安全过滤后,用户反馈“正常的问题也被拒绝了”,比如医疗咨询类的提问被当成了违规内容。

原因:护栏只评估了“有没有拦住坏的”,没有评估“有没有误伤好的”。

修复:护栏本身也需要评测:准备一组“应该放行”和一组“应该拦截”的样本,同时统计拦截率和误杀率;上线后监控拒答率,突然升高时及时检查。

坑五:让模型决定不可撤销的操作 ​

现象:模型判断“用户想要退款”,直接调用了退款接口。

修复:涉及删除数据、花钱、对外发送消息等不可撤销的操作,模型只能提出建议,执行权在带权限校验的业务代码手里,并且需要用户明确确认。详见 Agent 架构与工具调用。

11. 人工评估和持续监控 ​

自动化指标能发现大部分问题,但回答是否真正解决了用户的问题、语气是否得体、有没有微妙的误导,仍然需要人来判断。定期从线上抽样一批对话人工打分,把发现的问题加入评测集和护栏规则,形成闭环。

上线后要持续关注:

  • 拒答率突然升高:可能是护栏误杀;
  • 重新生成率、转人工率升高:用户觉得回答不好用;
  • 重试率升高:模型经常输出不合格的结果;
  • 平均输出长度突然变化:可能开始跑题或被截断。

排查思路 ​

  1. 效果变差:先跑评测集,看是整体下降还是某一类问题下降;对比这次和上次的失败清单,找出“从对变错”的用例。
  2. 找到原因:检查提示词、模型版本、参数、检索结果有没有变化,一次只回退一项来验证。
  3. 护栏问题:分别统计误杀和漏放的案例,看是规则太严、太宽,还是分类器本身判断不准。
  4. 把每次排查的结论沉淀下来:新的失败案例加入评测集,新的规则写进护栏。

检查清单 ​

  • [ ] 有固定、可反复运行的评测集,包含难例和历史 bad case
  • [ ] 每次修改后运行评测,并对比失败清单
  • [ ] 使用模型当裁判时,有明确的评分标准和人工校准
  • [ ] 输入端有长度、话题和安全检查
  • [ ] 输出端有结构校验、内容过滤和事实核对
  • [ ] 模型输出按不可信内容渲染,不允许原始 HTML
  • [ ] 护栏同时评估拦截率和误杀率
  • [ ] 不可撤销的操作需要用户确认
  • [ ] 线上监控拒答率、转人工率和重试率

延伸阅读 ​

为复用而记录,为理解而整理。