|
此版本仍在开发中,尚未被视为稳定版。为了获取最新的快照版本,请使用Spring AI 1.1.3! |
动态工具发现,使用工具搜索工具
随着AI代理连接到更多服务——如Slack、GitHub、Jira和MCP服务器——工具库迅速增长。一个典型的多服务器设置可能会有超过50个工具在任何对话开始前消耗大量token。更糟糕的是,当模型面临30多个同名工具时,工具选择的准确性会下降。
The 工具搜索工具模式,由Anthropic倡导,解决了这一问题:它不是一开始就加载所有工具定义,而是模型在需要时动态发现工具。它只提供一个搜索工具,当需要时查询能力,然后根据需要扩展相关的工具定义。
Spring AI的实现实现了在OpenAI、Anthropic和Gemini模型中34%至64%的token减少,同时保留了数百个工具的完全访问权限。
博客文章博客文章
博客文章详细介绍了完整实现细节、性能基准测试以及高级使用场景。
快速开始
依赖项
在你的项目中添加一个依赖项:Tool Search Tool。
-
Maven
-
Gradle
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>tool-search-tool</artifactId>
<version>2.0.0</version>
</dependency>
<!-- Choose a search strategy -->
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>tool-searcher-lucene</artifactId>
<version>2.0.0</version>
</dependency>
dependencies {
implementation 'org.springaicommunity:tool-search-tool:2.0.0'
// Choose a search strategy
implementation 'org.springaicommunity:tool-searcher-lucene:2.0.0'
}
基本用法
@SpringBootApplication
public class Application {
@Bean
CommandLineRunner demo(ChatClient.Builder builder, ToolSearcher toolSearcher) {
return args -> {
var advisor = ToolSearchToolCallAdvisor.builder()
.toolSearcher(toolSearcher)
.build();
ChatClient chatClient = builder
.defaultTools(new MyTools()) // 100s of tools registered but NOT sent to LLM initially
.defaultAdvisors(advisor) // Activate Tool Search Tool
.build();
var answer = chatClient.prompt("""
Help me plan what to wear today in Amsterdam.
Please suggest clothing shops that are open right now.
""").call().content();
System.out.println(answer);
};
}
static class MyTools {
@Tool(description = "Get the weather for a given location at a given time")
public String weather(String location,
@ToolParam(description = "YYYY-MM-DDTHH:mm") String atTime) {
// implementation
}
@Tool(description = "Get clothing shop names for a given location at a given time")
public List<String> clothing(String location,
@ToolParam(description = "YYYY-MM-DDTHH:mm") String openAtTime) {
// implementation
}
@Tool(description = "Current date and time for a given location")
public String currentTime(String location) {
// implementation
}
// ... potentially hundreds more tools
}
}
如何工作
The 零 extends Spring AI’s 一 to implement dynamic tool discovery:

-
索引: 在对话开始时,所有注册的工具都会在
ToolSearcher中进行索引(但不会发送给大语言模型) -
Initial Request: 只将工搜索工具定义发送至LLM
-
发现调用: 当LLM需要能力时,它会通过搜索工具发送查询
-
搜索与扩展
: TheToolSearcherfinds matching tools and their definitions are added to the next request -
工具调用: LLM现在能够识别并调用搜索工具和发现的工具定义
-
工具执行: 发现的工具被执行,结果被返回
-
响应: LLM生成最终答案
搜索策略
The ToolSearcher interface supports multiple search implementations:
| 策略模式 | 实现 | 最适合 |
|---|---|---|
语义 |
|
自然语言查询,模糊匹配 |
关键字 |
|
精确术语匹配,已知工具名称 |
正则表达式 |
|
工具名称模式( |
See 工具搜索者 查看所有可用实现。
性能
初步基准测试结果表明,使用28种工具显著节省了Tokens数量:
| 模型 | 基于工具搜索 | 没有 | 储蓄 |
|---|---|---|---|
双子座 |
2,165 tokens |
5,375 个标记 |
60% |
OpenAI |
4,706 tokens |
7,175个token |
34% |
人类的 |
### 中文翻译 6,273 tokens |
一万七千三百四十二个Tokens |
64% |
当使用时
| 工具搜索工具方法论 | 传统方法 |
|---|---|
20+ 工具在您的系统中 |
小型工具库(共20个以下工具) |
工具定义消耗了超过5千个Tokens |
在每个会话中,经常使用的工具 |
构建基于 MCP 的多服务器系统 |
非常简洁的工具定义 |
体验工具选择准确性问题 |
示例项目
-
工具搜索工具演示示例 - 完整交互示例
-
预选工具演示 - 不涉及LLM的确定性工具选择
社区资源
-
Awesome Spring AI(社区示例和资源) - Community examples and resources
参考资料
-
Anthropic 高级工具使用 - 原始模式描述
-
Spring AI 递归顾问博客 - 工具搜索实现的基础