使用 Tool Search Tool 进行动态工具发现
随着 AI 智能体连接更多服务——Slack、GitHub、Jira、MCP servers——工具库会迅速增长。典型的多服务器配置很容易拥有 50+ 个工具,在任何对话开始前就消耗大量 token。更糟糕的是,当模型面对 30+ 个名称相似的工具时,工具选择准确率会下降。
Tool Search Tool 模式,由 Anthropic 首创,解决了这个问题:模型不会预先加载所有工具定义,而是按需发现工具。它最初只接收一个搜索工具,在需要时查询所需能力,并使相关工具定义被展开到上下文中。
Spring AI 的实现 across OpenAI、Anthropic 和 Gemini 模型实现了 34-64% 的 token 减少,同时保持对数百个工具的完整访问。
简介
Tool Search Tool 扩展了 Spring AI 的 Recursive Advisors,以实现动态工具发现,可适用于 Spring AI 支持的 任何 LLM provider。
主要优势:
-
Token 节省 - 仅将发现的工具定义发送给 LLM
-
准确性提升 - 模型可以从更小、更相关的集合中更可靠地选择工具
-
可扩展性 - 管理数百个工具而不会造成上下文膨胀
-
可移植性 - 支持 OpenAI、Anthropic、Gemini、Ollama 等
博客文章
该博客文章涵盖了完整的实现细节、性能基准测试和高级用例。
快速开始
依赖
使用 Spring Boot starter 进行最简单的配置(包含 Lucene 和自动配置):
- Maven
- Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-tool-search-advisor</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-tool-search-advisor'
}
使用 starter,在 application.properties 中启用 advisor —— 无需 Java configuration:
spring.ai.chat.client.tool-search-advisor.enabled=true
完整配置属性和 ToolIndex 选择选项请参见 Tool Search Tool 自动配置。
或者,仅添加用于手动 @Bean 配置的库:
- Maven
- Gradle
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tool-search-advisor</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.ai:spring-ai-tool-search-advisor'
}
基本用法
@SpringBootApplication
public class Application {
@Bean
CommandLineRunner demo(ChatClient.Builder builder, ToolIndex toolIndex) {
return args -> {
var advisor = ToolSearchToolCallingAdvisor.builder()
.toolIndex(toolIndex)
.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
}
}
工作原理
ToolSearchToolCallingAdvisor 扩展了 Spring AI’s ToolCallingAdvisor 以实现动态工具发现:

-
索引:在对话开始时,所有已注册工具都会在
ToolIndex中建立索引(但不会发送给 LLM) -
初始请求:只有 Tool Search Tool 定义会发送给 LLM
-
发现调用:当 LLM 需要某些能力时,它会使用查询调用搜索工具
-
搜索与扩展:
ToolIndex会查找匹配的工具,并将它们的定义添加到下一个请求中 -
工具调用:LLM 此时会同时看到搜索工具和已发现工具的定义
-
工具执行:已发现工具会被执行,并返回结果
-
响应:LLM 生成最终答案
搜索策略
ToolIndex 接口支持多种搜索实现:
| 策略 | 实现 | 适用场景 |
|---|---|---|
| 语义 | VectorToolIndex | 自然语言查询、模糊匹配 |
| 关键词 | LuceneToolIndex | 精确术语匹配、已知工具名称 |
| 正则表达式 | RegexToolIndex | 工具名称模式 (get_*_data) |
有关所有可用的实现和配置选项,请参见 Tool Search Tool。
性能
使用 28 个工具进行的初步基准测试显示,可显著节省 token:
| 模型 | 使用 Tool Search | 无 Tool Search | 节省 |
|---|---|---|---|
| Gemini | 2,165 tokens | 5,375 tokens | 60% |
| OpenAI | 4,706 tokens | 7,175 tokens | 34% |
| Anthropic | 6,273 tokens | 17,342 tokens | 64% |
何时使用
| Tool Search Tool 方案 | 传统方案 |
|---|---|
| 系统中有 20+ 个工具 | 小型工具库(<20 个工具) |
| 工具定义消耗 >5K tokens | 所有工具在每个会话中都经常使用 |
| 构建具有多个服务器的 MCP 驱动系统 | 非常紧凑的工具定义 |
| 遇到工具选择准确性问题 |
相关文档
参考文献
-
Anthropic Advanced Tool Use - 原始模式描述
-
Spring AI Recursive Advisors Blog - 工具搜索实现的基础