这类问题我又碰上了一次。用 text-embedding-3-small 批量取向量,一批一百条并发发四个请求,返回后按响应到达顺序拼回文档 id,结果部分文档的向量和原文对不上,检索出来的答案开始引用错误段落。

第一反应是「失败重试的批次被追加到了结果尾部」,验证下来不成立。

排查方向其实有限,先把可能性排一排。并发请求的返回顺序和提交顺序不一致;响应里没有回传自定义 id,只能靠下标映射;分片时按字节截断,同一文档被拆成两段。

第一件事是看响应里每条数据带的序号

python -c "import json;d=json.load(open('resp.json'));print([(x['index'],len(x['embedding'])) for x in d['data']])"

再往下按序号排序后再写库

python -c "import json;d=json.load(open('resp.json'));e=sorted(d['data'],key=lambda x:x['index']);print(e[0]['index'],e[-1]['index'])"

校验向量与文本的对应关系

python check_pairs.py --emb emb.npy --texts texts.jsonl --model text-embedding-3-small

末了重跑检索并用已知问答对验证

python eval_retrieval.py --cases golden.jsonl --top-k 5

恢复的判定其实很直接。向量与文本一一对应,十条已知问答对全部命中原文段落,检索结果里不再出现错位引用。

批量接口的返回顺序不保证和输入一致,响应里的序号才是唯一可靠的对应关系。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189