Jev Search 给出的回答和问题对不上时,先不要在提示词上来回改。通常只有两种可能:检索层返回的片段本身就跟问题无关,或者片段是相关的,但模型在拼接和总结时掺入了来源里没有的内容。把召回片段单独打印出来、再和模型回答并排比对,能把问题落到具体某一层,后面的修改才有方向。
Jev Search 答非所问时,先把召回片段单独打印出来核对主题和时间,再与模型回答并排比对,看回答里是否出现了来源中没有的说法。召回片段本身不相关,属于检索侧问题,先收窄查询范围或过滤低相关来源;片段相关而回答跑偏,多半出在拼接和总结环节,应先固定检索结果再调整提示词。单次现象不足以定论,换一组来源更明确的输入重复观察。
把同一条查询的召回片段单独打印出来
先确认检索层实际交给了模型什么内容,包括片段顺序、分数和截断长度。如果日志里只留了最终答案,先用下面的骨架把中间结果打出来;字段名以实际返回结构为准,不要照抄。
resp = search_call(query) # 换成项目里真实的检索调用
print(resp.keys()) # 先看返回结构,确认键名
items = resp.get("results") or resp.get("hits") or resp.get("data") or []
for i, it in enumerate(items):
print("index:", i)
print("score:", it.get("score"))
print("title:", it.get("title") or it.get("name"))
print("url:", it.get("url") or it.get("link"))
body = it.get("content") or it.get("text") or it.get("snippet") or ""
print("len:", len(body))
print("body:", body[:500])
print("-" * 60)
要点有三个:保留原始排序和分数,它们是判断检索质量的直接依据;把切片长度也打出来,很多时候相关句子被截在了片段之外;把这段输出和真正送进模型的 prompt 一起落盘,方便对齐。如果检索调用做了二次改写(同义词扩展、查询重写),把改写后的查询串一并打印。
逐条判断召回片段和问题是否相关
拿到片段后逐条判断,不要只看第一条。判定标准建议只用两条,减少主观:主题是否命中,即问题里的实体、动作、版本或型号是否在片段中出现;时间是否对得上,即片段的发布时间或更新时间是否落在问题隐含的时间范围内。标题命中但正文没有对应信息,记作“命中但信息不足”,不要算相关。
| 序号 | 标题 / URL | 主题命中 | 时间对得上 | 判定 | 备注 |
|---|---|---|---|---|---|
| 0 | 是 / 否 | 是 / 否 / 未知 | 相关 | 命中哪一句 | |
| 1 | 是 / 否 | 是 / 否 / 未知 | 弱相关 | 缺哪个关键信息 | |
| 2 | 是 / 否 | 是 / 否 / 未知 | 不相关 | 为什么无关 |
整表看完,通常会出现两种局面。召回为空,或者召回到的全是同类无关页面,说明问题在检索侧——没搜到。召回里有明显相关片段,但模型回答仍然对不上,说明问题在模型侧——搜到了但没说对。这两种局面后续处理完全不同,先分清楚再动手改配置。
把召回片段和模型回答并排比对
把问题和片段放一边,模型回答放另一边,逐句过一遍,按三类记录:
- 来源有且回答有:正常情况。需要重点确认表述是否忠实,有没有把“可能”写成“是”。
- 来源无但回答有:模型用自带知识补全,或者直接编造。若落在关键结论、数字、日期上,优先按模型层问题处理。
- 来源有但回答漏掉:常见于片段排序靠后、上下文被截断,或多来源拼接时被挤掉。要记清楚被漏掉的信息在第几条片段。
问题:...
片段1(url):要点A、要点B
片段2(url):要点C
回答句1:... -> 来源有且回答有(片段1)
回答句2:... -> 来源无但回答有(无对应片段)
回答句3:... -> 与片段2冲突
遗漏:要点C -> 来源有但回答漏掉(片段2)
这一轮的目的不是打分,而是看“来源无但回答有”和“遗漏”分别有多少、出现在不重要的细节还是关键结论上。前者偏多,先收紧提示词里的引用约束;后者偏多,先看检索结果的排序和长度限制。
只在检索侧收窄范围再跑一次
为了验证是不是召回噪声把模型带偏,保持模型、提示词和采样参数不动,只改检索侧一项,再跑同一条查询:
- 查询串:补上问题里的实体名或时间限定,去掉口语化的修饰词。
- top_k:从较大值收小到能覆盖答案的量。
- 过滤条件:限定域名、语言或时间范围,排除明显无关的来源类型。
- 二次改写:临时关掉同义词扩展或查询重写,看召回是否更贴题。
把改动项、改动前后的召回列表和最终回答并排记下来。如果收窄之后回答明显贴合问题,说明原来的噪声在干扰总结,优先在检索侧做过滤和排序;如果召回已经变干净、回答依然跑偏,问题更可能在拼接和总结环节。
同一条查询建议重复跑两到三次。如果模型侧存在采样随机性,先把温度调低再比较,否则回答差异可能来自采样,而不是检索改动。差异能稳定复现,才值得据此调整配置。
换一组来源更明确的输入再观察
单条查询的现象不足以定性。换两到三组输入:问题边界清楚、正确来源集中(例如某份公开文档、某份内部规范),答案可以人工核对。每组都按同一流程走一遍,记录原始查询、召回片段列表、模型回答,再做一次并排比对。
把复现步骤和判断结果记下来,通常落在三种情况里:多组输入都在召回侧失手,说明查询改写、过滤或切片有问题,优先修检索层;多组输入的召回都干净,但回答反复出现来源里没有的说法,优先修模型层,比如要求逐句对应来源、无依据时明确说明;只有个别输入对不上,先补日志再观察,不要为一次现象改索引或提示词。
需要提醒的是,召回片段的相关性和模型回答的忠实度是两个独立指标,任何一层改动后都要重新走一遍上面的比对流程。先固定检索结果再调提示词,或者先固定提示词再调检索,一次只动一层,判断才站得住。