想象你经营一家生意红火的餐厅。为了保证菜品质量,你在每张桌上放了一张“满意卡”,客人可以给刚上的菜点一个赞或踩。很快你发现,光是统计“今天有多少个赞、多少个踩”远远不够——如果招牌菜被人踩了,你必须知道是哪个厨师做的、用的哪份菜谱、上菜的时间对不对、甚至当天厨房是不是换了新设备。否则,你只能看着踩的数量发愁,却不知道下一步该改哪道菜。 LLM 应用的用户反馈收集,正是这张“满意卡”的数字化升级。用户对 AI 回答点下 thumbs up 或 thumbs down,这是最直接的质量信号。但与餐厅一样,仅仅把赞和踩存进数据库毫无意义:工程上必须把这条反馈与具体的对话轮次(哪道菜)、提示词参数与模型版本(哪份菜谱、哪个厨师)、以及完整的请求链路(从点单到出菜的每一步)关联起来。这就是“反馈收集与关联”要做的事——让每一次赞美与抱怨都能被精确定位、归因,最终驱动产品体验持续变好。

岗位关联

掌握反馈收集与关联能力,你就能把用户的每一声抱怨变成可定位、可追踪、可改进的工程资产,让 LLM 应用的质量优化不再靠猜。

目录
  1. 可视化演示
  2. 反馈价值概述
  3. 前端埋点设计
  4. 会话上下文绑定
  5. Trace关联机制
  6. 反馈数据仓库
  7. 归因分析实战
  8. 体验优化闭环
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示用户反馈Thumbs Up/的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

用户反馈Thumbs Up/:用户反馈 用户反馈采集前端埋点与交互设计 会话上下文绑定与对话轮次关联 核心机制可视化 用户反馈Thumbs Up/整体架构与关键组件

反馈价值概述

餐厅老板在大堂放了一本“客人意见本”。刚开始他只看一个数字:今天被赞了几次、被踩了几次。这本意见本就像 LLM 应用里的 thumbs up/down 按钮,是用户用手指投出的最直接的票。它不需要用户写长评,成本极低,却包含了明确的态度——而态度,就是质量最直接的信号。

在 LLM 应用里,可观测指标千千万——延迟、token 消耗、显存占用——但只有用户反馈直接回答“这个回答到底好不好”。点赞与踩是用户对生成内容的真实投票。工程师可以把延迟优化到极致,但如果用户持续点踩,产品体验依然糟糕。

但单看总数远远不够。一条“踩”背后可能是幻觉、是格式错误、是检索没命中、是模型版本回退。因此工程上首先要建立反馈价值的基本认知:主动反馈(赞/踩)加上隐式反馈(复制、重问、停滞)共同构成体验晴雨表。在建立收集体系之前,先定下最基础的观测指标——差评率:

就像意见本上的每一个“差”都必须对应一道具体的菜,差评率这个数字只有持续下降时才说明后厨真正变好了。记住:反馈的价值不在数字本身,而在数字能否指引改进方向。

Rneg=NdownNup+Ndown×100%\displaystyle R_{neg}=\frac{N_{down}}{N_{up}+N_{down}}\times 100\%
差评率 = 踩的数量 ÷(赞 + 踩),衡量全体明确表态用户中不满意的比例。
  1. 分子统计踩的数量 $N_{down}$分子只统计用户点击“踩”的反馈条数,代表负面信号的绝对数量,是问题的直接来源。
    NdownN_{down}
  2. 分母取明确反馈总数 $N_{up}+N_{down}$把赞与踩相加,得到所有做出了明确态度的反馈总量,排除了沉默用户带来的干扰。
    Nup+NdownN_{up} + N_{down}
  3. 比值换算成百分比分子除以分母后再乘以 100%,得到差评在全部明确反馈中的占比,便于跨时段、跨版本比较。
    NdownNup+Ndown×100%\frac{N_{down}}{N_{up} + N_{down}} \times 100\%

前端埋点设计

餐厅服务员递满意卡的时机和位置很讲究。客人刚吃完一道菜,立刻问“这道菜合口味吗”最有效;要是等客人结账离开,他早忘了哪道菜咸哪道菜淡。LLM 应用也一样:点赞/踩按钮必须出现在每一条 AI 回答旁边,而不是藏在设置页或帮助中心里。

埋点(instrumentation),就是在产品界面中安插“事件探测器”。对 thumbs up/down 来说,最小埋点方案包括:把赞/踩按钮放在消息气泡下方、为按钮绑定点击回调、并在回调中组装上报载荷。载荷至少要携带:评分内容(rating)、消息轮次(message_index)、会话标识(session_id)、链路标识(trace_id)以及时间戳。

工程细节容易踩坑:按钮要防重复提交——用户连点两次不能产生两条记录;误触要能容忍——必要时允许用户修改评分;上报要带重试与补偿机制,网络抖动不能丢事件。衡量埋点完备程度,使用埋点覆盖率:

服务员递卡的位置对了,客人才愿意写;按钮放在 AI 回答旁边,用户才愿意点。埋点覆盖率不达标,后面所有的归因分析都是无米之炊。

Ctrack=EtrackedEtotal×100%\displaystyle C_{track}=\frac{E_{tracked}}{E_{total}}\times 100\%
埋点覆盖率 = 已埋点的事件种类 ÷ 应当埋点的事件种类,衡量反馈采集的完备程度。
  1. 统计已埋点事件数 $E_{tracked}$已经设计并上线了采集逻辑的事件种类数,例如“点赞点击”“踩点击”各算一类。
    EtrackedE_{tracked}
  2. 统计应埋点事件数 $E_{total}$根据产品交互定义,所有需要反馈能力的位置对应的目标事件种类总数。
    EtotalE_{total}
  3. 两者相除取百分比覆盖率越接近 100%,说明反馈信号的触角越完整,漏采的关键路径越少。
    EtrackedEtotal×100%\frac{E_{tracked}}{E_{total}} \times 100\%

会话上下文绑定

满意卡上如果只写着“不好吃”,后厨没人知道该改哪道菜。所以饭店会在卡片背面印上桌号、菜名和上菜时间——这些信息就是“上下文”。没有上下文的评价,只是一句空洞的抱怨。

对话上下文绑定,就是把反馈钉在具体的对话历史上。两个最小锚点缺一不可:session_id 标识是哪一个会话,message_index 标识是第几轮问答。试想一场 20 轮的咨询对话,用户在第 18 轮点了个踩——如果不知道是哪一轮,工程师只能对着整场对话猜谜。

更进一步,还要绑定“当时的提示参数”:比如 system prompt 的哈希值(一段固定长度的指纹字符串,用于识别提示词模板是否变化)、采样温度等生成参数、以及模型版本号。同一轮对话,换一个模型版本或提示词模板,答案可能天差地别。绑定越完整,后续归因越精确。量化这一环节的完备程度,用会话关联率:

桌号 + 菜名 + 上菜时间,让后厨能还原那道菜;session_id + message_index + 参数快照,让工程师能还原那轮对话。上下文绑定是反馈从“数字”变成“证据”的关键一跃。

Rsession=NboundNfeedback×100%\displaystyle R_{session}=\frac{N_{bound}}{N_{feedback}}\times 100\%
会话关联率 = 成功绑定到具体会话与消息的反馈数 ÷ 反馈总数,衡量“每一条反馈是否都找得到出处”。
  1. 统计成功绑定的反馈 $N_{bound}$同时拥有有效 session_id 与 message_index 的反馈记录数,说明这些反馈能定位到具体对话轮次。
    NboundN_{bound}
  2. 统计反馈总数 $N_{feedback}$进入收集系统的全部 thumbs up/down 事件数量,作为分母基线。
    NfeedbackN_{feedback}
  3. 计算绑定比例比值越接近 100%,说明“每一条反馈都能找到对应那道菜”,后续分析才有据可依。
    NboundNfeedback×100%\frac{N_{bound}}{N_{feedback}} \times 100\%

Trace关联机制

找到了是哪道菜还不够。如果是招牌菜翻车,老板还想知道:是换了厨师?还是改了菜谱?还是原料批次有问题?后厨的流水账把每一道菜与厨师、菜谱版本、原料批次绑在一起。这道流水账,在系统里就是 Trace。

一次 LLM 请求从进入网关开始,可能经历鉴权、提示词组装、模型调用、知识库检索、结果后处理等多个环节。每个环节被称为一个 Span(链路中的一段处理记录),所有 Span 通过同一个 trace_id 串成一条完整链路。Langfuse、Phoenix 等可观测性平台工具,就是帮我们记录并回放这条链路的“后厨流水账系统”。

反馈关联的关键操作是:前端上报反馈时携带 trace_id;服务端在生成反馈记录的同时,把该 trace 下所有 span 列表、模型版本快照、prompt 哈希一并归档。这样一条 thumbs down 就能回放出当时请求的每一步——检索到了什么、模型答了什么、后处理改了什么。用 Trace 还原率衡量完备程度:

老板翻开流水账,看到那盘招牌菜是“实习厨师 + 菜谱 v2 + 新供应商的鱼”,问题就清楚了。工程师拿到 trace,看到“检索片段为空 + 模型版本 v3 + 提示词模板更新”,幻觉的根因也清楚了。

Rtrace=NrestoredNfeedback×100%\displaystyle R_{trace}=\frac{N_{restored}}{N_{feedback}}\times 100\%
Trace 还原率 = 能完整还原请求链路的反馈数 ÷ 反馈总数,决定“事后复现现场”的能力上限。
  1. 统计可还原链路的反馈 $N_{restored}$通过 trace_id 能找回完整 Span 列表的反馈数,意味着可以回放该次请求全流程。
    NrestoredN_{restored}
  2. 统计反馈总数 $N_{feedback}$全部反馈事件数,包含 trace 丢失、前端未上报等异常情况。
    NfeedbackN_{feedback}
  3. 比值反映还原能力还原率越高,越接近“每条差评都能翻流水账定位到具体环节”的理想状态。
    NrestoredNfeedback×100%\frac{N_{restored}}{N_{feedback}} \times 100\%

反馈数据仓库

餐厅每晚打烊后,经理会把当天所有满意卡收进柜台,按日期、桌号、菜名归档到台账本。一个月后,他想看“哪道菜差评最多”,翻台账一目了然。这就是反馈数据仓库的雏形——把零散的评价沉淀成可查询的资产。

反馈数据仓库,就是把前端埋点记录、会话上下文、trace 信息汇聚成统一可查的数据资产。难点在于:埋点数据是流式的,大小字段不一致;同一用户可能重复提交;会话数据与 trace 数据来自不同系统,需要对齐 ID 才能关联。

典型的分层设计分三层:原始数据层(ODS)原样保留每条事件,是“只记账不改账”的底稿;清洗聚合层(DWD/DWS)负责去重、补全会话信息、关联 trace、按消息维度聚合统计;应用层则面向看板与归因查询提供结果。写入路径上既要有实时管道入库,也要有离线批量回填,保证数据不丢。衡量仓库数据可用性,看有效反馈率:

台账本按日期和菜名归档,让经理一个月后还能回答“酸菜鱼是不是越来越差”;数据仓库按会话与 trace 归档,让工程师三个月后还能回答“v3 版本上线后幻觉差评是否上升”。归档的粒度,决定归因的深度。

Rvalid=NcompleteNtotal×100%\displaystyle R_{valid}=\frac{N_{complete}}{N_{total}}\times 100\%
有效反馈率 = 同时具备评分、会话、Trace 三种关键字段的反馈数 ÷ 总反馈数,衡量“能用于归因的完整记录”占比。
  1. 统计完整记录数 $N_{complete}$评分、会话绑定、trace 关联三要素齐全的反馈记录数,这类记录才具备归因分析的资格。
    NcompleteN_{complete}
  2. 统计总记录数 $N_{total}$仓库中落库的全部反馈事件数,包含各种残缺、重复、失联的脏数据。
    NtotalN_{total}
  3. 比值反映数据资产质量有效反馈率越高,说明仓库里的“真金白银”越多,垃圾数据越少,分析结论越可信。
    NcompleteNtotal×100%\frac{N_{complete}}{N_{total}} \times 100\%

归因分析实战

经理翻开台账:本月差评榜首是“酸菜鱼”,踩的客人集中在周末两晚;再翻厨师排班表,周末是替班师傅掌勺,用的还是旧菜谱 v1。三本账一对,根因浮出水面。这就是归因分析——用证据链拼出问题的完整拼图。

归因分析,就是从反馈出发,沿着已绑定的上下文与 trace 逐层定位根因。常见的分析模式有三种:缺陷定位——找出差评最集中的 prompt 模板或消息场景;版本对比——比较新老模型版本在同一批问题上的差评率差异;趋势监控——观察差评率随发布时间的变化曲线,捕捉突然的爬升。

还要学会挖掘弱反馈:用户没有点踩,但复制回答后立刻删除、在短时间内反复重问、长时间停滞不再交互——这些“隐式的踩”比主动差评更早出现。把它们纳入归因,可以提前发现体验滑坡,而不是等差评率爆表才后知后觉。归因环节的核心指标是归因定位率:

三本账对齐,老板锁定“替班师傅 + 旧菜谱”;反馈 + session + trace 对齐,工程师锁定“某 prompt 模板 + 某模型版本”。归因的价值,是让优化从“拍脑袋”变成“看证据”。

Rlocate=Nroot_causeNdown×100%\displaystyle R_{locate}=\frac{N_{root\_cause}}{N_{down}}\times 100\%
归因定位率 = 能明确确定根因的差评数 ÷ 差评总数,衡量团队“找到病根”的成功率。
  1. 统计确定根因的差评 $N_{root\_cause}$通过上下文与 trace 能锁定到具体提示词、模型版本或检索缺陷的差评数量。
    Nroot_causeN_{root\_cause}
  2. 统计差评总数 $N_{down}$全部踩的反馈数量,其中包含 trace 缺失、上下文不全而无法归因的悬案。
    NdownN_{down}
  3. 比值衡量归因能力定位率越高,说明反馈体系的关联建设越完善,优化团队越能“弹无虚发”。
    Nroot_causeNdown×100%\frac{N_{root\_cause}}{N_{down}} \times 100\%

体验优化闭环

老板决定:替换班师傅周末只做拿手菜,并把酸菜鱼的菜谱升级到 v2。一个月后再翻台账——差评率从 12% 降到 5%。菜谱改对了,但还得盯着:新菜谱会不会让“水煮鱼”翻车?这是优化闭环的日常——改一处,盯全局。

反馈驱动优化的闭环,是一个周而复始的循环:收集差评 → 归因定位 → 修改提示词或更换模型版本 → 回归验证 → 灰度上线 → 继续收集差评。其中最容易被忽视的一环是回归测试:用固定的回归验证集反复测试,确保“修好了 A 问题,没弄坏 B 能力”。就像厨师改菜谱时必须让老顾客再尝一遍招牌菜。

上线方式不要“一把梭”,建议采用灰度或 A/B 对比:把流量分成两组,新版本与旧版本各自收集 thumbs up/down,用差评率的相对变化衡量真实收益,而不是凭感觉宣布胜利。优化收益的计算方式:

餐馆的招牌菜品质,靠的是“收集→归因→改进→再收集”的每日循环;LLM 应用的回答质量,靠的是同一套循环。闭环一旦跑起来,用户的每一声抱怨都会变成产品前进的燃料。

G=Rbefore−RafterRbefore×100%\displaystyle G=\frac{R_{before}-R_{after}}{R_{before}}\times 100\%
优化收益 =(优化前差评率 − 优化后差评率)÷ 优化前差评率,衡量优化动作带来的相对改善幅度。
  1. 取优化前差评率 $R_{before}$记录优化动作上线前一段时间的差评率作为基线,代表“旧菜谱”的水平。
    RbeforeR_{before}
  2. 取优化后差评率 $R_{after}$记录优化上线后同一口径计算得到的差评率,代表“新菜谱”的水平。
    RafterR_{after}
  3. 相减后除以基线差评率下降得越多,G 越大,说明优化动作真实有效,可以放心推广到全量流量。
    Rbefore−RafterRbefore×100%\frac{R_{before} - R_{after}}{R_{before}} \times 100\%

AI 应用场景

智能客服差评溯源

阶段:可观测性与监控

解决的问题:客服机器人每天收到大量差评,传统做法只能统计“今天 100 个踩”,却不知道是哪个知识库片段、哪个提示词模板、哪个模型版本导致的。通过反馈与 trace 关联,一条差评可以回放当时的检索结果,快速区分“知识库缺文档”还是“提示词指令不清”。

具体案例:某金融客服应用上线后差评率 15%,工程师按版本聚合发现 gpt-4o-mini 的差评率是 gpt-4o 的三倍,且集中在“转账限额”类问题;进一步查看 trace,发现小模型经常漏读限额表格。换上大模型并加固提示词后,差评率降到 6%。

RAG 检索幻觉追责

阶段:归因分析

解决的问题:RAG 应用的“幻觉”往往来自检索召回错误片段。只看最终回答文本,无法判断是生成问题还是检索问题,导致修错方向。

具体案例:医疗问答应用收到“回答与指南不符”的踩。通过 trace 还原发现,召回片段来自一篇过期的博客而非权威指南。于是给 RAG 加上“来源白名单”过滤,并为此类问题补充回归用例,同类差评率随后下降了七成。

模型版本发布质量门禁

阶段:发布验证

解决的问题:新模型版本上线前,团队担心引入回归。传统人工抽测成本高、覆盖少,无法回答“新版本是不是真的更好”。

具体案例:团队在灰度期间将流量按版本分流,以固定回归集 + 线上差评率双指标作为门禁:新版本差评率超过旧版本 1.5 倍则自动回滚;低于旧版本则放量到全量。上线两周后,整体差评率下降了 22%。

Python 演示

python83 行
"""用户反馈收集与Trace关联的演示脚本"""import jsonimport randomfrom datetime import datetime class FeedbackCollector:    def __init__(self):        self.feedback_list = []        self.cursor_id = 0     def collect(self, session_id, message_index, trace_id,                model_version, prompt_hash, rating):        """收集一条反馈, 绑定会话上下文与trace"""        self.cursor_id += 1        record = {            "feedback_id": self.cursor_id,            "session_id": session_id,            "message_index": message_index,            "trace_id": trace_id,            "model_version": model_version,            "prompt_hash": prompt_hash,            "rating": rating,            "created_at": datetime.now().isoformat(),        }        self.feedback_list.append(record)        return record     def trace_bind_rate(self):        """计算trace关联完整度"""        if not self.feedback_list:            return 0.0        bound = sum(1 for r in self.feedback_list if r["trace_id"])        return bound / len(self.feedback_list)     def negative_rate(self):        """计算差评率"""        total = len(self.feedback_list)        if total == 0:            return 0.0        down = sum(1 for r in self.feedback_list if r["rating"] == 0)        return down / total     def group_by_version(self):        """按模型版本聚合差评统计"""        grouped = {}        for r in self.feedback_list:            ver = r["model_version"]            entry = grouped.setdefault(ver, {"total": 0, "down": 0})            entry["total"] += 1            if r["rating"] == 0:                entry["down"] += 1        return grouped     def export(self):        """导出为JSON便于下游仓库摄入"""        return json.dumps(self.feedback_list, ensure_ascii=False, indent=2)  def main():    random.seed(42)    collector = FeedbackCollector()    traces = ["trace-1001", "trace-1002", "trace-1003"]    versions = ["gpt-4o-2024-05", "gpt-4o-mini-2024-07"]    for i in range(300):        collector.collect(            session_id="session-%d" % (i % 50),            message_index=i % 6,            trace_id=traces[i % 3] if i % 5 != 4 else "",            model_version=versions[i % 2],            prompt_hash="hash-%d" % (i % 4),            rating=0 if i % 7 < 2 else 1,        )    print("反馈总数:", len(collector.feedback_list))    print("Trace关联完整度: %.1f%%" % (collector.trace_bind_rate() * 100))    print("整体差评率: %.1f%%" % (collector.negative_rate() * 100))    print("按版本聚合:")    for ver, stats in sorted(collector.group_by_version().items()):        rate = stats["down"] / stats["total"] * 100        print("  %s: 差评 %d/%d, 差评率 %.1f%%" % (ver, stats["down"], stats["total"], rate))  if __name__ == "__main__":    main()
目的:模拟生产环境中用户反馈的收集、上下文绑定、Trace 关联与版本聚合,输出关联完整度和差评率指标,演示归因分析的前置数据准备。
  1. self.feedback_list = []相当于餐厅的“意见台账”,存储所有反馈记录。
  2. trace_id=traces[i % 3] if i % 5 != 4 else ""模拟部分请求因前端未上报或采样丢失而缺失 Trace 的现实情况。
  3. bound = sum(1 for r in self.feedback_list if r["trace_id"])统计可还原链路的记录数,用于计算 Trace 关联完整度。
  4. grouped.setdefault(ver, {"total": 0, "down": 0})按模型版本分组并初始化计数器,对应“按厨师查台账”的版本对比分析。
  5. if __name__ == "__main__":保证脚本既可被导入调用,也可直接执行演示。

常见误区

误区用户没有按踩,说明这条回答至少是及格的,不需要关注。我只要盯着踩的数量就好。

正解沉默不等于满意。很多用户懒得点按钮,甚至根本没注意到按钮存在;而“没点踩”也可能意味着回答平庸无聊。要结合弱反馈信号(复制即删、快速重问、长时间停滞)一起判断,才能避免把“不差”误读成“好”。就像餐厅里没人抱怨,不代表菜品真的可口,也可能只是客人懒得写。

为何常见:因为 thumbs down 是显式的负信号,人们容易把“没有显式负信号”等价于“正信号”,忽略了沉默用户的存在。

误区统计每天的点赞数和踩数,画一张趋势图,就算完成反馈分析了。关联那么多字段太麻烦。

正解没有上下文绑定的分数是“死数据”。一条踩若不知道对应哪轮对话、哪个模型版本、哪个提示词,就无法指导任何修改。关联的价值远超计数本身——就像意见本上只写“差”却不写菜名,后厨根本无从下手。

为何常见:因为计数最简单直观,而关联需要埋点、ID 传递、存储设计等系统性工作,工作量大且容易被低估。

误区用户多按几次赞/踩,说明信号更强,数据更可靠,应该把每次点击都记录下来。

正解重复提交会造成统计偏差。一次请求的反馈应该是幂等的:同一会话同一消息只保留一条有效反馈。要用按钮置灰、提交令牌、后端按 (session_id, message_index) 去重等手段保证数据纯净。否则差评率会被连点行为污染,归因结论完全失真。

为何常见:把数据量和数据质量混为一谈,忽略了事件消费端必须具备幂等约束,以为“多一些总比少一些好”。

误区只要做了 trace 关联,任何一条差评都能一键找到 bug 并修复。定位不了就是工具不行。

正解实际生产中 trace 可能缺失(前端没上报、采样丢弃),上下文可能不完整(参数未快照),根因也可能在数据层面而非代码层面(知识库文档过时)。归因分析是概率性的:用“归因定位率”衡量能确定根因的比例,并用多条反馈的统计规律弥补单条缺失。

为何常见:因为演示环境里链路总是完整的,而生产环境充满各种丢失与竞态,新手容易把理想情况当作常态。

面试题

Q1. 产品中收集 thumbs up/down 反馈的根本目的通常是?

单选题 · easy

  • A.统计点赞总数多少
  • B.定位质量问题的根因← 正确答案
  • C.增加用户的互动乐趣
  • D.减少后端服务压力

答案:B。反馈收集不是为了展示数字,而是为了像餐厅老板翻台账一样,把每一次赞/踩与具体对话、模型版本、请求链路关联起来,从而定位质量问题的根因。选项 A 只是表面统计,C、D 与反馈质量优化无关。

Q2. 前端埋点中,防止用户重复提交反馈的常用做法是?

单选题 · easy

  • A.提交后立刻将按钮置灰← 正确答案
  • B.同时弹出多个确认弹窗
  • C.删除用户全部历史记录
  • D.禁止用户再次使用页面

答案:A。按钮置灰是最直接的防重复提交手段,保证同一轮消息只产生一条反馈记录。B 会恶化体验,C、D 更是对用户的粗暴惩罚,均非正解。这就像餐厅不允许同一道菜重复打分一样,保证台账干净。

Q3. 差评率的正确计算方式是哪一项?

单选题 · easy

  • A.差评数除以反馈的总数← 正确答案
  • B.好评数除以反馈的总数
  • C.差评数减去好评的数量
  • D.好评数乘以差评的数量

答案:A。差评率 = 踩的数量 ÷(赞 + 踩)。它衡量明确表态用户中不满意的占比。B 算的是好评率,C、D 的加减乘除没有物理意义,无法反映差评在全部反馈中的严重程度。

Q4. 反馈记录中的 message_index 字段的作用是?

单选题 · mid

  • A.定位会话中的具体某轮← 正确答案
  • B.记录用户密码的加密值
  • C.表示请求失败的错误码
  • D.存储模型输出的字符数

答案:A。message_index 就像满意卡上的“菜名”,标识反馈发生在整个会话的第几轮问答。它是会话上下文绑定四大字段之一,与 session_id 配合才能精确定位到具体消息。其余选项与消息定位无关。

Q5. 调试时发现某条反馈的 trace 缺失,优先排查哪里?

单选题 · mid

  • A.前端上报字段是否携带 trace_id← 正确答案
  • B.模型推理速度是否足够快
  • C.提示词模板是否过于复杂
  • D.数据库索引是否需要重建

答案:A。Trace 缺失常见原因是前端上报时没有携带 trace_id,或埋点 SDK 未正确透传链路标识。就好比服务员忘了在满意卡上记桌号,后厨自然无法还原那道菜。B、C、D 与链路标识丢失无关。

Q6. 反馈数据仓库分层设计中,原始数据层主要存放?

单选题 · mid

  • A.未经清洗的原始反馈记录← 正确答案
  • B.已经聚合好的统计报表
  • C.用户个人的明文密码
  • D.模型训练用的全部样本

答案:A。原始数据层(ODS)只记账不改账,原样保留每条反馈事件,方便日后回溯和重算。B 属于应用层,C 属于安全违规,D 属于训练管线。分层设计的核心就是让“底稿”与“报表”各司其职。

Q7. 一条高质量的用户反馈记录应当包含哪些内容?

多选题 · mid

  • A.会话标识和消息轮次← 正确答案
  • B.模型版本和提示词哈希← 正确答案
  • C.请求链路 trace 信息← 正确答案
  • D.用户银行卡的支付密码

答案:ABC。高质量反馈 = 能定位(会话与消息) + 能复现(模型版本与提示词) + 能还原(trace 链路),三者齐备才能完成归因闭环。D 涉及用户敏感隐私,采集它违反最小化原则,绝不能混入反馈数据。

Q8. 下列哪些属于隐式的弱负面反馈信号?

多选题 · hard

  • A.用户复制回答后立即删除← 正确答案
  • B.用户在短时间内反复重问← 正确答案
  • C.用户长时间停顿不再交互← 正确答案
  • D.用户点击产品的帮助文档

答案:ABC。复制即删说明回答看似可用实则没用,反复重问表示第一次回答没解决需求,长时间停滞意味着用户被卡住或放弃。这些都是“隐式的踩”,应纳入归因分析。D 是中性信息寻求行为,并不针对本次回答。

Q9. 新模型版本上线后差评率上升,为了确认是否回归,应使用?

单选题 · hard

  • A.固定的回归验证问题集← 正确答案
  • B.删除所有旧的测试用例
  • C.仅观察单个用户的反馈
  • D.暂停一切模型推理服务

答案:A。回归验证集是一批固定的、覆盖核心能力的问题,每次版本变更都用它复测,就像厨师改菜谱后请老顾客再尝招牌菜。B 会丢掉防护网,C 样本过少,D 直接停服,均不解决问题。

Q10. 在反馈驱动的持续优化中,测试集与监控指标配合的正确方式是?

多选题 · extreme

  • A.回归验证集需固定并随迭代扩充← 正确答案
  • B.差评率趋势需与版本发布时间对齐← 正确答案
  • C.反馈数据可直接覆盖全部测试场景
  • D.优化效果需通过 A/B 实验来确认← 正确答案

答案:ABD。回归集固定才能纵向对比,随迭代扩充才能覆盖新能力;差评率与发布时间对齐才能识别“哪个版本引入了滑坡”;A/B 实验用真实分流验证收益,避免凭感觉宣布胜利。C 错误:用户反馈只是真实信号,无法替代系统性测试集覆盖。