LLM Function Calling: 제공업체 간 스키마 및 도구 선택 비교
요약
LLM Function Calling의 성능을 제공업체 간에 객관적으로 비교하기 위한 벤치마크 방법론을 다룹니다. 도구 스키마 수락, 도구 결정, 인자 구성, 오류 복구의 4단계를 통해 모델의 도구 사용 능력을 평가하는 가이드를 제공합니다.
핵심 포인트
- Function Calling 평가를 위한 4단계(수락, 결정, 구성, 복구) 정의
- 제공업체 종속성을 피하기 위한 중립적인 내부 계약(Contract) 정의 권장
- 정규화된 표현을 통한 응답 비교 및 벤치마크 러너 구축 방법
- 중복 조회, 열거형, 포맷팅된 식별자 등 실제 발생 가능한 실패 사례 분석
LLM Function Calling: 재현 가능한 제공업체 비교 | Agent Lab Journal
Agent Lab Journal
Guides
...
실무 평가 · 중급
LLM Function Calling: 제공업체 간 스키마 및 도구 선택 비교
35분 읽기
중급
2026년 8월 1일 업데이트
...
목차
- 동일한 도구가 다르게 동작하는 이유
- 구체적인 테스트 케이스
- 제공업체 중립적인 계약(Contract) 정의
- 테스트 데이터셋 생성
- 제공업체 응답 정규화
- 벤치마크 러너(Runner) 구축
- 선택, 인자(Arguments), 복구(Recovery) 점수 산정
- 오류 처리 테스트
- 재현성 검증
- 일반적인 실패 사례
- 한계점
동일한 도구가 다르게 동작하는 이유
Function calling (함수 호출)은 모델이 호스트 애플리케이션에
구조화된 인자(Arguments)를 사용하여 명명된 작업을 실행하도록
요청하는 프로토콜입니다. 모델은 함수를 직접 실행하지 않습니다.
모델은 ...
유용한 비교를 위해 네 가지 단계를 구분합니다:
- 요청 수락 (Request acceptance): 제공업체가 도구 스키마 (Tool schema)를 수락했는가?
- 도구 결정 (Tool decision): 모델이 호출했는가, 자제했는가, 아니면 잘못된 도구를 선택했는가?
- 인자 구성 (Argument construction): 제공된 값들이 구조적 및 의미적으로 정확했는가?
- 복구 (Recovery): 유효성 검사(Validation) 또는 실행 오류 발생 후, 모델이 호출을 적절히 수정했는가?
핵심 규칙: 원시 요청(Raw requests)과 응답(Responses)을 기록하되,
정규화된 표현(Normalized representation)에 대해 점수를 매기십시오.
둘 다 없으면 제공업체의 구문(Syntax)이 비교를 왜곡할 수 있고,
정규화 버그가 보이지 않을 수 있습니다.
구체적인 사례: 고객 지원 운영 어시스턴트
우리는 가상의 지원 워크플로우를 위한 세 가지 읽기 전용 도구를 테스트할 것입니다.
실제 고객 데이터, 자격 증명 또는 측정된 제공업체 결과는 포함되지 않습니다.
벤치마크는 사용자가 테스트하려는 모델에 대해 실행할 때 자체적인 증거를 생성합니다...
{
"tools": [
{
...
이 도구 세트는 파괴적인 동작을 요구하지 않으면서도 다음과 같은 일반적인 문제들을 드러냅니다:
중복되는 조회(lookup) 및 검색(search) 함수, 포맷팅된 식별자(identifiers), 열거형(enums), 제한된 정수(bounded integers), 선택적 기본값(optional defaults), 대문자 정규화(uppercase normalization), 그리고 반드시 형식을 갖춰야 하는 우편번호(postal codes) 등입니다.
먼저 제공업체 중립적인 계약(provider-neutral contract)을 정의하십시오
애플리케이션 전체에 걸쳐 특정 제공업체의 요청 객체(request object)를 복사하여 사용하는 것으로 시작하지 마십시오.
작은 내부 표현(internal representation)을 정의한 다음, 각 LLM API의 경계(boundary)에서 이를 변환하십시오. 이렇게 하면 벤치마크에 단일 진실 공급원(source of truth)을 제공할 수 있습니다.
export type CanonicalTool = {
name: string;
description: string;
...
파싱된 인자(arguments)는 검증(validation) 전까지 unknown 상태로 유지하십시오. 만약 어댑터(adapter)가 "750"을 750으로 캐스팅(cast)하거나, 예상치 못한 속성을 제거하거나, 점수를 매기기 전에 기본값을 제공한다면, 이는 모델의 실제 출력값을 숨기는 행위가 됩니다.
주요 비교를 위해 스키마 교집합(schema intersection)을 사용하십시오
제공업체들은 서로 다른 스키마 하위 집합(schema subsets)을 지원합니다. 주요 벤치마크는 다음과 같은 보수적인 구조로 시작하십시오:
object, string, integer, number, boolean, array, properties, required, enum, 그리고 단순 범위(simple bounds). 고급 키워드(advanced keywords)는 별도로...
-
tools.core.json은 모델을 비교하는 데 사용되는 이식 가능한 스키마(portable schema)를 포함합니다.
-
tools.compatibility.json은 pattern, union, 중첩된 제약 조건(nested constraints), strictness 제어와 같은 키워드를 조사합니다.
예를 들어, 특정 제공업체가 pattern을 수용할 수 없다면, 해당 제공업체의 호환성 어댑터(compatibility adapter)에서만 이를 제거하고 그 변환 과정을 기록하십시오. 그 후 모든 모델이 의미론적으로 동일한 제약 조건(semantically identical constraints)을 받았다고 주장해서는 안 됩니다.
지침(instructions)을 고정하십시오
You are a support operations assistant.
Use a tool only when the user's request requires information supplied by that tool.
...
이 텍스트를 버전이 관리되는 픽스처(fixture)에 저장하십시오. 공백(whitespace)의 변경, 추가적인 예시, 그리고 제공업체별 지침(provider-specific instructions)은 해롭지 않은 편집이 아니라 실험적인 변수(experimental variables)입니다.
진단 테스트 데이터셋 생성
테스트 행(test row)에는 예상되는 함수 이름 이상의 정보가 필요합니다.
호출(call)이 예상되는지 여부, 허용 가능한 정확한 인자(arguments),
그리고 대안적인 동작이 왜 잘못되었는지를 명시해야 합니다.
{"id":"select-lookup-01","prompt":"Where is order ORD-104821?","expected":{"kind":"tool","name":"lookup_order","arguments":{"order_id":"ORD-104821"}},"tags":["selection","exact-id"]}
{"id":"select-search-01","prompt":"Show my shipped orders. My email is sam@example.test.","expected":{"kind":"tool","name":"search_orders","arguments":{"email":"sam@example.test","status":"shipped"}},"tags":["selection","enum"]}
{"id":"abstain-01","prompt":"Hello! What can you help me with?","expected":{"kind":"text"},"tags":["abstention"]}
...
example.test와 같은 예약된 도메인(reserved domain) 및 합성 식별자(synthetic identifiers)를 사용하세요.
제안된 호출(proposed call) 단계 이후에 첫 번째 평가 단계가 중단되므로,
픽스처(fixture)에 실제 주문 데이터베이스가 있을 필요는 없습니다.
다섯 가지 동작 클래스 커버하기
-
Positive selection (긍정적 선택): 요청이 정확히 하나의 함수로 명확하게 매핑되는 경우. -
Confusable selection (혼동 가능한 선택): 두 개의 도구(tools)가 어휘를 공유하지만, 요청을 충족하는 것은 하나뿐인 경우. -
Abstention (기권): 도구가 필요하지 않거나 사용 가능한 도구가 없는 경우. -
Argument pressure (인자 압박): 값이 변환(conversion), 정규화(normalization), 또는 문자열 형식(string formatting)의 보존을 필요로 하는 경우. -
Missing information (정보 누락): 모델이 필요한 값을 추측하는 대신 질문을 해야 하는 경우.
...
## 제공업체 요청 및 응답 정규화
각 제공업체 어댑터(provider adapter)는 세 가지 책임을 가져야 합니다:
- 표준화된 도구(canonical tools)와 메시지를 제공업체 요청(provider request)으로 변환합니다.
- 텍스트, 거부(refusals), 오류, 그리고 제안된 모든 도구 호출(tool call)을 추출합니다.
- 진단을 위해 수정되지 않은 요청과 응답을 보존합니다.
```
Runner의 나머지 부분을 제공업체에 독립적(provider-agnostic)으로 유지하십시오.
다음 인터페이스는 첫 번째 벤치마크를 수행하기에 충분합니다:
```
```typescript
export interface ModelAdapter {
provider: string;
model: string;
...
제공업체의 제어 방식이 동일한 것처럼 비교하지 마십시오
'auto'라는 이름의 모드는 텍스트 또는 호출(call) 중 하나를 허용할 수 있습니다.
'required'라는 이름의 모드는 제공업체에 따라 모든 도구, 특정 도구,
또는 최소 하나 이상의 도구를 강제할 수 있습니다. 모든 항목 옆에
실제 의미론(semantics)을 문서화하십시오...
OpenAI Function Calling 통합에 관한 참고 사항
OpenAI의 Function Calling 지원을 구현할 때, 현재의 요청 및 응답 변환 로직을
별도의 어댑터(adapter)로 격리하십시오. 표준 형식(canonical format)이
제공업체별 메시지 역할(message roles), 호출 ID(call IDs), 엄격함(strictness) 등에
의존하게 만들지 마십시오...
호출을 수정하지 않고 정규화하십시오
export function normalizeArguments(value: unknown): unknown {
if (typeof value !== "string") return value;
...
JSON 문자열을 파싱하는 것은 프로토콜 정규화(protocol normalization)입니다.
단위를 변환하거나, 열거형(enum) 철자를 수정하거나, 알 수 없는 키를 제거하거나,
타입을 변경하는 것은 의미론적 복구(semantic repair)입니다.
만약 운영 스택(production stack)에서 이러한 복구 작업을 수행한다면,
해당 복구 작업들에 대해 별도로 점수를 매기십시오.
벤치마크 러너(Benchmark Runner) 구축
러너(runner)는 구성된 모든 모델에 대해 모든 케이스를 실행하고, 케이스를 반복하며,
추가 전용(append-only) 레코드를 작성합니다. 또한 선택 단계(selection stage) 동안에는
실제 비즈니스 도구를 절대 호출하지 않습니다.
type TestCase = {
id: string;
prompt: string;
...
Temperature(온도)를 0으로 설정하면 변동성을 줄일 수 있지만, 이것이 결정론적 (deterministic) 동작을 보장하는 것은 아닙니다. 제공업체(Providers)는 서빙 인프라, 모델 버전, 또는 디코딩 내부 로직을 변경할 수 있습니다. 불안정성을 관찰할 수 있을 만큼 각 케이스를 충분히 반복하십시오.
...
권장 프로젝트 레이아웃 (Suggested project layout)
function-benchmark/
├── fixtures/
│ ├── system.txt
...
최소 로컬 명령어 (Minimal local commands)
mkdir function-benchmark
cd function-benchmark
npm init -y
...
실제로 사용하는 어댑터에 대해서만 제공업체 SDK (provider SDKs)를 설치하고, lockfile에 해당 버전을 고정(pin)하십시오. 각 제공업체에 범위가 지정된 환경 변수 이름을 사용하는 것을 권장합니다.
Fixture, 결과 파일, 콘솔 스냅샷, 또는 버전 정보에 비밀 값을 절대 작성하지 마십시오.
...
{
"datasetVersion": "1.0.0",
"repeats": 5,
...
동시성(concurrency)을 1로 시작하십시오. 그래야 속도 제한 (rate limits) 및 응답 순서를 진단하기가 더 쉽습니다. 베이스라인이 안정화된 후에만 동시성을 높이고, 이를 실험의 일부로 기록하십시오.
점수 선택 및 인자(arguments) 분리
단일 통과율 (pass rate)은 중요한 차이점을 숨깁니다. 어떤 모델은 올바른 도구 (tool)를 선택하지만 필요한 인자 (argument)를 임의로 만들어낼 수 있고, 다른 모델은 잘못된 작업에 대해 완벽한 인자를 생성할 수도 있습니다. 이들을 별개의 실패로 취급하십시오.
1. 요청 수락 (Request acceptance)
LLM API가 요청을 수락했는지 여부를 기록합니다. 권장되는 카테고리는 다음과 같습니다:
-
accepted (수락됨)
-
schema_rejected (스키마 거부됨)
-
authentication_error (인증 오류)
-
rate_limited (속도 제한됨)
-
timeout (시간 초과)
-
provider_error (제공업체 오류)
-
harness_error (하네스 오류)
인증, 속도 제한, 또는 하네스 실패를 모델의 잘못된 결정으로 계산하지 마십시오. 이를 커버리지 손실 (coverage loss)로 보고하십시오.
2. 도구 선택 (Tool selection)
다음 결과들을 사용하여 혼동 행렬 (confusion matrix)을 구축하십시오:
-
올바른 도구 (correct tool);
-
잘못된 도구 (wrong tool);
-
기권 (abstention)이 예상되었으나 도구가 호출됨;
-
호출이 예상되었으나 도구가 호출되지 않음;
-
정확히 하나가 예상되었으나 여러 번의 호출이 발생함;
-
테스트 케이스 (fixture)가 명확한 질문 (clarification)을 기대했을 때 명확한 질문을 함;
-
충분한 정보가 이미 존재함에도 불구하고 명확한 질문을 함.
마지막 구분 사항은 중요합니다. 안전하지만 불필요한 질문을 던지는 것은 잘못된 형식의 호출 (malformed call)은 피할 수 있겠지만, 사용자 경험 (user experience)을 저하시킬 수 있습니다.
3. 구조적 인자 유효성 (Structural argument validity)
수정되지 않은 모델 인자 (model arguments)를 표준 스키마 (canonical schema)와 대조하여 검증하십시오. Ajv를 사용하는 방법은 다음과 같습니다:
import Ajv from "ajv";
const ajv = new Ajv({
...
강제 형변환 (coercion), 기본값 삽입 (default insertion), 그리고 속성 제거 (property removal)를 비활성화한 것은 의도적인 설정입니다.
이는 측정 전 검증기 (validator)가 출력을 임의로 개선하는 것을 방지하기 위함입니다.
4. 의미적 인자 정확성 (Semantic argument correctness)
스키마 유효성 (Schema validity)은 필요조건이지만 충분조건은 아닙니다.
weight_grams: 1은 유효한 정수(integer)이지만, 사용자가 "1 kg"이라고 말했을 때는 틀린 값입니다.
검증 후에는 값을 테스트 케이스 (fixture)와 비교하십시오.
export function compareExpected(
expected: Record<string, unknown>,
actual: Record<string, unknown>,
...
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기