도구 인터페이스 — 에이전트에 구조화 입출력(Structured I/O)이 필요한 이유

언어 모델은 토큰을 생성합니다. 프로그램은 행동을 수행합니다. 이 둘 사이의 간극을 메우는 것이 도구 인터페이스(Tool Interface)입니다. 도구 인터페이스는 모델이 행동을 요청하고, 호스트(host)가 그 행동을 실제로 실행할 수 있게 해주는 계약(contract)입니다. 2026년의 모든 스택, 즉 OpenAI·Anthropic·Gemini의 함수 호출(Function Calling), MCP의 tools/call, A2A의 task parts는 모두 같은 4단계 루프를 서로 다른 방식으로 인코딩한 것입니다. 이 강의는 그 루프에 이름을 붙이고, 루프를 실행하는 데 필요한 최소 장치를 보여드립니다.

유형: Learn 언어: Python (표준 라이브러리, LLM 없음) 선수 지식: Phase 11 (LLM completion APIs) 예상 시간: 약 45분

학습 목표

  • 텍스트만 생성할 수 있는 LLM이 왜 스스로 현실 세계에 행동을 취할 수 없는지 설명할 수 있습니다.
  • 4단계 도구 호출 루프(describe → decide → execute → observe)를 그리고, 각 단계를 누가 책임지는지 말할 수 있습니다.
  • 도구 설명을 이름(name), JSON Schema 입력, 결정적(deterministic) 실행기(executor) 함수라는 세 부분으로 작성할 수 있습니다.
  • 순수 도구(Pure tool)와 부수효과가 있는 도구(Side-effecting / Consequential tool)를 구분하고, 이 분리가 안전(safety) 측면에서 왜 중요한지 설명할 수 있습니다.

문제

LLM은 다음 토큰(token)에 대한 확률 분포를 출력합니다. 그것이 LLM이 외부로 내보낼 수 있는 출력의 전부, 즉 출력 표면(output surface)입니다. 채팅 모델에게 "지금 Bengaluru의 날씨가 어때?"라고 물으면 그럴듯한 문장을 작성해줄 수는 있습니다. 하지만 날씨 API에 직접 접속할 수는 없습니다. 그래서 그 문장은 우연히 맞을 수도 있고, 사흘 전의 정보일 수도 있습니다.

이 간극을 메우는 것이 도구 인터페이스의 목적입니다. 호스트(host) 프로그램, 즉 에이전트 런타임(agent runtime)이나 Claude Desktop, ChatGPT, Cursor, 혹은 직접 작성한 스크립트는 호출 가능한 도구 목록을 모델에게 알려줍니다. 모델은 행동이 필요하다고 판단하면 도구 이름과 인자(arguments)를 담은 구조화된 페이로드(payload)를 출력합니다. 호스트는 그 페이로드를 파싱하고, 실제로 도구를 실행한 뒤, 결과를 다시 모델에 입력으로 넣어 줍니다. 모델이 더 이상 호출이 필요 없다고 판단할 때까지 이 루프(loop)는 계속됩니다.

이 계약의 첫 버전은 2023년 6월 OpenAI의 "functions" 파라미터로 공개되었습니다. Anthropic은 Claude 2.1에서 tool_use 블록(block)으로 뒤따라 제공했습니다. Gemini는 몇 달 뒤 functionDeclarations를 추가했습니다. 이제 모든 제공자(provider)는 같은 형태를 제공합니다. 요청으로는 JSON Schema 타입의 도구 목록이 들어가고, 응답으로는 JSON 형태의 도구 호출 페이로드가 돌아옵니다. 모델 컨텍스트 프로토콜(Model Context Protocol; MCP, 2024년 11월)은 이 계약을 일반화해 하나의 도구 레지스트리(registry)가 모든 모델에 제공될 수 있게 만들었습니다. A2A(2026년 4월 v1.0)는 같은 기본 단위를 에이전트 간 위임(agent-to-agent delegation)에 그대로 얹은 형태입니다.

이 모든 것의 아래에서 변하지 않는 것은 4단계 루프입니다. Phase 13의 나머지 강의는 모두 이 루프의 확장에 해당합니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.LLM 도구 인터페이스가 해결하는 핵심 과제는?

2.LLM 도구 인터페이스 이전의 주요 한계는?

0/2 답변 완료

개념

Step one: describe (1단계: 설명)

호스트는 각 도구를 세 가지 필드로 선언합니다.

  • 이름(Name). 안정적이고 기계가 판독 가능한 식별자입니다. "weather thing"이 아니라 get_weather처럼 표기합니다.
  • 설명(Description). 한 문단 분량의 자연어 안내입니다. 예: "사용자가 특정 도시의 현재 상태를 물을 때 사용합니다. 과거 데이터에는 사용하지 않습니다."
  • 입력 스키마(Input schema). 도구 인자를 설명하는 JSON Schema 객체입니다. 보통 draft 2020-12를 사용합니다.

모델은 이 목록을 받습니다. 최신 제공자(provider)들은 이 선언을 제공자별 템플릿으로 시스템 프롬프트(system prompt)에 직렬화해 주기 때문에, 호출하는 쪽에서는 구조화된 형태만 다루면 됩니다.

Step two: decide (2단계: 결정)

사용자 메시지와 사용 가능한 도구가 주어졌을 때, 모델은 다음 세 가지 행동 중 하나를 고릅니다.

  1. 텍스트로 직접 답변합니다. 이 경우 도구 호출은 발생하지 않습니다.
  2. 하나 이상의 도구를 호출합니다. 구조화된 호출 객체를 출력합니다. OpenAI와 Gemini에서는 기본값이고 Anthropic에서는 옵트인(opt-in)인 parallel_tool_calls: true 설정에서는, 모델이 한 차례(turn)에 여러 호출을 동시에 출력할 수도 있습니다.
  3. 거절(refuse)합니다. 엄격 모드(strict mode) 구조화 출력에서는 호출 대신 타입이 지정된 refusal 블록을 만들 수 있습니다.

도구 호출 페이로드(payload)에는 변하지 않는 세 가지 필드가 있습니다. 호출 id, 도구 name, JSON arguments 객체입니다. 여기서 id는 나중에 돌아오는 결과를 어떤 호출의 응답인지 연결하기 위한 식별자입니다. 병렬 호출(parallel call)의 결과가 순서대로 돌아오지 않을 때 특히 중요합니다.

Step three: execute (3단계: 실행)

호스트는 호출을 받아 선언된 스키마로 인자를 검증한 뒤, 실행기(executor)를 호출합니다. 잘못된 인자가 들어왔다는 것은 모델이 필드를 환각(hallucination)했거나 타입을 잘못 지정했다는 신호입니다. 성능이 약한 모델에서 매우 흔한 실패 양상입니다. 프로덕션 호스트는 잘못된 인자에 대해 보통 세 가지 중 하나로 대응합니다. 빠르게 실패(fail fast)시키고 오류를 모델에게 그대로 보여주거나, 제약 파서(constrained parser)로 JSON을 복구하거나, 검증 오류를 프롬프트에 포함시켜 모델을 다시 호출하는 방식입니다.

실행기 자체는 평범한 코드입니다. Python, TypeScript, 셸 명령(shell command), 데이터베이스 쿼리 등 무엇이든 될 수 있습니다. 실행기는 결과를 만들어내며, 그 결과는 보통 문자열이지만 어떤 JSON 값이든 될 수 있고, 구조화된 콘텐츠 블록(content block)일 수도 있습니다. MCP에서는 텍스트, 이미지, 리소스 참조(resource reference)가 결과가 될 수 있습니다. 결과는 반드시 직렬화 가능해야 합니다.

Step four: observe (4단계: 관찰)

호스트는 도구 결과를 대화에 덧붙입니다. 보통은 같은 id를 가진 tool 역할(role) 메시지로 추가한 뒤 모델을 다시 호출합니다. 이제 모델은 도구의 출력을 문맥(context) 안에 갖고 있게 되며, 최종 답을 만들거나 추가 호출을 요청할 수 있습니다. 이 과정은 모델이 호출을 멈출 때까지, 또는 호스트가 미리 정한 반복 횟수의 안전 한계에 도달할 때까지 이어집니다.

신뢰 분리(Trust split)

안전(safety) 관점에서 중요한 도구는 다음 두 종류로 나뉩니다.

  • 순수 도구(Pure tool). 읽기 전용이고, 결정적(deterministic)이며, 부수효과(side effect)가 없습니다. 예로는 get_weather, search_docs, get_current_time이 있습니다. 추측 삼아 호출해도 안전합니다.
  • 결과를 바꾸는 도구(Consequential tool). 상태를 변경하거나, 비용을 지출하거나, 사용자 데이터를 건드립니다. 예로는 send_email, delete_file, execute_trade가 있습니다. 반드시 관문(gate)을 두어야 합니다.

Meta가 2026년에 제시한 에이전트 보안 원칙 "두 가지 규칙(Rule of Two)"은 한 차례(turn)가 다음 세 가지 중 최대 두 가지만 결합해야 한다고 말합니다. 신뢰할 수 없는 입력(untrusted input), 민감한 데이터(sensitive data), 결과를 바꾸는 행동(consequential action)이 그것입니다. 도구 인터페이스는 바로 이 규칙을 강제하는 지점입니다. 호출을 거절하거나, 사용자 확인을 요구하거나, 권한 범위(scope)를 단계적으로 확장(escalate)하는 방식으로 강제합니다. 보안 전체 내용은 Phase 13 · 15, 에이전트 수준의 권한 정책(permission policy)은 Phase 14 · 09를 참고해주세요.

루프는 어디에 있는가

맥락누가 describe(설명)하는가누가 decide(결정)하는가누가 execute(실행)하는가
단일 차례(turn) 함수 호출(OpenAI/Anthropic/Gemini)앱 개발자LLM앱 개발자
MCPMCP 서버(server)MCP 클라이언트(client)를 거친 LLMMCP 서버
A2AAgent Card 게시자호출하는 에이전트호출받는 에이전트
웹 브라우저(함수 호출 에이전트)브라우저 확장 프로그램(extension) / WebMCPLLM브라우저 런타임(runtime)

어디서든 동일한 네 단계입니다. 열의 이름은 바뀌지만 구조 자체는 바뀌지 않습니다.

그냥 모델에게 JSON을 출력하게 하면 안 되는가?

"JSON으로 답해"라고 모델에게 요청하는 방식은 함수 호출(Function Calling)이 등장하기 이전의 패턴이었습니다. 최전선(frontier) 모델에서도 약 5~15% 정도 실패하고, 작은 모델에서는 훨씬 더 자주 실패합니다. 실패 양상은 중괄호 누락, 끝에 붙은 쉼표(trailing comma), 환각된 필드, 잘못된 타입 같은 것들입니다. 그러면 JSON 복구(repair) 패스, 재시도(retry), 제약 디코더(constrained decoder)가 추가로 필요해집니다.

네이티브 함수 호출이 더 나은 이유는 세 가지입니다. 첫째, 제공자가 정확한 호출 형태에 맞춰 모델을 종단 간(end-to-end)으로 학습시키기 때문에, 엄격 모드에서는 올바른(valid) JSON 비율이 98~99%까지 올라갑니다. 둘째, 호출 페이로드가 자유 텍스트 안이 아니라 프로토콜의 별도 슬롯(slot)에 들어가므로, 도구 호출이 사용자에게 보이는 답변으로 새어 나가지 않습니다. 셋째, 제공자가 스키마 준수를 제약 디코딩(constrained decoding)으로 강제합니다. OpenAI의 엄격 모드, Anthropic의 tool_use, Gemini의 responseSchema가 여기에 해당합니다. 그 결과 출력이 항상 스키마 검증을 통과하도록 보장됩니다.

Phase 13 · 02는 세 제공자의 API를 나란히 비교하며, Phase 13 · 04는 구조화 출력(Structured Output)을 더 깊게 다룹니다.

회로 차단기(Circuit breaker)

루프는 모델이 호출을 멈추거나, 호스트가 최대 차례 수에 도달하면 종료됩니다. 프로덕션 호스트는 보통 이 값을 5~20 차례 사이로 설정합니다. 그 이상이면 모델이 빠져나오지 못하는 루프에 갇혔을 가능성이 큽니다. Claude Code는 기본값이 20이고, OpenAI Assistants는 10, Cursor의 에이전트 모드는 25입니다.

이 한계를 두지 않는 대안, 즉 무제한 루프는 6개월마다 한 번씩 "에이전트가 밤새 API 호출로 400달러를 썼다"는 사후 분석으로 어김없이 등장합니다. 한계(bound) 없이 출시해서는 안 됩니다.

Phase 14 · 12는 오류 복구와 자가 치유(self-healing)를 깊게 다루고, Phase 17은 프로덕션 환경의 속도 제한(rate limit)을 다룹니다.

Phase 13의 앞으로의 흐름

  • Lesson 02~05는 제공자 수준의 도구 호출 표면을 다듬습니다.
  • Lesson 06~14는 이 루프를 MCP로 일반화합니다.
  • Lesson 15~18은 적대적 서버(hostile server), 악의적 사용자(adversarial user), 인증되지 않은 원격 인증 표면(unauthenticated remote auth surface)으로부터 루프를 방어합니다.
  • Lesson 19~22는 이 패턴을 에이전트 간 협업(agent-to-agent collaboration), 관측 가능성(observability), 라우팅(routing), 패키징(packaging)으로 확장합니다.
  • Lesson 23은 모든 기본 단위(primitive)를 사용해 완전한 생태계(ecosystem)를 출시합니다.

남은 모든 강의는 이 4단계 루프의 확장입니다. 이 루프를 변하지 않는 불변식(invariant)으로 기억해두시면 좋겠습니다.

사용해보기

code/main.py는 LLM 없이도 4단계 루프를 실행합니다. 가짜 "결정자(decider)" 함수가 사용자 메시지에서 패턴 매칭(pattern matching)으로 모델을 흉내 냅니다. 실행기(executor), 스키마 검증기(schema validator), 관찰(observe) 단계의 하네스(harness)는 실제 구현입니다. 한 번 실행해 요청과 응답의 흐름(choreography)과 중간 상태가 출력되는 모습을 보신 뒤, 이후 강의에서 이 가짜 결정자를 실제 제공자로 바꿔보시면 됩니다.

눈여겨볼 지점은 다음과 같습니다.

  • 도구 레지스트리(registry)는 도구마다 이름(name), 설명(description), 스키마(schema), 실행기 참조(executor reference)라는 세 필드를 가집니다.
  • 검증기는 표준 라이브러리만으로 작성한 최소 JSON Schema 부분 집합(subset)입니다. 타입, required, enum, min/max를 다룹니다. Phase 13 · 04에서는 더 완성된 버전을 만듭니다.
  • 루프는 반복 횟수를 5로 제한합니다. 프로덕션 에이전트에는 정확히 이런 형태의 회로 차단기(circuit breaker)가 필요합니다.

산출물 만들기

이 강의는 outputs/skill-tool-interface-reviewer.md를 만듭니다. 도구 정의 초안(draft tool definition), 즉 이름 + 설명 + 스키마 + 실행기 윤곽(executor outline)이 주어지면, 이 스킬(skill)은 그 정의가 4단계 루프에 잘 맞는지(loop fitness)를 감사합니다. 이름이 기계적으로 안정적인지, 설명이 완전한 사용 안내(usage brief)인지, 스키마가 JSON Schema 2020-12를 올바르게 사용하고 있는지, 순수 도구와 결과를 바꾸는 도구(pure vs. consequential)의 분류가 명시적으로 드러나 있는지 점검합니다.

연습문제

  1. code/main.pyget_stock_price(ticker)라는 네 번째 도구를 추가하세요. 설명(description)은 "Use when the user asks for a current stock price by ticker. Do not use for historical prices or market summaries."로 작성합니다. 하네스를 실행해, 종목 코드(ticker)를 언급한 질의가 새 도구로 라우팅되는지 확인합니다.

  2. 스키마 검증기를 일부러 깨뜨려 보세요. arguments 객체에서 필수 필드(required field)가 빠진 호출을 전달해, 실행 전에 호스트가 그 호출을 거절하는지 확인합니다. 그다음으로는 알 수 없는 추가 필드가 포함된 호출을 전달해 봅니다. 그리고 결정해보세요. 호스트는 이를 거절해야 할까요, 아니면 무시해야 할까요? 안전(safety) 관점의 논거로 자신의 선택을 정당화해보세요.

  3. 하네스의 각 도구를 순수 도구(pure) 또는 결과를 바꾸는 도구(consequential)로 분류해보세요. 필요한 레지스트리 항목에 consequential: true 플래그를 추가하고, 결과를 바꾸는 도구가 선택될 때마다 루프가 "would confirm with user" 줄을 출력하도록 바꿉니다. 이것이 모든 프로덕션 호스트에 필요한 확인 관문(confirmation gate)의 기본 형태입니다.

  4. 위의 제공자 열 표를 Claude Desktop, Cursor, ChatGPT, 혹은 직접 쓰는 스택(stack) 중 좋아하는 클라이언트를 기준으로 채워보고, 4단계 루프를 종이에 그려보세요. MCP 전용 변형은 Phase 13 · 06과 대조해 보시면 좋습니다.

  5. OpenAI의 함수 호출(function-calling) 가이드를 처음부터 끝까지 읽어보세요. 여기서 제시한 4단계 루프에는 없지만 요청 안에는 들어 있는 필드를 하나 찾아내세요. 그 필드가 무엇을 더해주는지, 왜 본질적이라기보다는 편의적인지 설명해보세요.

핵심 용어

용어흔한 설명실제 의미
도구(Tool)"모델이 호출할 수 있는 것"이름 + JSON Schema 타입의 입력 + 실행기 함수로 구성된 삼중 구조
함수 호출(Function calling)"네이티브 도구 사용(tool use)"산문(prose) 대신 구조화된 도구 호출을 출력하도록 해주는 제공자 수준의 API 지원
도구 호출(Tool call)"행동하라는 모델의 요청"모델이 출력하는 id, name, arguments 필드를 가진 JSON 페이로드
도구 결과(Tool result)"도구가 반환한 것"실행기의 출력. 같은 id를 가진 tool 역할 메시지로 감싸 반환된다
병렬 도구 호출(Parallel tool calls)"한 번에 여러 호출"한 차례(turn) 안에 들어 있는 여러 호출 객체. id로 독립 실행과 정렬이 가능하다
엄격 모드(Strict mode)"보장된 JSON"모델 출력이 선언된 스키마를 따르도록 강제하는 제약 디코딩(constrained decoding)
순수 도구(Pure tool)"읽기 전용 도구"부수효과(side effect)가 없고 재실행해도 안전한 도구
결과를 바꾸는 도구(Consequential tool)"행동 도구"외부 상태를 변경하며 관문(gate), 감사(audit), 사용자 확인이 필요한 도구
4단계 루프(Four-step loop)"도구 호출 사이클(cycle)"describe → decide → execute → observe
호스트(Host)"에이전트 런타임(agent runtime)"도구 레지스트리를 보유하고 모델을 호출하며 실행기를 구동하는 프로그램

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

tool-interface-reviewer

Audit a tool definition (name + description + JSON Schema + executor outline) for loop fitness before it ships to an LLM.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.프로덕션에서 LLM 도구 인터페이스의 가장 중요한 설계 원칙은?

2.LLM 도구 인터페이스가 올바른 선택이 아닌 경우는?

3.LLM 도구 인터페이스는 AI 생태계에 어떻게 들어맞나요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다