1P by GN⁺ | ★ favorite | 댓글 1개
  • Pi의 edit 도구에서 Claude Opus 4.8Sonnet 5edits[] 내부에 스키마에 없는 필드를 덧붙여 호출이 거부됐고, 최신 모델이 특정 도구 스키마를 이전 모델보다 못 따르는 현상이 관찰됨
  • 도구 호출은 모델이 특수 마커와 JSON 형태의 텍스트를 생성하는 과정이라, 제약 없는 샘플링에서는 학습된 관례가 스키마보다 앞설 수 있음
  • 실패 사례에서는 oldTextnewText 자체가 맞았는데도 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 도구 호출은 모델이 대화 기록, 시스템 프롬프트, 사용 가능한 도구 목록을 받은 뒤 특수 마커가 포함된 큰 프롬프트 안에서 호출 형식을 생성하는 방식임
  • 파일 편집 도구의 의도된 인자는 다음처럼 pathedits 배열을 포함할 수 있음
{
  "path": "some/file.py",
  "edits": [
    {
      "oldText": "text to replace",
      "newText": "replacement text"
    }
  ]
}
  • 하네스는 인자를 검증하고 편집을 수행한 뒤 결과를 모델에 다시 넣으며, 검증 실패 시 모델은 오류를 보고 보통 다시 시도함
  • Anthropic 모델 내부 포맷은 공개되어 있지 않지만, ANTML 마커가 유출되거나 공개 커뮤니케이션에 나타난 적이 있음
  • 이 포맷은 XML처럼 보이지만 실제 XML이라기보다 토큰화와 학습에 편한 인밴드 신호에 가까움
    • 최상위 문자열 파라미터는 인라인으로 들어갈 수 있음
    • 객체 배열은 JSON 직렬화 형태로 들어가는 것으로 보임

제약 없는 생성과 문법 제약 생성

  • 모델이 구조화된 출력을 만드는 방식은 크게 두 가지임
    • 모델에게 스키마에 맞는 JSON을 생성하라고 요청한 뒤 사후 검증함
    • 샘플러가 잘못된 JSON이나 스키마 모양을 처음부터 샘플링하지 못하게 막음
  • 두 번째 방식은 문법 인식 디코딩 또는 제약 디코딩으로 불리며, 문법을 위반하는 토큰을 마스킹함
  • 스키마가 oldTextnewText만 허용한다면 샘플러는 "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 등으로 다양함
  • 확인된 잘못된 호출에서는 실제 oldTextnewText 페이로드가 바이트 단위로 정확했지만, 객체 끝에 말이 안 되는 키가 붙어 호출이 거부됨
  • 재현은 문맥에 크게 좌우됨
    • 새 단일 턴 프롬프트인 “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 복구가 있음
  • 도구별 파라미터 별칭도 있음
    • Editold_str, old_string, new_str, new_string을 받아들임
    • pathfile_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에 맞춰 학습된 행동이 다른 도구로 깨끗하게 전이된다고 가정하기 어려움
  • 하나의 지배적 하네스 안에서 후학습이 더 많이 일어날수록 다른 하네스는 그 하네스의 기묘한 특성을 상속해야 함
  • 제약 디코딩에는 품질 트레이드오프가 있을 수 있지만, 최신 모델이 작업 해결 능력은 좋아지면서 대체 도구 스키마를 충실히 방출하는 능력은 나빠진다면 하네스 어딘가에 더 강한 보장이 필요함

댓글과 토론

Lobste.rs 의견들
  • Fable이 궁금하다면, Fable은 이제 다운그레이드할 때 항상 명시적으로 알리는 것으로 이해하고 있음
    나도 분류기에 걸린 적이 있는데, “버그를 심각도순으로 정렬해줘”가 보안 연구처럼 들렸던 듯함

    • 테스트를 좀 해볼 예정임
      뒤에서 몰래 하지는 않겠다고 말한 건 알지만, 다운그레이드에 쓰는 메커니즘은 아직 확인하지 못했음
  • 이 가설이 맞다면 영향은 코딩 에이전트를 넘어갈 가능성이 큼
    안정적인 도구 호출에 의존하는 애플리케이션이라면, 모델이 특정 제공자의 선호 실행 환경에 맞춰 후학습된 뒤 비슷한 성능 저하를 겪을 수 있음

  • 참고로 이 글은 vibecoding이 아니라 ai로 올렸음
    이 사이트에서 vibecoding의 경계가 어디인지 정말 이해하기 어려움
    이 글은 기반 LLM, 강화학습, 그리고 그 주변의 실행 환경을 만드는 것과 훨씬 더 관련이 있음
    이것까지 vibecoding이라면 ai 태그는 어디에 남아 쓰이는 건지 모르겠음

    • 여기서 vibecoding은 생성형 AI와 조금이라도 닿았거나 닿았을 것처럼 보이는 모든 것에 붙는 거대한 주홍글씨처럼 되어버렸음
      분위기 있는 블로그 글, LLM 기여를 금지하는 주요 프로젝트의 README, “X가 아니라 Y” 같은 문장이 너무 많은 글까지 최근 몇 주 사이 전부 vibecoding 태그가 붙었음
      개인적으로는 그 태그를 신경 쓰는 걸 완전히 포기했음. 커뮤니티가 너무 반사적으로 붙이다 보니 실제 의미가 사라졌기 때문임
      다만 이 특정 글은 말하자면 실제로 그 용도에 쓰이는 모델에 관한 것이므로 vibecoding 태그가 붙는 데 동의함
      동시에 지적한 이유 그대로 ai제거되면 안 됨에도 동의함. 다시 추가하고 싶지만, 왜인지 이 글에서는 그 옵션이 없음
  • 놀랍지 않음. 벤더 종속은 아마 계획의 일부일 가능성이 큼

    • 비용 절감도 어느 정도 섞였을 듯함. 모두가 Claude Code를 쓰면 프롬프트 캐싱이 개선됨
      “Claude 구독료를 내고 이미 모든 코드를 우리에게 전송하고 있다면, 모델과 별개로는 충분히 강한 종속 수단이 아닐 수도 있는 무료 UI도 반드시 써야 한다”는 식은 순수한 벤더 종속이 보통 굴러가는 방식과는 좀 다름
  • 모델이 자신이 학습된 실행 환경, 즉 모델 개발자가 만든 환경에서 최적으로 동작하는 건 말이 됨
    Claude Code 같은 추적 기록에 대해 엄청난 강화학습을 거쳤다면, Claude Code처럼 동작하지 않는 실행 환경에서는 꽤 나빠질 거라고 예상했을 것임
    개인적으로는 Pi 같은 서드파티 실행 환경에서도 꽤 잘하는 듯해서 오히려 더 놀랐음
    버그가 에이전트 추적의 깊은 곳에서만 발생한다는 것도 타당해 보임
    올해 초 GPT 5.2와 5.3 모델에서, 추적 후반부에 에이전트가 ls -la 대신 ls -ლა를 출력하는 버그와 씨름했음
    간단히 여기에 기록해두었음: https://github.com/openai/codex/issues/7988
    내 경험상 이 역시 추적이 깊어진 뒤에만 발생했음
    긴 문맥에서는 모델이 명확하게 “생각”하지 못하고 원시적인 본능으로 되돌아가는 것처럼 보임
    아마 그 지점에서 모델의 학습 분포와 실행 환경 또는 사용자가 모델에게 강제하는 작업 사이의 차이가 성능에 가장 극적으로 영향을 줄 것임

    • 문제는 강화학습을 해서 자기 실행 환경에서 더 잘 동작한다는 게 아님
      너무 많이 강화학습해서 이전 릴리스에 비해 다른 실행 환경에서 퇴행한다는 게 문제임
      이 지점에서는 “다른 종류의 과적합도 시작되고 있는 건 아닌가?” 같은 질문을 해야 함