跳到主要内容
版本:2.0.1

使用 Tool Search Tool 进行动态工具发现

QWen Max 中英对照 Dynamic Tool Discovery Dynamic Tool Discovery with 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 和自动配置):

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-tool-search-advisor</artifactId>
</dependency>

使用 starter,在 application.properties 中启用 advisor —— 无需 Java configuration:

spring.ai.chat.client.tool-search-advisor.enabled=true

完整配置属性和 ToolIndex 选择选项请参见 Tool Search Tool 自动配置。

或者,仅添加用于手动 @Bean 配置的库:

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tool-search-advisor</artifactId>
</dependency>

基本用法​

@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 以实现动态工具发现:

Tool Search Tool 流程

  1. 索引:在对话开始时,所有已注册工具都会在 ToolIndex 中建立索引(但不会发送给 LLM)

  2. 初始请求:只有 Tool Search Tool 定义会发送给 LLM

  3. 发现调用:当 LLM 需要某些能力时,它会使用查询调用搜索工具

  4. 搜索与扩展:ToolIndex 会查找匹配的工具,并将它们的定义添加到下一个请求中

  5. 工具调用:LLM 此时会同时看到搜索工具和已发现工具的定义

  6. 工具执行:已发现工具会被执行,并返回结果

  7. 响应:LLM 生成最终答案

搜索策略​

ToolIndex 接口支持多种搜索实现:

策略实现适用场景
语义VectorToolIndex自然语言查询、模糊匹配
关键词LuceneToolIndex精确术语匹配、已知工具名称
正则表达式RegexToolIndex工具名称模式 (get_*_data)

有关所有可用的实现和配置选项,请参见 Tool Search Tool。

性能​

使用 28 个工具进行的初步基准测试显示,可显著节省 token:

模型使用 Tool Search无 Tool Search节省
Gemini2,165 tokens5,375 tokens60%
OpenAI4,706 tokens7,175 tokens34%
Anthropic6,273 tokens17,342 tokens64%

何时使用​

Tool Search Tool 方案传统方案
系统中有 20+ 个工具小型工具库(<20 个工具)
工具定义消耗 >5K tokens所有工具在每个会话中都经常使用
构建具有多个服务器的 MCP 驱动系统非常紧凑的工具定义
遇到工具选择准确性问题

参考文献​