패스노트
도메인 2. 툴 설계와 MCP 통합

2.1툴 스키마 설계

예상 학습 시간 35

Claude가 툴을 정확하게 호출하도록 만드는 첫 단계는 좋은 스키마 설계입니다. 이 수업에서는 툴 정의의 세 가지 구성 요소(name, description, input_schema)를 살펴보고, 모델이 툴을 올바르게 선택하고 파라미터를 정확히 채우게 만드는 설계 원칙을 다룹니다.

툴 정의의 구조

Claude API에서 툴(tool)은 세 가지 필드로 정의합니다. name은 툴의 식별자, description은 모델이 읽는 설명문, input_schema는 JSON Schema(JSON 스키마) 형식의 입력 명세입니다.

{
  "name": "get_weather",
  "description": "지정한 도시의 현재 날씨를 조회합니다. 도시 이름은 영문 또는 한글로 받을 수 있으며, 결과는 섭씨 기온과 날씨 상태를 포함합니다. 미래 예보는 제공하지 않습니다.",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "조회할 도시 이름. 예: '서울', 'Tokyo'"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "온도 단위. 기본값은 celsius"
      }
    },
    "required": ["city"]
  }
}

모델은 이 정의만 보고 툴을 사용할지, 어떤 값을 넣을지 결정합니다. 즉 툴 정의는 사람이 아니라 모델을 독자로 하는 문서입니다. 시스템 프롬프트에 툴 사용법을 장황하게 쓰는 것보다, 툴 정의 자체를 명확하게 쓰는 편이 훨씬 효과적입니다.

name^[a-zA-Z0-9_-]{1,64}$ 패턴을 따라야 하며, 동사_명사 형태(get_weather, create_ticket)가 관례입니다. 비슷한 툴이 여러 개라면 이름만으로 구분이 가능해야 합니다. search_docssearch_code처럼 대상을 이름에 드러내는 것이 좋습니다.

description이 품질의 80%를 결정한다

Anthropic 공식 문서가 가장 강조하는 원칙은 극도로 상세한 description을 쓰라는 것입니다. 좋은 description은 다음 질문에 답합니다.

  • 이 툴은 무엇을 하는가?
  • 언제 사용해야 하고, 언제 사용하면 안 되는가?
  • 각 파라미터는 무엇을 의미하며 결과에 어떤 영향을 주는가?
  • 어떤 값을 반환하는가? 반환하지 않는 것은 무엇인가?
  • 중요한 제약이나 한계는 무엇인가?

나쁜 예와 좋은 예를 비교해 봅니다.

나쁨: "주식 정보를 가져온다"

좋음: "지정한 종목 코드(ticker)의 현재 주가를 조회합니다.
미국 시장(NYSE, NASDAQ) 종목만 지원하며, 종목 코드는
'AAPL'처럼 대문자 심볼로 전달해야 합니다. 반환값은 달러
기준 현재가, 등락률, 거래량입니다. 과거 시세나 한국 시장
종목이 필요한 경우 이 툴을 사용하지 마세요."

경험적으로 description은 3~4문장 이상이 권장되며, 툴이 복잡할수록 길어져야 합니다. 파라미터 설명은 input_schema 안의 각 property별 description에 나눠 담는 것이 원칙입니다. 최상위 description에 모든 파라미터 설명을 몰아넣으면 모델이 특정 파라미터를 채울 때 해당 설명을 찾기 어려워집니다.

또 하나의 원칙은 모델이 이미 아는 것을 반복하지 않는 것입니다. "JSON 형식으로 호출하세요" 같은 안내는 불필요합니다. 대신 모델이 알 수 없는 것 — 데이터 출처, 지원 범위, 부작용(side effect) 여부, 요금 발생 여부 — 을 명시해야 합니다.

타입 제약으로 오류를 예방한다

JSON Schema의 제약 기능을 적극적으로 쓰면 모델의 잘못된 입력을 스키마 수준에서 차단할 수 있습니다.

  • enum: 허용 값이 유한하면 반드시 enum으로 고정합니다. 자유 문자열로 두면 모델이 "서울특별시", "seoul", "Seoul시" 같은 변형을 만들어냅니다.
  • required: 필수 파라미터를 명시합니다. required에 없는 파라미터는 모델이 생략할 수 있다고 가정해야 합니다.
  • format, pattern: 날짜(date-time), 이메일 등 형식이 정해진 값에 사용합니다.
  • minimum/maximum, minItems/maxItems: 수치·배열 범위를 제한합니다.
  • additionalProperties: false: 정의하지 않은 필드를 금지합니다.
{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": ["open", "in_progress", "resolved"],
      "description": "티켓 상태 필터"
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "반환할 최대 건수. 기본값 20"
    },
    "created_after": {
      "type": "string",
      "format": "date-time",
      "description": "이 시각 이후 생성된 티켓만 조회. ISO 8601 형식"
    }
  },
  "required": ["status"],
  "additionalProperties": false
}

주의할 점은 스키마 제약이 강제가 아니라 강한 유도라는 것입니다. 모델은 대체로 스키마를 따르지만, 서버 측 검증을 생략해도 된다는 뜻은 아닙니다. 스키마를 벗어난 입력이 오면 4.4 수업에서 다루는 검증·재시도 루프로 처리합니다. 반대로 구조화된 출력(structured outputs) 기능이나 strict 모드를 지원하는 플랫폼 기능을 사용하면 스키마 준수가 API 수준에서 보장됩니다.

툴 개수와 응집도 설계

툴을 몇 개, 어떤 단위로 나눌지는 스키마 문법만큼 중요한 설계 결정입니다.

툴 하나는 하나의 명확한 작업을 해야 합니다. manage_database(action, table, data, query, ...)처럼 action 파라미터로 여러 기능을 분기하는 만능 툴은 모델의 선택 난도를 높이고 오호출을 부릅니다. query_records, insert_record, delete_record로 나누는 편이 정확도가 높습니다.

반대로 지나친 세분화도 문제입니다. 툴이 수십 개가 되면 툴 정의가 컨텍스트를 잠식하고, 비슷한 툴 사이에서 모델이 혼란을 겪습니다. 실무 지침은 다음과 같습니다.

  • 한 에이전트에 노출하는 툴은 응집력 있는 소수(경험적으로 20개 이하)로 유지합니다.
  • 워크플로에서 항상 연달아 호출되는 툴들은 하나로 합치는 것을 검토합니다. 예: search_user 후 항상 get_user_detail을 호출한다면 find_user로 통합합니다.
  • 사용 빈도가 낮은 툴은 필요할 때만 동적으로 노출하는 방법(툴 서브셋 전환, MCP 서버 분리)을 고려합니다.

마지막으로 반환값 설계도 스키마 설계의 일부입니다. 툴 결과는 모델의 컨텍스트로 들어가므로, 사람이 아닌 모델이 소비하기 좋은 형태여야 합니다. 불필요한 필드를 제거하고, 다음 행동에 필요한 식별자(ID 등)를 반드시 포함하며, 대량 결과는 페이지네이션이나 요약으로 잘라 반환합니다. Anthropic의 툴 작성 가이드는 "토큰 효율적인 툴 결과"를 반복해서 강조합니다.

시험 함정

  • description은 사람이 아니라 모델이 읽는 문서다. '개발자 문서에 있으니 짧게 써도 된다'는 선택지는 오답이다.
  • 파라미터 설명은 최상위 description이 아니라 input_schema 각 property의 description에 넣는 것이 원칙이다.
  • 허용 값이 유한한 파라미터는 자유 문자열이 아니라 enum으로 제한해야 한다는 점을 묻는 문제가 자주 나온다.
  • JSON Schema 제약은 모델을 강하게 유도할 뿐 서버 측 검증을 대체하지 않는다.
  • action 파라미터로 여러 기능을 분기하는 만능 툴은 안티패턴이다. 기능별로 툴을 분리하는 선택지를 골라야 한다.
  • 툴 반환값도 설계 대상이다. '전체 원본 데이터를 그대로 반환한다'는 선택지는 컨텍스트 낭비로 오답이다.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

사내 티켓 시스템용 툴을 만들었는데, Claude가 status 파라미터에 '진행중', 'in progress', 'IN_PROGRESS' 등 제각각의 값을 넣어 호출이 자주 실패합니다. 가장 근본적인 해결책은 무엇입니까?

빌드 연습 · 날씨 API 툴 스키마 리팩터링

40
  1. 1.나쁜 스키마로 시작하기

    description이 한 줄뿐이고 모든 파라미터가 자유 문자열인 get_weather 툴을 정의해 Claude API로 호출해 본다

    기대 결과 · 도시명 형식 오류, 단위 혼동 등 잘못된 호출이 관찰된다

  2. 2.description 강화

    툴의 용도, 지원 범위, 반환값, 사용하면 안 되는 경우를 4문장 이상으로 다시 쓴다

    기대 결과 · 모델이 지원 범위 밖 요청에는 툴을 호출하지 않고 한계를 설명한다

  3. 3.타입 제약 추가

    unit에 enum, 날짜에 format, 수치에 minimum/maximum을 추가하고 required를 명시한다

    기대 결과 · 파라미터 형식 오류로 인한 호출 실패가 사라진다

  4. 4.반환값 다이어트

    API 원본 응답에서 모델에게 필요한 필드만 추려 반환하도록 서버 코드를 수정한다

    기대 결과 · 툴 결과 토큰이 크게 줄고 후속 응답 품질은 유지된다

  5. 5.전후 비교 평가

    동일한 테스트 프롬프트 10개로 리팩터링 전후의 호출 정확도를 비교한다

    기대 결과 · 오호출 비율이 눈에 띄게 감소한 것을 수치로 확인한다

출처 및 더 읽기