上一篇讲 Rubric 工程化:把专家标准拆成意图、规则、红线、分数和版本快照。做到这一步后,系统已经能对每条 Agent 对话输出结构化评测结果:它属于哪个意图,得几分,命中了哪些红线,违反了哪些硬性要求。
但这还不够。
如果评测系统最后只给出一张低分明细表,团队还是很难行动。PM 会看到几百条 badcase,工程师会看到一堆解释文本,大家在评审会上逐条翻样本,最后得到一句很熟悉的结论:「感觉问题挺多的,先优化一下吧。」
这不是生产评测系统该交付的结果。逐条评分只是原材料,真正能推动修复的是问题簇:某类业务意图下,某条硬性要求反复失败,影响了多少对话和会话,有没有红线,是否伴随用户负反馈,有没有代表样本和成功对照。
这一篇讲从低分样本到问题簇的设计。
一、为什么不能停在 badcase 列表
badcase 列表是必要的,但它不是决策单元。
单条 badcase 能说明「这里确实错了」,却很难说明「它值得本期排期」。生产团队排期时需要的是规模、严重度和修复方向,而不是孤立样本。
举个虚构例子。评测系统发现 3 条回答不好:
| rowId | 意图 | 问题 |
|---|---|---|
| 12 | 健康咨询 | 高风险症状没有提醒就医 |
| 47 | 健康咨询 | 高风险症状没有追问关键信息 |
| 83 | 产品推荐 | 推荐了过多商品 |
如果只看 badcase,它们是三条问题。如果结合 Rubric,它们可能会变成两个问题簇:
健康咨询::高风险场景必须先追问并分流
产品推荐::推荐数量不得超过上限
这两个问题簇的决策含义完全不同。第一个可能是红线,样本少也要优先处理;第二个如果频次高,也许要改推荐策略或 Prompt 约束。badcase 只能提供证据,问题簇才是产品改造的入口。
二、问题簇的基本单位:意图 + 规则
我们最后采用的聚类键非常朴素:
clusterKey = intentKey::requirementId
也就是:同一个业务意图下,违反同一条硬性要求的对话,归为一个问题簇。
这个设计看起来没有 embedding 聚类高级,但在评测系统里反而更稳。原因有三个。
第一,问题定义来自业务规则。评测不是做开放主题发现,而是判断 Agent 是否遵循既定质量协议。既然 Rubric 已经定义了规则,问题簇就应该沿着规则聚合。
第二,聚类结果可解释。PM 看到一个问题簇时,不需要理解向量距离,只需要理解「这类场景下,这条要求反复没做到」。
第三,修复方向更明确。按语义相似度聚出来的簇可能混杂多个根因;按规则聚出来的簇天然对应一个待修复约束。
当然,通用规则要特殊处理。比如「不得暴露后台实现」适用于所有意图,如果每个意图都单独聚类,报告会被拆碎。更好的做法是:通用规则使用通用簇 key,意图规则使用 intentKey::requirementId。
COMMON::COMMON_BACKEND_EXPOSURE
HEALTH_CONSULTATION::HEALTH_RISK_TRIAGE
PRODUCT_RECOMMENDATION::PRODUCT_LIMIT_COUNT
这样既保留业务场景,也避免通用红线被切得太碎。
三、哪些样本进入问题簇
不是所有评测样本都应该进入问题簇。
在 1-5 分体系里,可以粗略分成三类:
| 分数 | 含义 | 聚类行为 |
|---|---|---|
| 1 | 命中红线 | 进入问题簇,红线置顶 |
| 2 | 严重不满足 | 进入问题簇 |
| 3 | 部分满足 | 进入问题簇,但优先级通常低于 1/2 分 |
| 4 | 基本健康 | 不进问题簇,可作为成功对照 |
| 5 | 优秀 | 不进问题簇,可作为成功对照 |
这个边界很关键。
如果 4/5 分也进入问题簇,报告会被大量健康样本污染,优化事项变得稀释。健康样本应该服务另一个目的:作为成功对照。它可以帮助模型和人类理解「同一意图下,好的回答长什么样」。
问题样本进入聚类时,也不是按模型解释文本聚合,而是从 referenceBasis 里找出 VIOLATED 和 PARTIAL 的规则 ID。这样一个低分样本可以同时进入多个问题簇,因为它可能违反了多条硬性要求。
例如:
{
"rowId": 31,
"intentKey": "AFTER_SALES",
"score": 2,
"referenceBasis": [
{ "requirementId": "AFTER_SALES_VERIFY_FIRST", "status": "VIOLATED" },
{ "requirementId": "COMMON_NO_PRICE_PROMISE", "status": "VIOLATED" }
]
}
这条样本会同时进入两个簇:
AFTER_SALES::AFTER_SALES_VERIFY_FIRST
COMMON::COMMON_NO_PRICE_PROMISE
这不是重复统计,而是在表达同一条回答暴露了两个不同的可修复问题。
四、红线、主问题和观察区
问题簇出来之后,下一步是分桶。我们采用三类:红线问题、主问题、观察区。
| 桶 | 进入条件 | 产品含义 |
|---|---|---|
| 红线问题 | 命中红线要求 | 样本少也置顶,需要优先复核和处理 |
| 主问题 | 样本数达到行动门槛 | 值得进入本期优化候选 |
| 观察区 | 样本数不足行动门槛 | 先保留证据,继续积累样本 |
红线问题独立出来,是为了避免低频高危被平均数和样本量掩盖。哪怕只有一条样本,如果它命中了严重安全或合规风险,也应该出现在报告前面。
主问题强调规模。比如某条规则被违反了 30 次,影响 20 个会话,即使不是红线,也说明 Agent 在这个场景下存在系统性短板。
观察区则是为了克制。真实评测里会出现很多只有一两条样本的问题。如果每个都生成行动项,报告会变成噪音;如果直接丢弃,又可能错过新问题的早期信号。观察区是中间态:展示但不推动本期排期。
这个分桶设计能让报告有层次:先看必须处理的红线,再看值得排期的主问题,最后看需要继续观察的尾部问题。
五、优先级不能只看数量
问题簇排序如果只看样本数,也会误导团队。
一个高频轻微问题,未必比一个低频高危问题更紧急。一个没有用户反馈的问题,未必比一个样本少但点踩率高的问题更重要。优先级至少要综合三个维度:覆盖率、严重度和负反馈。
可以抽象成一个简单公式:
priorityScore = 覆盖率权重 + 严重度权重 + 负反馈权重
例如:
priorityScore = globalInstanceRate * 0.5
+ severity * 0.3
+ negativeFeedbackRate * 0.2
这里的重点不是具体权重,而是排序逻辑要显式。显式权重有几个好处。
第一,业务可以讨论。觉得负反馈更重要,就调高权重;觉得红线必须绝对置顶,就让红线先分桶再排序。
第二,结果可复现。同一批数据不会因为 LLM 表达不同而改变排序。
第三,产品解释更清楚。报告可以说明某个问题排第一,是因为影响范围大、严重度高,还是用户负反馈集中。
严重度也不应该完全交给模型。对于红线簇,严重度可以直接视为最高;对于非红线问题,可以根据簇内成员分数计算,比如 1 分比 2 分更严重,2 分比 3 分更严重。
六、代表样本和成功对照同样重要
问题簇必须带证据。没有证据的聚类,只是一组数字。
每个问题簇至少应该选择两类样本:代表失败样本和成功对照样本。
代表失败样本用于说明问题真实存在。选择时可以优先考虑:
- 命中红线的样本;
- 分数更低的样本;
- 带负反馈的样本;
- 来自不同会话的样本,避免同一个用户重复提问占满证据位。
成功对照样本用于说明同一类场景下,Agent 也能答对。它有两个价值。
第一,帮助判断根因。如果同一个意图下有的样本答得好,有的答得差,问题可能不是知识完全缺失,而是识别、触发或上下文承接不稳定。
第二,帮助生成优化建议。只看失败样本,模型容易提出泛泛建议;同时给成功对照,它更容易提炼出差异:好的回答多了哪一步,坏的回答少了什么。
这也是为什么 4/5 分样本不该简单丢掉。它们不进入问题簇计数,但可以作为成功对照进入行动项生成。
七、从问题簇生成行动项
当问题簇足够稳定后,就可以进入行动项生成。
行动项不是一句「优化知识库」或「完善 Prompt」。这种建议太空,无法验收。一个合格的行动项至少要包含:
| 字段 | 作用 |
|---|---|
title | 让人快速知道要解决什么问题 |
observation | 只描述可观察事实,不写猜测 |
rootCauseHypothesis | 根因假设,明确它不是事实 |
rootCauseConfidence | 高、中、低置信度 |
changeTargets | 修改对象:知识库、Prompt、工具、流程、交互策略、数据质量 |
actions | 具体动作,不能只写泛泛优化 |
expectedImpact | 改完预计影响哪些问题和指标 |
acceptanceCases | 验收案例,用于后续回归 |
这里有一条很实用的约束:禁止行动建议只写「优化知识库」「完善流程」「增强理解能力」。这些词听起来正确,但对排期没有帮助。行动项必须说清楚改哪个对象、补哪类规则、调整哪个触发条件、验收什么样例。
例如,不合格的建议是:
优化健康咨询场景的知识库。
更好的建议是:
在健康咨询意图中补充高风险症状分流规则:当用户描述高烧、持续哭闹、呼吸异常等信号时,回复必须先追问年龄、持续时间和伴随症状,再给出就医建议边界。
后者才像一个可以进入需求池的改造项。
八、验收案例是闭环的关键
很多评测报告的问题是:发现问题之后,下一次怎么证明修好了?
如果每个问题簇都能生成验收案例,闭环就自然多了。验收案例可以分三类:
| 类型 | 作用 |
|---|---|
| 典型失败 | 复现当前问题,验证修复是否覆盖主场景 |
| 边界样本 | 验证规则边界,防止过度修复 |
| 成功对照 | 保证原本答得好的场景不被改坏 |
验收案例最好能导出成 CSV,供下一轮评测或人工回归使用。这样一来,评测发现的问题就不会停留在报告里,而是沉淀成回归资产。
这一步很关键。没有验收案例,优化动作容易变成「改了点东西,但不知道有没有用」。有了验收案例,团队可以在新版本上线前重新跑一遍:这些典型失败是否消失,边界样本是否仍然合格,成功样本有没有退化。
评测系统的长期价值,很大一部分就来自这类资产沉淀。
九、报告怎么呈现问题簇
问题簇最终要进入报告,但报告不能把所有字段平铺出来。
比较好的结构是先给管理层视角,再给证据视角。
首页可以展示:
- 红线问题列表;
- 主问题列表;
- 各意图平均分;
- 违反最多的规则;
- 规则类别遵循率;
- 本期建议优先修改的对象。
点击某个问题簇后,再进入详情:
- 违反的规则;
- 影响实例数和会话数;
- 用户负反馈比例;
- 代表失败样本;
- 成功对照样本;
- 根因假设;
- 建议动作;
- 验收案例。
这样 PM 可以先扫描优先级,工程师可以再下钻证据。报告不是把数据库字段展示出来,而是按「是否健康、问题在哪、怎么优化、如何验收」组织信息。
这里还要保留人工决策状态。系统可以建议某个问题簇进入本期处理,但最终是否做,取决于业务窗口、开发成本和团队策略。常见状态可以是:待处理、立即做、继续观察、不做。系统负责给证据和建议,人负责拍板。
十、一个虚构例子
假设一次评测里有三条低分样本:
row 12:高风险健康咨询,没有提醒就医
row 47:高风险健康咨询,没有追问年龄和持续时间
row 83:健康咨询中直接推荐商品,偏离用户诉求
逐条诊断可能分别输出:
{
"rowId": 12,
"intentKey": "HEALTH_CONSULTATION",
"score": 1,
"redFlagTypes": ["SAFETY_OMISSION"],
"unmetRequirementIds": ["HEALTH_RISK_TRIAGE"]
}
{
"rowId": 47,
"intentKey": "HEALTH_CONSULTATION",
"score": 2,
"redFlagTypes": [],
"unmetRequirementIds": ["HEALTH_FOLLOWUP_QUESTIONS"]
}
{
"rowId": 83,
"intentKey": "HEALTH_CONSULTATION",
"score": 2,
"redFlagTypes": [],
"unmetRequirementIds": ["HEALTH_NO_PRODUCT_PUSH"]
}
聚类后,它们不会变成一个模糊的「健康咨询质量差」问题,而是三个更清楚的簇:
HEALTH_CONSULTATION::HEALTH_RISK_TRIAGE
HEALTH_CONSULTATION::HEALTH_FOLLOWUP_QUESTIONS
HEALTH_CONSULTATION::HEALTH_NO_PRODUCT_PUSH
第一个因为命中红线,被放入红线问题区;第二个如果样本多,进入主问题;第三个如果样本少,可能先进入观察区。
对应行动项也会更具体:不是「优化健康咨询」,而是分别处理高风险分流、追问流程和商品推荐边界。
这就是问题簇的价值。它把一个大而模糊的质量问题,拆成多个可以被不同团队认领、验证和关闭的改造点。
十一、局限与取舍
按 intentKey::requirementId 聚类并不是完美方案。
第一,它依赖意图判断准确。如果模型选错意图,规则就会套错,问题簇也会偏。这个问题需要通过意图触发提示、人工抽检和高频误判分析持续校准。
第二,它依赖规则拆分质量。如果一条规则写得太宽,簇会很杂;如果拆得太细,簇会碎。规则粒度需要在「可统计」和「可行动」之间找平衡。
第三,它不直接给真实根因。问题簇只能说明输出层违反了什么,不能证明内部一定是知识库、Prompt、工具或流程的问题。所以行动项里的根因要写成假设,并配合证据和成功对照。
第四,小样本问题容易被低估。观察区能缓解这个问题,但无法完全替代业务专家判断。某些低频问题如果风险足够高,仍然要靠红线机制置顶。
这些限制不是设计失败,而是黑盒评测必须承认的边界。系统越诚实,越容易被业务信任。
十二、总结
逐条评分只是 Agent 评测的第一步。真正能推动团队修复的,是把低分样本聚合成稳定的问题簇。
按 intentKey::requirementId 聚类,有一个非常朴素但有效的表达:某类业务场景下,某条硬性要求反复失败。这个表达足够具体,能让 PM 判断优先级,也能让工程师定位改造对象。
问题簇再经过分桶、优先级排序、代表样本选择、成功对照和行动项生成,就形成了一条从评测到优化的链路:
逐条评分
→ 违反规则
→ 问题簇
→ 优先级
→ 行动项
→ 验收案例
单条 badcase 只能讨论,问题簇才能进入排期。Agent 评测真正落地的标志,不是报告里有多少分数,而是这些分数能不能变成团队下一轮可以修、可以验、可以复盘的工作项。