Tool Search Tool로 동적 도구 탐색하기
Tool Search Tool로 동적 도구 탐색하기 (Dynamic Tool Discovery)
AI 에이전트가 Slack, GitHub, Jira, MCP 서버 같은 더 많은 서비스에 연결될수록 도구 라이브러리는 빠르게 커져요. 일반적인 다중 서버 구성에서는 대화가 시작되기 전에 50개가 넘는 도구가 상당한 토큰을 소모하기 쉽고, 모델이 30개 이상의 비슷한 이름의 도구를 마주하면 선택 정확도도 떨어져요. 이 글에서는 도구 정의를 전부 미리 보내는 대신 모델이 필요할 때 온디맨드로 도구를 찾는 Tool Search Tool 패턴을 다뤄 볼게요.
출처: 문서
본문
Tool Search Tool을 이용한 동적 도구 탐색 (Dynamic Tool Discovery with Tool Search Tool)
AI 에이전트가 Slack, GitHub, Jira, MCP 서버 등 더 많은 서비스에 연결되면서 도구 라이브러리는 빠르게 커져요. 일반적인 다중 서버 구성은 대화가 시작되기 전에도 50개가 넘는 도구가 상당한 토큰을 소모할 수 있어요. 더 나쁜 건, 모델이 30개 이상의 비슷한 이름을 가진 도구를 마주하면 도구 선택 정확도가 떨어진다는 점이에요.
Anthropic이 처음 제안한 Tool Search Tool 패턴은 이 문제를 해결해요. 모든 도구 정의를 미리 로드하는 대신, 모델이 온디맨드로 도구를 발견하는 방식이에요. 처음에는 검색 도구 하나만 받고, 필요할 때 기능을 질의하며, 관련 도구 정의가 컨텍스트에 확장되어 들어오는 구조예요.
Spring AI의 구현은 OpenAI, Anthropic, Gemini 모델에서 34-64%의 토큰 절감을 달성하면서도 수백 개의 도구에 대한 완전한 접근을 유지해요.
소개 (Introduction)
Tool Search Tool은 Spring AI의 Recursive Advisors를 확장해서, Spring AI가 지원하는 모든 LLM provider에서 동작하는 동적 도구 탐색을 구현해요.
주요 이점:
- 토큰 절감 (Token savings) - 발견된 도구 정의만 LLM에 전송돼요.
- 정확도 향상 (Improved accuracy) - 모델이 더 작고 관련성 높은 집합에서 도구를 더 안정적으로 선택해요.
- 확장성 (Scalability) - 컨텍스트 부풀림 없이 수백 개의 도구를 관리할 수 있어요.
- 이식성 (Portability) - OpenAI, Anthropic, Gemini, Ollama 등에서 동작해요.
블로그 포스트 (Blog Post)
📖 전체 튜토리얼: Smart Tool Selection: Achieving 34-64% Token Savings with Spring AI's Dynamic Tool Discovery
이 블로그 포스트는 완전한 구현 세부 정보, 성능 벤치마크, 고급 사용 사례를 다뤄요.
빠른 시작 (Quick Start)
의존성 (Dependencies)
가장 간단한 설정을 위해 Spring Boot starter를 사용해 주세요 (Lucene과 auto-configuration 포함):
- 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를 사용하면 Java 설정 없이 application.properties에서 advisor를 활성화할 수 있어요:
spring.ai.chat.client.tool-search-advisor.enabled=true
전체 구성 프로퍼티와 ToolIndex 선택 옵션은 Tool Search Tool auto-configuration을 참고해 주세요.
또는 수동 @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'
}
기본 사용법 (Basic Usage)
@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
}
}
동작 원리 (How It Works)
ToolSearchToolCallingAdvisor는 Spring AI의 ToolCallingAdvisor를 확장해서 동적 도구 탐색을 구현해요:
- 인덱싱 (Indexing): 대화 시작 시 모든 등록된 도구가
ToolIndex에 인덱싱돼요 (하지만 LLM에는 전송되지 않아요). - 초기 요청 (Initial Request): Tool Search Tool 정의만 LLM에 전송돼요.
- 탐색 호출 (Discovery Call): LLM이 기능이 필요할 때 질의로 검색 도구를 호출해요.
- 검색 및 확장 (Search & Expand):
ToolIndex가 일치하는 도구를 찾고, 그 정의가 다음 요청에 추가돼요. - 도구 호출 (Tool Invocation): LLM은 이제 검색 도구와 발견된 도구 정의를 모두 보게 돼요.
- 도구 실행 (Tool Execution): 발견된 도구가 실행되고 결과가 반환돼요.
- 응답 (Response): LLM이 최종 답변을 생성해요.
검색 전략 (Search Strategies)
ToolIndex 인터페이스는 여러 검색 구현을 지원해요:
| 전략 (Strategy) | 구현 (Implementation) | 가장 적합한 경우 (Best For) |
|---|---|---|
| 시맨틱 (Semantic) | VectorToolIndex |
자연어 질의, 퍼지 매칭 |
| 키워드 (Keyword) | LuceneToolIndex |
정확한 용어 매칭, 알려진 도구 이름 |
| 정규식 (Regex) | RegexToolIndex |
도구 이름 패턴 (get_*_data) |
사용 가능한 모든 구현과 구성 옵션은 Tool Search Tool을 참고해 주세요.
성능 (Performance)
28개 도구를 사용한 예비 벤치마크는 상당한 토큰 절감을 보여 줘요:
| 모델 (Model) | Tool Search 사용 시 (With Tool Search) | 미사용 시 (Without) | 절감 (Savings) |
|---|---|---|---|
| Gemini | 2,165 토큰 | 5,375 토큰 | 60% |
| OpenAI | 4,706 토큰 | 7,175 토큰 | 34% |
| Anthropic | 6,273 토큰 | 17,342 토큰 | 64% |
언제 사용할까 (When to Use)
| Tool Search Tool 방식 (Approach) | 전통적인 방식 (Traditional Approach) |
|---|---|
| 시스템에 20개 이상의 도구가 있을 때 | 작은 도구 라이브러리 (<20개 도구) |
| 도구 정의가 5K 토큰 이상 소모할 때 | 모든 도구를 매 세션에서 자주 사용할 때 |
| 여러 서버를 가진 MCP 기반 시스템을 구축할 때 | 매우 컴팩트한 도구 정의 |
| 도구 선택 정확도 문제를 겪을 때 |
관련 문서 (Related Documentation)
참고 자료 (References)
- Anthropic Advanced Tool Use - 원래 패턴 설명
- Spring AI Recursive Advisors Blog - 도구 검색 구현의 기초