본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2026. 2. 2. · 13 Views
Tool Routing & Selection 완벽 가이드
AI 에이전트가 적재적소에 올바른 도구를 선택하고 활용하는 방법을 다룹니다. 도구 라우팅 전략부터 동적 디스커버리까지, 에이전트 시스템의 핵심 메커니즘을 초급 개발자 눈높이에서 설명합니다.
목차
1. 도구 라우팅 전략
김개발 씨는 AI 에이전트 프로젝트를 처음 맡게 되었습니다. 사용자가 "오늘 날씨 알려줘"라고 말하면 날씨 API를 호출하고, "이 코드 설명해줘"라고 하면 코드 분석 도구를 실행해야 합니다.
그런데 어떻게 하면 에이전트가 수십 개의 도구 중에서 적절한 것을 골라낼 수 있을까요?
도구 라우팅은 사용자의 요청을 분석하여 가장 적합한 도구로 연결해주는 전략입니다. 마치 대형 병원의 접수 창구에서 환자의 증상을 듣고 적절한 진료과로 안내하는 것과 같습니다.
올바른 라우팅 전략이 없다면 에이전트는 매번 엉뚱한 도구를 선택하거나, 모든 도구를 일일이 확인하느라 시간을 낭비하게 됩니다.
다음 코드를 살펴봅시다.
class ToolRouter:
def __init__(self):
# 도구를 카테고리별로 분류합니다
self.routes = {
"weather": ["get_weather", "get_forecast"],
"code": ["analyze_code", "execute_code"],
"search": ["web_search", "document_search"]
}
self.classifier = IntentClassifier()
def route(self, user_query: str) -> list[str]:
# 사용자 의도를 파악합니다
intent = self.classifier.classify(user_query)
# 해당 의도에 맞는 도구 목록을 반환합니다
return self.routes.get(intent, ["general_assistant"])
김개발 씨는 입사 3개월 차 주니어 개발자입니다. 최근 회사에서 AI 챗봇 프로젝트를 진행하게 되었는데, 문제가 생겼습니다.
챗봇에 연결된 도구가 무려 50개나 되는데, 사용자가 질문할 때마다 어떤 도구를 써야 할지 에이전트가 헤매고 있었습니다. 선배 개발자 박시니어 씨가 코드를 살펴보더니 말했습니다.
"아, 라우팅 전략이 없구나. 이러면 에이전트가 매번 모든 도구를 훑어봐야 해서 느려질 수밖에 없어." 그렇다면 도구 라우팅이란 정확히 무엇일까요?
쉽게 비유하자면, 도구 라우팅은 마치 대형 백화점의 안내 데스크와 같습니다. 고객이 "화장품 사러 왔어요"라고 하면 1층으로, "가전제품 보러 왔어요"라고 하면 5층으로 안내해주죠.
모든 층을 돌아다니게 하지 않습니다. 도구 라우팅도 마찬가지로 사용자의 요청을 빠르게 파악해서 적절한 도구 그룹으로 안내합니다.
라우팅 전략이 없던 시절에는 어땠을까요? 에이전트는 사용자의 모든 요청에 대해 50개의 도구를 일일이 검토해야 했습니다.
"이 도구가 맞나? 저 도구가 맞나?" 하나씩 확인하다 보니 응답 시간이 길어졌습니다.
더 큰 문제는 비용이었습니다. LLM에게 50개 도구의 설명을 매번 전달하면 토큰 사용량이 급증했습니다.
바로 이런 문제를 해결하기 위해 도구 라우팅 전략이 등장했습니다. 핵심 아이디어는 간단합니다.
먼저 사용자의 의도를 파악하고, 그 의도에 해당하는 도구 그룹만 에이전트에게 전달하는 것입니다. 날씨를 물어보면 날씨 관련 도구 2~3개만, 코드 질문이면 코드 관련 도구만 보여주는 식이죠.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 routes 딕셔너리를 보면 도구들이 카테고리별로 분류되어 있습니다.
weather, code, search 같은 키 아래에 관련 도구들이 리스트로 묶여 있죠. 다음으로 route 메서드에서는 IntentClassifier를 사용해 사용자 의도를 파악합니다.
마지막으로 파악된 의도에 해당하는 도구 목록을 반환합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 고객 서비스 챗봇을 개발한다고 가정해봅시다. 주문 조회, 환불 요청, 배송 추적, 상품 문의 등 다양한 기능이 필요합니다.
이때 라우팅 전략을 사용하면 "주문 어디까지 왔어요?"라는 질문에 배송 관련 도구만 활성화되어 빠르게 응답할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 카테고리를 너무 세분화하는 것입니다. 카테고리가 100개가 되면 의도 분류 자체가 어려워집니다.
따라서 5~10개 정도의 큰 범주로 시작해서 필요에 따라 확장하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 조언대로 라우팅 전략을 적용한 뒤, 챗봇의 응답 속도가 3배나 빨라졌습니다. "아, 그래서 그랬군요!" 김개발 씨는 환하게 웃었습니다.
실전 팁
💡 - 카테고리는 5~10개로 시작하고, 사용 패턴을 보며 점진적으로 확장하세요
- 의도 분류기는 간단한 키워드 매칭부터 시작해도 충분합니다
- 어느 카테고리에도 속하지 않는 요청을 위한 기본 도구를 반드시 준비하세요
2. 컨텍스트 기반 도구 선택
김개발 씨가 만든 챗봇에 새로운 문제가 생겼습니다. 같은 "검색해줘"라는 요청인데, 어떤 사용자는 웹 검색을 원하고 어떤 사용자는 사내 문서 검색을 원했습니다.
단순히 키워드만 보고 도구를 선택하면 안 된다는 것을 깨달았습니다.
컨텍스트 기반 도구 선택은 사용자의 현재 상황, 이전 대화 내용, 환경 정보 등을 종합적으로 고려하여 도구를 선택하는 방식입니다. 마치 단골 카페 바리스타가 손님의 취향을 기억하고 "오늘도 아이스 아메리카노 드릴까요?"라고 묻는 것처럼, 에이전트도 맥락을 파악해야 합니다.
다음 코드를 살펴봅시다.
class ContextAwareSelector:
def __init__(self, tools: list[Tool]):
self.tools = tools
self.conversation_history = []
def select_tool(self, query: str, context: dict) -> Tool:
# 컨텍스트 정보를 수집합니다
enriched_context = {
"query": query,
"user_role": context.get("user_role", "general"),
"previous_tool": self._get_last_tool(),
"session_topic": self._infer_topic(),
"time_of_day": context.get("time", "daytime")
}
# 각 도구의 적합도 점수를 계산합니다
scores = [tool.calculate_relevance(enriched_context) for tool in self.tools]
return self.tools[scores.index(max(scores))]
김개발 씨는 고객지원 챗봇을 운영하던 중 이상한 민원을 받았습니다. "분명히 검색해달라고 했는데 왜 엉뚱한 결과가 나와요?" 확인해보니 개발팀 직원이 기술 문서를 찾으려고 한 건데, 챗봇이 일반 웹 검색을 실행한 것이었습니다.
박시니어 씨가 말했습니다. "라우팅만으로는 부족해.
누가, 어떤 상황에서, 무엇을 원하는지 맥락을 봐야 해." 그렇다면 컨텍스트 기반 도구 선택이란 무엇일까요? 쉽게 비유하자면, 이것은 마치 오랜 친구와 대화하는 것과 같습니다.
친구가 "그거 어땠어?"라고만 물어도 최근에 무슨 얘기를 했는지 기억하고 있으니 무슨 뜻인지 알죠. 에이전트도 대화의 흐름, 사용자의 역할, 이전에 사용한 도구 등을 기억하면 더 정확한 선택을 할 수 있습니다.
맥락을 무시하던 시절에는 어땠을까요? 매번 같은 질문에 같은 도구만 사용했습니다.
개발자가 "로그 확인해줘"라고 하면 시스템 로그를 보여줘야 하는데, 마케팅 담당자가 같은 말을 하면 분석 대시보드를 보여줘야 합니다. 맥락 없이는 이런 구분이 불가능했습니다.
바로 이런 한계를 극복하기 위해 컨텍스트 인식 선택 방식이 등장했습니다. 핵심은 여러 정보를 조합하는 것입니다.
사용자가 누구인지, 이전에 어떤 도구를 썼는지, 현재 대화 주제가 무엇인지, 심지어 시간대까지 고려할 수 있습니다. 이 모든 정보를 종합해서 각 도구의 적합도 점수를 계산합니다.
위의 코드를 살펴보겠습니다. enriched_context 딕셔너리에서 다양한 맥락 정보를 수집하는 것을 볼 수 있습니다.
사용자 역할, 이전에 사용한 도구, 세션의 주제, 시간대 정보까지 담깁니다. 그런 다음 각 도구에 대해 calculate_relevance 메서드로 적합도를 계산하고, 가장 높은 점수를 받은 도구를 선택합니다.
실제 현업에서는 이를 어떻게 활용할까요? 금융 서비스 챗봇을 예로 들어봅시다.
VIP 고객이 "계좌 확인"이라고 하면 프리미엄 서비스 도구를, 일반 고객이면 기본 조회 도구를 사용합니다. 또한 이전 대화에서 해외 송금 얘기를 했다면 "확인"이라는 단어만으로도 송금 상태 조회 도구를 선택할 수 있습니다.
하지만 주의할 점이 있습니다. 컨텍스트를 너무 많이 고려하면 오히려 역효과가 납니다.
이전에 날씨를 물었다고 해서 그 다음 모든 질문에 날씨 도구를 우선시하면 안 됩니다. 적절한 가중치 설정이 중요합니다.
김개발 씨는 컨텍스트 기반 선택을 적용한 후, 사용자 만족도가 크게 올라간 것을 확인했습니다. "맥락을 이해하니까 훨씬 자연스러워졌네요!"
실전 팁
💡 - 모든 컨텍스트가 똑같이 중요하지 않습니다. 가중치를 실험적으로 조정하세요
- 대화 히스토리는 최근 5~10개 턴만 유지해도 충분합니다
- 사용자 역할 정보는 도구 선택에 매우 강력한 신호입니다
3. 도구 성능 측정
어느 날 박시니어 씨가 김개발 씨에게 물었습니다. "자네가 연결한 도구들 중에서 어떤 게 제일 잘 작동하는지 알아?" 김개발 씨는 대답하지 못했습니다.
도구를 연결하기만 했지, 어떤 도구가 얼마나 효과적인지 측정해본 적이 없었기 때문입니다.
도구 성능 측정은 각 도구의 응답 시간, 성공률, 정확도 등을 지속적으로 모니터링하고 기록하는 것입니다. 마치 프로 스포츠팀이 선수들의 경기 기록을 분석해서 최적의 라인업을 구성하듯, 에이전트도 도구들의 성적표를 관리해야 합니다.
다음 코드를 살펴봅시다.
class ToolPerformanceTracker:
def __init__(self):
self.metrics = defaultdict(lambda: {
"total_calls": 0, "success_count": 0,
"total_latency": 0, "error_types": Counter()
})
def record_execution(self, tool_name: str, result: ToolResult):
# 실행 결과를 기록합니다
metrics = self.metrics[tool_name]
metrics["total_calls"] += 1
metrics["total_latency"] += result.latency_ms
if result.success:
metrics["success_count"] += 1
else:
metrics["error_types"][result.error_type] += 1
def get_success_rate(self, tool_name: str) -> float:
m = self.metrics[tool_name]
return m["success_count"] / max(m["total_calls"], 1)
김개발 씨의 챗봇이 운영된 지 한 달이 지났습니다. 대체로 잘 작동했지만, 가끔 특정 질문에 대한 응답이 유난히 느렸습니다.
어디가 문제인지 알 수가 없었습니다. 박시니어 씨가 조언했습니다.
"측정하지 않으면 개선할 수 없어. 각 도구가 얼마나 잘 작동하는지 기록해야 해." 그렇다면 도구 성능 측정이란 무엇일까요?
쉽게 비유하자면, 이것은 마치 자동차 계기판과 같습니다. 속도계, 연료계, 엔진 온도계가 있어야 운전자가 차의 상태를 파악하고 문제가 생기면 바로 알 수 있죠.
도구 성능 측정도 에이전트 시스템의 계기판 역할을 합니다. 성능을 측정하지 않던 시절에는 어땠을까요?
문제가 생겨도 어디서 발생했는지 알기 어려웠습니다. 사용자가 "챗봇이 느려요"라고 불만을 제기해도, 50개 도구 중 어떤 것이 원인인지 찾아내려면 오랜 시간이 걸렸습니다.
더 나쁜 경우, 특정 도구가 계속 실패하는데도 모르고 사용하는 일이 벌어졌습니다. 바로 이런 상황을 방지하기 위해 성능 추적 시스템이 필요합니다.
핵심 지표는 크게 세 가지입니다. 첫째, 성공률입니다.
도구가 오류 없이 정상적으로 결과를 반환하는 비율이죠. 둘째, 응답 시간입니다.
도구가 결과를 반환하기까지 걸리는 시간입니다. 셋째, 에러 유형입니다.
실패할 때 어떤 종류의 에러가 발생하는지 분류합니다. 위의 코드를 살펴보겠습니다.
record_execution 메서드에서 매 실행마다 결과를 기록합니다. 총 호출 횟수, 성공 횟수, 누적 응답 시간, 에러 유형별 카운트를 저장합니다.
get_success_rate 메서드는 이 데이터를 바탕으로 성공률을 계산해줍니다. 실제 현업에서는 이를 어떻게 활용할까요?
대규모 서비스에서는 이 데이터를 대시보드로 시각화합니다. 특정 도구의 성공률이 90% 아래로 떨어지면 알림을 보내고, 자동으로 해당 도구 사용을 줄이기도 합니다.
또한 성능 데이터를 분석해서 어떤 유형의 요청에 어떤 도구가 가장 효과적인지 파악할 수 있습니다. 하지만 주의할 점이 있습니다.
측정 자체가 성능에 영향을 주면 안 됩니다. 너무 많은 데이터를 저장하거나 복잡한 계산을 실시간으로 하면 오히려 시스템이 느려집니다.
핵심 지표만 가볍게 수집하는 것이 좋습니다. 김개발 씨는 성능 측정을 도입한 후, 특정 외부 API 도구가 유난히 느리다는 것을 발견했습니다.
해당 도구를 최적화하자 전체 응답 시간이 40% 개선되었습니다.
실전 팁
💡 - 핵심 지표 3개(성공률, 응답시간, 에러율)만 측정해도 충분합니다
- 지표는 시계열로 저장해서 추이를 파악할 수 있게 하세요
- 임계치를 설정하고 알림을 자동화하면 문제를 빠르게 발견할 수 있습니다
4. 폴백 및 대체 도구
금요일 저녁, 김개발 씨의 챗봇이 갑자기 먹통이 되었습니다. 알고 보니 날씨 API 서버가 다운된 것이었습니다.
"오늘 날씨 어때?"라는 단순한 질문에도 에러가 발생하니 사용자들의 불만이 쏟아졌습니다. 하나의 외부 서비스에 의존하면 안 된다는 교훈을 얻었습니다.
폴백 및 대체 도구는 주 도구가 실패했을 때 자동으로 백업 도구로 전환하는 메커니즘입니다. 마치 비행기에 여러 개의 엔진이 있어서 하나가 고장 나도 비행을 계속할 수 있는 것처럼, 에이전트도 대안을 준비해둬야 합니다.
다음 코드를 살펴봅시다.
class FallbackToolExecutor:
def __init__(self):
# 도구별 대체 도구 목록을 정의합니다
self.fallback_chain = {
"weather_api_v2": ["weather_api_v1", "web_search_weather"],
"code_executor": ["sandbox_executor", "static_analyzer"],
"database_query": ["cache_lookup", "fallback_response"]
}
async def execute_with_fallback(self, tool_name: str, params: dict) -> Result:
tools_to_try = [tool_name] + self.fallback_chain.get(tool_name, [])
for tool in tools_to_try:
try:
result = await self.execute_tool(tool, params)
if result.success:
return result
except ToolException as e:
logger.warning(f"{tool} failed: {e}, trying next")
return Result(success=False, message="All fallbacks exhausted")
김개발 씨는 그 금요일 밤을 잊을 수가 없습니다. 외부 API 하나가 다운되었을 뿐인데 전체 서비스가 마비되었습니다.
주말 내내 사과 메일을 보내야 했죠. 월요일 아침, 박시니어 씨가 말했습니다.
"외부 서비스는 언제든 장애가 날 수 있어. 항상 플랜 B를 준비해둬야 해." 그렇다면 폴백 메커니즘이란 무엇일까요?
쉽게 비유하자면, 이것은 마치 출근길의 대체 경로와 같습니다. 평소에는 지하철을 타지만, 파업이 있으면 버스를, 버스도 안 되면 택시를 탑니다.
목적지에 도착하는 것이 중요하지, 반드시 특정 수단을 써야 하는 것은 아닙니다. 폴백이 없던 시절에는 어땠을까요?
하나의 도구에만 의존했기 때문에 그 도구가 실패하면 전체 기능이 중단되었습니다. 사용자는 "잠시 후 다시 시도해주세요"라는 메시지만 보게 되었죠.
특히 외부 API에 의존하는 경우, 우리가 통제할 수 없는 이유로 서비스가 중단되는 일이 빈번했습니다. 바로 이런 위험을 줄이기 위해 폴백 체인을 구성합니다.
핵심 아이디어는 도구들을 우선순위대로 나열하는 것입니다. 첫 번째 도구가 실패하면 두 번째, 두 번째도 실패하면 세 번째 도구를 시도합니다.
모든 대안이 실패하면 그때서야 에러를 반환하거나, 최소한의 응답이라도 제공합니다. 위의 코드를 살펴보겠습니다.
fallback_chain 딕셔너리에서 각 주 도구에 대한 대체 도구 목록을 정의합니다. execute_with_fallback 메서드에서는 주 도구부터 시작해서 대체 도구들을 순차적으로 시도합니다.
하나라도 성공하면 즉시 결과를 반환하고, 실패하면 다음 도구로 넘어갑니다. 실제 현업에서는 이를 어떻게 활용할까요?
결제 시스템을 예로 들어봅시다. 주 결제 게이트웨이가 실패하면 보조 게이트웨이로 전환합니다.
검색 기능에서는 실시간 검색 API가 느리면 캐시된 결과라도 보여줍니다. 이렇게 하면 완벽하지 않더라도 사용자에게 최소한의 서비스는 제공할 수 있습니다.
하지만 주의할 점이 있습니다. 폴백 도구는 주 도구와 같은 수준의 품질을 보장하지 않을 수 있습니다.
사용자에게 폴백 결과임을 알려주거나, 품질 저하에 대해 양해를 구하는 것이 좋습니다. 또한 폴백 체인이 너무 길면 전체 응답 시간이 늘어날 수 있습니다.
김개발 씨는 폴백 시스템을 구축한 후, 비슷한 장애가 발생해도 서비스가 멈추지 않게 되었습니다. "이제 주말에도 마음 편히 쉴 수 있겠어요!"
실전 팁
💡 - 폴백 도구는 주 도구와 동일한 입출력 형식을 유지하세요
- 타임아웃을 설정해서 느린 도구에 너무 오래 기다리지 않도록 하세요
- 최후의 폴백으로 캐시된 응답이나 정적 메시지라도 준비해두세요
5. 도구 조합 최적화
김개발 씨는 새로운 기능을 추가하려고 합니다. 사용자가 "이번 주 서울 날씨 알려주고, 좋은 날에 갈 만한 맛집도 추천해줘"라고 하면 날씨 도구와 맛집 도구를 함께 사용해야 합니다.
그런데 어떤 순서로, 어떻게 조합해야 효율적일까요?
도구 조합 최적화는 여러 도구를 함께 사용할 때 최적의 실행 순서와 병렬 처리 전략을 결정하는 것입니다. 마치 요리사가 여러 재료를 준비할 때 삶는 동안 다른 재료를 썰어두는 것처럼, 도구들도 효율적으로 조합하면 전체 처리 시간을 크게 줄일 수 있습니다.
다음 코드를 살펴봅시다.
class ToolOrchestrator:
def __init__(self):
self.dependency_graph = {}
async def execute_optimized(self, tool_calls: list[ToolCall]) -> list[Result]:
# 의존성을 분석하여 실행 계획을 수립합니다
execution_plan = self._build_execution_plan(tool_calls)
results = {}
for stage in execution_plan:
# 같은 단계의 도구들은 병렬로 실행합니다
stage_tasks = [
self._execute_single(call, results) for call in stage
]
stage_results = await asyncio.gather(*stage_tasks)
for call, result in zip(stage, stage_results):
results[call.id] = result
return list(results.values())
김개발 씨의 챗봇이 점점 인기를 얻으면서 복잡한 요청이 늘어났습니다. 사용자들은 한 번에 여러 가지를 물어보곤 했습니다.
그런데 도구를 하나씩 순차적으로 실행하다 보니 응답이 너무 느렸습니다. 박시니어 씨가 코드를 보더니 말했습니다.
"이 도구들은 서로 의존성이 없잖아. 왜 하나씩 기다리면서 실행해?" 그렇다면 도구 조합 최적화란 무엇일까요?
쉽게 비유하자면, 이것은 마치 식당 주방의 동선과 같습니다. 숙련된 주방장은 파스타 면을 삶는 동안 소스를 만들고, 샐러드를 준비합니다.
면이 다 삶아지기를 가만히 기다리지 않죠. 도구 조합 최적화도 이처럼 동시에 할 수 있는 작업은 병렬로 처리합니다.
최적화 없이 순차 실행만 하던 시절에는 어땠을까요? 날씨 조회에 2초, 맛집 검색에 3초, 교통 정보에 2초가 걸린다면 총 7초를 기다려야 했습니다.
사용자에게 7초는 매우 긴 시간입니다. 복잡한 요청일수록 응답 시간이 선형적으로 증가해서 사용자 경험이 나빠졌습니다.
바로 이런 문제를 해결하기 위해 실행 계획 최적화가 필요합니다. 핵심 원리는 의존성 분석입니다.
도구 A의 결과가 도구 B에 필요하다면 A를 먼저 실행해야 합니다. 하지만 A와 C가 서로 독립적이라면 동시에 실행할 수 있습니다.
이렇게 의존성 그래프를 분석해서 단계별 실행 계획을 세웁니다. 위의 코드를 살펴보겠습니다.
_build_execution_plan 메서드가 도구 호출들의 의존성을 분석해서 단계별로 묶습니다. 그런 다음 각 단계 내의 도구들은 asyncio.gather로 병렬 실행합니다.
한 단계가 완료되면 그 결과를 다음 단계에서 사용할 수 있도록 저장합니다. 실제 현업에서는 이를 어떻게 활용할까요?
여행 플래너 챗봇을 생각해봅시다. 사용자가 "도쿄 3박 4일 여행 계획 짜줘"라고 하면 항공권 검색, 호텔 검색, 관광지 추천, 환율 조회 등 여러 도구가 필요합니다.
이 중 항공권과 호텔은 병렬로 검색하고, 관광지 추천은 날짜가 확정된 후에 실행합니다. 하지만 주의할 점이 있습니다.
무조건 병렬화한다고 좋은 것은 아닙니다. 너무 많은 동시 요청은 외부 API의 속도 제한에 걸리거나 시스템 리소스를 고갈시킬 수 있습니다.
적절한 동시 실행 개수를 제한하는 것이 좋습니다. 김개발 씨는 도구 조합을 최적화한 후, 복잡한 요청의 응답 시간이 절반으로 줄어든 것을 확인했습니다.
"병렬 처리의 힘이 이렇게 대단하군요!"
실전 팁
💡 - 의존성 그래프는 시각화해두면 디버깅할 때 유용합니다
- 동시 실행 개수에 상한선을 두어 리소스 고갈을 방지하세요
- 가장 오래 걸리는 도구를 먼저 시작하면 전체 시간이 단축됩니다
6. 동적 도구 디스커버리
회사가 성장하면서 새로운 팀들이 자체 도구를 만들기 시작했습니다. 마케팅팀의 분석 도구, 운영팀의 모니터링 도구, 재무팀의 보고서 도구...
김개발 씨는 매번 새 도구가 추가될 때마다 에이전트 코드를 수정해야 했습니다. "더 좋은 방법이 없을까요?"
동적 도구 디스커버리는 에이전트가 실행 중에 새로운 도구를 자동으로 발견하고 등록하는 메커니즘입니다. 마치 스마트폰의 앱스토어처럼 새 앱이 올라오면 바로 설치해서 사용할 수 있는 것처럼, 에이전트도 새 도구를 동적으로 인식하고 활용할 수 있습니다.
다음 코드를 살펴봅시다.
class DynamicToolRegistry:
def __init__(self):
self.tools = {}
self.discovery_sources = []
async def discover_tools(self):
# 등록된 모든 소스에서 도구를 검색합니다
for source in self.discovery_sources:
new_tools = await source.fetch_available_tools()
for tool in new_tools:
# 도구 스키마를 검증하고 등록합니다
if self._validate_schema(tool):
self.tools[tool.name] = tool
logger.info(f"Discovered new tool: {tool.name}")
def register_source(self, source: ToolSource):
# 새로운 도구 제공 소스를 등록합니다
self.discovery_sources.append(source)
def get_tool(self, name: str) -> Tool | None:
return self.tools.get(name)
김개발 씨의 회사는 빠르게 성장하고 있었습니다. 매주 새로운 내부 도구가 만들어지고, 외부 서비스도 추가되었습니다.
그때마다 에이전트 코드에 도구를 하드코딩하고 배포하는 작업이 반복되었습니다. 어느 날 박시니어 씨가 말했습니다.
"도구가 100개가 되면 어떡할 거야? 매번 코드를 수정할 수는 없잖아." 그렇다면 동적 도구 디스커버리란 무엇일까요?
쉽게 비유하자면, 이것은 마치 플러그 앤 플레이와 같습니다. USB 장치를 컴퓨터에 꽂으면 자동으로 인식되어 바로 사용할 수 있죠.
별도로 드라이버를 설치하거나 설정 파일을 수정할 필요가 없습니다. 동적 디스커버리도 마찬가지로 새 도구가 등록되면 에이전트가 자동으로 인식합니다.
하드코딩하던 시절에는 어땠을까요? 새 도구가 추가될 때마다 개발자가 직접 코드를 수정했습니다.
도구 이름, 설명, 파라미터 스키마를 일일이 입력하고, 테스트하고, 배포했습니다. 도구가 많아질수록 관리가 어려워졌고, 실수로 설정을 잘못 입력하는 일도 생겼습니다.
바로 이런 번거로움을 해결하기 위해 자동 디스커버리 시스템이 등장했습니다. 핵심 원리는 표준화된 인터페이스입니다.
모든 도구가 같은 형식으로 자신을 설명하도록 합니다. 이름, 설명, 입력 파라미터, 출력 형식 등을 정해진 스키마에 따라 제공하면 에이전트가 이를 읽고 자동으로 등록합니다.
위의 코드를 살펴보겠습니다. DynamicToolRegistry 클래스는 도구들을 관리합니다.
register_source 메서드로 도구를 제공하는 소스를 등록합니다. 소스는 내부 API 서버일 수도 있고, 외부 서비스 카탈로그일 수도 있습니다.
discover_tools 메서드는 모든 소스를 순회하며 사용 가능한 도구를 가져와서 스키마를 검증한 후 등록합니다. 실제 현업에서는 이를 어떻게 활용할까요?
대기업의 내부 플랫폼을 생각해봅시다. 각 팀이 만든 마이크로서비스들이 API 게이트웨이에 자동 등록됩니다.
AI 에이전트는 주기적으로 이 게이트웨이를 조회해서 새로운 서비스를 발견합니다. 인사팀이 새 휴가 조회 API를 배포하면 에이전트가 자동으로 "휴가 몇 일 남았어?" 같은 질문에 답할 수 있게 됩니다.
하지만 주의할 점이 있습니다. 자동으로 도구가 추가된다는 것은 보안 위험이 될 수 있습니다.
악의적인 도구가 등록되면 에이전트가 이를 실행할 수 있습니다. 따라서 도구 등록 전에 반드시 검증 과정을 거쳐야 합니다.
승인된 소스에서만 도구를 가져오고, 스키마 검증을 엄격히 하세요. 김개발 씨는 동적 디스커버리를 도입한 후, 새 도구 추가에 드는 시간이 90% 줄었습니다.
"이제 각 팀이 도구를 직접 등록할 수 있으니 훨씬 편해졌어요!"
실전 팁
💡 - 도구 스키마는 OpenAPI나 JSON Schema 같은 표준을 사용하세요
- 도구 등록 시 권한 검증과 승인 프로세스를 반드시 포함하세요
- 주기적인 디스커버리와 이벤트 기반 디스커버리를 병행하면 더 효과적입니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
vLLM 통합 완벽 가이드
대규모 언어 모델 추론을 획기적으로 가속화하는 vLLM의 설치부터 실전 서비스 구축까지 다룹니다. PagedAttention과 연속 배칭 기술로 GPU 메모리를 효율적으로 활용하는 방법을 배웁니다.
Web UI Demo 구축 완벽 가이드
Gradio를 활용하여 머신러닝 모델과 AI 서비스를 위한 웹 인터페이스를 구축하는 방법을 다룹니다. 코드 몇 줄만으로 전문적인 데모 페이지를 만들고 배포하는 과정을 초급자도 쉽게 따라할 수 있도록 설명합니다.
Sandboxing & Execution Control 완벽 가이드
AI 에이전트가 코드를 실행할 때 반드시 필요한 보안 기술인 샌드박싱과 실행 제어에 대해 알아봅니다. 격리된 환경에서 안전하게 코드를 실행하고, 악성 동작을 탐지하는 방법을 단계별로 설명합니다.
Voice Design then Clone 워크플로우 완벽 가이드
AI 음성 합성에서 일관된 캐릭터 음성을 만드는 Voice Design then Clone 워크플로우를 설명합니다. 참조 음성 생성부터 재사용 가능한 캐릭터 구축까지 실무 활용법을 다룹니다.
Tool Use 완벽 가이드 - Shell, Browser, DB 실전 활용
AI 에이전트가 외부 도구를 활용하여 셸 명령어 실행, 브라우저 자동화, 데이터베이스 접근 등을 수행하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 패턴과 베스트 프랙티스를 담았습니다.