tool calling이 엉뚱한 도구를 고를 때, 설명문부터 고치는 순서

tool calling

tool calling 기능을 붙인 에이전트에서 모델이 분명 존재하는 도구를 두고 엉뚱한 함수를 호출하는 문제는, 프롬프트보다 도구 설명문(description)에서 시작되는 경우가 많습니다. 이름이 비슷하거나 설명이 짧은 도구 두세 개만 나란히 등록돼 있어도 모델이 그중 하나를 잘못 고르는 일이 흔하게 일어납니다. 그래서 함수 호출이 꼬였을 때는 시스템 프롬프트부터 뜯어고치기 전에, 도구 설명문을 먼저 점검하는 순서로 접근하는 편이 효율적입니다.

tool calling에서 도구를 잘못 고르는 원인, 설명문에 있습니다

모델은 도구의 코드를 보지 않습니다. 이름과 description, 파라미터 스키마에 적힌 텍스트만 보고 어떤 함수를 부를지 판단합니다. 그래서 search_docssearch_knowledge_base처럼 이름과 설명이 겹치는 도구가 함께 등록돼 있으면, 두 도구의 역할이 사람에게는 명확해도 모델 입장에서는 경계가 흐릿해집니다.

MCP(Model Context Protocol)처럼 여러 서버를 연결해 도구 목록을 한꺼번에 불러오는 구조에서는 이 문제가 더 두드러집니다. 서버마다 비슷한 이름의 도구가 추가되면 시스템 프롬프트에 들어가는 도구 정의 텍스트 자체가 늘어나고, 그 안에서 모델이 골라야 할 후보도 함께 늘어나기 때문입니다. 도구 개수를 줄이기 어렵다면, 남은 선택지는 설명문의 품질을 올리는 쪽입니다.

도구가 많아질수록 왜 헷갈릴까요?

도구 정의는 결국 컨텍스트에 함께 들어가는 텍스트입니다. OpenAI의 Chat Completions/Responses API든 Anthropic의 Messages API든, tools 배열에 담긴 namedescription은 시스템 프롬프트와 사실상 같은 층위에서 모델에게 읽힙니다. 설명이 “데이터를 가져옵니다” 수준으로 짧으면, 비슷한 역할을 하는 다른 도구와 구분할 근거가 모델에게 남지 않습니다.

또한 파라미터 이름도 판단 근거로 쓰입니다. query라는 파라미터를 가진 도구가 두 개면, 모델은 설명문에서 “언제 이 도구를 쓰고 언제 쓰면 안 되는지”에 대한 단서를 찾으려 합니다. 그 단서가 없으면 도구 이름의 뉘앙스나 등록 순서 같은, 개발자가 의도하지 않은 요인에 기대어 도구 선택이 이뤄집니다.

여러 함수 목록 앞에서 고민하는 개발자

설명문 고치는 순서를 단계별로 잡아보세요

무작정 설명을 길게 늘리기보다는 아래 순서를 따라가는 편이 원인 파악에 유리합니다.

  1. 잘못 호출된 로그를 모읍니다. 어떤 사용자 요청에서, 정답 도구 대신 어떤 도구가 불렸는지를 먼저 표로 정리합니다.
  2. 헷갈린 도구 쌍의 description을 나란히 놓고 겹치는 표현을 찾습니다.
  3. “이 도구를 쓰는 상황”뿐 아니라 “쓰면 안 되는 상황”까지 한 문장 덧붙입니다.
  4. 파라미터에도 예시 값을 넣어 스키마만으로는 안 보이는 사용 조건을 보완합니다.

실제 OpenAI 함수 정의를 예로 들면 아래와 같이 바꿀 수 있습니다.

// 수정 전
{
  "type": "function",
  "function": {
    "name": "get_data",
    "description": "데이터를 가져옵니다.",
    "parameters": {
      "type": "object",
      "properties": { "query": { "type": "string" } },
      "required": ["query"]
    }
  }
}

// 수정 후
{
  "type": "function",
  "function": {
    "name": "search_internal_wiki",
    "description": "사내 위키 문서에서만 검색합니다. 실시간 웹 검색이 필요하면 이 도구 대신 search_web을 호출하세요. query에는 사람이 쓸 법한 자연어 문장을 그대로 넣습니다.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "예: '휴가 신청 절차', '법인카드 한도'"
        }
      },
      "required": ["query"]
    }
  }
}

이름을 get_data에서 search_internal_wiki로 바꾸고, “이 도구가 아니라 저 도구를 써야 하는 경우”를 설명문 안에 직접 넣은 부분이 핵심입니다. OpenAI의 function calling 공식 가이드에서도 도구 이름과 설명을 명확하고 구체적으로 작성할 것을 권장하고 있습니다.

이름과 파라미터 스키마도 함께 봐야 하는 이유

설명문만 고쳐서 해결되지 않을 때는 파라미터 스키마도 함께 살펴볼 필요가 있습니다. 자유 문자열로 받던 값을 JSON Schemaenum으로 제한하면, 모델이 도구를 고른 뒤에도 값을 잘못 채우는 실수를 줄일 수 있습니다. 예를 들어 status 파라미터를 문자열로만 받던 도구를 "enum": ["open", "closed", "pending"]으로 바꾸면, 모델이 실제 시스템에는 없는 값을 지어내는 일이 줄어듭니다.

노트북 화면에 도구 설명문을 작성하는 모습

OpenAI API에는 parameters 스키마를 엄격하게 강제하는 strict 옵션도 있어, 스키마에 정의되지 않은 필드나 타입 불일치를 원천적으로 줄이는 데 쓸 수 있습니다. 다만 이 옵션은 지원 여부와 제약 조건이 API 버전마다 다를 수 있으므로, 적용 전 해당 모델의 공식 문서에서 지원 범위를 직접 확인하는 절차가 필요합니다.

설명문만으론 안 풀리는 상황도 있습니다

설명문 개선이 만능은 아닙니다. 아래 표처럼 증상별로 원인이 다르면 접근 방식도 달라져야 합니다.

증상 흔한 원인 우선 조치
비슷한 이름 도구 사이에서 혼동 description 내용 중복 상호 참조 문구 추가
파라미터 값이 스키마에 없는 값으로 채워짐 자유 문자열 파라미터 enum·타입 제한
도구가 20개 넘게 등록된 상태에서 산발적 오선택 컨텍스트 내 도구 정의 과다 도구 그룹화·라우팅 계층 도입
소형·경량 모델에서 유독 오선택 잦음 모델 자체의 tool calling 처리 한계 설명 개선보다 모델 교체 검토

도구 수 자체가 수십 개를 넘어가면 설명문을 아무리 다듬어도 개선 폭이 제한적입니다. 이 구간에서는 도구를 카테고리별로 묶어 1차 라우팅 도구를 두고, 실제 실행 도구는 2단계에서 골라 쓰는 계층 구조가 더 효과적입니다. 또한 설명을 지나치게 길게 쓰면 도구 정의 자체가 컨텍스트 토큰을 많이 차지해, 정확도와 비용 사이의 트레이드오프가 생긴다는 점도 함께 고려해야 합니다.

설명문을 다 고쳤는데 왜 가끔 여전히 틀릴까요?

설명문을 손봤는데도 간헐적으로 오선택이 남아 있다면, 도구 정의 자체보다 호출 환경 쪽을 의심해볼 차례입니다. temperature가 높게 설정돼 있으면 같은 입력에도 도구 선택 결과가 매번 달라질 수 있고, 클라이언트가 캐싱해둔 도구 정의가 서버에 실제 배포된 최신 정의와 어긋나 있는 경우도 실무에서 흔히 생깁니다. 이럴 때는 설명문을 더 손대기보다, 호출 직전에 모델에게 전달되는 tools 배열을 로그로 그대로 찍어 실제 값과 비교하는 절차가 먼저입니다.

정리하면, 함수 호출이 엉뚱한 도구를 고를 때는 프롬프트 전체를 흔들기보다 실패 로그를 모으고, 겹치는 설명문을 찾아 “쓰는 상황·쓰지 않는 상황”을 명시하는 순서로 접근하는 편이 원인 파악에 유리합니다. 다음 단계로는 최근 오선택이 발생한 요청 다섯 건 정도를 골라, 관련된 도구들의 description을 나란히 펼쳐놓고 겹치는 문장부터 지워보는 작업을 권해드립니다.

크롤링이 403으로 막힐 때 확인할 순서: UA·robots·속도

Leave a Comment