- Pi의 edit 도구에서 Claude Opus 4.8과 Sonnet 5가 edits[] 내부에 스키마에 없는 필드를 덧붙여 호출이 거부됐고, 최신 모델이 특정 도구 스키마를 이전 모델보다 못 따르는 현상이 관찰됨
- 도구 호출은 모델이 특수 마커와 JSON 형태의 텍스트를 생성하는 과정이라, 제약 없는 샘플링에서는 학습된 관례가 스키마보다 앞설 수 있음
- 실패 사례에서는 oldText와 newText 자체가 맞았는데도 requireUnique, oldText2, matchCase, in_file 같은 가짜 키가 붙었고, 에이전트 이력과 thinking block 포함 여부에 따라 재현율이 달라짐
- Claude Code는 닫힌 하네스지만 잘못된 호출 재시도, 파라미터 별칭, 타입 보정, Unicode 복구, 알 수 없는 키 필터링 등 느슨한 보정을 많이 수행하며 strict 모드는 쓰지 않음
- Anthropic의 strict 도구 호출은 이 문제를 없앴고, 모델 성능이 좋아질수록 대체 도구 스키마가 불리해질 수 있다면 하네스에는 문법 제약 같은 더 강한 보장이 필요함
Pi edit 도구에서 나타난 회귀
- Pi 이슈를 추적하던 중 최신 Claude 모델이 Pi의 edit 도구를 호출할 때 edits[] 배열 안에 존재하지 않는 필드를 추가하는 문제가 발견됨
- 작은 모델이 아니라 Opus 4.8에서 나타났고, Sonnet 5에서도 같은 현상이 확인됨
- 이전 Anthropic 모델에서는 같은 문제가 보이지 않아, 최신 고성능 모델이 이 특정 도구 스키마에서는 오히려 나쁘게 동작함
- Fable은 분류기가 요청을 조용히 Opus로 낮출 가능성이 있어 테스트하지 않음
도구 호출은 텍스트 생성에 가까움
- LLM 도구 호출은 모델이 대화 기록, 시스템 프롬프트, 사용 가능한 도구 목록을 받은 뒤 특수 마커가 포함된 큰 프롬프트 안에서 호출 형식을 생성하는 방식임
- 파일 편집 도구의 의도된 인자는 다음처럼 path와 edits 배열을 포함할 수 있음
{
"path": "some/file.py",
"edits": [
{
"oldText": "text to replace",
"newText": "replacement text"
}
]
}
- 하네스는 인자를 검증하고 편집을 수행한 뒤 결과를 모델에 다시 넣으며, 검증 실패 시 모델은 오류를 보고 보통 다시 시도함
- Anthropic 모델 내부 포맷은 공개되어 있지 않지만, ANTML 마커가 유출되거나 공개 커뮤니케이션에 나타난 적이 있음
- 이 포맷은 XML처럼 보이지만 실제 XML이라기보다 토큰화와 학습에 편한 인밴드 신호에 가까움
- 최상위 문자열 파라미터는 인라인으로 들어갈 수 있음
- 객체 배열은 JSON 직렬화 형태로 들어가는 것으로 보임
제약 없는 생성과 문법 제약 생성
- 모델이 구조화된 출력을 만드는 방식은 크게 두 가지임
- 모델에게 스키마에 맞는 JSON을 생성하라고 요청한 뒤 사후 검증함
- 샘플러가 잘못된 JSON이나 스키마 모양을 처음부터 샘플링하지 못하게 막음
- 두 번째 방식은 문법 인식 디코딩 또는 제약 디코딩으로 불리며, 문법을 위반하는 토큰을 마스킹함
- 스키마가 oldText와 newText만 허용한다면 샘플러는 "in_file"이나 "type" 같은 키 생성을 막을 수 있음
- 이런 제약이 없으면 모델은 추상 계약을 엄밀히 따르기보다 학습된 관례를 따라 생성함
실제 실패 패턴
- Pi의 edit 도구는 한 번의 호출에서 여러 정확한 문자열 치환을 지원하기 때문에 edits 배열을 사용함
- 실패한 호출에서는 다음처럼 허용되지 않은 필드가 붙음
{
"oldText": "...",
"newText": "...",
"requireUnique": true
}
{
"oldText": "...",
"newText": "...",
"oldText2": "",
"newText2": ""
}
- 반복 실험에서 나온 가짜 키는 type, id, kind, unique, requireUnique, matchCase, in_file, forceMatchCount, children, notes, cost, oldText2, newText2, oldText_2, newText_2, event.0.additionalProperties 등으로 다양함
- 확인된 잘못된 호출에서는 실제 oldText와 newText 페이로드가 바이트 단위로 정확했지만, 객체 끝에 말이 안 되는 키가 붙어 호출이 거부됨
- 재현은 문맥에 크게 좌우됨
- 새 단일 턴 프롬프트인 “edit this file”에서는 재현되지 않음
- 모델이 파일을 읽고 문제를 진단한 뒤 여러 줄 편집을 구성한 에이전트 이력에서는 재현됨
- Petr Baudis의 트랜스크립트가 있어야 재현 가능했음
- 해당 사용자 세션을 이어가면 Opus 4.8이 약 20% 확률로 실패함
- 이력에서 thinking block을 제거하면 실패율이 절반으로 줄어듦
- strict 도구 호출을 켜면 해당 실행에서는 문제가 사라짐
왜 더 나빠졌는가
- 가장 강한 가설은 이것이 무작위 성능 저하가 아니라 학습 산물이라는 점임
- 이전 Anthropic 모델은 일부 도구로 학습됐지만, Claude Code 같은 사용자 제공 하네스가 명확한 목표로 자리 잡기 전이었음
- 최신 Anthropic 모델은 Claude Code 또는 그와 매우 비슷한 하네스를 포함한 후학습을 받았을 가능성이 크며, 그 환경에서 성공적인 도구 호출과 허용되는 실수를 함께 학습했을 수 있음
- Claude Code의 edit 도구는 Pi의 중첩된 edits[] 구조가 아니라 file_path, old_string, new_string, 선택적 replace_all에 가까운 평평한 구조임
- Claude Code 클라이언트는 잘못된 도구 사용 재시도, 파라미터 별칭, 타입 강제 변환, Unicode 복구, 알 수 없는 키 필터링 등 상당한 오류를 보정함
- 강화학습이 이런 하네스나 그 시뮬레이션 안에서 일어난다면 약간 잘못된 도구 호출도 작업을 완료하고 보상을 받을 수 있음
- 다른 하네스가 같은 의미의 편집 도구를 다른 스키마로 제공하면 모델 입장에서는 점점 분포 밖 도구가 될 수 있음
- Opus 4.5 출시 당시에는 다른 edit 도구에 매우 잘 적응했지만, 현재 관찰된 방향은 대체 도구 스키마가 특정 관대한 도구 생태계에서 불리해질 수 있음을 보여줌
- 문서화된 text editor tool이 있지만 Claude Code는 그 형식을 그대로 따르지 않으며, Claude Code 내부 동작은 닫힌 소스 하네스라 보이지 않음
Claude Code의 느슨한 하네스
- Claude Code는 닫힌 소스이지만 축소된 코드를 보면 들어오는 데이터에 매우 관대함
- 모델의 보이는 텍스트에 <invoke 마크업이 새어 나왔는지 확인하고, 그런 경우 텔레메트리를 내보낸 뒤 자체 상태 머신으로 잘못된 호출을 다시 시도함
- 문자열 값 안의 깨진 \uXXXX 시퀀스와 lone surrogate를 고치는 Unicode escape 복구가 있음
- 도구별 파라미터 별칭도 있음
- Edit는 old_str, old_string, new_str, new_string을 받아들임
- path를 file_path의 별칭으로 받아들임
- 예상하지 못한 키는 조용히 필터링함
- strict 모드는 사용하지 않음
- Anthropic은 strict 모드에서 도구 정의 복잡도 제한을 적용해 API 요청이 실패할 수 있음
- Claude Code가 strict 모드를 시도하지 않는 이유로 보임
strict 모드와 다른 생태계
- Anthropic 모델과 하네스는 모두 닫혀 있어 다른 하네스에서도 같은 문제가 이어질지 판단하기 어려움
- Codex 모델도 닫혀 있지만 하네스는 닫혀 있지 않음
- gpt-oss는 OpenAI의 harmony 응답 형식을 쓰도록 명시적으로 학습됐고, OpenAI 측 사고방식을 보여주는 문서가 많음
- harmony는 채널과 도구 호출 콘텐츠 타입을 프롬프트 포맷의 일부로 만들며, 도구 호출 본문에 <|constrain|>json 같은 마커를 포함할 수 있음
<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
- <|constrain|>json은 추론 스택이 도구 호출 본문에서 JSON 제약 샘플링으로 전환할 경계를 쉽게 찾게 함
- 호스팅 GPT 모델에는 사용자 도구가 따라야 할 문법을 위해 LARK 문법을 제공하는 옵션도 있음
- Anthropic도 strict 모드에서는 일부 유사한 처리를 하는 것으로 보이지만, 중첩 배열 파라미터에서는 모델이 긴 멀티라인 파일 내용을 문자열 리터럴 안에 이스케이프한 JSON으로 생성해야 함
- 가짜 키는 수백 토큰 길이의 newText 문자열을 닫은 직후, 모델이 }와 , "..." 중 선택해야 하는 고엔트로피 지점에서 나타남
- Opus 4.8과 Sonnet 5는 edit 도구 호출 형태에 대한 더 강한 사전분포를 가진 것으로 보이며, 그 사전분포는 Claude Code의 평평한 edit 스키마에 가까움
- Anthropic의 strict 모드가 문제를 고친다는 점은 서버 쪽에서 JSON 스키마 구조상 허용되지 않은 키 샘플링을 거부하기 때문일 수 있음
- 테스트한 Codex 모델에서는 이런 유형의 회귀가 보이지 않았고, 접근 권한이 없는 5.6은 제외됨
하네스 설계에 주는 영향
- Anthropic 모델에서 도구 스키마는 중립적인 추상 계약이 아닐 수 있음
- 어떤 도구 모양은 후학습에서 본 것과 가깝고, 어떤 모양은 멀리 있음
- 어떤 모양은 제공자의 숨겨진 인코딩에서 쉬울 수 있지만, 어떤 모양은 긴 멀티라인 문자열 뒤 중첩 배열 안에 큰 이스케이프 JSON 객체를 써야 해 어렵게 작동함
- 모델이 스키마를 이해하더라도 압박이 있는 상황에서는 정확한 구조를 샘플링하는 데 실패할 수 있음
- Anthropic에서는 strict 샘플링을 켜면 이 문제는 사라질 수 있음
- 다만 최신 모델의 행동은 강화학습이 모델에 미치는 영향을 보여주며, 특정 하네스의 사전분포와 싸우는 방식은 최고 성능을 얻는 데 불리할 수 있음
- Claude Code는 오픈소스가 아니고 RL 환경에서 무엇을 하는지도 알 수 없으므로, Claude Code에 맞춰 학습된 행동이 다른 도구로 깨끗하게 전이된다고 가정하기 어려움
- 하나의 지배적 하네스 안에서 후학습이 더 많이 일어날수록 다른 하네스는 그 하네스의 기묘한 특성을 상속해야 함
- 제약 디코딩에는 품질 트레이드오프가 있을 수 있지만, 최신 모델이 작업 해결 능력은 좋아지면서 대체 도구 스키마를 충실히 방출하는 능력은 나빠진다면 하네스 어딘가에 더 강한 보장이 필요함