
【AI 에이전트 해부학: 제2회】 지능에 손발을 부여하기: Function Calling과 구조화된 출력 (Structured Outputs)
요약
AI 에이전트가 외부 도구 및 API와 상호작용할 수 있도록 돕는 Function Calling과 Structured Outputs의 개념을 설명합니다. LLM의 모호한 출력을 엄격한 JSON 형식으로 변환하여 프로그램이 안정적으로 실행할 수 있는 메커니즘을 다룹니다.
핵심 포인트
- Function Calling은 LLM이 외부 API를 호출할 수 있는 '손발' 역할을 수행함
- Structured Outputs를 통해 100% 보장된 JSON 형식을 출력하여 파싱 에러 방지
- 사용자 질문, 도구 사양(Schema), 의도 추출, 함수 실행으로 이어지는 데이터 흐름 이해
- 프롬프트 엔지니어링의 한계를 모델 학습과 디코딩 제어로 해결
【
새 연재: AI 에이전트 해부학】 ※본 연재는, 아무 말도 할 수 없는 텅 빈 「챗봇 (Chatbot)」 앞에 서서, 그에게 생명을 불어넣으며 자신의 의지로 움직이는 「AI 에이전트 (AI Agent)」로 파트별로 만들어가는 개발 다큐멘터리입니다.
지난 회차에서 우리는 로봇의 뇌 빈 슬롯에, 사고와 행동의 기본 회로인 「ReAct」 칩을 삽입했습니다.
이를 통해 그는 「현상을 정리하고, 다음에 필요한 행동을 머릿속으로 계획하는」 지적인 고동을 시작했습니다.
하지만 지금의 그는 아직 「머릿속으로 생각만 하고 있는」 존재입니다.
「날씨를 조사하기 위해, 일기 예보 API를 호출할 필요가 있다」라고 사고할 수는 있어도, 실제로 네트워크 너머에 있는 API를 호출하거나, PC의 파일을 읽고 쓰는 구체적인 「손발」은 아직 가지고 있지 않습니다.
이번에는 그의 언어로서의 의지를, 프로그램이나 API를 물리적으로 동작시키는 손발로 전기적으로 연결하는 신경 인터페이스, 「Function Calling (함수 호출)과 구조화된 출력 (Structured Outputs)」이라는 신경 케이블을 로봇에게 장착합니다.
암(Arm)에 케이블을 배치하여 외부 시스템과 동기화시켜 봅시다.
LLM의 본질은 「입력된 문장에 이어질, 확률적으로 가장 그럴듯한 말을 계속해서 생성하는 것」입니다.
하지만 컴퓨터 프로그램이나 API를 움직이기 위해서는, 인간이 사용하는 모호한 말이 아니라, 함수명이나 인자 (인자의 이름과 타입)와 같은 「단 한 글자의 오차도 없는 엄격한 데이터 포맷 (JSON)」이 필요합니다.
「도쿄의 날씨를 조사해줘」라는 인간의 모호한 요구로부터, 프로그램이 처리할 수 있는 get_weather(city="Tokyo")라는 엄격한 형식을 LLM이 어떻게 출력하게 만들 수 있을까요?
Function Calling이 등장하기 전에는, 프롬프트에 「반드시 JSON 형식으로 출력해 주세요. 불필요한 설명문은 일절 생략해 주세요」라고 눈물겨운 노력으로 간청하곤 했습니다. 하지만 그럼에도 LLM은 변덕스럽게 「네, JSON을 출력하겠습니다: json ... 」라며 불필요한 서두를 붙여버렸고, 프로그램 측에서 파싱 (Parsing) 에러를 일으켜 폭주하는 것이 일상이었습니다.
이 과제를 모델의 학습과 디코딩 제어를 통해 해결한 것이 「Function Calling」과, JSON 형식을 100% 보장하는 「구조화된 출력 (Structured Outputs)」입니다.
Function Calling을 구현한 에이전트의 내부에서는 다음과 같은 데이터의 왕복이 발생하고 있습니다.

※그림: 사용자 요구와 도구 정의 (Schema)로부터 JSON을 추출하고, 함수를 실행하여 결과를 돌려주는 Function Calling의 데이터 흐름 (AI 생성 다이어그램)
사양서 제시:
프로그램 측은 사용자의 질문과 함께, 에이전트가 사용할 수 있는 함수의 「사양서 (JSON Schema)」를 LLM에 제시합니다.
의도 추출 (Tool Call):
LLM은 질문과 사양서를 읽고 「이 질문에 답하기 위해서는 이 함수를 이 파라미터로 호출해야 한다」라고 판단합니다. 그리고 인간을 향한 대화 텍스트가 아닌, 「함수명과 인자를 담은 JSON 데이터」만을 출력하고 응답을 일시 정지합니다.
함수 실행:
프로그램 측이 해당 JSON을 파싱하여, 로컬 환경에서 실제 함수 (API 호출 등)를 실행합니다.
결과 관찰:
실행 결과 (Raw Data)를 LLM에 다시 전달하면, LLM이 그것을 바탕으로 최종적인 답변 텍스트를 작성합니다.
이를 통해 모호한 「언어의 바다」와 엄격한 「프로그램 코드의 세계」가, 안전하고 확실한 JSON 신경계로 연결되었습니다.
실제 Web API를 호출하지 않더라도, LLM이 제시된 스키마 (사양서)를 해석하고 프로그램 측이 그 출력 JSON을 바탕으로 함수를 동적 실행하는 「Function Calling의 동작 원리」를 체험할 수 있는 Python 코드입니다.
가지고 계신 환경에서 실행해 보세요.
import json
# 에이전트가 사용할 수 있는 로컬 함수 (손발)
def calculate_distance(speed: float, hours: float) -> str:
...
이 코드를 실행하면, LLM이 출력한 JSON 문자열 (mock_llm_json_output)을 Python 시스템이 파싱하여, 안전하게 로컬 함수 calculate_distance를 선택하고 올바른 인자로 실행하는 흐름이 재현됩니다.

※이미지: 로봇의 팔에 언어(JSON)를 전기 신호로 바꾸어 외부 API로 연결하는 신경 케이블을 연결하는 이미지 (AI 생성 이미지)
이로써 우리의 로봇 팔에 "Function Calling"이라는 신경 케이블이 깔렸으며, 그의 두뇌와 외부 세계를 조작하는 손발이 전기적으로 동기화되었습니다.
하지만 여기서 또 다른 과제가 떠오릅니다.
세상에는 일기 예보, 데이터베이스, Slack, 파일 시스템 등 무수히 많은 외부 도구가 존재합니다. 새로운 도구를 추가할 때마다 우리가 수작업으로 JSON Schema를 작성하고, 개별 연결 프로그램(API 클라이언트)을 일일이 작성하는 것은 너무나 비효율적이며 스마트하지 못한 방식입니다.
만약 전 세계의 모든 도구와 AI를 마치 컴퓨터와 USB 포트처럼 "꽂기만 하면 바로 사용할 수 있는" 공통의 플러그 앤 플레이(Plug & Play) 규격이 있다면 어떨까요?
다음 회차, 제3회.
Anthropic이 제창하며 AI 업계에 혁명을 일으키고 있는 최신 연결 표준, "Model Context Protocol (MCP)의 혁신"이라는 공통 USB 소켓을 그에게 장착하겠습니다.
로봇의 확장성이 전 세계의 모든 도구로 무한히 확장되는 순간을 함께 지켜봐 주십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기