"同样的输入,为什么这次结果不一样"
这是 AI 系统最常见的追问 ✔。原因通常有三类:模型/版本变了、提示词变了、数据(检索结果)变了 ✗。
如果这三件事没有一起记录下来,就永远答不清楚 ✗。
一、可复现调用要记录什么
每次调用至少记录四组:
- 模型标识(名称 + 版本 + 关键参数:温度、上限);
- 提示词版本(含模板版本号与变量值摘要 ✔);
- 数据版本(检索结果集:用了哪些片段、它们的哈希、来源文档版本);
- 组装清单(哪些组件参与、各多少 token —— 见可组装上下文那篇 ✔)。
关键:不要只记"最终拼好的字符串" ✗ —— 那样无法归一化、无法定位是哪一段变了 ✗。
二、把"版本"绑成一个整体
做法:给每次调用生成一个调用指纹(fingerprint):
fingerprint = hash(模型 + 参数 + 提示词版本 + 数据片段哈希 + 组装策略版本)
好处:
- 同一指纹 → 结果应该一致(除模型本身的不确定性 ✔);
- 指纹变化 → 能立刻知道是哪一类变了 ✔;
- 评测时按指纹分组,避免把"换了版本"的差异算成"提示词的效果" ✗。
三、缓存与可复现的关系
- 缓存键必须包含指纹 ✔(否则换了版本还在吃旧结果 ✗ —— 见缓存那篇 ✔);
- 反过来,指纹也让你能主动失效:提示词升版本时批量清掉旧键 ✔。
四、评测里的用法
- 对照实验:冻结指纹里除被测项以外的全部 ✔;
- 回归:同一批样本用同一指纹重跑,结果应稳定 ✔;不稳定说明还有未记录的自由度 ✗;
- 事故复盘:用指纹串起"当时到底给了模型什么" ✔(这是复盘里最先要回答的问题 ✔)。
五、落地顺序
- 先加提示词版本号与模型参数记录(半天 ✔);
- 再把检索片段的哈希记下来 ✔;
- 然后算指纹并进缓存键 ✔;
- 最后把组装清单也纳入(用于定位"哪一段变了")✔。
一条判据
只给你一条日志,你能否在 5 分钟内回答"当时模型看到了什么" ✔?
答不上,说明可复现性还没做到位 ✗。