AI 에이전트가 잘못된 도구를 호출하는 이유 — 대부분은 JSON 스키마 때문입니다
요약
AI 에이전트의 도구 호출 실패는 모델의 지능 문제보다 불완전한 JSON 스키마 설계에서 비롯됩니다. 스키마를 단순한 문서가 아닌 모델을 위한 정교한 프롬프트로 취급하여 모호성을 제거해야 합니다.
핵심 포인트
- 에이전트의 단계별 작업 성공률은 각 단계의 성공 확률이 복리로 작용하여 급격히 낮아짐
- JSON 스키마의 description은 모델이 도구를 사용하는 유일한 지침임
- 모호한 설명과 느슨한 타입 지정은 모델의 잘못된 추측을 유발함
- 스키마 내에 호출 시점과 인자의 의미를 명확히 인코딩해야 함
여러분이 생각하는 것보다 더 걱정해야 할 수치가 있습니다. 올바른 인자(arguments)로 올바른 도구를 95%의 확률로 호출하는 에이전트라 할지라도, 8단계로 구성된 작업을 정확하게 완료할 확률은 약 **66%**에 불과합니다. 신뢰성은 한 번의 극적인 충돌로 실패하는 것이 아닙니다. 서서히 누수됩니다. 매 단계는 20번 중 19번은 앞면이 나오는 동전 던지기와 같으며, 당신은 이 동전을 연속으로 8번 던지고 있는 것입니다.
좋은 소식은 이러한 누수의 대부분이 모델이 멍청해서 발생하는 것이 아니라는 점입니다. 이는 당신이 완전히 제어할 수 있는 두 가지 요소, 즉 모델에게 전달하는 **JSON 스키마 (JSON schema)**와 모델이 해서는 안 될 상황에서 **추측 (guess)**하도록 방치하는지 여부로 귀결됩니다. 이 두 가지를 해결하면 호출당 성공률이 올라가며, 이 효과는 복리로 작용하기 때문에 작은 이득이 엄청난 보상으로 돌아옵니다.
스키마는 문서가 아니라 프롬프트입니다
이것은 이후의 모든 문제를 해결하는 관점의 전환입니다. 도구를 정의할 때, description 필드는 팀 동료를 위한 문서가 아닙니다. 그것은 모델이 해당 도구를 언제, 어떻게 사용할지에 대해 받는 유일한 지침입니다. 모델은 당신의 구현(implementation)을 절대 보지 못합니다. 모델은 스키마만을 봅니다. 그게 전부입니다.
따라서 다음과 같은 스키마는 "충분히 좋지" 않습니다:
{
"name": "send_email",
"description": "Sends an email",
...
모델이 읽는 방식으로 읽어보세요. 이메일을 언제 보내야 할까요, 아니면 초안을 작성해야 할까요? to는 주소인가요, 아니면 연락처 이름인가요? body는 HTML이 될 수 있나요? 필수 항목이 있나요? 당신은 답을 알고 있습니다. 모델은 추측하고 있으며, 바로 그 추측이 5%의 오류를 만들어내는 지점입니다.
잘못된 호출을 유발하는 네 가지 스키마 버그
수많은 잘못된 도구 정의를 살펴본 결과, 동일한 네 가지 문제가 계속해서 나타납니다:
1. 모호하거나 누락된 설명 (Vague or missing descriptions). "이메일을 보냅니다(Sends an email)", "데이터를 가져옵니다(Gets data)", "요청을 처리합니다(Handles the request)". 두 도구의 설명이 빈약하면 모델은 이를 구분할 수 없어 잘못된 것을 선택합니다. 해결책은 도구를 잘못된 시점에 사용하여 해고될 수도 있는 신입 사원에게 도구를 설명하듯 설명을 작성하는 것입니다. 언제 호출해야 하는지, 언제 호출하면 안 되는지, 그리고 각 인자(argument)가 무엇을 의미하는지를 명시하세요.
2. 타입이 지정되지 않았거나 느슨하게 타입 지정된 매개변수(Untyped or loosely typed params). ISO 날짜를 의도했지만 string으로 처리하는 경우, 네 가지 상태 중 하나를 의도했지만 string으로 처리하는 경우가 있습니다. 타입이 값을 제한하지 못하면 모델은 그럴듯해 보이는 값(
이러한 많은 부분을 스키마 자체에 인코딩할 수 있습니다. 모델이 합리적으로 추론할 수 없는 필드는 required로 표시하지 말고, 설명(description)에 그렇게 명시하세요. — "사용자가 시간대를 지정하지 않았다면 질문하세요. 추측하지 마세요." 스키마는 모델의 판단을 위한 기본값(defaults)을 설정하는 곳입니다.
모델의 출력을 신뢰할 수 없는 입력으로 취급하세요
제공업체(provider)가 잘 구성된 JSON(well-formed JSON)을 보장하더라도, '잘 구성되었다'는 것이 '정확하다'는 것과 같지는 않습니다. 구조화된 출력(Structured-output) 모드는 모델이 깨진 JSON을 생성하는 것은 막아주지만, 유효해 보이지만 잘못된 인자(argument)를 전달하는 것까지 막아주지는 못합니다. 따라서 실행하기 _전_에 매번 여러분 쪽에서 검증(validate)을 수행하세요. 실제 제약 조건에 따라 값을 확인하고(이 사용자 ID가 존재하는가? 이 금액이 범위 내에 있는가?), 실패할 경우 실행을 중단(crash)시키는 대신 모델이 읽고 복구할 수 있는 명확한 에러를 반환하세요. 모델의 출력은 입력입니다. 폼 필드(form field)의 가공되지 않은 입력을 신뢰하지 않듯, 이 입력 또한 신뢰하지 마세요.
실제로 이를 잡아내는 방법
이러한 버그를 찾기 위해 직접 스키마를 읽는 것은 어렵습니다. 특히 required가 누락된 속성을 참조하는 문제는 프로덕션(prod) 환경의 모든 호출을 망가뜨리기 전까지는 보이지 않습니다. 그래서 저는 정확히 이 문제를 위해 의존성이 없는 아주 작은 린터(linter)를 작성했습니다: tool-schema-lint (npx tool-schema-lint your-tools.json). 이 도구는 Anthropic과 OpenAI의 도구 형식 모두에 대해 모호한 설명, 타입이 지정되지 않은 파라미터(params), 열거형(enum)이 필요한 곳에 자유 텍스트(free-text)가 사용된 경우, 그리고 소리 없이 발생하는 required/properties 불일치를 찾아냅니다. 무료이며 MIT 라이선스로 제공됩니다. 여러분의 도구 정의(tool definitions)를 대상으로 실행하여 무엇이 발견되는지 확인해 보세요.
더 큰 그림, 즉 다단계 에이전트 (multi-step agents)를 궤도에 유지시키는 도구 패턴과 "올바른 단계에서 올바른 인자 (args)로 올바른 도구를 호출했는가"를 점수화할 수 있는 실행 가능한 평가 루브릭 (eval rubric)이 필요하다면, Agent Builder's Toolkit을 확인해 보세요. 만약 아직 초기 단계라면, 이메일 등록 없이도 7가지 신뢰성 규칙과 바로 복사해서 사용할 수 있는 3가지 가드레일 (guardrails)을 다루는 무료 필드 가이드 (free field guide)가 도움이 될 것입니다.
한 단락 요약
도구 호출 (Tool-calling)의 신뢰성은 복리로 감소합니다. 호출당 95%의 성공률은 8단계를 거치면 약 66%로 떨어지므로, 호출당 미세한 이득이 매우 중요합니다. 대부분의 오류는 통제 가능한 두 가지 요소에서 발생합니다. 첫째는 스키마 (schema)입니다. 이는 모델이 받는 유일한 지침이므로, 실제적인 설명을 작성하고, 파라미터 (params)의 타입 (type)과 열거형 (enum)을 지정하며, required에 포함된 모든 이름이 실제로 properties에 존재하는지 확인해야 합니다 (마지막 버그는 모든 호출을 조용히 망가뜨립니다). 둘째는 추측입니다. 누락된 필드가 돈, 게시, 삭제 또는 고객 통신과 관련되어 있다면, 값을 지어내는 대신 에이전트가 질문하도록 만드세요. 그런 다음 모델의 출력을 실행하기 전에 신뢰할 수 없는 입력 (untrusted input)으로 간주하고 검증하십시오. 신뢰성은 더 똑똑한 모델이 아니라, 스키마와 판단력의 결합에서 나옵니다.
여러분이 배포한 사례 중 가장 최악이었던 잘못된 도구 호출은 무엇이었나요? 답글로 알려주세요. 제가 수집하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기