iBetter Books
수정

도구 정의의 구조

도구 하나는 세 가지 필드로 정의된다. 이름(name), 설명(description), 그리고 입력 스키마(input_schema)다. 이 셋은 모두 모델이 읽는 컨텍스트의 일부이며, 모델은 이 세 가지만 보고 "이 도구를 지금 부를지, 어떤 인자로 부를지"를 결정한다. 하네스가 실제 함수를 어떻게 구현했는지는 모델이 알지 못한다. 따라서 도구 정의는 구현 명세가 아니라 모델을 향한 인터페이스 설계다.

가장 기본적인 도구 정의는 다음과 같다.

# tools/get_weather.pyget_weather_tool = {    "name": "get_weather",    "description": "Get current weather for a location. Call this when the user asks about current temperature, conditions, or forecast for a specific place.",    "input_schema": {        "type": "object",        "properties": {            "location": {                "type": "string",                "description": "City and state, e.g., San Francisco, CA",            },            "unit": {                "type": "string",                "enum": ["celsius", "fahrenheit"],                "description": "Temperature unit",            },        },        "required": ["location"],    },}

세 필드의 역할을 정확히 구분하자. name은 모델이 호출 시 지정하는 식별자이고, 동시에 하네스가 디스패치(어떤 함수를 실행할지 분기)하는 키다. description은 모델이 "언제 부를지"를 판단하는 근거다. 자연어 설명이 부실하면 모델은 호출 시점을 잘못 판단한다. input_schema는 JSON Schema이며 인자의 형태를 규정한다. 최상위는 반드시 type: "object"여야 하고, 각 property에 description을 달아 모델이 인자를 올바르게 채우도록 돕는다.

JSON Schema에서 지원되는 것과 안 되는 것

시험은 스키마 제약을 자주 묻는다. 특히 구조화 출력(strict)과 함께 쓸 때 어떤 키워드가 허용되는지가 함정이다. 지원되는 것은 기본 타입(object, array, string, integer, number, boolean, null), enum, const, anyOf, allOf, $ref/$def, 그리고 date-time·email·uri·uuid 같은 문자열 포맷이다. 지원되지 않는 것은 재귀 스키마, 수치 제약(minimum, maximum, multipleOf), 문자열 길이 제약(minLength, maxLength), 복잡한 배열 제약이다. 또한 strict 모드의 모든 object는 additionalProperties: false를 명시해야 하며, 이 값을 false 외의 것으로 두는 것은 허용되지 않는다. Python·TypeScript SDK는 지원되지 않는 제약을 자동으로 제거하고 클라이언트 측에서 검증하지만, 원시 HTTP나 다른 언어에서는 직접 챙겨야 한다.

tool_choice — 호출 시점을 강제하기

tool_choice는 모델이 도구를 쓸지 말지를 제어한다. 네 가지 값이 있다.

동작
{"type": "auto"} 모델이 도구 사용 여부를 스스로 결정(기본값)
{"type": "any"} 반드시 도구 하나 이상을 사용
{"type": "tool", "name": "..."} 지정된 도구를 반드시 사용
{"type": "none"} 도구를 사용하지 못함

어느 값이든 "disable_parallel_tool_use": true를 함께 줄 수 있고, 그러면 한 응답에 도구를 하나만 호출하도록 강제한다. 기본적으로 Claude는 한 응답에서 여러 도구를 동시에 요청할 수 있다는 점을 기억하라. 시험은 "추출 작업에서 자유 텍스트 없이 무조건 특정 도구로만 출력받고 싶다"는 시나리오에서 {"type": "tool", "name": ...}을 고르게 하거나, "병렬 호출을 막아야 하는 이유"를 묻는 식으로 나온다.

strict와 구조화 출력 — 두 개의 다른 보장

여기가 가장 헷갈리는 지점이다. 도구 출력의 형태를 보장하는 방법은 두 가지이고, 적용 대상이 다르다. strict: true는 도구 정의 안에 넣는 필드로, 모델이 만들어 내는 도구 인자(input)가 스키마를 정확히 만족하도록 보장한다.

# tools/book_flight.pybook_flight_tool = {    "name": "book_flight",    "description": "Book a flight to a destination. Call this only after the user has confirmed dates and passenger count.",    "strict": True,    "input_schema": {        "type": "object",        "properties": {            "destination": {"type": "string"},            "date": {"type": "string", "format": "date"},            "passengers": {"type": "integer", "enum": [1, 2, 3, 4, 5, 6, 7, 8]},        },        "required": ["destination", "date", "passengers"],        "additionalProperties": False,    },}

반면 구조화 출력은 모델의 최종 응답(도구가 아니라 텍스트 응답) 형태를 제약하며, output_config.format을 사용한다. 옛 output_format 파라미터는 폐기되었으므로 새 코드에서는 쓰지 않는다. 또한 구조화 출력은 인용(citations)과 함께 쓸 수 없고, 메시지 프리필과도 호환되지 않는다.

# scripts/extract_contact.pyimport anthropicclient = anthropic.Anthropic()response = client.messages.create(    model="claude-opus-4-8",    max_tokens=16000,    messages=[{"role": "user", "content": "Extract: John Smith ([email protected]) wants the Enterprise plan."}],    output_config={        "format": {            "type": "json_schema",            "schema": {                "type": "object",                "properties": {                    "name": {"type": "string"},                    "email": {"type": "string"},                    "plan": {"type": "string"},                },                "required": ["name", "email", "plan"],                "additionalProperties": False,            },        }    },)

시험 함정 정리. 첫째, "도구 인자 검증"과 "최종 응답 형식 제약"을 섞어 묻는다. strict는 전자, output_config.format은 후자다. 둘째, output_format(폐기) 대 output_config.format(현행)을 구분하게 한다. 셋째, 구조화 출력 응답에서 stop_reason"refusal"이거나 "max_tokens"이면 출력이 스키마를 만족하지 못할 수 있으므로, 응답을 읽기 전에 stop_reason을 확인해야 한다는 점을 묻는다. 넷째, strict 스키마에서 additionalProperties: false 누락은 흔한 오답 유발 요소다.

정리

  • 도구 정의는 name·description·input_schema 세 필드로 이루어지며, 셋 모두 모델이 읽는 인터페이스다. name은 호출·디스패치 키, description은 호출 시점 판단 근거, input_schema는 인자 형태 규정이다.
  • JSON Schema는 기본 타입·enum·const·anyOf·포맷을 지원하지만 재귀·수치 제약·문자열 길이 제약은 지원하지 않는다. strict 모드의 object는 additionalProperties: false가 필수다.
  • tool_choice는 auto·any·tool·none으로 호출 시점을 제어하고, disable_parallel_tool_use로 병렬 호출을 막는다.
  • strict: true는 도구 인자 검증을, output_config.format은 최종 응답 형식을 보장한다. 둘은 적용 대상이 다르며 시험은 이를 섞어 출제한다. 폐기된 output_format 대신 output_config.format을 쓴다.