1. 从搜索框到 Agent 的演进逻辑
1.1 为什么传统搜索框模式走到了瓶颈
做过 Chatbot 的人都有一个共同体会:用户问“今天有什么值得关注的科技新闻”,如果机器人只能从训练数据里翻答案,那它给出的内容大概率是几个月前的旧闻。这就是纯生成式模型的硬伤——知识截止日期。早期大家用 RAG 来补,把文档切片塞进向量库,检索回来再让模型组织语言。这套方案在垂直知识库场景下确实能跑,但一旦面对开放域的实时信息,RAG 的短板就暴露得很明显。
RAG 的本质是“先检索、后生成”,检索的质量直接决定生成的上限。而检索依赖的是预先构建好的索引,索引之外的东西一概看不见。用户问“某公司昨天发布了什么新品”,你的向量库里没有这条数据,检索结果就是空的,模型只能硬编或者拒答。更麻烦的是,RAG 对多跳推理的支持很弱。用户问“A 公司的 CEO 上个月在 B 会议上说了什么关于 C 技术的观点”,这需要先找到 CEO 是谁、再找到会议记录、再定位到具体发言,传统 RAG 很难把这条链路串起来。
所以行业里开始出现一个共识:光靠静态知识库不够,Chatbot 需要“联网搜索”的能力。这就是 web_search 被引入的直接原因。但联网搜索本身也不是终点,它只是 Agent 能力的一个子集。从搜索框到 Agent,中间经历了几个关键阶段,每个阶段解决的问题不同,技术选型也不同。
1.2 三个阶段的技术分水岭
第一个阶段是“搜索增强生成”,也就是 Search-Augmented Generation。做法很直接:用户提问后,先调用搜索引擎 API 拿到网页摘要,把摘要拼进 prompt 里让模型回答。这个阶段的核心问题是“怎么把搜索结果塞进上下文”,工程上主要处理截断、排序、去重。优点是实现快,缺点是模型对搜索结果几乎没有控制权,搜到什么就用什么。
第二个阶段是“工具调用式搜索”,模型开始具备决定“要不要搜、搜什么、搜几次”的能力。这时候 Function Calling 机制成熟了,模型可以输出一个结构化的搜索请求,系统执行后再把结果喂回去。这个阶段的关键变化是:搜索从“固定流程”变成了“模型自主决策”。但问题也随之而来——模型经常该搜的时候不搜,不该搜的时候乱搜,搜索词的质量也参差不齐。
第三个阶段就是现在大家说的 Agent 化搜索。Agent 不只是调用一次搜索,而是把搜索当成一个可编排的工具,配合规划、记忆、反思等能力,形成“搜索-阅读-推理-再搜索”的循环。比如用户问一个复杂问题,Agent 会先拆解成子问题,逐个搜索,发现信息冲突时主动追加搜索验证,最后综合多源信息给出带引用的答案。这个阶段的核心技术点包括:任务规划、工具编排、上下文管理、结果验证。
注意:很多团队一上来就想做第三阶段,结果连第一阶段的检索质量都没打磨好。我的建议是先把搜索结果的清洗和排序做扎实,再往上叠 Agent 能力,否则就是在沙地上盖楼。
1.3 一张表看清三个阶段的差异
| 维度 | 搜索增强生成 | 工具调用式搜索 | Agent 化搜索 |
|---|---|---|---|
| 决策主体 | 固定流程 | 模型单次决策 | 模型多轮规划 |
| 搜索次数 | 通常 1 次 | 1-3 次 | 动态多轮 |
| 上下文管理 | 简单拼接 | 结果回填 | 记忆+压缩+引用 |
| 典型问题 | 信息过时 | 搜索时机不准 | 编排复杂度高 |
| 适用场景 | 简单问答 | 中等复杂度查询 | 研究型任务 |
这张表不是要说明哪个阶段更高级,而是帮助你在做技术选型时快速定位:你的业务到底需要哪一档能力。很多客服场景其实第一阶段就够了,硬上 Agent 反而增加延迟和成本。
2. 联网搜索的核心技术拆解
2.1 搜索 API 的选型与免费方案
做联网搜索,第一步是解决“搜什么”的问题。市面上可选的搜索接口大致分几类:通用网页搜索、垂直领域搜索、学术搜索、新闻搜索。选型时重点看三个指标:结果质量、调用延迟、配额限制。
免费方案里,常见的有基于开源搜索引擎自建、调用公开的搜索接口、以及一些平台提供的免费额度。自建的话,可以用开源的爬虫框架配合索引引擎,但维护成本不低,尤其是反爬策略变化频繁。调用公开接口相对省事,但要注意稳定性和结果格式的统一。我的经验是,如果只是做原型验证,先用免费额度跑通流程;如果要上生产,一定要准备至少两个搜索源做兜底,避免单点故障。
搜索结果的返回格式通常包括标题、摘要、URL、发布时间。这里有个容易被忽略的点:发布时间。很多搜索接口不返回这个字段,或者返回得不准确。但对于时效性要求高的场景,没有时间戳就没法做结果过滤。我的做法是在结果清洗阶段,用启发式规则从摘要或 URL 里提取时间信息,提取不到的就标记为“未知时间”,在排序时降权。
2.2 搜索结果如何喂给模型:截断、排序与去重
搜索结果拿到手之后,不能直接一股脑塞进 prompt。原因很简单:上下文窗口有限,而且无关信息会干扰模型判断。这里要做三件事。
第一是去重。不同搜索源返回的结果经常高度重叠,尤其是热门话题。去重不能只看 URL,因为同一篇文章可能被多个站点转载。我的做法是计算标题和摘要的相似度,超过阈值的只保留一条。相似度可以用简单的 Jaccard 或者编辑距离,不需要上 embedding,省时省力。
第二是排序。搜索接口返回的顺序未必适合模型阅读。我会综合几个信号重新排序:来源权威性、时间新鲜度、摘要与问题的语义相关度。语义相关度可以用一个轻量级的交叉编码器算,也可以用关键词覆盖率做近似。实测下来,加一层重排序能让最终答案的准确率提升不少。
第三是截断。每条结果不能全文塞入,通常只保留标题加前 200-300 字摘要。如果摘要本身就不完整,可以考虑抓取网页正文再做摘要。但抓取正文有延迟和失败风险,需要设置超时和降级策略。
def prepare_search_context(results, max_tokens=2000): # 去重 seen = set() unique = [] for r in results: key = r['title'][:50] if key not in seen: seen.add(key) unique.append(r) # 排序:时间新鲜度 + 来源权重 unique.sort(key=lambda x: (x.get('freshness', 0), x.get('authority', 0)), reverse=True) # 截断拼接 context = "" for r in unique: snippet = f"标题:{r['title']}\n摘要:{r['snippet'][:300]}\n来源:{r['url']}\n\n" if len(context) + len(snippet) > max_tokens * 4: break context += snippet return context这段代码是个简化版,实际用的时候还要考虑 token 计算方式、多语言处理等细节。但核心思路就是:先去重、再排序、后截断,三步不能省。
2.3 让模型学会“什么时候该搜”
这是工具调用式搜索最核心的问题。模型如果太保守,该搜的时候不搜,答案就会过时;如果太激进,每句话都搜,延迟和成本都受不了。解决办法是在系统提示里明确搜索的触发条件。
我常用的触发规则有这么几条:涉及具体时间点的事件、涉及实时数据(股价、天气、比分)、涉及训练数据截止日期之后的信息、涉及需要验证的事实性陈述。反过来,常识性问题、纯推理问题、创意写作类请求,就不需要搜。
但光靠提示词还不够稳。更可靠的做法是加一个轻量级的分类器,判断当前 query 是否需要联网。这个分类器可以用小模型微调,也可以用规则加关键词匹配做冷启动。我的经验是,规则覆盖 80% 的常见情况,剩下的交给模型自己判断,同时在提示里给出 few-shot 示例,效果比纯规则好很多。
还有一个细节:搜索词的质量。用户的原话往往不适合直接拿去搜,需要改写成更精准的查询。比如用户问“那个新出的手机怎么样”,直接搜这句话效果很差,应该先让模型改写成“某品牌最新型号 评测”,再去搜。这个改写步骤可以放在工具调用之前,作为 Agent 规划的一部分。
3. 从 RAG 到 Agent 搜索的实操路径
3.1 RAG 知识库与联网搜索的边界划分
很多团队纠结一个问题:我已经有 RAG 知识库了,还需要联网搜索吗?答案是看场景。RAG 知识库适合存私有数据、领域知识、历史文档,这些内容搜索引擎搜不到,或者搜到的版本不对。联网搜索适合获取公开的、实时的、开放域的信息。两者不是替代关系,而是互补关系。
我的做法是做一个路由层:先判断用户问题属于哪一类。如果问题涉及内部文档、产品手册、历史记录,走 RAG 检索;如果涉及实时新闻、公开数据、外部事件,走联网搜索;如果两者都涉及,就并行执行再合并结果。路由的判断可以基于关键词,也可以用一个小的意图分类模型。
这里有个坑要注意:RAG 知识库和联网搜索的结果格式不一样,合并时要做归一化。RAG 返回的是文档片段,联网搜索返回的是网页摘要,两者的粒度、可信度、时效性都不同。合并时我会给 RAG 结果更高的权重,因为私有数据的准确性通常更高;联网结果作为补充,标注来源和时间,让用户自己判断。
3.2 Agent 搜索的编排流程设计
一个完整的 Agent 搜索流程通常包含这几个环节:意图理解、任务规划、搜索执行、结果阅读、信息综合、答案生成。每个环节都可以独立优化。
意图理解阶段,要判断用户到底想要什么。是想要一个事实答案,还是想要一份综述,还是想要对比分析?不同的意图对应不同的搜索策略。事实型问题可能一次搜索就够,综述型问题需要多轮搜索加信息聚合。
任务规划阶段,把复杂问题拆成子问题。比如“对比 A 和 B 两个方案的优缺点”,可以拆成“A 方案的优缺点”“B 方案的优缺点”“两者的差异点”三个子任务。每个子任务独立搜索,最后汇总。拆解的好处是每个子问题更聚焦,搜索结果质量更高。
搜索执行阶段,要注意并发控制。多个子任务可以并行搜索,但要注意 API 的速率限制。我的做法是用一个任务队列,控制并发数,失败的任务自动重试,重试超过次数就降级为“未找到相关信息”。
结果阅读阶段,模型需要从搜索结果里提取关键信息。这一步可以用模型直接读,也可以用抽取式方法先筛一遍。对于长网页,我倾向于先做段落级的相关度打分,只把最相关的段落喂给模型,减少干扰。
信息综合阶段,要把多个来源的信息整合成连贯的答案。这里最大的挑战是处理冲突信息。不同来源说法不一致时,Agent 应该标注出来,而不是随便选一个。我的做法是让模型输出时附带置信度,低置信度的部分明确说明“存在不同说法”。
3.3 上下文管理与记忆机制
Agent 多轮搜索会产生大量中间结果,上下文很快就会爆。所以必须有压缩和记忆机制。我的做法是分三层:短期记忆存当前轮次的搜索结果,中期记忆存已经提取的关键事实,长期记忆存用户偏好和历史交互。
短期记忆用滑动窗口管理,只保留最近几轮的结果。中期记忆用结构化的形式存储,比如“事实:某公司于某日发布某产品;来源:某链接;置信度:高”。长期记忆可以存到外部存储,需要时再检索回来。
压缩的策略有两种:一种是摘要式压缩,让模型把长文本缩成短摘要;另一种是抽取式压缩,只保留关键句子。摘要式压缩信息损失小但成本高,抽取式压缩成本低但可能漏掉重要信息。我通常混合使用:先抽取关键句,再对关键句做摘要。
提示:上下文压缩是有损的,压缩比例越高,信息损失越大。建议在压缩后保留原始结果的引用链接,方便需要时回溯。
4. 常见问题与排查技巧实录
4.1 搜索结果质量差的排查思路
搜索结果质量差是最常见的问题,表现是模型给出的答案和搜索结果对不上,或者答案明显过时。排查时按这个顺序来:先看搜索词是否准确,再看搜索接口是否正常返回,再看结果清洗是否过度,最后看模型是否忽略了搜索结果。
搜索词的问题最常见。用户的原话直接拿去搜,往往搜不到想要的东西。解决办法是加一层查询改写,让模型把口语化的问题转成关键词组合。改写时要注意保留时间、地点、实体等关键约束,不要改得面目全非。
搜索接口的问题通常是配额用完或者接口变更。建议加监控,记录每次调用的返回状态和耗时,异常时及时告警。另外,不同接口的结果格式可能不一样,解析逻辑要写得健壮一些,遇到字段缺失要有默认值。
结果清洗过度也会导致问题。比如去重阈值设得太低,把相关但略有差异的结果误删了;或者截断太狠,把关键信息截掉了。这些参数需要根据实际数据调,没有万能值。
模型忽略搜索结果,通常是因为提示词没写清楚。要在系统提示里明确要求“优先使用搜索结果中的信息”“如果搜索结果与你的知识冲突,以搜索结果为准”。同时,搜索结果在 prompt 里的位置也很重要,放在靠前的位置模型更容易注意到。
4.2 延迟与成本的平衡技巧
联网搜索会显著增加响应时间,因为要等搜索接口返回、要抓取网页、要多轮推理。优化延迟的手段有几个:并行搜索、缓存结果、预取、降级。
并行搜索是最直接的,多个子问题同时搜,总耗时取决于最慢的那个。缓存结果适合高频重复的查询,比如热门新闻,缓存几分钟就能省掉大量重复调用。预取是在用户还没问之前就提前搜好可能相关的内容,适合有明确上下文的多轮对话。降级是在搜索超时或失败时,退回到不搜索的模式,至少给用户一个回复。
成本方面,搜索 API 通常按调用次数计费,所以要控制搜索次数。我的做法是设置一个上限,比如单次对话最多搜 5 次,超过就停止搜索,用已有信息回答。另外,结果清洗阶段尽量用轻量级方法,不要每个结果都调大模型,那样成本会失控。
4.3 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决建议 |
|---|---|---|---|
| 答案过时 | 未触发搜索 | 检查触发规则 | 补充时效性关键词 |
| 答案与搜索无关 | 搜索词质量差 | 打印实际搜索词 | 加查询改写层 |
| 响应超时 | 搜索接口慢 | 记录接口耗时 | 设超时+降级 |
| 信息冲突 | 多源结果不一致 | 检查来源权重 | 标注冲突+置信度 |
| 上下文溢出 | 结果未压缩 | 统计 token 数 | 加压缩+滑动窗口 |
| 重复搜索 | 规划不合理 | 检查任务拆解 | 合并相似子任务 |
这张表是我在实际项目中踩坑后整理的,基本覆盖了八成以上的常见问题。遇到新问题时,先对照这张表排查,能省不少时间。
4.4 几个容易被忽略的细节
第一个细节是搜索结果的时效标注。很多搜索接口不返回发布时间,但用户对时效很敏感。我的做法是在结果展示时,如果时间未知就标注“时间未知”,不要假装是新的。这样用户自己会判断可信度。
第二个细节是引用格式。Agent 给出的答案最好附带来源链接,方便用户核实。引用格式要统一,不要一会儿是 URL 一会儿是标题。我通常用“来源: 标题 ”的格式,简洁清晰。
第三个细节是失败处理。搜索失败是常态,不能假设每次都成功。失败时要给用户明确的反馈,比如“暂时无法获取最新信息,以下回答基于已有知识”,而不是假装搜到了。
第四个细节是多语言处理。如果用户用中文问,但搜索结果主要是英文,需要做翻译或者跨语言检索。跨语言检索可以用多语言 embedding,也可以先翻译查询再搜。翻译查询的成本更低,但可能损失一些语义细节。
5. Agent 搜索的进阶方向
5.1 多 Agent 协作搜索
单 Agent 搜索能力有限,复杂任务可以拆给多个 Agent 协作。比如一个 Agent 负责规划,一个负责搜索,一个负责阅读,一个负责综合。每个 Agent 专注自己的环节,通过消息传递协作。这种架构的好处是每个环节可以独立优化,坏处是通信开销大,调试复杂。
我的经验是,不要一上来就搞多 Agent。先把单 Agent 的搜索流程跑通,找到瓶颈在哪,再决定要不要拆。很多时候瓶颈在搜索质量,拆成多 Agent 也解决不了。只有当任务确实需要并行处理、或者不同环节需要不同模型时,多 Agent 才有明显收益。
5.2 搜索结果的验证与反思
Agent 搜到信息后,应该有一个验证环节。验证的方式包括:交叉验证(多个来源是否一致)、逻辑验证(信息是否自洽)、时效验证(信息是否过时)。发现可疑信息时,Agent 应该主动追加搜索,而不是直接采用。
反思机制是让 Agent 回顾自己的搜索过程,判断是否有遗漏或偏差。比如问“还有哪些角度没搜到”“搜索结果是否偏向某一方”。这个机制能显著提升答案的全面性,但会增加延迟和成本,适合对质量要求高的场景。
5.3 与知识库的深度融合
联网搜索和 RAG 知识库的融合是未来的方向。理想状态下,Agent 能自动判断信息应该从知识库取还是从网上搜,取回来后统一做冲突检测和置信度评估。这需要统一的知识表示格式和检索接口,目前还没有特别成熟的方案,但已经有一些框架在尝试。
我的建议是,先把两条链路分别跑通,再考虑融合。融合的难点不在技术,而在数据治理——知识库的更新频率、搜索结果的可靠性、两者的优先级规则,这些都需要业务侧明确。
5.4 安全与合规的边界
Agent 联网搜索会接触到大量外部内容,其中可能包含不准确、不适宜的信息。所以必须有内容过滤机制,在结果进入模型之前做一轮筛查。筛查的维度包括:来源可信度、内容合规性、是否包含敏感信息。这一步不能省,否则一旦出问题,影响很大。
另外,Agent 的搜索行为要有日志记录,方便追溯。记录内容包括:搜索词、返回结果、模型决策、最终输出。这些日志既能用于排查问题,也能用于优化搜索策略。
6. 我个人的实操体会
做联网搜索这个方向有一段时间了,最大的体会是:搜索质量决定上限,编排逻辑决定下限。很多人把精力花在 Agent 框架的选型上,纠结用哪个编排工具,但真正影响效果的是搜索词的质量和结果的清洗。我见过太多项目,框架用得很花哨,但搜索词就是用户原话,结果自然好不了。
另一个体会是,不要追求一步到位。从最简单的搜索增强开始,跑通流程,收集 bad case,逐步优化。每次只改一个变量,观察效果变化。这样虽然慢,但每一步都扎实。我见过一些团队一上来就搞多 Agent 加反思加验证,结果调试成本极高,最后不了了之。
还有一点,延迟和质量的平衡要尽早考虑。用户对延迟的容忍度是有限的,超过几秒就会流失。所以搜索策略要设计降级路径,宁可给一个稍差但快的答案,也不要让用户等太久。我的做法是设一个总超时,超时就用已有信息回答,同时标注“信息可能不完整”。
最后分享一个小技巧:把搜索结果当成“参考材料”而不是“标准答案”。模型的任务是综合这些材料给出回答,而不是照抄。所以在提示词里要强调“综合多源信息”“如果信息冲突要说明”,这样能减少模型被单一来源误导的概率。
这个方向还在快速演进,新的工具和框架层出不穷。但底层逻辑是不变的:理解用户意图、获取相关信息、综合给出答案。把这三步做好,用什么工具都是次要的。