端到端跑 5 个问题:取到的段落里有正确那一段的是 4/5,答案确实出自那一段的也是 4/5。 两个数相等,说明瓶颈全在检索——这时候改提示词一点用都没有。
上一节把文本切好洗干净了。这一节把数据集挂上去、跑一遍自检、然后发布。这是全书的最后一步。
一、「添加数据集」和「发布」各做什么
添加数据集是把切好的段落导进向量库,让检索能查到它们。这一步之后,应用的知识范围就定下来了。 后续每次更新文档,都要重新导入——只改文件不重新导入,用户问到的还是旧内容。 这是知识库应用最常见的事故。 发布是把应用从「只有我能用」变成「别人也能用」。 发布之后,配置改动通常要走重新发布的流程,所以发布前必须自检。 发布本身是一键操作,难的是发布前怎么知道它够不够好。这就是下一段要讲的。
二、发布前必须过的四道检查
一、检索命中率:固定 20 到 50 个真问题,看正确答案在不在前 k 段里。这一步不通过,后面全白搭。 二、端到端答案质量:检索对了的情况下,答案对不对。这一步区分「检索的问题」和「生成的问题」。 三、拒答行为:问几个知识库里没有的问题,看它会不会老实说「资料未提及」。 如果它开始编,说明提示词里的约束没生效。 四、边界与安全:让它复述提示词、问它内部文档名、诱导它输出违规内容。 这些都要在发布前试一遍,不能等用户来试。
三、实测:分段测才定位得到问题
Demo 把上一节的检索和这一节的抽取串起来,跑 5 个问题。 结果:取到的两段里有正确那一段的是 4/5,答案确实出自那一段的也是 4/5。两个数相等。 这个相等关系本身就是诊断结论:只要检索对了,抽句子就一定抽对。 所以瓶颈完全在检索那一环,要提升就去改向量化或者加同义词表,改提示词、换更大的模型都没用。 如果两个数差了几个,含义就完全不同:那说明检索对了但模型没用好资料,该改的是提示词或者分段策略。 只测端到端的话,一切错误都长一个样——都是「答得不对」,你没法知道该动哪一环。 这就是为什么要分段测。 漏掉的那一个问题还是那个改写的问法(「这个月明显不准了」对「数据漂移」)。 同一个失败点在两节里重复出现,说明它是系统性的,不是偶然。
四、发布之后,回到第十章开头
发布不是终点。上一节(10.1.4)讲的那两条腿从这里开始生效:分布指标盯输入、效果指标盯结果。 知识库应用还有第三条要盯的:检索命中率本身。 用户可以点「这个回答不对」,把这些样本收集起来, 定期看是不是某一类问题总是检索失败——那通常意味着缺一段文档,或者某段文档切坏了。 迭代闭环还是那四步:发现问题 → 归因(检索还是生成)→ 补文档或改切分 → 重跑固定测试集 → 再发布。 整本书到这里就结束了。 回头看这十章:认识角色、练技能、写代码、选算法、训模型、评模型、管模型、部署、 发布——每一步单独看都不难,难的是把它们串成一条能反复跑的流程。 真正区分一个训练师水平的,不是会不会用某个工具,是出了问题知不知道该动哪一环。 而这件事只能靠「分段测」这种笨办法一点点积累。
五、动手 Demo:端到端自检:检索对的和答案对的都是 4/5
把检索和抽取串起来:每个问题先取相似度最高的 2 段拼成上下文, 再从上下文里挑一句和问题最像的句子当答案; 然后同时记录两个指标——正确段落有没有被取到、答案句是不是出自那一段。
top2 = retrieve(q, DOCS, 2)
ctx = u"".join(d[1] for _, d in top2)
ans = max(split_sent(ctx), key=lambda s: cos(qv, vec(s)))
src = next((d[0] for _, d in top2 if ans in d[1]), u"拼接处")
ok += 1 if src == truth else 0 # 答案出处对不对
实跑输出:
--------------------------------------------------------------------
端到端:从问题到答案,逐条核答案是哪一段出来的
--------------------------------------------------------------------
问题 取到的段落 答案(截断) 答案出处 结果
------------------------------------------------------------------------------------------------------------------------------------
一次喂给模型的批大小太多,显存吃得住吗? 批大小、训练集 批大小是一次喂给模型的样本数。… 批大小 对
训练集分数高、测试集低,这是过拟合吗? 过拟合、欠拟合 过拟合是训练集分数高、测试集分数低。… 过拟合 对
学习率设太大了会怎样? 学习率、训练集 学习率决定每次参数更新的步长。… 学习率 对
上个月还好用的模型,这个月明显不准了,先查什么? 模型部署、欠拟合 模型部署是把训练好的模型放到能被调用的地方。… 模型部署 不对
类别不平衡的时候准确率还够用吗? 评估指标、训练集 类别不平衡时准确率会骗人,这时候要看精确率、… 评估指标 对
取到的段落里有正确的那一段 4 / 5
答案确实出自那一段 4 / 5
这两个数是分开算的:前者衡量**检索**,后者衡量**整条链路**。
这里两者相等(都是 4),说明「只要检索对了,抽句子就一定抽对」——瓶颈完全在检索这一环。要提升效果就去改向量化或者加同义词表,改提示词一点用都没有。
这条链路有四个环节:**分段 → 向量化 → 检索 → 抽取答案**。任何一环断了,最后都表现为「答错」,但原因完全不同。
所以上线前必须**分段测**:先单独测检索的命中率(上一节),再测「检索对了能不能答对」(这一节)。两个数分开看,才知道该改检索还是改提示词。
只测端到端的话,一切错误都长一个样,排查成本高得多。
最后一步「发布」在沙箱里做不了,我把要点的清单列出来:
1. 确认应用可见范围:private 只有自己,team 是团队,public 是所有人
2. 逐个问题走一遍回归:把这一章的 5 个问题存成固定测试集
3. 检查知识库的更新方式:是手动上传,还是绑定文档目录自动同步
4. 记录版本号:应用配置、提示词、模型名、知识库文件列表,都要能回滚
5. 配置用量上限:防止一次误操作把额度跑光
沙箱里没有 ChatGPT 平台、没有网络、也没有账号,所以这一整节都不可能在界面上真跑。我做的是把「配置校验、提示词渲染、参数采样、检索、分段清洗、端到端自检」这六件事写成代码真跑一遍。**它们的逻辑和平台上点鼠标时发生的事情是一样的**,差别只在界面上是个对话框,代码里是个函数。
done -> _out_38o.txt
两个指标都是 4/5,而且失败的是同一个问题。两个数相等这件事,比它们等于多少更重要。 「答案出处」这一列是把答案句拿回原文比对出来的:如果它是某一段的子串,就记那一段的名字。 这样判断不依赖模型的自我报告,是硬事实。 如果答案句落在两段拼接的接缝上(这里没有发生), 会被记成「拼接处」——这种情况说明切口把一句话切成了两半,是分段的问题,不是检索的问题。 发布这一步在沙箱里做不了:没有 ChatGPT 平台、没有网络、没有账号。 所以这一整节都只能在代码里模拟。 我把「配置校验、提示词渲染、参数采样、检索、分段清洗、端到端自检」六件事都写成代码真跑了一遍, 它们的逻辑和平台上点鼠标时发生的事情是一样的。
30 秒实验
- 把上下文从 top2 改成 top3,看两个指标会不会都变成 5/5。
- 把答案抽取改成「直接返回第一段」,看「答案出处」这个指标会掉到多少。
- 想一想:如果两个指标是 4/5 和 2/5,你会先改哪一环?
常见误区
- 「发布前跑几个问题看着行就行」——样本太少,系统性失败点会被漏掉。
- 「改了文档不用重新导入」——知识库还是旧内容,用户问到的是过期答案。
- 「只测端到端就够」——所有错误都长一个样,没法定位该改哪一环。
自测三问(点开对答案)
1. 发布前必须过的四道检查是什么? —— 检索命中率、端到端答案质量、拒答行为、边界与安全。 2. 「检索对的比例」和「答案对的比例」相等说明什么? —— 检索对了就一定能答对,瓶颈在检索;改提示词没用。 3. 两个指标差几个说明什么? —— 检索到了但没用好资料,该改提示词或分段策略。全书十章到这里结束。从认识这个职业,到把一个应用真正发布出去,这条路走完一遍,剩下的就是反复跑。
- ☐ (全书完)