AI 에이전트의 도구 호출 실패는 종종 모델 능력 부족처럼 보이지만, 실제로는 도구 이름·설명·스키마·오류 반환이 모델에게 잘못된 인터페이스를 제공해서 생긴다. 좋은 도구 설계는 모델이 추측할 일을 줄이고, 실패 후 복구 경로를 명시한다.
1. 한 도구는 한 책임만 맡겨라
manage_customer(action="create")처럼 하나의 도구가 여러 행동을 action 파라미터로 처리하면 모델은 작업 전에 모드 선택 문제부터 풀어야 한다.
더 나은 기본값은 작업을 나누는 것이다.
create_customer(data: CustomerInput) -> Customer
get_customer(customer_id: str) -> Customer
suspend_customer(customer_id: str, reason: str) -> SuspensionResult셸, 파일시스템, 브라우저처럼 원래 행동 공간이 넓은 도구는 예외가 될 수 있다. 하지만 비즈니스 도메인 API는 단일 책임 도구가 관찰성과 오류 처리를 단순하게 만든다.
2. 스키마로 불가능한 상태를 막아라
모델은 파라미터 스키마를 보고 호출 인자를 만든다. 자유 문자열과 dict가 많을수록 모델은 제약을 추측한다.
좋은 스키마는 다음을 포함한다.
- enum으로 선택지를 제한
min_length,max_length, regex 등 validation 명시- 날짜·ID·금액 형식 설명
- 기본값의 의미 설명
- nullable 필드 최소화
스키마는 런타임 검증만이 아니라 모델에게 제공되는 설계 문서다.
3. 설명에는 “언제 쓰지 말아야 하는가”를 포함하라
도구 설명은 목적만 적으면 부족하다. 모델은 유사 도구 사이에서 선택해야 하므로 scope boundary가 필요하다.
나쁜 설명:
Search for documents in the knowledge base.좋은 설명:
Search the internal knowledge base for policies and documented workflows.
Use for company procedures and product specs.
Do not use for real-time prices, availability, or current status; use get_live_data instead.
Returns up to 5 ranked results. If empty, the information is not in the knowledge base.4. 오류는 구조화해서 반환하라
스택트레이스나 자유 텍스트 오류는 모델에게 복구 전략을 주지 않는다. 오류 객체에는 적어도 다음 필드가 있어야 한다.
class ToolError(BaseModel):
error_code: str
message: str
recoverable: bool
suggested_action: strrecoverable=false인 quota 초과 오류와 recoverable=true인 record not found 오류는 모델이 다르게 처리해야 한다. 이 차이를 명시하지 않으면 모델은 재시도하면 안 되는 오류를 반복하거나, 복구 가능한 오류에서 멈춘다.
5. 상태 변경 도구는 멱등적으로 만들어라
에이전트 루프에서는 네트워크 실패, 타임아웃, 중간 관찰 누락 때문에 같은 도구가 두 번 호출될 수 있다. 이메일 발송, 결제, 티켓 생성, 파일 삭제 같은 도구는 idempotency key를 받아야 한다.
send_email(
to: str,
subject: str,
body: str,
idempotency_key: str
) -> SendResult같은 key로 재호출되면 원래 결과를 반환하고 부작용을 반복하지 않아야 한다.
6. 부분 성공을 숨기지 마라
배치 작업에서 일부 항목만 성공했는데 성공한 ID만 반환하면 모델은 전체가 성공했다고 가정한다. 반환 타입에는 success, partial_success, created_ids, failed_items처럼 분기 가능한 필드가 필요하다.
부분 성공을 명시하면 모델은 실패 항목만 재시도하거나 사용자에게 불완전한 상태를 보고할 수 있다.
7. 파괴적 작업은 두 단계로 나눠라
삭제, 외부 메시지 발송, 금융 거래, 권한 변경은 단일 호출로 실행되면 안 된다. 안전한 패턴은 staging과 confirmation을 분리하는 것이다.
stage_deletion(ids, reason) -> confirmation_token
confirm_deletion(token) -> deletion_resultconfirmation token은 짧은 만료 시간, 단일 사용, 세션 바인딩, replay protection을 가져야 한다. 프롬프트 안의 “정말 할까요?”보다 구조적 경계가 더 중요하다.
설계 체크리스트
| 영역 | 좋은 기본값 |
|---|---|
| 도구 범위 | 단일 책임 |
| 파라미터 | enum·validator·typed field |
| 설명 | 사용 조건과 비사용 조건 모두 명시 |
| 오류 | error_code, recoverable, suggested_action |
| 쓰기 작업 | idempotency key |
| 배치 작업 | partial_success와 failed_items |
| 위험 작업 | stage/confirm 2단계 승인 |
| 도구 수 | 현재 단계에 필요한 도구만 로드 |
관련 문서
- agent-harness — 모델 외부 하네스와 도구 설계가 에이전트 성능에 미치는 영향
- mcp-tips-vs-agent-skills — MCP 도구와 에이전트 스킬의 역할 차이
- ai-agent-security-tips-docker-sandbox — 에이전트 실행 환경 격리 설계
참고 자료
- AI Agent Tool Design: What Works and What Doesn’t — MachineLearningMastery.com (2026-06-15)
- Writing effective tools for AI agents — Anthropic Engineering