Skip to content

在 AI 超级智能体项目中,你开发的联网搜索工具是如何实现的? ​

  • 标签:后端、编程导航

🏛 业务架构师 ​

联网搜索工具的实现链路:模型判断需要时效信息 → 调用搜索工具(关键词由模型从对话中提炼)→ 搜索 API 返回结果列表 → 抓取正文/摘要 → 结果回填模型 → 模型组织答案并标注来源。

工程实现要点:

  • 搜索源封装:接第三方搜索 API(Tavily、Bing、博查等),按"结果质量 × 单价 × 配额"选型——搜索 API 是按次计费的,工具层要配调用缓存(相同关键词短时间去重);
  • 结果裁剪:原始网页动辄几千 token,全塞回去成本爆炸——取 top3~5 条、每条截取摘要/正文片段,出处(标题+链接)随答案返回;
  • 关键词质量:让模型把口语问题转成 2~4 个搜索关键词("那事儿最新进展"→精确查询词),关键词生成就是一次内置的查询重写;
  • 失败兜底:搜索超时/无结果时明确告知"未找到最新信息",禁止模型编造来源。

业务架构视角的三点:

  1. 来源标注是信任资产:"根据 XX 网报道"与裸答案的可信度天差地别——AI 产品的竞争终局是信任,搜索工具天然给了溯源能力;
  2. 成本控制:一次问答 = 模型调用 + 搜索计费 + 结果回填的 token——每个工具都要算单次成本,高频工具做缓存与限流;
  3. 合规审查:抓取内容的使用边界(版权、robots 协议)与内容安全过滤(不良信息可能经搜索进入答案)——工具打开了外部世界的门,也把外部风险带了进来。

一句话:联网搜索让 AI 的答案有了时间维度,但"搜得准、裁得省、标得清"三件事决定了它是加分项还是成本黑洞。

🏗 系统架构师 ​

联网搜索工具的实现链路(Tool Calling 标准实现):

1. 工具定义(@Tool 注解 + 精确描述):

java
@Tool(description = "联网搜索工具:当问题涉及实时信息、新闻、最新数据或模型知识可能过期的内容时调用")
public String webSearch(@ToolParam(description = "搜索关键词,提炼问题的核心实体与意图") String query,
                        @ToolParam(description = "结果数量,默认5", required = false) Integer topK) {
    // 2. 调用搜索 API
    // 3. 结果精炼
}

2. 搜索 API 层:选型 Tavily(LLM 友好,直接返回提炼内容)/ Bing Search API / SerpAPI;封装 HTTP 客户端(超时 5s、重试 1 次、密钥配置中心管理);参数:query、top_k、是否含摘要。

3. 结果处理(决定效果的关键):

  • 原始结果精炼:标题 + URL + snippet 拼成紧凑文本(token 预算控制),去掉广告/无关域名;
  • 可选二次抓取:top1 结果的正文抓取(Jsoup)截断到 2000 token,给模型更完整的上下文;
  • 返回结构化文本(模型消费),失败返回明确错误信息("搜索服务超时,请基于已有知识回答并说明")。

4. 调用循环:模型决策调用 → 框架反射执行 → 结果回传 → 模型综合作答(引用来源 URL);用户问复杂问题时模型可能连续多次调用(先搜实体 A 再搜实体 B)。

工程要点:搜索 API 按次计费,配全局限流与缓存(相同 query 5 分钟内复用);Query 由模型生成,质量通常好于用户原文(这是隐含收益);把"是否需要搜索"的判断也交给模型(描述里写清适用场景),不要在业务代码硬编码关键词路由。

💻 全栈开发专家 ​

结构:一个 @Tool 方法封装第三方搜索 API + 结果精炼,关键全在"token 纪律"。

java
public class WebSearchTool {
    private final SearchClient client;   // 博查/Tavily/SerpAPI

    @Tool(description = "联网搜索最新信息。当问题涉及实时数据、新闻、"
        + "最新版本号或你不确定时效性的事实時调用。query 为搜索关键词")
    public String webSearch(
            @ToolParam(description = "精炼的搜索关键词,不是原问题") String query) {
        try {
            List<SearchResult> results = client.search(query, 5);   // 5s 超时
            return results.stream()
                .limit(3)                                            // 只取 top3
                .map(r -> "标题:%s\n摘要:%s\n来源:%s".formatted(
                        r.title(), truncate(r.snippet(), 300), r.url()))
                .collect(Collectors.joining("\n---\n"));
        } catch (Exception e) {
            return "搜索失败:" + e.getMessage();   // 错误信息模型能读懂并应对
        }
    }
}

工程细节(拉开差距的点):

  1. query 提炼:description 里要求"传关键词不是原问题"——用户原话往往带口语噪声,模型提炼后搜索质量更高;
  2. 结果预算:top3 × 300 字符 ≈ 1000 token,可控;绝不让原始 HTML 进上下文;
  3. 超时与降级:搜索 API 5s 超时,失败返回可读错误让模型转告用户"搜索暂不可用",而不是整个请求失败;
  4. 白名单触发:description 明确"什么情况调/不调",配合 system prompt("不确定时效就先搜索"),避免模型滥用工具烧钱;
  5. 结果带来源 url,回答时模型可引用出处,可信度加分。