从搜索框到Agent:联网搜索智能体的架构设计与工程实践
1. 从搜索框到 Agent 的演进逻辑1.1 为什么传统搜索框模式走到了瓶颈做过 Chatbot 的人都有一个共同体会用户问今天有什么值得关注的科技新闻如果机器人只能从训练数据里翻答案那它给出的永远是几个月前甚至几年前的信息。这不是模型不够聪明而是知识截止这个硬伤决定的。搜索框模式解决的是我告诉你关键词你去索引库里找但 Chatbot 面对的是自然语言提问关键词提取本身就存在信息损耗。我早期做过一个客服机器人用户问你们那个能连蓝牙的耳机保修多久传统做法是先分词、抽关键词、拼查询串、调搜索接口、拿回一堆网页、再截取片段塞给模型。这条链路里每一步都在丢信息分词可能把连蓝牙拆散搜索接口返回的是网页标题和摘要摘要里未必有保修政策模型拿到残缺上下文只能瞎编。RAG检索增强生成的出现缓解了一部分问题但 RAG 本质上还是检索-拼接-生成的管道检索质量决定上限。真正的转折点在于 Agent 概念的落地。Agent 不是简单的模型搜索工具而是具备规划、执行、反思能力的智能体。它会把帮我查一下附近评分最高的川菜馆顺便看看能不能订位拆成多个子任务先搜餐馆列表再逐个查评分再找订位入口最后汇总。这个过程中搜索不再是单次调用而是被 Agent 编排进一个动态决策循环。1.2 联网搜索在 Agent 体系中的角色定位很多人把联网搜索当成一个普通工具函数web_search(query)返回结果就完事。但在 Agent 架构里联网搜索承担的是外部世界感知接口的角色。它和模型内部知识的关系类似于人的记忆和现场观察——记忆可能过时现场观察永远最新。从技术演进看联网搜索经历了三个阶段阶段典型形态核心特征主要瓶颈搜索框时代关键词检索人工构造查询语义鸿沟、信息碎片化RAG 时代向量检索生成语义匹配、上下文拼接检索召回率、上下文窗口限制Agent 时代工具调用编排动态规划、多轮搜索、结果验证编排复杂度、成本控制、安全边界这个演进不是替代关系而是叠加关系。Agent 时代的联网搜索底层依然可能走 RAG 管道但上层多了规划器和验证器。Agent 的核心价值在于决定什么时候搜、搜什么、搜几次、结果可不可信而不是简单地执行一次搜索。1.3 适合哪些人深入这个方向如果你正在做 Chatbot 产品发现用户频繁问实时性问题而你的机器人答不上来那联网搜索 Agent 是必须补的课。如果你在做 RAG 项目检索质量卡在某个瓶颈上不去Agent 化的查询改写和多轮检索可能是突破口。如果你是 AI 应用开发者想理解 Agent 框架里工具调用怎么设计才合理联网搜索是最好的练手场景——它足够简单一个 API 调用又足够复杂涉及规划、验证、容错。我个人的经验是不要一上来就搞多 Agent 协作。先把单 Agent 的联网搜索闭环跑通能判断是否需要搜索、能构造有效查询、能解析搜索结果、能验证结果相关性、能在结果不足时重新搜索。这个闭环跑通了再考虑加记忆、加多工具、加多 Agent。2. 核心架构拆解从单次检索到动态编排2.1 查询理解与改写搜索质量的第一道闸门用户输入最近有什么好看的科幻片直接拿这句话去搜返回的可能是购票网站、影评聚合页、甚至几年前的榜单。问题出在查询意图没有被结构化。Agent 的第一步不是搜索而是理解用户要的是近期上映的科幻电影推荐时间范围是最近一个月类型是科幻输出形式是片单。我通常会在 Agent 里加一个查询改写节点用一个小模型或者规则引擎把自然语言转成结构化查询。比如# 查询改写示例伪代码 def rewrite_query(user_input, context): # 提取时间意图 time_range extract_time_intent(user_input) # 最近 - 2024-01 至 2024-02 # 提取实体和类型 entities extract_entities(user_input) # 科幻片 - category: movie, genre: sci-fi # 结合对话历史补全指代 resolved resolve_coreference(user_input, context) # 那个导演的新片 - 诺兰的新片 # 生成搜索查询 queries generate_search_queries(resolved, time_range, entities) return queries # [2024年1月上映科幻电影, 最新科幻片推荐 2024]这里的关键是生成多个查询而不是一个。单个查询的召回率有限多查询并行搜索再合并结果能显著提升覆盖率。但查询数量不能无限膨胀一般控制在 3-5 个否则搜索成本和延迟都扛不住。注意查询改写不要过度依赖大模型自由发挥最好用 few-shot 示例约束输出格式。我见过模型把最近改写成2023年的情况因为训练数据里最近对应的就是那个时间。时间意图提取建议用规则模型混合方案规则兜底保证不出大错。2.2 搜索工具选型免费 API 与自建索引的取舍热词里有人问免费的联网搜索 API 有哪些这确实是实操中的第一个卡点。我的建议是分场景原型验证阶段用公开的搜索 API 免费额度快速跑通链路。重点验证 Agent 编排逻辑不要纠结搜索质量。小规模生产考虑自建轻量索引用开源爬虫抓取目标站点配合向量数据库做语义检索。可控性高但维护成本不低。大规模生产混合方案。通用查询走商业搜索 API垂直领域查询走自建索引。用路由层决定走哪条路。选型时重点看三个指标延迟、召回率、结果结构化程度。延迟决定用户体验召回率决定答案质量结构化程度决定解析成本。有些搜索 API 返回的是纯 HTML 片段解析起来非常痛苦有些返回结构化 JSON省去大量清洗工作。我实测下来搜索结果的解析和清洗往往比搜索本身更耗时。网页里的导航栏、广告、版权信息都是噪声如果不做清洗直接塞给模型模型很容易被带偏。建议在搜索工具和 Agent 之间加一个结果净化层做去重、去噪、正文提取、关键段落截取。2.3 Agent 编排循环规划、执行、验证、重试这是整个系统最核心的部分。一个完整的联网搜索 Agent 循环通常包含以下步骤意图判断当前问题是否需要联网搜索如果模型内部知识足够且不涉及实时信息直接回答省一次搜索调用。查询规划生成一个或多个搜索查询确定搜索策略并行还是串行。工具调用执行搜索获取原始结果。结果验证搜索结果是否相关是否足够回答问题如果不够回到步骤 2 重新规划。答案生成基于验证通过的结果生成最终回答并标注信息来源。反思记录记录本次搜索的成功/失败经验供后续类似查询参考。这个循环的难点在于终止条件的设计。如果不设终止条件Agent 可能陷入无限搜索如果终止太早答案质量不够。我的做法是设置最大搜索轮次通常 3 轮和置信度阈值结果相关性评分低于阈值就重试两者结合。# Agent 搜索循环简化逻辑 MAX_ROUNDS 3 CONFIDENCE_THRESHOLD 0.7 def search_agent_loop(question, context): for round in range(MAX_ROUNDS): queries plan_queries(question, context, round) results parallel_search(queries) cleaned clean_results(results) confidence evaluate_relevance(cleaned, question) if confidence CONFIDENCE_THRESHOLD: return generate_answer(question, cleaned) # 置信度不足调整查询策略 context.update(failed_queriesqueries, reasonlow_confidence) # 达到最大轮次用现有结果生成答案并标注不确定性 return generate_answer(question, cleaned, uncertainTrue)实操心得验证环节不要只用模型打分可以结合规则。比如搜索结果里是否包含问题中的关键实体、时间范围是否匹配、来源域名是否在可信列表里。规则模型混合验证比纯模型验证稳定得多。2.4 记忆与上下文管理让 Agent 记住搜过什么多轮对话里用户可能先问2024年有什么科幻片再问刚才说的那部导演是谁。如果 Agent 不记录搜索历史第二轮就得重新搜。搜索记忆至少包含查询历史、结果摘要、已验证的事实、未解决的问题。我一般用两层记忆短期记忆存当前会话的搜索轨迹长期记忆存跨会话的高频查询和优质结果。短期记忆用对话上下文窗口管理长期记忆用向量库存储。注意长期记忆要设过期策略实时性强的查询结果如股价、天气不适合长期缓存。上下文管理还有一个容易忽略的点搜索结果太长会挤爆上下文窗口。我的做法是搜索结果先做摘要压缩只保留与问题最相关的段落原文存在外部存储里需要时再检索。这样既节省 token又保留追溯能力。3. 实操落地从零搭建一个联网搜索 Agent3.1 环境准备与基础依赖假设你用 Python 做原型核心依赖包括一个大模型调用库如 OpenAI SDK 或兼容接口、一个搜索工具封装、一个向量库可选用于结果去重和记忆、一个编排框架LangChain、LlamaIndex 或自己写。我的建议是先用自己写的轻量编排不要一上来就上重框架。原因很简单联网搜索 Agent 的核心逻辑不复杂自己写能完全掌控每一步排查问题也方便。等逻辑稳定了再考虑用框架重构。# 基础依赖安装示例 pip install openai requests beautifulsoup4 numpy # 如果要用向量去重 pip install sentence-transformers faiss-cpu搜索工具封装要注意超时和重试。搜索 API 偶尔抽风是常态不设超时会把整个 Agent 卡死。我一般设 5 秒超时失败重试 2 次重试间隔指数退避。3.2 搜索工具封装与结果清洗搜索工具不是简单包一个 HTTP 请求就完事。你需要处理请求参数构造、响应解析、错误处理、结果标准化。不同搜索源返回格式不同封装层要统一成内部格式。# 搜索工具封装示例 import requests from bs4 import BeautifulSoup from typing import List, Dict class SearchTool: def __init__(self, api_key, timeout5, max_retries2): self.api_key api_key self.timeout timeout self.max_retries max_retries def search(self, query: str, num_results: int 5) - List[Dict]: for attempt in range(self.max_retries 1): try: resp requests.get( https://api.example.com/search, params{q: query, num: num_results}, headers{Authorization: fBearer {self.api_key}}, timeoutself.timeout ) resp.raise_for_status() return self._parse_results(resp.json()) except Exception as e: if attempt self.max_retries: return [] time.sleep(2 ** attempt) def _parse_results(self, raw: dict) - List[Dict]: results [] for item in raw.get(items, []): results.append({ title: item.get(title, ), url: item.get(url, ), snippet: self._clean_text(item.get(snippet, )), source: item.get(source, ), timestamp: item.get(timestamp, ) }) return results def _clean_text(self, text: str) - str: # 去除 HTML 标签和多余空白 soup BeautifulSoup(text, html.parser) return .join(soup.get_text().split())结果清洗的重点是正文提取。搜索 API 返回的 snippet 往往太短不足以回答问题。如果条件允许对高相关结果做二次抓取提取正文关键段落。但要注意抓取频率和 robots 协议不要给目标站点造成压力。3.3 查询规划器的实现细节查询规划器决定搜什么、怎么搜。我的实现方案是规则模型混合规则层处理明确的时间、地点、实体提取用正则和词典。模型层处理模糊意图和复杂查询改写用 few-shot prompt 约束输出。# 查询规划器示例 def plan_queries(question: str, context: dict, round_num: int) - List[str]: # 第一轮直接改写 if round_num 0: prompt f将以下问题改写成适合搜索引擎的查询输出 JSON 数组 问题{question} 要求生成 2-3 个不同角度的查询覆盖问题的不同方面。 示例输出[查询1, 查询2] queries call_llm(prompt) return parse_json_array(queries) # 后续轮次基于失败原因调整 failed context.get(failed_queries, []) reason context.get(reason, ) prompt f之前的查询 {failed} 效果不佳原因是 {reason}。 请生成新的查询策略避免重复之前的思路。 原问题{question} return parse_json_array(call_llm(prompt))注意查询规划器输出的查询要过滤掉明显无效的如空字符串、超长查询、包含敏感词的查询。我见过模型生成过 200 字符的查询搜索引擎直接截断效果很差。查询长度控制在 50 字符以内比较稳妥。3.4 结果验证与答案生成结果验证是区分能用和好用的关键。我的验证分三步相关性打分用模型对每个结果和问题的相关性打分0-1。事实一致性检查多个结果之间是否矛盾如果矛盾标记为不确定。时效性检查结果的时间戳是否满足问题的时间要求答案生成时强制模型标注信息来源。这不仅提升可信度也方便排查问题。如果模型说根据搜索结果但实际没引用任何结果那就是幻觉需要拦截。# 答案生成 prompt 示例 ANSWER_PROMPT 基于以下搜索结果回答问题。要求 1. 只使用搜索结果中的信息不要编造。 2. 每个关键结论后面标注来源编号 [1][2]。 3. 如果搜索结果不足以回答明确说根据现有搜索结果无法确定。 4. 如果结果之间有矛盾指出矛盾点。 搜索结果 {search_results} 问题{question} 答案3.5 成本控制与性能优化联网搜索 Agent 的成本主要来自三块模型调用、搜索 API、抓取流量。优化方向缓存相同查询在短时间内直接返回缓存结果。我一般设 10 分钟缓存实时性要求高的场景缩短到 1 分钟。并行搜索多个查询并行执行降低总延迟。但要注意 API 的并发限制。结果去重不同查询可能返回相同网页去重后再送给模型节省 token。模型分级查询改写用便宜的小模型答案生成用强模型。验证环节可以用规则小模型组合。我实测下来缓存能省 30%-50% 的搜索调用尤其是热门查询。去重能省 20% 左右的 token。这两项加起来成本下降非常明显。4. 常见问题与排查技巧实录4.1 搜索结果不相关怎么办这是最高频的问题。排查顺序检查查询本身把 Agent 生成的查询打印出来人工判断是否合理。如果查询本身就跑偏了问题在规划器。检查搜索源同一个查询在不同搜索源上结果差异很大。如果某个源持续不相关考虑换源或加源。检查时间范围很多搜索 API 默认按相关性排序不按时间。如果问题有时效性要求要显式加时间参数。检查语言和地区中文查询在英文搜索源上效果差反之亦然。确保搜索源支持目标语言。我踩过的一个坑查询里带了引号搜索 API 把引号当成精确匹配符号结果返回空。后来在查询清洗里统一去掉特殊符号问题解决。4.2 Agent 陷入无限搜索循环典型表现Agent 反复搜索同一个问题每次都说结果不够好然后继续搜。原因通常是验证阈值设得太高或者重试策略没有变化。解决方法设最大轮次硬限制到轮次强制输出。每轮重试必须改变查询策略不能重复之前的查询。验证阈值动态调整第一轮高阈值后续轮次逐步降低避免死循环。实操心得我一般会在 Agent 状态里记录已搜索的查询集合新查询如果和已有查询相似度超过 0.9直接拒绝强制换角度。4.3 搜索结果被模型幻觉污染模型有时候会脑补搜索结果里没有的信息。排查方法在答案生成后用另一个模型调用做事实核查逐句检查答案是否能在搜索结果中找到依据。找不到依据的句子标记为待确认。更彻底的做法是引用强制要求模型每个结论必须带来源编号生成后解析编号检查编号对应的原文是否支持该结论。这个检查可以用规则做成本低。4.4 搜索 API 限流和超时免费 API 限流是常态。应对策略请求队列令牌桶限流控制请求速率。多源备份主源限流时自动切备源。超时设短一点3-5 秒快速失败快速重试。非关键搜索可以降级返回缓存结果或提示用户稍后重试。我一般会维护一个搜索源健康度表记录每个源的成功率、平均延迟、限流频率。路由时优先选健康度高的源。4.5 常见问题速查表问题现象可能原因排查动作解决方案搜索结果不相关查询构造差/搜索源不匹配打印查询人工检查优化规划器/换搜索源无限搜索循环验证阈值过高/重试无变化查看轮次和查询历史设最大轮次/强制换查询答案含幻觉模型脑补/结果不足事实核查/引用检查强制引用/不足时明确说API 限流请求频率过高查看响应状态码限流队列/多源备份延迟过高串行搜索/结果太大打点各环节耗时并行搜索/结果压缩上下文溢出搜索结果太长查看 token 用量摘要压缩/外部存储5. 进阶方向从单 Agent 到多 Agent 协作单 Agent 跑通后可以考虑多 Agent 协作。比如一个规划 Agent负责拆解问题一个搜索 Agent负责执行搜索一个验证 Agent负责检查结果一个汇总 Agent负责生成最终答案。每个 Agent 职责单一通过消息传递协作。但多 Agent 的复杂度是指数级上升的。我建议不要为了多 Agent 而多 Agent。只有当单 Agent 的 prompt 复杂到难以维护或者不同环节需要不同模型/不同工具时才考虑拆分。拆分后要重点解决Agent 之间的通信协议、状态同步、错误传播、成本控制。另一个方向是搜索结果的深度加工。比如把搜索结果和知识图谱结合做实体链接和关系抽取让 Agent 不仅知道是什么还知道和什么有关。这在垂直领域如医疗、法律、金融价值很大但需要领域知识库支撑。还有一个容易被忽略的方向是搜索安全。Agent 联网搜索意味着它会接触外部内容外部内容可能包含注入攻击、误导信息、恶意链接。我一般会在结果清洗层加内容安全过滤检测 prompt 注入模式、过滤不可信域名、标记可疑内容。这个环节不能省尤其是面向 C 端用户的产品。最后分享一个我个人的体会联网搜索 Agent 的瓶颈往往不在技术而在评估。你怎么知道这次搜索是成功的答案是对的没有更好的搜索策略建立一套自动评估体系相关性、准确性、时效性、覆盖率比优化单个环节更重要。我现在的做法是维护一个测试集每次改动后跑一遍看各项指标的变化。没有评估优化就是盲人摸象。