Function Calling은 모델이 도구 Schema를 바탕으로 JSON 호출 요청을 만들도록 설계하고, 실제 API 실행은 애플리케이션의 실행기에 맡기는 방식으로 구현해야 합니다. 이번 주에는 공통 호출 계약을 먼저 만들고, OpenAI·Gemini·Claude API별 변환 계층을 분리하는 작업부터 시작하는 편이 안전합니다.
이 글은 처음 도구형 AI를 만드는 백엔드 개발자, 여러 모델을 연결하는 플랫폼 엔지니어, 인증 정보와 고위험 작업을 관리하는 보안 담당자를 위한 안내서입니다. 단일 모델 실험과 다중 모델 운영을 나눠 판단할 수 있도록 구성했습니다.
공통 호출 흐름과 책임 분리
Function Calling JSON API의 핵심은 모델에게 외부 시스템의 권한을 넘기는 것이 아닙니다. 모델은 사용자의 의도를 해석하고, 등록된 도구 가운데 하나를 선택한 뒤, 이름과 입력값을 구조화해 반환합니다. 실행기는 그 요청을 검증한 후 실제 API나 내부 함수를 호출합니다.
공통 흐름은 다음과 같습니다.
- 개발자가 도구 이름, 설명, 입력 Schema를 등록합니다.
- 모델이 도구 호출 여부와 JSON 매개변수를 반환합니다.
- 실행기가 인증·네트워크·시간 초과·중복 실행을 처리합니다.
- 실행 결과를 모델에 돌려보내 최종 답변을 생성합니다.
Google Gemini 공식 안내도 모델이 함수를 직접 실행하지 않으며, 애플리케이션이 함수 이름과 매개변수를 추출해 실행해야 한다고 설명합니다. (ai.google.dev)
이 흐름을 역할별로 나누면 책임이 선명해집니다.
- 모델 접속 담당자: 사용할 도구와 Schema를 선언합니다.
- 공급업체 적응 계층 담당자: 응답 블록, 함수 이름, 호출 식별자, 매개변수 필드를 내부 이벤트로 바꿉니다.
- 도구 실행 담당자: 실제 API 호출과 결과 포장을 담당합니다.
- 보안·업무 담당자: 읽기, 쓰기, 파괴적 작업, 개방형 네트워크 도구의 승인 기준을 정합니다.
- 테스트 담당자: 전체 호출 순환과 실패 경로를 검증합니다.
주의: Schema 검증에 통과한 JSON이라도 사용자의 승인이나 자원 소유권을 증명하지는 않습니다. 형식 검증과 권한 검증을 반드시 분리해야 합니다.
플랫폼별 형식과 내부 적응 계층
세 플랫폼의 개념은 비슷하지만 JSON 요청 형식이 같지는 않습니다. 하나의 “공통 요청 JSON”을 만들어 그대로 세 곳에 보내면 호출 식별자와 상태 정보가 사라질 수 있습니다.
| 플랫폼 | 도구 선언 핵심 | 모델 응답 형태 | 실행 결과 연결 방식 |
|---|---|---|---|
| OpenAI | name, description, parameters, 선택적 strict |
tool_calls 안의 함수 이름·인수·호출 ID |
도구 호출 ID와 후속 메시지로 연결 |
| Google Gemini | 함수 이름, 설명, parameters |
function_call 단계 또는 함수 호출 부분 |
호출의 id를 함수 결과에 그대로 포함 |
| Claude API | 도구 설명과 input_schema, 선택적 strict |
tool_use 블록 |
tool_use_id를 tool_result에 포함 |
OpenAI 문서는 함수 이름에 허용 문자와 최대 64자 제한이 있으며, parameters를 JSON Schema 객체로 정의한다고 설명합니다. 또한 모델이 항상 유효한 JSON이나 Schema에 정의된 매개변수만 생성한다고 가정하지 말고 코드에서 검증해야 한다고 안내합니다. (platform.openai.com)
Google Gemini는 함수 호출과 결과를 function_call, function_response 또는 상호작용 단계로 표현합니다. 결과를 다시 보낼 때는 원래 호출의 id를 유지해야 API가 요청과 결과를 연결할 수 있습니다. 최신 상호작용 방식에서는 상태를 서버에 맡기는 방법과 전체 기록을 애플리케이션이 관리하는 무상태 방식이 구분됩니다. (ai.google.dev)
Claude API는 tool_use 블록으로 호출을 반환하고, 실행 뒤 tool_result 블록을 다시 보냅니다. 사용자 정의 도구는 애플리케이션에서 실행되며, strict: true를 사용하면 도구 호출의 Schema 준수를 강화할 수 있습니다. (docs.anthropic.com)
따라서 내부 이벤트에는 최소한 다음 정보를 보존하는 편이 좋습니다.
{
"provider": "openai",
"call_id": "원본 호출 식별자",
"tool_name": "get_order_status",
"arguments": {},
"raw_response": {},
"state": "requested"
}
provider와 raw_response를 버리지 마십시오. 세 플랫폼을 같은 내부 객체로 압축하면 Gemini의 상태 서명, OpenAI의 호출 목록, Claude의 콘텐츠 블록처럼 플랫폼별로 필요한 정보를 복원하기 어려워집니다.
다중 도구 연결의 개념은 MCP와 Function Calling의 차이에서도 이어집니다. Function Calling이 한 모델과 실행기 사이의 호출 표현이라면, MCP는 여러 도구와 클라이언트 사이의 연결 규약을 다루는 방향에 가깝습니다.
Schema 설계와 실행기 안전장치
JSON 자체는 문법만 맞으면 여러 형태의 값을 담을 수 있습니다. JSON Schema는 객체의 구조, 자료형, 필수 항목과 제약 조건을 설명해 검증 기준을 제공합니다. 공식 안내에서는 type, properties, required 같은 키워드로 데이터 구조와 제약을 정의합니다. (json-schema.org)
예를 들어 주문 상태 조회 도구는 다음처럼 설계할 수 있습니다.
{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "조회할 주문 식별자"
}
},
"required": ["order_id"],
"additionalProperties": false
}
하지만 Schema만으로는 다음 문제가 해결되지 않습니다.
- 모델이 존재하지 않는 주문 식별자를 만들 수 있습니다.
- 읽기 도구처럼 보여도 개인정보를 반환할 수 있습니다.
- 쓰기 작업이 재시도되면 중복 결제가 발생할 수 있습니다.
- 네트워크 오류 뒤 재실행하면 동일한 작업이 두 번 수행될 수 있습니다.
- 도구 결과에 악성 지시문이 섞여 모델의 다음 행동을 바꿀 수 있습니다.
실행기는 모델과 외부 API 사이의 방화벽처럼 동작해야 합니다. 장기 인증 토큰을 프롬프트나 모델이 읽을 수 있는 파일에 넣지 마십시오. 서버 측 비밀 저장소에서 꺼내 필요한 요청에만 사용하십시오.
실행 전 검사는 다음 순서가 적합합니다.
- 호출 식별자와 도구 이름을 허용 목록과 대조합니다.
- JSON 파싱과 Schema 검증을 수행합니다.
- 사용자·조직·자원 소유권을 확인합니다.
- 작업 등급에 따라 자동 실행 또는 승인 요청으로 분기합니다.
- 시간 초과, 재시도, 멱등 키를 적용합니다.
- 외부 결과에서 민감 정보를 제거한 뒤 모델에 반환합니다.
도구 권한을 읽기, 변경, 파괴적 작업, 개방형 네트워크 접근으로 나누면 승인 정책을 만들기 쉽습니다. 읽기 도구도 무제한으로 열어두지 말고 대상 자원과 반환 필드를 제한해야 합니다.
역할별 구축 순서와 선택 조건
이번 주에 바로 적용할 작업은 다음 체크리스트입니다.
- [ ] 업무 예시를 하나만 정하고 읽기 전용 도구로 시작합니다.
- [ ] 세 플랫폼에서 같은 도구 이름과 입력 의미를 유지합니다.
- [ ] 공급업체별 원본 응답을 저장합니다.
- [ ] 실행기에서 Schema와 업무 규칙을 각각 검증합니다.
- [ ] 호출 실패, 빈 결과, 잘못된 결과를 별도 오류 코드로 기록합니다.
- [ ] 병렬 호출과 순차 호출을 구분해 테스트합니다.
- [ ] 대화 기록이 누락된 상태에서 재시작하는 경우를 시험합니다.
- [ ] 최종 답변이 도구 결과와 다르게 말하는 경우를 검출합니다.
조건에 따른 구조 선택
- 한 모델, 한 애플리케이션, 읽기 중심 도구라면 공식 SDK를 직접 사용해도 됩니다. 호출량이 적고 공급업체 변경 가능성이 낮다면 적응 계층의 초기 비용을 줄일 수 있습니다.
- 두 모델 이상, 공용 도구, 장기 운영이라면 내부 계약과 공급업체 적응 계층을 선택하십시오. 모델을 바꿀 때 실행기와 권한 정책을 다시 작성하지 않아도 됩니다.
- 쓰기·결제·삭제가 포함되면 자동 실행보다 승인 단계를 우선하십시오. Schema가 맞아도 업무 규칙과 사용자 동의가 필요합니다.
- macOS 명령, Xcode 빌드, 애플 자동화가 필요하면 일반 서버만으로 끝내지 말고 원격 Mac 실행 노드를 별도로 평가하십시오. 도구의 권한과 작업 주기가 짧다면 원격 Mac 실행 환경 구성 사례를 참고할 수 있습니다.
- 보안 검토가 핵심이면 Mac 개발 환경의 보안과 원격 접근 기준처럼 자격 증명, 접근 범위, 감사 로그를 함께 점검해야 합니다.
완성도 검증과 실패 회귀
테스트팀은 모델이 도구를 골랐는지만 확인하면 안 됩니다. 호출 요청부터 최종 답변까지 전체 순환을 같은 업무 예시로 검증해야 합니다.
첫째, 필수 매개변수가 빠진 경우를 시험합니다. 실행기는 외부 API에 빈 요청을 보내지 않고 재질문 또는 오류 응답으로 끝내야 합니다.
둘째, 여러 도구를 동시에 호출하는 경우를 확인합니다. 서로 독립적인 읽기 작업은 병렬화할 수 있지만, 첫 번째 결과가 있어야 가능한 두 번째 작업은 순차 실행해야 합니다. Gemini 공식 문서와 Claude 공식 문서는 병렬 도구 호출을 각각 지원하지만, 실제 필드와 기록 방식은 서로 다릅니다. (ai.google.dev)
셋째, 도구가 시간 초과하거나 잘못된 결과를 반환하는 경우를 기록합니다. 모델에게 “실패하지 않았다”고 꾸미지 말고, 오류의 종류와 재시도 가능 여부를 명확히 전달해야 합니다.
넷째, 대화 기록이 일부 사라진 상태를 재현합니다. Gemini의 무상태 방식처럼 이전 모델 응답과 호출 결과를 직접 관리해야 하는 구조에서는 기록 누락이 다음 호출의 맥락 오류로 이어질 수 있습니다. (ai.google.dev)
다섯째, 최종 답변 검사를 추가합니다. 도구가 “조회 실패”를 반환했는데 모델이 정상 결과처럼 답한다면 제품 결함입니다. 실행 결과의 상태 코드와 모델의 최종 문장을 비교하는 회귀 테스트가 필요합니다.
Function Calling을 처음 도입한다면 JSON Schema 호환성 점검 방법처럼 입력 구조와 검증 범위를 먼저 고정하는 편이 좋습니다.
현재 서버 환경에서 macOS 명령이나 Xcode 작업까지 한곳에서 처리하려 하면 운영 부담이 커집니다. macOS 권한과 애플 도구 체인에 묶이고, GUI 자동화는 일반 리눅스 실행기와 다르며, 장시간 유지되는 환경의 인증·업데이트·접속 관리도 추가됩니다. 단순 API 호출만 필요하다면 기존 서버가 더 적합하지만, 짧은 기간의 macOS 빌드·자동화·검증 작업이라면 Hashvps의 원격 Mac 자원을 작업 주기와 권한 범위에 맞춰 비교해 보는 편이 현실적입니다. тұрақ.
함수 호출 개발을 위한 안정적인 원격 환경을 시작하세요
Hashvps의 원격 맥 대여로 함수 호출과 외부 도구 연동을 실제 개발 환경에서 편리하게 테스트할 수 있습니다.
구조화된 요청 처리와 응답 검증이 필요한 개발 작업에 맞춰 필요한 맥 환경을 유연하게 이용할 수 있습니다.