在 AI 超级智能体项目中,你开发的联网搜索工具是如何实现的?
- 标签:后端、编程导航
🏛 业务架构师
联网搜索工具的实现链路:模型判断需要时效信息 → 调用搜索工具(关键词由模型从对话中提炼)→ 搜索 API 返回结果列表 → 抓取正文/摘要 → 结果回填模型 → 模型组织答案并标注来源。
工程实现要点:
- 搜索源封装:接第三方搜索 API(Tavily、Bing、博查等),按"结果质量 × 单价 × 配额"选型——搜索 API 是按次计费的,工具层要配调用缓存(相同关键词短时间去重);
- 结果裁剪:原始网页动辄几千 token,全塞回去成本爆炸——取 top3~5 条、每条截取摘要/正文片段,出处(标题+链接)随答案返回;
- 关键词质量:让模型把口语问题转成 2~4 个搜索关键词("那事儿最新进展"→精确查询词),关键词生成就是一次内置的查询重写;
- 失败兜底:搜索超时/无结果时明确告知"未找到最新信息",禁止模型编造来源。
业务架构视角的三点:
- 来源标注是信任资产:"根据 XX 网报道"与裸答案的可信度天差地别——AI 产品的竞争终局是信任,搜索工具天然给了溯源能力;
- 成本控制:一次问答 = 模型调用 + 搜索计费 + 结果回填的 token——每个工具都要算单次成本,高频工具做缓存与限流;
- 合规审查:抓取内容的使用边界(版权、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(); // 错误信息模型能读懂并应对
}
}
}工程细节(拉开差距的点):
- query 提炼:description 里要求"传关键词不是原问题"——用户原话往往带口语噪声,模型提炼后搜索质量更高;
- 结果预算:top3 × 300 字符 ≈ 1000 token,可控;绝不让原始 HTML 进上下文;
- 超时与降级:搜索 API 5s 超时,失败返回可读错误让模型转告用户"搜索暂不可用",而不是整个请求失败;
- 白名单触发:description 明确"什么情况调/不调",配合 system prompt("不确定时效就先搜索"),避免模型滥用工具烧钱;
- 结果带来源 url,回答时模型可引用出处,可信度加分。