大模型在接入联网搜索能力后,经常会出现一种尴尬情况:后端明明调用了搜索接口并取回了网页片段,前端模型生成的答案却像完全没看见这些资料。这种忽略不是模型故意为之,而是工程链路中多个环节都可能悄悄把信息削弱甚至丢弃。本文从上下文注入、工具返回协议和提示词约束三个角度,系统梳理排查路径与修复方案。

上下文注入环节的断点排查
第一个要怀疑的是搜索结果到底有没有真正进入模型的上下文窗口。很多开发者把检索服务封装成一个独立微服务,只把命中的URL列表或者极短的摘要拼进用户输入,原始正文则存放在缓存里等待二次拉取,但二次拉取逻辑因为超时或鉴权失败并没有执行。此时模型收到的其实只是一串链接,它自然无法引用没见过的内容。
建议在请求发出前打印完整的payload,确认messages数组里是否包含搜索文本。可以用如下Node.js片段做中间件日志:
const logSearchInjection = (req, res, next) => {
const msgs = req.body.messages || [];
const hasSearchText = msgs.some(m => m.role === 'system' && m.content.includes('[搜索结果]'));
console.log('搜索文本已注入:', hasSearchText);
next();
};
另一个常见断点是长度截断。搜索引擎返回的单篇网页可能上万字,若在网关层设置了最大token为两千,超出的部分直接被切掉,而核心结论往往落在文章后半段。模型看到的是开头导航和广告,当然选择忽略。应当按语义分块,用向量召回最相关块再注入,而不是整页硬塞。
工具返回协议与格式设计的坑
当联网搜索以function calling或tool形式存在时,返回值的 schema 决定了模型如何理解。如果只定义了url和title字段,模型会认为工具仅用于「发现资源」而非「提供答案依据」。必须把snippet或full_text作为必填字段,且在描述里写清「这些内容必须用于回答」。
下面给出一个合理的工具定义示例,注意用中文强调引用义务:
{
"name": "web_search",
"description": "联网搜索最新资料,返回结果中的snippet必须作为回答依据",
"parameters": {
"type": "object",
"properties": {
"query": { "type": "string" },
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"url": { "type": "string" },
"snippet": { "type": "string", "description": "网页核心段落,回答时须引用" }
}
}
}
}
}
}
格式混乱也会让模型放弃解析。有些系统把搜索结果写成HTML片段直接丢进提示词,里面满是<div>和<script>标签,模型 tokenizer 会把噪声当结构处理,重要句子权重被稀释。正确做法是先抽取纯文本,再用清晰的分隔符如「### 搜索结果1」标注,降低模型识别成本。
提示词约束与注意力引导策略
即便上下文里有完整资料,若系统提示词没明确要求「优先依据搜索结果」,模型仍会依赖预训练记忆。因为训练数据让它学会了流畅作答,而引用外部片段需要额外遵从指令。应在system prompt固定写入:若提供了[搜索结果],你的每一句事实陈述都必须对应其中内容,不得凭空生成。
还可以用 few-shot 示范来矫正行为。在提示词里放一个例子,用户问某股价,搜索结果给的是数字,助手回答先写「根据搜索结果」再列数据。模型通过模仿学会不忽略。与此同时,降低 temperature 到0.2以下,减少它自由发挥概率。若仍无效,可用对比实验:同一问题一组带搜索一组不带,观察差异,定位是否是模型版本对工具响应不敏感。
最后别忽视评测闭环。把忽略率做成指标,每天跑一批问题计算搜索片段被引用的比例。一旦跌破阈值就报警,说明上述某一层又引入了新过滤。排查不是一次性工作,而是伴随系统迭代的持续动作。
LLMretrieval_augmented_generationtool_calling修改时间:2026-08-17 01:20:13