32 反馈系统:把用户评价变成可优化的数据
反馈系统:把用户评价变成可优化的数据
反馈系统不是在答案下面放两个按钮,而是把用户评价、原始问题、检索结果、模型输出和版本信息连接起来,形成 RAG 优化闭环。
[TOC]
1. 这一节到底解决什么问题
前面我们已经把文档上传、解析、切片、Embedding、向量入库、向量检索和基础问答串起来了。到这里,RAG 已经不再只是一个“能回答”的 demo。
从 Day30 开始,重点要慢慢转向工程质量:
答案为什么可信
错误为什么能定位
效果为什么能比较
成本为什么能估算
部署为什么能复现
项目为什么能讲清楚
用户点了“无用”,如果系统只记录 dislike,你仍然不知道问题出在哪里。反馈要能追溯当时的检索、Prompt、模型和答案。
2. 先看一个业务场景
用户问“发票抬头怎么修改”,系统回答了旧流程。用户点了无用并备注“新系统已经改了”。这条反馈应该进入低质量样本池,标记为资料过期,然后推动知识库更新和评测集补充。
这个场景里,最容易出错的地方通常不是某一行代码,而是链路边界没有想清楚。
输入是什么
依赖哪份资料
中间结果怎么保存
失败时返回什么
如何证明改动有效
带着这些问题往下看,后面的设计就不会变成空泛理论。
这一节要先想清楚:反馈系统不是为了页面上多一个点赞按钮。
它要解决的是 RAG 迭代时缺少真实样本的问题。
判断顺序可以这样写:
1. 先明确用户反馈要定位哪类问题:答案错、来源错、找不到资料、表达不清
2. 再把反馈和 traceId、question、retrievedChunks、answer、sources 关联起来
3. 反馈标签不要太多,第一版先覆盖最常见失败类型
4. 后台要能按标签聚合失败样本,反推是检索、Prompt 还是资料问题
5. 最后用反馈样本进入评测集,形成下一轮优化闭环
它解决的是迭代闭环问题:反馈表真正保存的不是“满意/不满意”,而是后续排查和评测能复用的证据。
3. 核心概念
1. 二元反馈
有用/无用门槛低,适合收集趋势。但它只能告诉你结果好坏,不能告诉你根因。
可以把它记成一句话:点赞点踩看趋势。
2. 原因标签
答非所问、资料过期、引用错误、回答太长、权限问题等标签能降低用户填写成本。
可以把它记成一句话:标签帮助归因。
3. 问答快照
反馈必须关联当时的问题、检索结果、答案、引用、模型、Prompt 版本和 traceId。
可以把它记成一句话:快照用于复现。
4. 低质量样本池
无用反馈要进入处理流程,经过人工复核后加入评测集。
可以把它记成一句话:反馈最终要变成改进。
4. 整体流程
graph TD;
A["答案返回"] --> B["用户评价"];
B["用户评价"] --> C["选择原因标签"];
C["选择原因标签"] --> D["保存问答快照"];
D["保存问答快照"] --> E["进入样本池"];
E["进入样本池"] --> F["人工复核"];
F["人工复核"] --> G["修复并回归"];
图里每个节点都应该能单独打日志、单独统计耗时、单独写测试。
这就是我一直强调的:不要把 RAG 写成一个黑盒方法。黑盒方法演示时很爽,排查时很痛苦。
5. 落地步骤
1. 设计轻量交互
默认展示有用/无用。点无用后再展开原因标签和评论框,避免一开始就打扰用户。
落地时要留下可检查的产物:一套反馈交互原型。
2. 保存不可变快照
文档和模型之后会变化,历史反馈必须保留当时的上下文,否则无法复盘。
落地时要留下可检查的产物:answer_snapshot 表或文档。
3. 建立处理状态
pending、confirmed、fixed、verified 等状态能让反馈从收集走向闭环。
落地时要留下可检查的产物:反馈处理看板。
4. 把样本加入评测
确认过的失败样本要进入回归集,防止下一次版本升级又出同样错误。
落地时要留下可检查的产物:新增评测 case。
6. 数据结构或配置示例
| 项目 | 说明 |
|---|---|
| answerId | 被评价的答案 ID |
| rating | useful 或 not_useful |
| reasonCode | 用户选择的问题原因 |
| traceId | 关联完整调用链 |
| status | 反馈处理状态 |
如果项目里已经有自己的字段命名,可以不照抄这张表。但这些信息最好都能找到对应位置,否则排查问题时会缺证据。
7. 示例
feedback
- id
- answer_id
- user_id
- rating
- reason_code
- comment
- created_at
answer_snapshot
- question
- retrieved_chunks
- answer
- citations
- model
- prompt_version
- top_k
- trace_id
示例的重点不是格式,而是思路:把规则、参数、输入、输出和失败状态显式写出来。
8. 为什么不能简单粗暴地做
不能只看点赞率。点赞率低可能是检索问题,也可能是资料旧、答案太长、引用错、权限错。没有快照和原因标签,后续只能猜。
很多初学者会希望有一个“最简单固定答案”。但 RAG 项目里,简单粗暴通常会把问题藏起来:短期好像能跑,长期很难维护。
9. 调试和排查路径
当结果不符合预期时,建议按这个顺序排查:
1. 输入问题是否正确
2. 权限范围是否正确
3. 检索候选是否包含正确证据
4. 排序或过滤是否把正确证据丢掉
5. Prompt 是否把证据清楚交给模型
6. 模型是否按证据回答
7. 引用是否能支持结论
8. 日志、成本、耗时是否异常
不要一看到答案不对就去改 Prompt。很多时候问题根本不在 Prompt,而是在解析、切片、过滤、召回或数据版本。
10. 工程取舍
- 反馈入口越简单,数量越多;字段越细,定位越准。
- 用户评论有价值,但要做长度限制和隐私处理。
- 低质量样本需要人工复核,不能全部自动进入评测集。
取舍要写在文档里。因为过几周再回来看,你很可能只记得“当时这么做了”,却忘了“为什么这么做”。
11. 常见坑
- 只存点赞点踩,不存当时检索结果。
- 反馈很多,但没有负责人处理。
- 把用户评论直接拼进 Prompt。
- 只统计总体满意度,不看高风险问题。
这些坑不是为了吓人,而是为了让你知道项目坏掉时从哪里下手。
12. 验收清单
- ☐ 反馈能关联 answerId 和 traceId
- ☐ 无用反馈有原因标签
- ☐ 问答快照不可变
- ☐ 低质量样本有处理状态
- ☐ 修复样本进入回归评测
验收清单是博客里很有价值的部分。它能把一篇文章从“我讲了一个概念”变成“你可以跟着做出一个结果”。
13. 面试怎么讲
可以说:我没有把反馈当成 UI 小功能,而是把它设计成 RAG 优化闭环。每条负反馈都能追溯检索结果和 Prompt 版本,复核后进入评测集。
如果被追问,尽量用自己的项目样本回答,不要只背定义。比如:
我当时遇到的问题是……
我先用评测集确认是不是检索问题……
后来发现是……
最后我用……方式处理,指标变化是……
这样的回答比单纯说“我用了某某框架”更像真正做过项目的人。
14. 今日练习
- ☐ 设计反馈表和快照表
- ☐ 准备 5 个无用原因标签
- ☐ 把 3 条反馈转成评测样本
- ☐ 写一个反馈处理流程
练习做完后,建议把结果截图或记录到项目文档里。后面写 README、简历和面试话术时,这些都是现成证据。
15. 小结
反馈系统的价值,不是让用户发泄情绪,而是把真实使用中的失败变成可定位、可修复、可回归的样本。
到这里,你应该能把今天的主题讲成一个完整故事:为什么需要它、它解决哪一层问题、怎么落地、怎么验证、有什么代价。