본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 29. 08:10

LLM이 도구를 정확하게 호출하도록 설계하는 방법: CCA-F 블루프린트의 5가지 패턴

요약

LLM 에이전트가 도구를 정확하게 호출하도록 설계하는 5가지 패턴을 소개합니다. 도구 설명을 단순한 docstring이 아닌 프롬프트처럼 작성하고, 스키마를 엄격하게 정의하여 모델의 추측을 최소화하는 방법을 다룹니다.

핵심 포인트

  • 도구 설명을 '언제' 사용해야 하는지 명시하는 프롬프트로 취급할 것
  • 도구의 응답 내용, 사용 시점, 사용 금지 시점, 예외 상황을 포함할 것
  • 스키마 설계 시 enum 등을 사용하여 모호함을 제거하고 엄격하게 정의할 것
  • 단일 도구에 여러 동작을 넣기보다 명확한 도구 분리를 고려할 것

제가 처음으로 도구 사용 에이전트(tool-using agent)를 출시했을 때, 모델은 계속해서 잘못된 도구를 호출했습니다. 가끔 그러는 것이 아니라, 출시를 못 할 정도로 빈번하게 발생했습니다. 도구들은 제대로 작동했습니다. 스키마(schemas)도 유효했습니다. 설명(descriptions)도 기술적으로는 정확했습니다. 하지만 모델은 계속해서 잘못된 도구를 반복해서 선택했습니다.

고통스럽게 배운 점은, LLM 호출자를 위한 도구를 설계하는 것은 함수 시그니처(function signature)를 작성하는 것보다 기술 문서(technical documentation)를 작성하는 것에 더 가깝다는 사실입니다. 모델은 도구를 호출할지 여부와 어떻게 호출할지에 대한 결정 과정의 일부로 여러분의 도구 정의를 읽습니다. 만약 설명이 모호하다면, 모델은 추측을 하게 될 것이며, 여러분은 그런 상황을 원하지 않을 것입니다.

이 포스트에서는 제가 이제 기본적으로 사용하는 다섯 가지 패턴을 살펴봅니다. 이 패턴들은 모두 Claude Certified Architect Foundations 시험의 Tool Design & MCP 도메인 내용과 직접적으로 연결됩니다 (우연하게도, 이 도메인은 많은 유능한 백엔드 엔지니어들이 점수를 잃는 영역이기도 합니다).

패턴 1: 도구 설명을 docstring이 아닌 프롬프트(prompt)로 취급하라

가장 흔한 안티 패턴(anti-pattern)은 Python의 docstring을 작성하듯이 도구 설명을 작성하는 것입니다.

{
  "name": "get_user",
  "description": "주어진 사용자 ID에 대한 사용자 객체를 반환합니다.",
...

이 설명은 모델에게 _도구가 무엇을 하는지_를 알려줍니다. 하지만 모델에게 언제 호출해야 하는지, 언제 호출하지 말아야 하는지, 또는 _"사용자 객체"가 실제로 무엇을 포함하고 있는지_는 알려주지 않습니다. 따라서 모델은 추측을 해야만 합니다.

다시 작성하면 다음과 같습니다:

{
  "name": "get_user",
  "description": "내부 사용자 ID를 통해 사용자의 프로필(이름, 이메일, 플랜 등급, 가입 날짜)을 가져옵니다. 사용자가 특정 계정에 대해 묻고 있고 사용자 ID를 보유하고 있을 때 이 도구를 사용하십시오. 이메일 기반 조회에는 이 도구를 사용하지 마십시오. 대신 lookup_user_by_email을 사용하십시오. 사용자가 존재하지 않으면 null을 반환하며, 에러를 발생시키지 않습니다.",
...

이렇게 다시 작성하면 모델이 추측해야 했던 네 가지 질문에 답을 줍니다: 응답에 무엇이 들어있는지, 언제 사용해야 하는지, 언제 사용하지 말아야 하는지, 그리고 예외적인 경로(unhappy path)에서 어떤 일이 발생하는지 말입니다. 이것이 기준점입니다.

휴리스틱(Heuristic): 만약 도구 설명(tool description)에 "언제(when)"라는 단어가 포함되어 있지 않다면, 아마도 아직 완성되지 않은 것일 겁니다.

패턴 2: 모호함이 불가능할 때까지 스키마(schema)를 엄격하게 만들기

LLM은 그럴듯해 보이는 인자(arguments)를 생성하는 데 매우 뛰어납니다. 하지만 스키마가 모호함을 허용할 경우, 정확한 인자를 생성하는 능력은 그보다 떨어집니다.

느슨한 스키마:

{
  "properties": {
    "status": { "type": "string" },
...

엄격하게 개선된 버전:

{
  "properties": {
    "status": {
...

실패 유형을 각각 제거하는 세 가지 변화:

  1. status가 이제 열거형(enum)이 되었습니다. 모델은 `

특히 REST API를 작성해 본 경험이 있다면, modeaction 파라미터를 사용하여 동작을 전환하는 단일 도구를 설계하고 싶은 강한 유혹을 느낄 수 있습니다:

{
  "name": "manage_ticket",
  "description": "티켓을 생성, 업데이트, 종료 또는 재오픈합니다.",
...

이 방식은 우아해 보입니다. 하지만 실제로는 네 개의 별도 도구를 사용하는 것보다 더 나쁩니다.

이유는 다음과 같습니다:

  • 모델은 어떤 동작에 어떤 필드가 필수적인지 추론해야 합니다. ticket_id는 업데이트/종료/재오픈 시에는 필수적이지만 생성 시에는 필요하지 않습니다. 스키마(schema)는 oneOf 없이는 이를 강제할 수 없으며, oneOf를 사용하더라도 모델의 준수율(adherence rate)이 떨어집니다.

  • 설명(description)이 네 가지 동작을 모두 다뤄야 하므로, "언제 사용해야 하는지"에 대한 신호가 희석됩니다.

  • 에러 메시지가 일반적이게 됩니다. `

  • 공유 상태(counters, queues, locks)를 변경합니다.

  • 이전 호출의 출력을 입력으로 사용하는 종속성이 있습니다.

  • 특정 순서 내에서만 의미가 있는 결과를 반환합니다.

병렬 실행이 안전하지 않은(not parallel-safe) 도구를 가지고 있다면, 설명(description)에 이를 명시적으로 문서화하세요: "이 도구는 fetch_session 이후에 호출되어야 하며, 다른 쓰기 작업과 병렬로 실행되어서는 안 됩니다.". 모델은 이를 준수할 것입니다.

더 중요한 핵심은 이렇습니다. 새로운 도구를 설계할 때 스스로에게 질문해 보세요. "만약 모델이 동일한 턴(turn)에서 이 도구를 두 번 호출하면 어떻게 될까?" 만약 그 답이 "정의되지 않은 동작(undefined behavior)"이라면, 당신은 더 많은 작업을 수행해야 합니다.

MCP에 관한 짧은 노트

Model Context Protocol (MCP)를 통해 도구를 노출하는 경우에도 다섯 가지 패턴은 여전히 적용됩니다. 프로토콜은 단지 호스트가 도구를 발견하고 호출하는 방식을 표준화할 뿐입니다. MCP는 알아둘 가치가 있는 두 가지 인접한 프리미티브(primitives)를 추가합니다:

  • **리소스 (Resources)**는 읽기 전용이며 주소 지정이 가능한 콘텐츠(파일, 데이터베이스 행, URL)입니다. 모델은 URI를 통해 이를 참조할 수 있습니다.
  • **프롬프트 (Prompts)**는 호스트가 사용자에게 제공할 수 있는 재사용 가능한 매개변수화된 템플릿(parameterized templates)입니다.

실질적인 시사점은 다음과 같습니다. 만약 당신의 도구가 근본적으로 "X의 내용을 나에게 달라"는 식이라면, 도구가 아닌 리소스가 되는 것이 좋을 수 있습니다. 리소스는 노출 비용이 더 저렴하고, 캐싱하기 쉬우며, 읽기 위해 에이전트 루프(agent-loop)의 턴을 소모하지 않습니다.

마치며

"모델이 잘못된 도구를 호출했다"는 대부분의 버그는 모델의 버그가 아닙니다. 그것은 설계가 모호할 때 추측하려는 모델의 성향으로 인해 드러난 도구 설계의 버그입니다. 위에서 언급한 다섯 가지 패턴 — 언제 호출해야 하는지 명시하는 설명, 엄격한 스키마(schemas), 지침이 포함된 에러 메시지, 좁은 범위의 도구, 그리고 병렬 안전성(parallel-safety) — 은 LLM이 빠지기 가장 쉬운 모호함의 간극을 메워줍니다.

만약 Claude Certified Architect Foundations 시험을 준비하고 있다면, 도구 설계 및 MCP (Tool Design & MCP) 도메인(블루프린트의 18%)은 정확히 이러한 트레이드오프(tradeoffs)를 테스트하는 시나리오 기반 문제들이 많이 출제됩니다. 제가 운영하는 claudecertifiedarchitect.dev의 독립 연습 플랫폼에는 현재 자신의 수준을 측정해 볼 수 있는 15문제 무료 세트가 준비되어 있으며, 이 중 몇 문제는 이 도메인을 다룹니다. 테스트가 끝나면 진단 결과가 이메일로 발송되며, 체험을 위한 별도의 결제는 필요하지 않습니다.

Anthropic과 제휴 관계는 아니며, 기존에 없던 블루프린트 가중치 기반의 연습 문제를 만들고 싶어서 직접 구축한 서비스입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0