MCP tool design: Practical approaches and tradeoffs
Author: Daniel Wells, Raian Osman (AWS) | Source: AWS ML Blog | Published: 2026-07-10
한 줄 요약
MCP 툴이 부진할 때 원인은 프로토콜이 아니라 툴 설계이며, 거의 모든 실패가 bloat(정의가 컨텍스트를 먹음) 와 confusion(모델이 잘못 고름) 두 축의 균형 문제로 환원된다 — 하나를 고치면 다른 하나가 나빠지는 구조.
핵심 주장/내용
- 기존 API를 그대로 노출하고 에이전트가 알아서 하길 기대하는 것이 자연스러운 출발이고 단순한 케이스에서는 통하지만, 자주 통하지 않는다. 실패한 툴 콜, 잘못된 파라미터 값, 컨텍스트를 낭비하고 성능을 떨어뜨리는 재시도로 이어진다
- 두 가지 근본 문제:
- bloat — 툴 정의는 사용 여부와 무관하게 매 호출마다 LLM 컨텍스트에 로드된다. MCP 서버 여러 개가 연결되면 사용자가 질문 하나 하기 전에 상당한 컨텍스트가 소모된다. 컨텍스트가 차면 추론 능력이 저하된다(context rot)
- confusion — 추론이 저하되면 잘못된 툴을 고르고 잘못된 파라미터를 고른다. 재시도가 bloat를 더 키워 문제를 복리로 만든다. 툴 간 의미론적 유사성, 너무 많은 선택지, 모호한 이름도 기여
- 흔한 해법은 설명을 풍부하게 하는 것이고 confusion에는 도움이 되지만, 추가하는 모든 것이 bloat를 악화시켜 해결하려던 문제를 키운다
- 6가지 접근과 트레이드오프 (동일한 K-12 콘텐츠 검색 백엔드, 14개 필터 필드 위에 각각 다른 툴 설계):
| 버전 | 접근 | 트레이드오프 |
|---|---|---|
| V1 | Raw passthrough (baseline anti-pattern) | 정의는 작지만 유효값 안내가 없어 churn으로 실제 비용이 올라감 |
| V2 | Rich descriptions (유효값 + 동의어 매핑) | 정확도 ↑, 정의 커짐 |
| V3 | Schema + defaults (rename, enum, 기본값) | 정확도 ↑ 하면서 정의는 오히려 작아짐 |
| V4 | Restructuring + lazy loading (get_taxonomy 분리) | 가장 가벼운 baseline, 추가 왕복 |
| V5 | Server-side introspection (자체 LLM) | 모호성 처리, 추론 비용 지불 |
| V6 | Agent-as-tool | 직접 통제, 인프라 비용 최고 |
- descriptions & responses: 툴이 결과당 50필드를 반환하면 컨텍스트가 빨리 찬다. 결정에 5개면 충분하면 기본 응답을 그것으로 하고 상세 뷰는 별도 옵션으로. 좋은 에러 메시지도 효율의 일부 — “search requires 2 or more terms in query”는 다음 시도를 정확히 안내하지만 “no results”만 주면 모델은 포기하거나 계속 추측한다
- schema constraints — 설명이 유도한다면 스키마는 추측 자체를 없앤다:
- 파라미터 이름을 DB 컬럼 라벨이 아니라 LLM이 도메인을 이해하는 방식에 맞춰 rename (
content_bucket→resource_class) - 가장 흔한 값을 기본값으로 두어 LLM이 달라지는 것만 명시하게
- 유한값 필드는 enum(
Literal)으로 제약 — 스키마 자체가 유효값을 말한다 - 거의 안 쓰이거나 LLM이 잘 못 쓰는 필드는 삭제. AWS 권고는 툴 파라미터를 8개 이하로
- V3의 응답에
defaults_applied필드를 포함해 LLM이 무엇이 암묵적으로 필터됐는지 알게 함
- 파라미터 이름을 DB 컬럼 라벨이 아니라 LLM이 도메인을 이해하는 방식에 맞춰 rename (
- lazy loading: 항상 로드되는 컨텍스트에서 복잡한 설명을 빼고 온디맨드 조회용 별도 툴로. V4는 검색 툴에 짧은 힌트만 남기고
get_taxonomy가 현재 쿼리에 관련된 필드의 유효값·자연어 매핑만 반환. 모호한 쿼리면 taxonomy를 먼저 부르고, 힌트로 충분한 직관적 쿼리면 건너뛴다. Skills는 클라이언트 측 lazy loading이지만 필요할 때 로드된다는 보장도, 설치 후 변하지 않는다는 보장도 없다 - server-side inference: 내 지시를 어떤 모델이 해석할지 통제할 수 없다는 게 context engineering의 난점. 한 모델에 맞춰 튠한 설명이 다른 모델을 혼란시킬 수 있고 모든 후보 모델을 테스트하는 건 비현실적. introspection 툴이 외부 LLM을 직접 호출해 자연어 질의에 대해 다른 툴 사용법을 반환 — 내가 모델을 고르므로 프롬프트 엔지니어링과 golden query 테스트가 신뢰할 만하다. 최종 툴 콜은 여전히 클라이언트 LLM이 하지만 해석은 서버 측이라 컨텍스트가 가볍게 유지된다. 용도가 좁으므로 작고 빠른 모델로 충분
- agentic tool: MCP 서버 전체를 내 에이전트로 백킹. 툴이 클라이언트에게는 자연어 엔드포인트가 된다. V6는 파라미터 하나짜리 툴 하나(
agentic_search_content(question))만 노출하고 taxonomy 조회·검색·상세 조회·응답 포매팅은 클라이언트가 보지 못하는 내부 툴로 처리. 대화 히스토리가 호출 간 유지되어 후속 질문이 자연스럽고, 어떤 클라이언트 모델이 붙어도 동작이 일관
주요 수치 / 사실
- Anthropic 연구: 상세 출력을 온디맨드로 전환하면 응답 토큰 약 2/3 감소
- Anthropic: 관련 있을 때만 툴 정의를 로드하면 최대 85% 토큰 감소 (Tool Search Tool, Bedrock AgentCore Gateway가 같은 개념의 대규모 적용)
- V2 vs V1 비교 관찰법: 호출당 오버헤드는 더 높지만 재시도가 줄어 총 소비량은 종종 더 낮다
- 어떤 버전도 모든 차원에서 이기지 않는다. 선택은 필드 수, vocabulary 안정성, 레이턴시 예산, 클라이언트 간 일관성 요구 수준에 달렸다
- 테스트 방법: 첫 호출에 올바른 필터 값을 골랐는지, 몇 번의 툴 콜이 걸렸는지, 응답에 불필요한 정보가 있었는지, 컨텍스트 윈도우가 얼마나 빨리 차는지
관련 위키
- MCP (Model Context Protocol)
- Context Engineering
- AI Agent
- LLM Platform Engineering
- Tokenization Economics
Source: 원문 보기