JSON 출력과 Function Calling의 본질적 차이
누가 인터페이스를 정의하고, 누가 파라미터를 검증하며, 누가 실행 경계를 책임지는가
- JSON 출력이 해결하는 것은 구조화 표현이며, 본질은 여전히 자연어 생성이다. 필드가 빠질 수 있고, 타입이 틀릴 수 있고, 괄호가 깨질 수 있고, 열거값이 범위를 벗어날 수 있으므로 백엔드가 반드시 폴백해야 한다
- Function Calling이 해결하는 것은 통제된 도구 호출이다. 모델은 사전 정의된 Schema 하에서 「호출 의도 + 파라미터」만 산출하고 실행권은 시스템 손에 남으며, 타입/권한/업무 3계층 검증이 가능하다. 실제 동작을 유발하는 모든 장면(DB 조회, 요청 발송, 티켓 작성, 일정 생성, 설정 변경)은 반드시 Function Calling을 타야 하며, 최소 권한·사용자 확인·실패 롤백·감사 기록을 함께 갖춰야 한다
| 차원 | JSON 출력 | Function Calling |
|---|
| 무엇을 해결하나 | 구조화 표현 | 통제된 도구 호출 |
| 중점 | 필드 포맷 | Schema 제약, 파라미터 검증, 권한 통제, 실행 폐루프 |
| 위치 | 「구조화 텍스트」 쪽 | 「통제된 동작」 쪽 |
| 시스템 역할 | 모델이 결과 텍스트를 직접 제시 | 모델 출력이 명확한 도구 Schema로 제약되고, 다시 시스템이 실행 여부·방법·결과 기록을 결정 |
| 외부 동작 유발 여부 | 유발하지 않음, 업무 코드가 읽을 뿐 | 실제 시스템에 연결 |
| 전형적 동작 | | DB 조회, 요청 발송, 티켓 작성, 일정 생성, 설정 변경 |
JSON 출력의 잠재 리스크: 본질은 여전히 자연어 생성
- 필드가 빠질 수 있음
- 타입이 틀릴 수 있음
- 괄호가 깨질 수 있음
- 열거값이 범위를 벗어남
- 백엔드 폴백 필요
Function Calling: Schema가 사전에 정의하는 것
| 항목 | 설명 |
|---|
| 함수명(Name) | 도구의 고유 식별자 |
| 파라미터 필드(Parameters) | 입력 파라미터 이름 |
| 타입 | 파라미터 타입 제약 |
| 열거값 | 취할 수 있는 값의 범위 |
| 필수 항목 | 어떤 파라미터가 생략 불가한가 |
| 설명 | 모델이 용도를 이해하기 위한 서술 |
Function Calling: 실행 경계
- 최소 권한
- 사용자 확인
- 실패 롤백
- 감사 기록
정리
- JSON 출력은 구조화 생성으로 볼 것
- Function Calling은 도구 호출 프로토콜로 볼 것
- JSON은 추출과 분류에 적합하고, Function Calling은 실제 도구와 업무 동작 연결에 적합하다
- 실행이 관련되면 반드시 Schema, 권한, 검증, 감사를 설계에 넣어야 한다
핵심 통찰
- 포맷 문제라는 껍데기 아래에서 묻는 것은 「제어권의 귀속」이다 — 3문(누가 인터페이스를 정의하나 / 누가 파라미터를 검증하나 / 누가 실행 경계를 책임지나)의 본질은 모델과 시스템 사이의 신뢰 경계를 어디에 그을 것인가다. 이 주선을 먼저 세우면 이후 모든 디테일은 그것의 전개다.
- JSON 출력은 언제나 「확률의 산물」이지 「계약」이 아니다 — Prompt를 아무리 엄격히 써도 그것은 여전히 자연어 생성이며 필드/타입/괄호/열거값이 모두 틀릴 수 있다. 모델 출력을 신뢰할 수 없는 입력으로 처리하는 것이 AI 애플리케이션 공학의 제1원칙이다.
- Function Calling의 가치는 「포맷이 더 정확함」이 아니라 「실행권을 시스템 측에 남기는 것」이다 — 모델은 호출 의도 + 파라미터만 산출하고, 실제로 실행할지는 시스템이 재정한다. 이는 모델과 실세계 사이에 프로그래밍 가능한 관문을 하나 끼워 넣는 것과 같다.
- Schema는 「양방향」이다 — 모델에게는 생성 제약이고(Schema를 엄격히 따라 생성), 시스템에게는 검증 근거다(타입/권한/업무 3계층 검증). 같은 Schema가 Prompt 공학과 입력 검증이라는 두 역할을 동시에 맡는다는 점이 자유 텍스트보다 값진 이유다.
- 어느 쪽을 쓸지는 한 문장만 물으면 된다: 부작용이 생기는가 — 읽기만 하고 표현만 하면 → JSON 출력, DB를 쓰고 메시지를 보내고 설정을 바꾸면 → Function Calling + 안전 4종 세트. 이 기준이 「어느 쪽이 더 안정적인가」보다 훨씬 실용적이다.
- 관측성은 대다수가 빠뜨리는 세 번째 차원이다 — JSON은 오류 시 「파싱 실패」만 보이는 귀인 불가능한 블랙박스지만, Function Calling은 「어떤 도구를 골랐나 / 어떤 파라미터를 넘겼나 / 검증을 통과했나 / 무엇을 반환했나」라는 구조화된 궤적을 태생적으로 생산한다. 이것이 바로 이후의 평가(eval)와 운영 트러블슈팅의 데이터 기반이다. 설계 시점에 이 궤적을 남겨야지 사고 후에 로그를 붙이면 안 된다.
- 분수령은 「모델 출력이 어떻게 업무 시스템으로 들어가는지」를 서술할 수 있는가에 있다 — Prompt만 쓸 줄 아는 것은 애플리케이션 계층이고, 시스템 경계를 규정할 수 있어야 시스템 설계 계층이다.
엔지니어링 실전 Tips
- 열거값은 반드시 Schema에 써넣을 것. Prompt 설명에만 쓰지 말 것: 열거값 범위 이탈은 JSON 출력에서 가장 빈도 높은 나쁜 냄새다. Schema 계층 제약 + 백엔드 화이트리스트 이중 보험.
- 필수 항목 + 타입 + 설명 셋 중 하나도 빠지면 안 된다: 설명 필드(description)는 모델이 도구를 고르는 주요 근거이며, 모호하게 쓰면 파라미터를 잘못 채우는 게 아니라 도구를 잘못 고르게 된다.
- 검증 순서에 요령이 있다: 먼저 타입(저렴하고 정적으로 판단 가능) → 그다음 권한(할 수 있는지 결정) → 마지막에 업무(DB 조회가 필요할 수 있어 가장 비쌈). 순서가 틀리면 백엔드 자원을 헛되이 소모한다.
- 쓰기 동작 전에 「사용자 확인」을 전치할 것: 모델의 호출 의도를 사람의 말 한 문장으로 렌더링해 보여주는 것(「X에게 면접 초대를 발송하려 합니다. 확인하시겠습니까?」)이 사후 롤백보다 비용이 훨씬 낮다.
- 감사 기록은 「4요소」를 기록할 것: 어떤 도구를 골랐나, 어떤 파라미터를 넘겼나, 검증 결론, 도구 반환값. 이 기록은 트러블슈팅 근거이자 이후 자동화 평가를 위한 데이터셋이 된다.
- 실패 롤백은 설계 시점에 보상 동작을 정의할 것: 다중 시스템 연동(레코드 생성 → 초대 발송 → 채용 시스템 동기화) 중간에 실패하면 보상 동작이 없을 때 더러운 데이터가 남는다.
- JSON 출력을 맨몸으로 파싱하지 말 것: 파싱 실패 시 강등 경로(한 번 재시도 / 더 엄격한 프롬프트로 전환 / 사람 전환)가 있어야 하며, 괄호 하나 깨진 것이 전체 링크를 관통하게 두면 안 된다.