
1. 从搜索框到 Agent 的演进逻辑1.1 为什么传统搜索框模式走到了瓶颈做过 Chatbot 的人都有一个共同体会用户问“今天有什么值得关注的科技新闻”如果机器人只能从训练数据里翻答案那它给出的内容大概率停留在知识截止日期之前甚至直接编造一条看起来很像真的假消息。这不是模型不够聪明而是它的信息边界被锁死了。传统搜索框模式的核心逻辑是“用户主动检索、系统返回链接列表、用户自行筛选”。这套模式在 PC 互联网时代运转了二十多年因为它假设用户有耐心、有能力去判断哪些链接可信。但到了对话式交互场景里这个假设不成立了。用户对着 Chatbot 说一句话期望的是直接拿到整合好的答案而不是十个蓝色链接。于是就有了第一代“联网搜索”方案在对话流程里硬插一个搜索 API 调用把返回的摘要塞进 Prompt 里让模型润色。这种做法我早期也用过能用但问题很多。最典型的是搜索结果和用户意图对不上——用户问的是“对比”搜索 API 返回的是单点事实用户问的是“最新”返回的却是几个月前的缓存页面。根本原因在于搜索 API 本身不理解对话上下文它只是一个无状态的关键词匹配器。1.2 Agent 模式带来的根本性变化Agent 和传统 Chatbot 联网搜索最大的区别在于“决策权”的归属。传统模式下是否搜索、搜什么、搜几次都是代码里写死的 if-else 逻辑。Agent 模式下这些决策由模型自己根据当前对话状态来判断。我举个实际例子来说明这个差异。用户先问“英伟达最近一个季度的营收是多少”接着追问“那它的数据中心业务占比呢”。传统联网搜索方案在第二轮很可能重新发起一次完整的搜索把“英伟达 数据中心 占比”当成独立查询丢失了“最近一个季度”这个时间约束。而 Agent 会把第一轮的搜索结果保留在上下文里第二轮只需要针对“数据中心业务占比”做一次补充检索甚至直接从已有结果里提取。这个差异看起来很小但在实际产品里体验差距巨大。Agent 模式下的联网搜索本质上是一个“带记忆的、可多轮迭代的检索决策循环”。它包含几个关键能力判断是否需要搜索、生成合适的查询词、评估搜索结果质量、决定是否继续搜索、把结果整合进最终回答。这五个能力缺一个体验就会明显退化。1.3 从 RAG 到 Agentic Search 的定位差异很多人把 RAG 和 Agent 联网搜索混为一谈其实两者的定位完全不同。RAG 解决的是“私有知识库的检索增强”它的检索范围是固定的、预先索引好的文档集合。而 Agent 联网搜索面对的是开放互联网没有预先索引没有固定的文档边界每次查询的返回结果都可能不一样。这个差异决定了技术选型的不同。RAG 可以用向量数据库做语义检索因为文档集合是已知的、可控的。但联网搜索不行你没法把整个互联网预先向量化。所以联网搜索更多依赖关键词检索加结果重排再配合模型做摘要和事实提取。不过两者也有融合的趋势。我见过不少项目采用“混合检索”策略先用联网搜索拿到实时信息再把关键段落写入临时知识库后续对话直接从这个临时知识库里做 RAG 检索。这样既保证了时效性又避免了重复搜索带来的延迟和成本。2. 联网搜索的核心技术拆解2.1 查询改写决定搜索质量的第一道关卡用户的原话往往不适合直接拿去搜索。比如用户说“那个最近很火的 AI 编程工具怎么样”直接拿这句话去搜返回结果大概率是泛泛的新闻稿。有经验的开发者会在这里加一层查询改写把口语化的表达转成搜索引擎友好的关键词组合。查询改写的核心思路是“意图提取加实体补全”。以上面那句话为例改写后的查询可能是“AI 编程工具 2024 评测 对比”。这里做了三件事把“最近很火”转成时间限定词把“那个”这种指代词消解掉补充“评测 对比”这类能触发高质量结果的修饰词。实际实现时查询改写通常由一个小模型或者规则引擎来完成。用大模型做改写当然效果更好但延迟和成本要考虑。我的经验是对于高频查询模式用规则模板覆盖百分之七八十的场景剩下的长尾交给小模型处理这样能在效果和成本之间取得比较好的平衡。注意查询改写不要过度。我见过一些实现把用户问题改得面目全非加了一堆同义词和扩展词结果搜索返回的内容偏离了原始意图。改写的原则是“补全必要信息不引入新意图”。2.2 搜索结果重排与可信度评估搜索 API 返回的结果列表质量参差不齐。排在第一位的可能是广告第二位的可能是内容农场第三位才是真正有用的技术文档。如果直接把前几条塞给模型输出质量完全靠运气。重排环节要解决两个问题相关性和可信度。相关性判断相对容易用交叉编码器或者简单的关键词覆盖率就能做。可信度评估更麻烦需要综合考虑域名权威度、内容时效性、信息密度等因素。我通常会用一套打分公式来做重排大致是这样的def rerank_score(result): relevance cross_encoder_score(query, result.snippet) authority domain_authority.get(result.domain, 0.5) freshness compute_freshness(result.publish_date) density information_density(result.snippet) score ( 0.4 * relevance 0.25 * authority 0.2 * freshness 0.15 * density ) return score这套权重不是拍脑袋定的是经过多轮 A/B 测试调出来的。相关性权重最高因为如果内容和问题不相关其他维度再好也没用。权威度和时效性各占四分之一左右信息密度作为辅助。当然不同场景下权重需要调整比如做学术问答时权威度权重要提高做新闻摘要时时效性权重要提高。2.3 多轮检索的终止条件设计Agent 联网搜索和传统搜索的另一个关键差异是“搜几轮”。传统方案通常只搜一次Agent 方案可以搜多轮但多轮会带来延迟累积和成本上升。所以必须设计合理的终止条件。我常用的终止条件有三个信息充分性判断、边际收益递减判断、硬性轮次上限。信息充分性判断是让模型评估“当前收集到的信息是否足以回答用户问题”如果够了就停止。边际收益递减判断是看新一轮搜索是否带来了新的关键信息如果连续两轮都是重复内容就停止。硬性轮次上限是兜底一般设三到五轮防止无限循环。这三个条件里信息充分性判断最难做准。模型有时候会过于自信觉得信息够了实际上还差关键数据。我的做法是让模型在判断时输出一个置信度分数低于阈值就继续搜。同时把已收集的信息摘要和用户问题一起给模型让它做对比判断而不是凭空判断。2.4 结果整合与引用标注搜到的信息最终要整合成一段连贯的回答。这里有两个坑一是信息冲突不同来源的数据对不上二是引用缺失用户不知道哪些信息来自搜索哪些来自模型自身知识。信息冲突的处理策略取决于冲突程度。如果是细微差异比如两个来源的数值差在误差范围内可以取平均值或者标注范围。如果是根本性冲突比如一个说增长一个说下降那就需要把冲突呈现给用户而不是强行选一个。我倾向于在回答里明确写“关于这一点不同来源存在分歧”然后列出各自的数据和来源。引用标注是提升可信度的关键。我的做法是在生成回答时要求模型对每个来自搜索的事实性陈述标注来源编号然后在回答末尾附上来源列表。这样用户既能快速验证也能判断信息的可靠程度。3. 实操搭建一个可运行的 Agent 联网搜索流程3.1 整体架构与工具选型先说一下我实际用的架构。整个流程分四层接入层负责接收用户消息和管理对话状态决策层负责判断是否需要搜索和生成查询执行层负责调用搜索 API 和重排结果生成层负责整合信息并输出回答。工具选型方面搜索 API 我试过不少。免费方案里有些开放平台的 web search 接口可以用但稳定性和结果质量参差不齐。付费方案里主流搜索引擎的官方 API 质量更稳但成本要考虑。我的建议是先用免费方案跑通流程验证效果后再根据预算切换到付费方案。Agent 框架的选择上如果只是做联网搜索这一个功能没必要上重型框架。用轻量的函数调用机制就够了。但如果后续要扩展成多技能 Agent那还是选一个支持工具编排的框架更省事。3.2 搜索工具的函数定义与接入把搜索能力封装成一个工具函数是 Agent 调用搜索的标准做法。函数定义要清晰描述功能、参数和返回格式这样模型才能正确调用。search_tool { name: web_search, description: 搜索互联网获取实时信息。当用户问题涉及最新事件、实时数据或模型知识截止日期之后的信息时使用。, parameters: { type: object, properties: { query: { type: string, description: 搜索查询词应该是简洁的关键词组合不要用完整句子 }, num_results: { type: integer, description: 返回结果数量默认5条, default: 5 }, time_range: { type: string, description: 时间范围限定可选值day, week, month, year, enum: [day, week, month, year] } }, required: [query] } }这个定义里description 的写法很关键。要明确告诉模型“什么时候该用这个工具”而不是只描述工具本身。我见过很多实现只写“搜索互联网”结果模型在不需要搜索的时候也乱调浪费延迟和成本。3.3 决策循环的代码实现决策循环是整个流程的核心。我用伪代码展示一下逻辑def agent_search_loop(user_query, max_rounds3): context [] collected_info [] for round_num in range(max_rounds): # 判断是否需要搜索 need_search decide_search(user_query, context, collected_info) if not need_search: break # 生成查询词 search_query generate_query(user_query, context, collected_info) # 执行搜索 raw_results web_search(search_query) # 重排和筛选 ranked_results rerank(raw_results, user_query) # 提取关键信息 extracted extract_info(ranked_results, user_query) collected_info.extend(extracted) # 判断信息是否充分 if is_sufficient(user_query, collected_info): break # 生成最终回答 answer generate_answer(user_query, collected_info) return answer这段代码里decide_search和is_sufficient是两个关键判断点。我的实现是把用户问题、对话历史、已收集信息一起给模型让它输出布尔值和理由。理由很重要方便调试时定位问题。3.4 延迟优化与并发处理联网搜索的延迟是用户体验的杀手。一次搜索 API 调用可能就要一两秒加上模型决策和结果重排整个流程跑下来三五秒很正常。如果搜多轮延迟会累积到十秒以上。优化手段有几个。第一是并行搜索如果生成了多个查询词可以并发调用搜索 API而不是串行。第二是流式输出在搜索完成之前先把“正在搜索”的状态展示给用户搜索完成后逐步输出结果。第三是缓存对于高频查询把搜索结果缓存一段时间下次直接命中。并发处理方面如果服务要扛住大量用户同时使用搜索 API 的调用需要做限流和排队。我的做法是用一个异步队列管理搜索请求控制并发数避免把搜索 API 打挂。同时给每个请求设超时超时了就降级到模型自身知识回答并告知用户“实时信息获取失败”。提示搜索 API 的限流策略要提前确认。有些免费 API 限制每分钟调用次数如果不做限流高峰期会大量失败。我一般会在客户端做一层令牌桶限流确保不超过 API 的限制。4. 常见问题与排查实录4.1 搜索结果与问题不匹配这是最常见的问题。用户问“Python 异步编程的最佳实践”搜索结果却返回一堆“Python 入门教程”。排查思路分三步先看查询词是否被过度改写再看搜索 API 是否支持语义匹配最后看重排环节是否把相关结果排到了后面。我的经验是大部分不匹配问题出在查询改写环节。改写时加了太多限定词把搜索范围缩得太窄。解决办法是保留多个查询变体分别搜索后合并结果。比如同时用“Python 异步编程 最佳实践”和“Python asyncio 实践”两个查询覆盖不同表述习惯的内容源。4.2 信息时效性判断失误用户问“最新的 XX 政策”搜索结果却返回去年的旧闻。这个问题通常是因为搜索 API 的时间过滤参数没设对或者重排时时效性权重太低。我的做法是在查询改写阶段就识别时间意图如果用户问题里有“最新”“最近”“今年”这类词就自动加上时间范围限定。同时在重排公式里对时效性敏感的问题提高 freshness 权重。另外在最终回答里标注信息的发布时间让用户自己判断是否够新。4.3 多轮搜索陷入死循环Agent 有时候会反复搜索同一个问题每次都觉得信息不够。这通常是因为信息充分性判断过于严格或者搜索 API 返回的结果确实质量太差。解决办法是加一个“搜索历史去重”机制如果新一轮生成的查询词和之前高度相似就跳过搜索直接进入回答生成。同时给信息充分性判断设一个递减阈值第一轮要求高后续轮次逐步降低避免无限循环。4.4 引用来源丢失或错乱生成回答时模型有时候会忘记标注来源或者把来源标错。这个问题在长回答里尤其常见。我的做法是在生成阶段用结构化输出要求模型对每个事实性陈述输出{content, source_id}的格式然后在后处理阶段统一渲染引用。这样比让模型自由发挥要可靠得多。另外来源列表要在回答末尾完整列出方便用户核查。问题类型典型表现排查方向解决手段结果不匹配返回内容与问题无关查询改写、重排权重多查询变体、调整权重时效性差返回旧信息时间意图识别、API 参数自动加时间限定、提高 freshness 权重死循环反复搜索同一问题充分性判断、查询去重递减阈值、查询相似度检测引用错乱来源标注缺失或错误生成格式、后处理结构化输出、统一渲染4.5 成本控制与降级策略联网搜索的成本主要来自两块搜索 API 调用费用和模型 token 消耗。多轮搜索会同时放大这两块成本。我的降级策略是分层的。第一层对于模型能直接回答的问题不触发搜索。第二层对于需要搜索但要求不高的问题只搜一轮。第三层对于复杂问题允许搜多轮但设硬上限。同时监控每次对话的平均搜索轮次和 token 消耗超过预算阈值就自动收紧策略。这套策略在实际运行中能把成本控制在可预期范围内。我建议在项目初期就把成本监控做进去不要等到账单出来才后悔。4.6 安全与内容过滤联网搜索返回的内容不可控可能包含不适宜的信息。必须在结果进入模型之前做一层过滤。我的做法是在重排环节之后、信息提取之前加一个内容安全过滤。过滤规则包括关键词黑名单、来源域名黑名单、内容类型判断。对于不确定的内容宁可丢弃也不要冒险。同时在最终回答生成时要求模型不要复述搜索结果中的敏感表述只提取事实性信息。注意内容过滤规则要定期更新。互联网上的内容形态变化很快上个月有效的规则这个月可能就漏了。我一般每两周 review 一次过滤日志看看有没有漏网之鱼。5. 从单点搜索到搜索 Agent 的扩展方向5.1 多源搜索的融合策略单一搜索 API 的结果覆盖面和视角都有限。把多个搜索源的结果融合起来能显著提升信息完整度。我试过同时调用两三个搜索 API把结果合并后统一重排效果比单源好不少。融合的关键是去重和互补。不同搜索源返回的结果可能有大量重叠需要做内容指纹去重。同时要识别各源的互补性比如有的源擅长新闻有的源擅长技术文档根据问题类型动态调整各源的权重。5.2 搜索记忆与个性化如果用户经常问某一领域的问题可以把历史搜索结果存下来形成个性化的搜索记忆。下次遇到相关问题先从记忆里检索不够再走联网搜索。这个思路本质上是在联网搜索和 RAG 之间做混合。实现上可以把每次搜索的关键信息提取出来存入一个轻量级的向量库带上时间戳和来源信息。检索时先查这个库命中且时效性满足就直接用否则再联网搜。5.3 搜索结果的深度加工搜到信息只是第一步深度加工才能产生更大价值。比如把多个来源的数据整合成对比表格把时间序列数据画成趋势图把分散的事实点组织成结构化摘要。这些加工能力可以封装成独立的工具由 Agent 根据用户需求自主调用。比如用户问“对比这几款产品的参数”Agent 可以先搜索各产品信息再调用表格生成工具输出对比表。这种“搜索加加工”的组合比单纯返回搜索结果要有用得多。5.4 评估体系的建立做联网搜索 Agent没有评估体系就是盲人摸象。我建议从三个维度建立评估准确性、时效性、完整性。准确性看回答中的事实性陈述是否与来源一致有没有编造。时效性看引用的信息是否在合理时间范围内。完整性看是否覆盖了用户问题的所有关键点。每个维度可以用人工标注加自动检查结合的方式来做。自动检查方面可以用一个独立的模型做事实一致性验证把回答和来源一起给它让它判断有没有矛盾。人工标注则用于校准自动检查的准确率以及发现自动检查覆盖不到的问题类型。这套评估体系跑起来之后每次调整查询改写策略或重排权重都能快速看到效果变化而不是凭感觉调参。我在实际项目里最大的体会就是联网搜索的效果优化七分靠评估体系三分靠算法调整。没有好的评估再多的优化都是瞎猜。