728x90
반응형

(개념) AI 모델이 도구 호출(tool call / function calling) 시 인자(argument)를 채워 넣는 방식에 나타나는, 프롬프트로는 쉽게 바뀌지 않는 모델 고유의 습관

 

핵심 근거: 25개 파라미터 중 몇 개를 채우는가

Ploy 에이전트의 code 도구는 25개의 최상위 파라미터를 가지며 그중 action 하나만 필수입니다. 그런데 Claude는 실제로 사용하는 2~3개 파라미터만 보내고 나머지는 생략하는 반면, GPT-5.6은 매 호출마다 25개 전부를 보내면서 사용하지 않는 파라미터에도 offset: 0, timeout: 120000, siteId에 전부 0으로 된 UUID 같은 그럴듯한 값을 채워 넣었습니다

 

3일치 프로덕션 트레이스를 집계한 결과는 이렇습니다:

( 이 통계는 세 모델의 3일간 프로덕션 code(read) 호출 트레이스를 기반으로 합니다.)

모델 호출 수 25개 속성 전부 포함
gpt-5.6 6,635 100%
claude-opus-4.8 2,898 0.1% (4)
claude-sonnet-5 1,933 0%

 

단순한 "장황함(verbosity)"이 아니었다

진짜 문제는 파일 읽기 구현이 모델이 지어낸 값과 의도한 값을 구분할 수 없었다는 점이었습니다. offset: 0을 실제 지정된 값으로 처리해버려 GPT-5.6 파일 읽기의 52~64%가 빈 결과를 반환했습니다. 더 나쁜 건, 도구가 유효한 읽기든 빈 읽기든 상관없이 항상 success: true를 반환했기 때문에 모델 스스로도 자신이 빈 파일을 읽고 있다는 걸 알 수 없었고, 이를 보완하려 더 많은 호출을 시도하면서 결과가 오히려 나빠졌습니다.

 

프롬프트로는 고쳐지지 않았다는 결정적 증거

"사용하지 않는 파라미터는 생략하라"는 도구 설명 수준의 지시를 넣어도 여전히 25개 전부가 채워졌고, 파라미터별로 "선택 사항, 사용하지 않으면 생략"이라는 힌트를 달아도 동일했습니다. OpenAI strict 모드로도 같은 동작이 재현됐는데, 이를 도입하려면 모든 스키마에서 pattern, format, 배열 범위 검증을 제거해야 했습니다.

, 프롬프트·스키마 설명·API 옵션 어느 것도 이 습관을 바꾸지 못했고, 결국 이것이 모델 자체의 방출 패턴이라는 결론에 도달합니다.

 

해결책은 프롬프트가 아니라 스키마 구조의 변환으로

실제로 통한 해법은 제공자(provider) 경계에서의 스키마 변환이었습니다. OpenAI 계열 모델에 대해서는 모든 선택적 속성을 anyOf: [T, null] 형태로 "필수이지만 null 허용"으로 다시 작성해, 모델에게 "이 값은 사용 안 함"을 표현할 명시적인 값을 준 것입니다. 이후 도구 실행 전 공유 경계에서 null 값을 제거해 실제 도구 구현 자체는 바뀌지 않도록 했습니다.

그 결과 이 속성을 변경한 이후 빈 파일 읽기 비율이 52%에서 0%로 떨어졌고, 같은 작업에 필요한 도구 호출 수도 약 30% 줄었습니다.

 

"방출 특성"이 시사하는 바는,

같은 함수 호출 스펙(JSON 스키마)을 주더라도 모델마다 "무엇을, 얼마나, 어떻게 채워 넣는가"에 대한 학습된 스타일이 다르며 — Claude는 최소주의(필요한 것만), GPT-5.6은 완전성 지향(스키마 전체를 채움) — 이 차이는 프롬프트 레벨이 아니라 도구 스키마 설계 레벨에서 대응해야 한다는 것입니다. 멀티 모델 아키텍처를 운영하는 팀이라면 모델 교체 시 이런 방출 패턴 차이가 비용·정확도·도구 신뢰성에 실질적 영향을 준다는 점을 염두에 둘 만합니다.

 

https://ploy.ai/blog/migrating-a-production-ai-agent-to-gpt-5-6

출처: https://charstring.tistory.com/2443 [Char:티스토리]

 

 

 

728x90
Posted by Mr. Slumber
,