AI Agent · MCP

AI Agent가 JSON 없이는 못 살아나는 이유: Tool Calling, Function Calling, MCP 데이터 흐름

AI Agent가 Tool Calling과 MCP를 위해 JSON에 의존하는 이유

Function Calling / Tool Calling / MCP JSON-RPC — 네 번의 왕복 / 스키마 방언 / 관측 가능성과 격리

Cursor, Claude Code 또는 Agent 프레임워크 디버그 로그를 열면 거의 모든 페이로드가 JSON입니다. 도구 카탈로그는 JSON Schema, 모델 tool_calls는 JSON, MCP Server 프레임은 JSON-RPC 2.0입니다. 이는 우연이 아닙니다 — Agent는 예측 불가능한 자연어와 실행 가능한 프로그램 인터페이스를 연결해야 하고, JSON은 양쪽이 안정적으로 파싱할 수 있는 교환 형식입니다.

이 글은 Function Calling → Tool Calling → MCP를 따라가며 완전한 도구 호출에서 네 번의 JSON 왕복을 매핑합니다. 클라우드 Mac에 MCP Server를 배포하거나 GitHub Agent 선정 목록에서 프레임워크를 고르는 중이라면, API 문서를 외우는 것보다 이 흐름을 이해하는 편이 디버깅에 더 낫습니다.

Agent는 거의 모든 곳에서 JSON을 사용한다

LLM은 토큰 스트림을 출력하고, Shell·데이터베이스·HTTP API는 구조화된 인자가 필요합니다. 초기 관행은 프롬프트에 「이 JSON 형식으로 답해」라고 쓰는 것이었습니다 — 모델은 trailing comma를 넣거나 따옴표를 빼거나 Markdown fence로 감싸고, 파서는 계속 실패했습니다.

2023년 이후 주요 API는 구조화된 액션을 프로토콜 계층으로 옮겼습니다: 모델이 임의의 JSON 텍스트를 자유롭게 출력하지 않고, 서버가 출력 형태를 제한하고 Host가 실행합니다. 파이프라인은 다음과 같습니다:

  • Declare — JSON Schema로 도구 등록;
  • Decide — 제한된 문법 안에서 도구 이름과 파라미터 결정;
  • Execute — 로컬 코드 또는 MCP Server로 실행;
  • Write back — 결과를 JSON 메시지로 컨텍스트에 되돌려 쓰기.

설계 원칙: Agent 관측 가능성 = 모든 JSON 단계를 로깅·재생·diff. 구조화된 중간 단계 없이는 자동화를 감사할 수 없습니다.

Function Calling: 자연어에서 구조화된 액션으로

OpenAPI 시대의 function 객체

OpenAI는 Chat Completions에 functions / tools를 추가했습니다. 요청에 도구 정의를 붙이면 모델은 regex로 파싱해야 하는 텍스트 대신 function_call 또는 tool_calls를 반환합니다.

일반적인 요청 스니펫

json
{
  "model": "gpt-4o",
  "messages": [{"role": "user", "content": "도쿄 날씨?"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "도시별 현재 날씨",
      "parameters": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  }]
}

프롬프트의 수기 JSON 템플릿은 프로토콜 제약으로 대체되고, Host는 arguments를 스키마로 검증한 뒤 실제 함수를 호출합니다. Function Calling은 모델이 말하는 것을 고정합니다 — 도구가 어디서 실행되는지, 어떻게 발견되는지, 인증이 어떻게 되는지는 아닙니다. Tool Calling 생태계와 MCP가 그것을 담당합니다.

Tool Calling: 턴당 네 번의 JSON 왕복

  1. Register — Host가 JSON Schema가 포함된 tools[]를 모델 API에 전송;
  2. Decide — API가 id, name, arguments(JSON 문자열)를 포함한 tool_calls 반환;
  3. Execute — Host가 인자를 파싱하고 로컬 코드 또는 MCP 호출;
  4. Write backrole: tool 메시지가 결과 반환, 모델이 사용자용 답변 생성.
json
{
  "tool_calls": [{
    "id": "call_abc123",
    "type": "function",
    "function": {
      "name": "get_weather",
      "arguments": "{\"city\":\"Tokyo\"}"
    }
  }]
}

arguments는 중첩 객체가 아니라 문자열입니다 — 스트리밍과 SDK 호환을 위해. Host는 검증 전에 JSON.parse(arguments)를 실행해야 합니다. DevTools에서 Ctrl + Shift + I를 누르면 Network 탭에서 같은 구조를 볼 수 있습니다.

단계방향페이로드파서
① RegisterHost → APItools[] + JSON SchemaAPI 게이트웨이
② DecideAPI → Hosttool_callsHost / SDK
③ ExecuteHost → Tool파싱된 객체도구 구현
④ Write backHost → API{role:"tool", content:"..."}모델

API 스키마 방언

OpenAI / 호환 엔드포인트
tools + tool_choice; 스트리밍은 delta.tool_calls 청크 사용.
Anthropic
input_schema가 있는 tools; 응답은 tool_use 블록과 tool_result 회신.
Google Gemini
필드명이 다른 functionDeclarationsfunctionCall.
Ollama 로컬
OpenAI 호환 tools; 기능은 모델 학습에 따라 다름.

LangGraph, DeepSeek Harness 같은 프레임워크(우리 Harness 가이드 참고)는 이런 방언을 하나의 Tool 추상화로 압축합니다 — 아래는 여전히 JSON입니다.

MCP: JSON-RPC가 도구 계층을 표준화

Model Context Protocol (MCP)는 Function Calling 아래에 있습니다 — 도구 프로세스가 Host 간에 어떻게 발견·파라미터화·재사용되는지. 전송은 stdio 또는 SSE일 수 있지만 메시지는 항상 JSON-RPC 2.0입니다.

계층프로토콜예시
Model APIREST / OpenAI 호환chat/completions + tools
MCPJSON-RPC 2.0tools/list, tools/call
Business임의파일, DB, HTTP

Host는 시작 시 tools/list를 호출하고, 카탈로그를 API tools[]로 변환한 뒤, 모델이 결정한 후 tools/call을 전송합니다 — 두 번의 방언 변환, 하나의 의미적 파이프라인.

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "read_file",
    "arguments": { "path": "/tmp/demo.txt" }
  }
}
stdio 모드에서 JSON 프레임은 어떻게 구분되나요?

MCP stdio는 newline 구분 JSON이 아니라 Content-Length 헤더 + JSON 본문(LSP와 유사)을 사용합니다. 큰 페이로드(예: base64 리소스)도 한 프레임에 들어갑니다. SSE는 HTTP 이벤트 스트림으로 JSON-RPC를 감싸 멀티 클라이언트 Server를 지원합니다.

전체 데이터 흐름: 사용자 입력부터 도구 실행까지

Agent Tool Calling JSON 데이터 흐름 다이어그램
사용자 입력부터 MCP 실행까지 — 모든 단계를 로깅하고 재생할 수 있습니다.
  • 로그가 각 tools/list 버전과 도구 수를 기록하는가?
  • 실행 전에 arguments가 스키마로 검증되는가?
  • MCP 타임아웃이 읽기 쉬운 tool 메시지로 매핑되는가?
  • 로깅 전에 비밀 정보가 제거되는가?

우리 AI Coding Workflow의 Verify 단계와 같은 아이디어입니다 — 파싱 가능한 중간 단계 없이는 Agent가 올바른 도구를 실제로 호출했는지 자동 검증할 수 없습니다.

Protobuf나 XML은 왜 아닐까?

  • 모델 API는 JSON 우선; 바이너리는 직렬화 계층을 추가;
  • 디버깅 — 엔지니어가 로그에서 파라미터를 읽음;
  • 스키마 생태계 — JSON Schema와 OpenAPI가 사실상 표준;
  • 스크립트와 브라우저 — curl, n8n, 프론트엔드 데모는 JSON을 가정.

트레이드오프: 크기와 CPU. High-QPS 설정은 내부 캐시와 로그 압축을 사용하고, 큰 blob은 JSON 필드 안에 base64 — JSON envelope을 대체하지 않습니다.

JSON 비용과 엔지니어링 대응

증상원인대응
arguments parse error모델의 잘못된 JSON 문자열더 엄격한 스키마, 낮은 temperature, 재시도
잘못된 도구모호하거나 너무 많은 도구 설명도구 병합, 부정 예시 추가
MCP 멈춤불완전한 stdio 프레임 또는 죽은 프로세스launchd 감독, 헬스 체크
로그에 비밀 노출도구 결과에 환경 변수 포함결과 redact, 별도 실행 계정

프로덕션 팁: 격리된 클라우드 Mac에서 MCP 실행 — 노트북의 Cursor가 SSH로 JSON-RPC를 전송하고, Shell은 일상 기기에 두지 않습니다.

Agent가 JSON에 의존하는 이유는 자연어 결정프로그램 실행이 사람이 읽을 수 있고 기계가 검증할 수 있으며 플러그 가능한 계약이 필요하기 때문입니다. Function Calling은 모델이 말하는 것을 정의하고, Tool Calling은 Host가 한 턴을 어떻게 실행하는지 정의하고, MCP는 도구 프로세스가 생태계에 어떻게 연결되는지 정의합니다 — JSON은 세 가지를 잇는 실입니다.

클라우드 Mac에서 MCP의 JSON 실행 계층 운영

M4 전용 노드, 일 단위 과금, SSH 즉시 사용

싱가포르 · 일본 · 한국 · 홍콩 · 미국 리전

격리된 클라우드 Mac에서 tools/call을 실행하고, 로컬 Host는 JSON-RPC만 전송합니다. ZekVPS 클라우드 Mac mini 플랜 보기

한정 혜택