1. 搜索框时代:Chatbot 是怎么“假装”会联网的
如果你做过几年 Chatbot 相关产品,一定见过这个场景:用户问“今天北京天气怎么样”,Chatbot 回一句“我无法获取实时信息,请查询天气应用”。用户表面上接受了,但心里已经在骂人了。
早年的闲聊型 Chatbot 只能基于静态语料作答,知识截止日期一过,任何与时间相关的提问都会翻车。于是大家开始给 Chatbot 做联网能力,最早的方案就是检索增强生成(RAG)。思路不复杂:用户提问后,先从搜索引擎或知识库里拉一批相关文本,把这些文本和问题一起塞进大模型的提示词,让模型“看着资料回答”。
1.1 RAG 链路:从向量库到搜索结果
我做第一版带联网的 Chatbot 时,整个链路分四段:先做查询改写,把口语化的问题转成适合搜索的关键词;再用搜索引擎拿回 top 10 结果的标题、链接和摘要;然后把正文抓回来做清洗和截断;最后把文本片段拼进 Prompt 让模型总结回答。
说实话,第一阶段还算稳。因为 RAG 主要解决的是“知识过时”和“事实幻觉”问题,把外部资料灌进上下文,模型只要能做阅读理解就行,不需要它自己掌握最新信息。对用户来说,体验从“无法回答”变成了“能给出带来源的回答”,已经是质的飞跃。
但问题也随之而来:RAG 里最麻烦的是检索质量。搜索词改写不对,结果就完全跑偏;正文抓取回来经常混入导航、广告、推荐位这些噪声,清洗不干净,模型会拿垃圾信息当依据。更头疼的是,如果检索到的内容相互矛盾,模型会一本正经地选一个“看起来最合理”的答案,然后被用户抓包。
1.2 把搜索结果硬塞进 Prompt 的代价
当时我踩得最深的坑是 Token 预算。一组搜索结果随便就是几千字,加上问题本身和系统提示词,一轮请求动辄消耗上万 Token。用户多问两句,成本就刷刷往上涨。你们可能见过某些 Chatbot 回答到一半就断掉,或者越到后面回答越简短,多半就是上下文太长把模型窗口塞满了。
这个阶段的核心矛盾是:搜索框和对话天生不同。搜索框给用户看十条链接,用户自己选;Chatbot 必须替用户做完判断,给一个答案。搜索框时代的 RAG,本质上只是把搜索能力作为“外挂”挂在对话系统上,模型负责总结,但搜索、筛选、决断这些真正的“联网动作”并没有被纳入模型决策。
所以后来大家开始琢磨另一条路:与其把搜索结果塞进 Prompt,不如直接让模型调用搜索工具,像人一样决定什么时候搜、搜什么、怎么用结果。这就是后面 Agent 形态的雏形,但这条路不是一蹴而就的,中间还经历了一段非常折腾的过渡期。
2. 搜索引擎 API 接入:免费、付费与“看起来免费”的坑
把搜索能力嵌到 Chatbot 里,最朴素的做法是直接调用搜索引擎的 API。市面上做这个的服务不少,价格天差地别,效果也参差不齐。早期网上很多人问“免费的联网搜索 API 有哪些”,我几乎都试过一遍,这里把我的真实体验整理出来。
2.1 常见联网搜索 API 盘点
先看这张表,基本都是我用过的,按适用场景做了分类:
| API | 特点 | 适合场景 | 成本 |
|---|---|---|---|
| Tavily Search API | 专为 AI 设计,返回内容直接做过提炼,支持 AI 模式 | 快速搭建带搜索的 Agent,省去清洗流程 | 有免费额度,付费按次计费 |
| SearchAPI.io | 聚合 Google、Bing、百度等几十种搜索引擎接口 | 需要多渠道对比、爬取实时数据 | 免费额度较少,付费较便宜 |
| Brave Search API | 独立索引,隐私保护强,结果干净 | 对结果质量要求高的应用 | 免费额度够开发测试 |
| Bing Web Search API | 微软生态,索引覆盖广,结构化数据丰富 | 企业级项目,需要稳定服务 | 按量付费,有免费层级 |
| SerpAPI | 把 Google 搜索结果结构化返回,支持解析广告、知识图谱等模块 | 需要解析复杂结果页的项目 | 有免费试用,正式使用较贵 |
| Jina AI Reader | 不是搜索引擎,但能把网页正文提取为干净的 Markdown | 配合搜索 API 做网页内容抽取 | 有免费额度,付费按调用量 |
说句实在话,如果只是做个人项目或 Demo,Tavily 和 Brave 的免费额度基本够用。但如果目标是给生产环境用,免费额度完全扛不住流量,该付费就得付费。我之前见过一个团队为了省成本,所有请求走免费额度,QPS 一高直接触发限流,用户那边看到的错误比回答还多。
2.2 限流、脏数据与截断:API 接入的三座大山
哪怕选好了 API,接入过程也不是一帆风顺。我列几个当时踩过的具体问题。
第一个是限流。某些免费 API 的限流策略是“每小时 X 次”,X 看起来不小,但 Chatbot 的搜索请求往往是突发性的,比如某个话题上热搜,用户集中提问,几秒钟就能把全天的配额打光。我当时做了个简单的本地缓存,把热门的搜索结果缓存 30 分钟,直接减少了一半以上的 API 调用。
第二个是结果截断。搜索引擎返回的摘要经常在关键结论处断掉,比如“研究表明该方案有效,但”,后面没了。这种情况下模型只能靠残缺信息脑补,很容易出错。我的处理方案是二次抓取正文:把摘要里信息不够的链接用爬虫拉全文,再截断处理。这个操作对结果质量提升非常明显。
第三个是脏数据。搜索结果里大量混入 SEO 垃圾、广告号、内容农场,纯靠关键词去匹配,模型会把广告当答案。最离谱的一次,用户问“什么牌子的洗衣液好”,模型引用了一篇明显是软文的文章,推荐了一个当时刚上市的新品牌。后来我加了一层“来源可信度打分”,对域名权重、页面发布时间、内容长度做加权,才勉强把这类问题压下去。
但所有 API 方案都有一个绕不开的天花板:一次搜索能拿到的结果,不一定覆盖用户真正需要的信息。用户问“A 和 B 哪个好”,可能需要搜十几轮才能凑齐足够信息,而 API 搜索返回的只是“一次查询”的结果,不做多轮探索。这个短板,单纯靠调搜索接口是补不上的。
3. 无头浏览器方案:把“假装成用户”的野路子走通之后
API 方案受限于“查询-返回”的简单模式,于是有人开始想:既然搜索 API 给出的结果不够丰富,我们干脆用无头浏览器直接模拟用户在搜索引擎里输入关键词、点击链接、读取页面,这不就完全不受 API 限制了吗?
我当时还真这么干过一段时间。起因是想抓一个实时行情页面,但那个站点没有任何开放 API,用无头浏览器反而最省事。后来类推到搜索场景,用 Playwright 开一个无头 Chrome,访问搜索页,填表单,回车,等页面渲染,再用选择器抓取结果列表。整个流程自动化以后,看起来就像有一个真人在用浏览器搜东西。
3.1 无头浏览器搜索的实现逻辑
实现上其实不难,核心步骤就这么几步:
- 用 Playwright 或 Puppeteer 启动一个无头浏览器实例
- 访问搜索引擎页面,定位到搜索框元素,填入查询词
- 等待结果页渲染完成,提取搜索结果列表里的标题、链接、摘要
- 对需要的链接逐个访问,抓取正文内容
- 把内容交给模型处理
这套路子的最大优势是“绕过所有 API 限制”。没有配额,没有付费墙,搜索结果和真实用户看到的一模一样,包括那些 API 不返回的评论、问答、知识图谱模块。
但它的劣势同样致命。稳定性是一大问题——搜索引擎的前端结构说改就改,昨晚还能用的选择器,今早起来可能就全部失效。我当时维护了三个搜索引擎的后备解析规则,还是挡不住它们隔三差五的改版。还有 IP 被限制的问题,大量自动化请求会在短时间内触发风控,搜索页直接弹出滑块验证,脚本当场废掉。
3.2 为什么这条路最终没有成为主流
平心而论,无头浏览器方案在特定场景下依然有价值,比如对方完全不提供 API 的时候,但拿来给 Chatbot 做联网搜索是走不通的,原因有三点。
第一是延迟。无头浏览器要完整加载页面、执行 JavaScript、等网络请求完成,单次搜索至少三五秒,多搜几个关键词,用户体验就完全垮掉。Chatbot 对话讲究即时反馈,用户等不起。
第二是脆弱。我在维护这套方案时最怕收到“搜索失败”的告警,因为排查原因极其繁琐,可能是页面改版、可能是网络抖动、可能是被风控、也可能是那台机器的字体加载异常导致布局偏移,选择器没匹配上。
第三是合规风险。绕过官方的 API 接口去抓取搜索页面,等于擅自使用服务,而且自动化流量对搜索引擎的服务器也有压力,即使是个人项目,我也不建议大家把这条路当主业来用。
所以无头浏览器只能算一个过渡型方案。真正让联网搜索质变的,是后面 Agent 形态的出现——它把“联网”这件事从工程行为变成了模型行为。
4. Agent 形态登场:Function Calling 让搜索从“外挂”变成“工具”
从搜索框到 API 再到无头浏览器,本质上都是把联网搜索当成一个“外部功能”:问题进来,我们写代码去搜,搜完再喂给模型。这种模式里的主动权始终在工程端,模型只负责最后的总结。
Agent 形态出现以后,情况完全不同了。模型不仅能“说话”,还能“动手”——通过 Function Calling(现在更常叫 Tool Use / 工具调用),模型可以在对话过程中自主决定调用搜索工具、传入关键词、接收结果,再根据结果决定下一步动作。
4.1 思维转变:模型从“填填空”变成“做决定”
第一次上手 Function Calling 时,最让我震撼的是思维模式的转变。以前写代码是“用户输入问题 -> 我们调搜索 -> 结果拼给模型”,现在是“把问题交给模型 -> 模型自己说‘我需要搜索’ -> 模型生成搜索参数 -> 系统执行搜索 -> 结果返回给模型 -> 模型自行判断是否继续搜”。
用大白话说,以前的模型像个实习生,你查好资料递给它,它负责整理;现在的模型像个小主管,它会自己发现问题缺口,自己安排搜索任务,自己评价搜索结果够不够用,不够就再搜一轮。
比如用户问“最新的 iPhone 和小米旗舰机哪个更适合拍照”,老方案会拿这句原话去搜,结果出来一堆通用对比帖。Agent 方案里,模型会把问题拆成“iPhone 最新旗舰影像配置”“小米最新旗舰影像配置”“两者拍照对比评测”三个搜索目标,逐一搜索,然后在思考里比对信息,给出综合判断。
4.2 ReAct 循环:搜索只是 Agent 决策的一步
Agent 的运作核心是 ReAct 模式,也就是“思考-行动-观察”循环。模型的每一步输出都可以是三类内容:Thought(思考当前还缺什么信息)、Action(调用搜索工具)、Observation(观察搜索结果)。系统把搜索返回值作为观察结果再喂回给模型,模型继续思考,直到它认为信息足够,才输出最终答案。
这个循环我以前写过最简实现,只有几十行代码就能跑出初步效果:
def run_agent(query): messages = [{"role": "user", "content": query}] while True: response = model.chat(messages, tools=[search_tool]) if response.get("tool_calls"): for call in response["tool_calls"]: result = execute_search(call["arguments"]["query"]) messages.append({"role": "tool", "content": result}) else: return response["content"]核心点在循环的判断逻辑:只要模型还想调工具,我们就继续执行;一旦模型输出了最终答复,就停下来。这套逻辑看起来简单,但模型的思考质量和工具设计直接决定了最终效果。
4.3 多步搜索、反思和重试的实际收益
接入了多步搜索之后,我拿一批真实问题做过对比测试。同样是问“今年有哪些值得关注的 AI 开源项目”,单次搜索+RAG 回答的信息基本停留在两三个热门项目,Agent 形态会先搜“2025 热门 AI 开源项目”,发现结果太泛,再搜“GitHub 上 star 增长最快的 AI 项目”,然后对其中几个重点项目分别做详情搜索,最后给出的答案无论是覆盖面还是时效性,都明显高一个档次。
另外值得说的是反思机制。Agent 可以对自己的中间步骤做评价,比如搜出来的结果太旧、来源不太权威、两篇文章数据冲突,模型都能察觉到,并调整下一步搜索词。这种“搜得不好就换个姿势再搜”的能力,是传统 API 方案完全做不到的。
但 Agent 的自由度也带来了新问题:模型可能会做无用搜索,比如明明一次能搜到的东西,它分了三步去搜,白白增加 Token 消耗;也可能陷进循环,反复搜同一个关键词。后来的工程优化里,我加了两道保险:设置最大搜索轮数(比如 5 轮),超了强制输出;另外在工具描述里明确写清楚“搜索时应尽量使用精确关键词,避免重复查询”。
5. 搜索 Agent 的工程账:Token 成本、上下文管理与并发设计
Agent 让联网搜索从“外挂”变成了“工具”,但工程实现难度也随之上升。网上总有“AI Agent 怎么扛并发”这类提问,我先说结论:Agent 应用比传统 RAG 慢得多、消耗大得多,扛并发不能靠简单扩容,得从 Token 账本和调度策略两方面下手。
5.1 Agent Token 到底花在了哪里
很多人问“AI Agent token 是什么意思”,简单讲,Token 就是模型处理文本的最小单位,一个汉字大约对应 1-2 个 Token。Agent 场景的 Token 消耗要分三块看:系统提示词、历史对话、工具调用和工具返回结果。
系统提示词一般不大,几十到几百 Token,固定开销。历史对话如果无限累积,很快就会膨胀。最大的消耗来源是工具调用返回的搜索结果——每次搜索动辄几千 Token,如果 Agent 搜了五轮,光搜索结果就上万 Token。而且这些 Token 要反复喂给模型,多轮迭代时是翻倍消耗。
我做过一个粗略统计,同样一个问题,搜索框时代的 RAG 方案平均耗 3.5k Token,Agent 方案平均耗 12k Token,接近四倍。翻译成成本,如果按百万 Token 计费,一次复杂搜索的成本确实不低。所以 Token 优化是 Agent 上线前必须做的功课。
5.2 上下文窗口管理:搜索内容往哪放
Agent 搜索的上下文管理比普通对话更讲究。搜索结果如果是一次性使用的临时信息,用完就应该从上下文里清掉,只保留模型的最终判断结果。我当时用了一个很简单的策略:把搜索过程和结果摘要固定放在一个独立的“工作记忆区”,每轮只保留最近一两轮的原始搜索内容,更早的搜索只保留地图式摘要,避免上下文无限膨胀。
还有一个小技巧:搜索结果不一定要全量灌进上下文,可以先做信息抽取,只保留与当前问题相关的句子。比如搜出来一篇 5000 字的评测文章,模型实际需要的可能只有“主摄传感器型号、光圈大小、夜景表现”这几句。你可以在工具内部先让一个小模型做摘要,再传给主模型,Token 省一半以上。
5.3 “AI Agent 怎么扛并发”的实践答案
Agent 应用有个天然瓶颈:单次任务耗时长、消耗大,并发上来以后,API 限流、内存占用、延迟都会爆。我踩过几次坑之后的经验是,优先做“任务队列 + 结果缓存”,而不是盲目上容器扩容。
任务队列的思路是:不追求每个请求即时返回,而是把请求拆成“开始任务 -> 轮询结果 -> 返回”三个动作,Agent 在后台排队执行。这样即使同时来 100 个请求,也只有 5 个在真实执行,剩下 95 个在队列里等待。用户侧感知到的是结果出来慢了几秒,但系统不会被打垮。
结果缓存更直接:很多用户问的问题高度相似,缓存的命中率其实很可观。我把过去一周的搜索 Agent 结果按问题语义做了 embedding,存入向量库,新问题进来先算相似度,相似度超过阈值直接返回缓存结果。这套方案上线后,系统整体搜索调用量下降了 40% 左右。
另外提一句并发时的安全考量。Agent 不像普通 API 那样只做“输入-输出”,它会主动发起搜索、访问网页。生产环境必须对 Agent 的工具调用做白名单、频控和日志审计,至少知道哪些搜索请求是 Agent 发出的,避免脚本失控产生大量对外请求。
6. Agent 框架选型与搭建实操:LangChain、Dify、CrewAI 怎么选
聊到这里,已经有人会问:实际做一个带联网搜索的 Agent,到底该用什么框架?网上天天有人在比较 LangChain、Dify、CrewAI 哪个好,坦白说这问题没有标准答案,只看你的场景。我三个都用过,简单说一下它们的差别和我自己的选型逻辑。
6.1 三个框架的适用边界
我用一张表把关键差异列出来:
| 特性 | LangChain | Dify | CrewAI |
|---|---|---|---|
| 定位 | 开发者工具库 | 低代码平台 | 多 Agent 编排框架 |
| 上手难度 | 中高,需要写 Python | 低,界面可视化 | 中,需要写 Python |
| 对联网搜索的支持 | 内置 Tavily、SerpAPI 等多工具 | 有配套的工具节点,配置简单 | 通过自定义工具或集成支持 |
| 灵活度 | 高,几乎所有环节可编程 | 中,受平台抽象限制 | 中高,专注 Agent 协作 |
| 部署模式 | 完全自托管 | 平台托管或自托管 | 完全自托管 |
| 适合人群 | 程序员,想深入控制 Agent 行为 | 产品经理、快速验证想法的人 | 需要多个 Agent 分工协作的场景 |
LangChain 胜在组件全、社区大,几乎所有搜索 API 都有现成的封装。它的问题是抽象层次太多,版本升级经常破坏 API,我升级过一次大版本,改配置改了一天。Dify 适合做内部工具和快速 MVP,搜索、知识库、工作流都能在界面上拖出来,不需要写太多代码,但它不是万能的,复杂的 Agent 循环在低代码平台里编排很痛苦。CrewAI 则是做“多 Agent 协作”的,比如一个搜索 Agent、一个写作 Agent、一个审核 Agent 组成一个团队,各自角色清晰。
我的建议是:如果你本身会写代码,且对 Agent 行为控制要求高,选 LangChain;如果团队以产品为主,想一两天出个 Demo,选 Dify;如果确实需要多个 Agent 协同才能完成任务,CrewAI 值得一试。技术无关对错,只看匹配度。
6.2 用 Dify 搭一个带联网搜索的最小 Agent
为了提供一个能直接上手的参考,我以 Dify 为例说下搭建流程。你可能没装过,没关系,跟着走一遍就懂了。
第一步,准备好大模型 API Key 和搜索 API Key。搜索 API 我用的是 Tavily,因为它返回的是 AI 友好格式,省掉清洗步骤。
第二步,进入 Dify 控制台,创建一个“Chatflow”类型的应用。
第三步,在编排界面里加入两个节点:一个是“问题理解”节点,作用是把用户的原话改写成适合搜索的关键词;另一个是“工具调用”节点,接入 Tavily 工具,传入改写后的关键词,执行联网搜索。
第四步,把搜索返回结果接到一个“LLM 处理”节点上,提示词大致写成“你是一个信息整理助手,请根据搜索结果回答用户问题,标注信息出处,如果信息不足请明确说明”。
第五步,把整个工作流的起点设为用户输入,终点设为 LLM 处理节点的输出,发布应用。
整个过程大约二十分钟,就能得到一个具备联网搜索能力的 Chatbot。当然这是最小的可用版本,实际更完善的 Agent 还会加上历史记录、意图识别、答案质量评估等节点。但作为入手,这个流程足够让新人理解“工具调用 + 模型判断”的 Agent 基本形态。
6.3 让搜索 Agent 真正可用的避坑清单
最后把我这些年做搜索 Agent 踩过的坑集中列一份,供大家对照:
- 工具参数描述必须写清楚。模型不知道你的搜索工具接受什么格式,示例越多越好,否则它会生成错误参数,白白浪费一轮调用。
- 设置最大迭代次数。没有上限的 Agent 循环是会跑飞的,我在测试环境见过一个 agent 连搜 23 次还没给答案。
- 对搜索返回内容做安全过滤。网页内容可能包含七七八八的东西,模型直接读取原始页面会有风险,接入一个内容安全过滤层很有必要。
- 注意模型选择。并不是所有模型都擅长工具调用,有些模型在 Function Calling 场景下表现拉胯,换一个模型效果差距可能非常大。
- 降级兜底。Agent 搜索失败时,要能自动降级为普通 RAG 或直接回答“信息不足”,不要让它空手硬编答案。
很多人追求“全自动”“零人工干预”,但以我亲测的经验,Agent 的自主性是把双刃剑。上线商用搜索 Agent,一定要配好监控和兜底机制。比如在回答里显著标注信息来源、对不确定的答案降低肯定语气,这些都是提升可靠度最朴素有效的做法。踩过几次坑之后,我现在做任何 Agent 项目的第一件事就是先写降级方案,先把最坏的情况兜住,再谈智能。