← 에세이

Fable 5, Opus 4.8 및 Sonnet 4.6: 자체 코드에서 LLM을 정직하게 비교하는 방법

통제 실험: Fable 5, Opus 4.8, Sonnet 4.6이 동일한 프롬프트로 실제 코드베이스를 감사한다. 자체 프로젝트에서 LLM을 정직하게 비교하는 방법론.

7 분 소요
Telegram원문
Fable 5, Opus 4.8 및 Sonnet 4.6: 자체 코드에서 LLM을 정직하게 비교하는 방법

새 모델이 나오면 발표문은 "벤치마크에서 얼마나 더 나은가"라는 질문에 답합니다. 그리고 저에게 유일하게 중요한 질문에는 답하지 않습니다. 바로 제 업무에서 무엇이 달라지는가입니다. 저는 통제 실험을 진행했습니다. 세 개의 Claude 모델 — Fable 5, Opus 4.8 및 Sonnet 4.6 — 이 이 블로그의 코드베이스 감사라는 동일한 과제를 글자 그대로 받았고, 각각 격리된 저장소 사본에서, 사전에 합의된 평가 기준표를 가지고 작업했습니다. 이 글에서는 어떤 프로젝트에서든 재현할 수 있는 방법론 자체와 결과, 그리고 실험이 두 번 실패한 경위와 그로부터 배운 점을 별도로 다룹니다.

벤치마크가 제 질문에 답하지 못하는 이유

공개 벤치마크에는 두 가지 문제가 있고, 둘 다 근본적입니다. 첫째는 데이터 오염입니다. 테스트 사례가 학습 데이터에 스며들어 모델이 과제를 해결하는 대신 답을 부분적으로 "기억"합니다. 이는 주변적인 의심이 아니라 하나의 연구 분야 전체의 주제입니다. Xu와 공저자들의 리뷰(2024) 는 벤치마크 오염 연구를 체계화하고, EMNLP 2025 리뷰 는 업계의 대응 — 정적 테스트에서 동적 생성 테스트로의 전환 — 을 기록합니다.

두 번째 문제는 더 단순합니다. 벤치마크는 제 과제를 측정하지 않습니다. 저는 올림피아드 문제를 가장 잘 푸는 모델이 필요하지 않습니다. 제 Laravel 블로그에서 실제 버그를 찾아내고, 존재하지 않는 것을 지어내지 않으며, 자신의 수정이 작동함을 증명하는 모델이 필요합니다.

여기서 간단한 생각이 따라옵니다. 모델 비교를 위한 최고의 테스트베드는 자체 프로젝트입니다. 그 코드는 이런 조합으로 학습 데이터에 존재하지 않고, 그 위의 과제는 정확히 제가 비용을 지불하는 바로 그것이며, 저는 이 코드를 알기 때문에 결과를 직접 확인할 수 있습니다.

실험 설계: 하나의 프롬프트, 세 개의 격리된 세계

세 모델 모두에게 주어진 과제는 글자 그대로 동일했고, 브랜치 이름과 결과 폴더만 달랐습니다. 네 단계: 코드 인용과 함께 файл:строка 형태로 각 발견을 증명하는 블로그 기사의 이중 언어 시스템 감사; 주요 발견 세 가지에 대한 해결책 선택과 트레이드오프 설명; 자체 검증을 포함한 수정 하나의 구현; 러시아어와 영어로 된 결과 노트. 고립된 "질문-답변"이 아닌 전체 엔지니어링 작업 주기 — 이러한 접근을 Anthropic도 권장합니다: 실행 전에 합의된 기준표에 따라 실제 제품의 과제로 에이전트를 평가하라는 것입니다.

세 가지 규칙이 비교를 정직하게 만들었습니다:

격리. 각 모델은 별도의 git worktree — 자체 브랜치를 가진 작업 디렉터리의 자체 사본 — 에서 작업했습니다. 모델들은 물리적으로 서로의 결과를 볼 수 없었고 서로를 방해할 수도 없었습니다.

환각 방지 — 프롬프트 자체에. 과제의 핵심 문장: "지어낸 발견(존재하지 않는 코드, 잘못된 줄)은 발견이 없는 것보다 나쁘다." 이 자극이 없으면 문제를 찾으라고 요청받은 모델은 어떤 경우에도 그것들을 "찾아내는" 경향이 있습니다. 이것이 있으면 모든 발견은 수동 검증을 견뎌야 합니다.

힌트를 점수에서 제외. 저장소에는 프로젝트의 알려진 함정 — 예를 들어 언어 접두사가 있는 URL에서 깨지는 에셋 상대 경로 — 을 설명하는 CLAUDE.md가 있습니다. 세 모델 모두 이 파일을 읽으므로 그러한 발견은 "무료"입니다. 이는 꼼꼼함에 대해 인정되지만 깊이에 대해서는 인정되지 않습니다.

기준표: 직접 확인할 수 있는 것만 평가

실행 전에 저는 각 5점인 여섯 개의 축을 고정했습니다: 감사 정확성(발견 표본을 файл:строка로 수동 검증), 깊이(힌트에 없는 확인된 발견), 트레이드오프 추론의 품질, 코드와 자체 검증의 실재성, 러시아어 및 영어 텍스트의 품질, 규율(사람에게 질문 0회, 제약 위반 0회). 원칙은 좋은 코드 리뷰와 같습니다. 축이 취향에 덜 의존하고 검증 가능한 사실에 더 의존할수록 더 신뢰할 수 있습니다.

처음에 모든 것이 무너진 경위

첫 실행은 잘못되었고, 그것이 실험에서 가장 이식 가능한 부분으로 드러났습니다. 저는 같은 저장소 폴더에서 세 개의 대화형 세션을 동시에 열었습니다. 몇 분 후 작업 트리에는 귀속시킬 수 없는 커밋되지 않은 변경 사항이 있었습니다. 공유 체크아웃은 한 세션이 git checkout -b를 할 때 세션 모두의 브랜치가 전환되고 그들의 변경과 커밋이 뒤섞인다는 것을 의미합니다. 게다가 세션 중 하나는 git stash 를 실행하고 실험과 무관한 제 파일까지 포함해 모든 것을 그 안으로 쓸어 담았습니다.

"한 폴더에 있는 병렬 AI 에이전트는 병렬 실험이 아니다. 그것은 세 명의 저자가 있는 하나의 거대한 충돌이다."

– 재시작을 치르게 한 결론

두 세션의 결과는 사용 불가로 판정할 수밖에 없었다. 끝까지 마무리했다 해도 어느 쪽 수정을 평가하는지 솔직히 말할 수 없었을 것이다. 두 번째 실행은 격리된 worktree에서 진행되었지만 요금제 한도에 부딪혔다. 에이전트 두 개는 시작 단계에서 죽었고, 세 번째는 인터페이스에서 여전히 '작동 중'으로 보이면서 멈춰 있었다. 진단은 상태 표시기가 아니라 파일 시스템이 내렸다. 이십 분 동안 그의 작업 사본에는 파일이 하나도 생기지 않았다. 이것이 두 번째 이식 가능한 교훈이다. 에이전트의 생존 여부는 디스크의 변경 사항으로 확인한다. 재시작 후 세 모델 모두 동일한 조건에서 전체 주기를 완수했다.

결과: 모델이 같은 부분과 다른 부분

가장 중요한 결과는 일어나지 않은 일이다: 어느 모델에서도 환각이 없었다. 나는 각 모델의 발견 사항을 세 개 이상씩 직접 확인했다. 모든 인용과 줄 번호가 글자 단위까지 정확했다. 감사 작업에서 이것이 신뢰의 핵심 기준이며, 세 모델 모두 이를 통과했다.

이제 차이가 시작된다:

Fable 5 Opus 4.8 Sonnet 4.6
확인된 발견 11 5 9
비자명한 고유 발견 3 1 2
수정 자체 검증 임시 DB 기반 통합 렌더링, xmllint, 타인의 실패한 테스트 귀속 린터 + 렌더링; 자체 버그 포착 린터와 라우트 목록만
토큰 / 시간 164k / 21분 101k / 12분 131k / 12분
루브릭 총점 (30점 만점) 30 24 25.5

정성적 차이가 점수보다 정보량이 많다. Opus 4.8 은 sitemap에서 깨진 제목 Content-Type 을(를) 유일하게 발견하지 못했고(다른 두 모델은 발견했다) 자신의 수정안에 그대로 남겨두었다. 또한 러시아어 텍스트에 영어 단어가 흘러들었다 — 'и even путь к картинке'. Sonnet 4.6 은 올바른 수정을 했지만 자체 검증이 선언적이었다: 실행 대신 린터만 돌렸다. Fable 5 는 바로 자체 검증에서 두각을 나타냈다: php 이 내 컴퓨터에서 메인 디렉터리에 마운트된 docker 컨테이너의 래퍼임을 발견하고, 모든 검증을 일회용 컨테이너로 재구성했으며, 자신의 수정을 임시 DB에서 통합적으로 실행했다. '내가 했다'와 '내가 했다는 것을 증명했다' 사이의 차이가 바로 에이전트 작업에서 가장 변별력 있는 축이다.

또 다른 유용한 신호는 수렴이다: 세 모델 모두 독립적으로 sitemap 관련 동일한 문제를 최우선 발견으로 꼽았다. 독립적인 감사자들이 최우선 발견에서 일치하면, 이는 전문가 간 일치도의 저렴한 대용물이다: 그 문제는 거의 확실히 실재한다.

참가자 중 한 명인 심판

루브릭 평가는 Fable 5 가 수행했다 — 비교에 참여한 바로 그 모델이다. 이는 방법론적 허점이며 이를 직접 말해야 한다: LLM 심판은 자신의 텍스트에 체계적으로 높은 점수를 주며, 그 경향은 모델이 자신의 텍스트를 더 잘 알아볼수록 강해진다 — 이는 Panickssery와 공저자들의 NeurIPS 2024 논문. 에서 보여졌다. 편향을 완화하는 방법은 두 가지이며 나는 둘 다 사용했다: 첫째, 루브릭을 취향 축에서 검증 가능한 사실로 최대한 옮겼다 — 줄 정확도, 수정의 완전성, 흘러든 외국어 단어는 심판의 호오와 무관하다; 둘째, 이해 충돌을 명시적으로 선언하고 논쟁적인 축은 다른 모델이나 사람의 교차 검증에 맡겼다. 내 총평의 주관적 축 — 텍스트 품질, 추론 품질 — 은 이 보정을 염두에 두고 읽어야 한다.

정직성의 한계

모델당 한 번의 실행은 n=1이다: 1~2점 차이는 아무 의미가 없으며, 정성적 격차 — 놓친 버그, 자체 검증의 깊이 — 만 신뢰할 만하다. 이 실험은 한 도메인의 한 과제에서 세 모델을 측정한다; 'Fable 5 가 전반적으로 더 낫다'는 결론은 나오지 않는다. 그리고 비용을 기억해야 한다: 최상위 모델은 가장 경제적인 참가자보다 1.6배 많은 토큰과 거의 두 배의 시간을 썼으며, 그 토큰은 가격표상 자체도 더 비싸다 — 정기적인 작업에는 더 단순한 모델을 선호할 만한 중대한 근거다.

내가 챙기는 것

방법론은 어떤 프로젝트와 어떤 모델에도 통하는 짧은 체크리스트로 정리되었다:

  • 테스트 과제는 합성 문제가 아니라 자신의 코드에서 실제 작업의 전체 주기여야 한다.
  • 모두에게 동일한 프롬프트, 개별 worktree를 통한 격리, 결과는 개별 브랜치에.
  • 프롬프트에 환각의 명시적 비용을 담는다: 지어낸 발견은 발견하지 못한 것보다 나쁘다.
  • 모두가 접근 가능한 힌트(문서, 저장소 내 노트)는 깊이 평가에서 제외한다.
  • 루브릭은 실행 전에 고정하며 인상이 아니라 검증 가능한 사실에 근거한다.
  • 발견 표본은 직접 확인한다; 독립적인 모델들의 최우선 발견 일치는 그 실재성의 신호다.
  • 참가자 심판은 선언된 이해 충돌이다: 논쟁적인 축은 교차 평가에 맡긴다.
  • 에이전트의 생존 여부는 인터페이스 표시기가 아니라 디스크로 확인한다.

계획에 없던 보너스: 실험이 스스로 본전을 뽑았다. 세 개의 독립적 감사가 블로그에서 실제 문제를 찾아냈다 — 영어 페이지가 없는 sitemap부터 컨트롤러의 죽은 쿼리까지 — 그리고 두 개의 준비된 수정이 이미 브랜치에 있어 프로덕션 이관을 기다리고 있다. 벤치마크를 읽는 것과 달리 자신의 코드에서 모델을 비교하면 의견 이상의 무언가가 남는다.

출처 및 참고 자료