|
此版本仍在开发中,尚未被视为稳定版。如需最新的快照版本,请使用 Spring AI 1.1.3! |
使用工具搜索工具进行动态工具发现
随着 AI 代理连接到更多服务——Slack、GitHub、Jira、MCP 服务器——工具库迅速增长。一个典型的多服务器设置可以轻松拥有 50 多个工具,在任何对话开始前消耗大量Tokens。更糟糕的是,当模型面对 30 多个名称相似的工具时,工具选择的准确性会下降。
工具搜索工具 模式,由 Anthropic 率先提出,解决了这一问题:不是一次性加载所有工具定义,而是按需发现工具。模型最初只接收一个搜索工具,在需要时查询功能,并将相关的工具定义扩展到上下文中。
Spring AI 的实现在 OpenAI、Anthropic 和 Gemini 模型上实现了 34-64% 的 token 减少,同时保持对数百个工具的完全访问。
快速开始
依赖项
将工具搜索工具依赖项添加到您的项目中:
-
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
}
}
工作原理
ToolSearchToolCallAdvisor 扩展了 Spring AI 的 ToolCallAdvisor 来实现动态工具发现:
-
索引:在对话开始时,所有注册的工具都会被索引到
ToolSearcher中(但不会发送给 LLM) -
初始请求: 仅将工具搜索工具的定义发送给LLM
-
发现调用: 当LLM需要能力时,它会调用搜索工具并附带查询
-
搜索与扩展:
ToolSearcher查找匹配的工具,并且它们的定义会被添加到下一个请求中 -
工具调用:LLM现在可以看到搜索工具和发现的工具定义
-
工具执行: 发现的工具被执行并返回结果
-
响应: 大型语言模型生成最终答案
搜索策略
ToolSearcher 接口支持多种搜索实现:
| 策略 | 实施 | 最适合 |
|---|---|---|
语义 |
|
自然语言查询,模糊匹配 |
关键字 |
|
精确术语匹配,已知工具名称 |
正则表达式 |
|
工具名称模式 ( |
请参阅 tool-searchers 以获取所有可用的实现。
性能
使用 28 种工具进行的初步基准测试显示可显著节省Tokens:
| 模型 | 使用工具搜索 | 没有 | 储蓄 |
|---|---|---|---|
Gemini |
2,165 个Tokens |
5,375 个Tokens |
60% |
OpenAI |
4,706 个Tokens |
7,175 个Tokens |
34% |
Anthropic |
6,273 个Tokens |
17,342 个Tokens |
64% |
何时使用
| 工具搜索工具方法 | 传统方法 |
|---|---|
您的系统中有 20+ 个工具 |
小型工具库(<20 个工具) |
消耗超过 5K Tokens的工具定义 |
每次会话中经常使用的所有工具 |
构建使用多个服务器的 MCP 驱动系统 |
非常紧凑的工具定义 |
遇到工具选择准确性问题 |
社区资源
-
超棒的 Spring AI - 社区示例和资源
<p>参考文献</p>
-
Anthropic 高级工具使用 - 原始模式描述
-
Spring AI 递归顾问博客 - 工具搜索实现的基础