
「Fable 5의 지능을 반값으로」 Claude Opus 5를 동일한 47만 행의 유적에서 발굴하여 확인하기
요약
Anthropic이 출시한 Claude Opus 5의 성능과 비용 효율성을 기존 벤치마크 데이터(Mifos 유적)를 통해 검증합니다. Fable 5 대비 절반 가격임에도 디버깅과 근본 원인 분석 능력이 향상되었음을 실측합니다.
핵심 포인트
- Claude Opus 5 출시: Fable 5 대비 절반 가격의 효율적 모델
- 코딩 능력 향상: 에러 복구 및 복잡한 문제 해결 능력 강화
- 비용 경쟁력: $5/$25의 가격으로 중간 난이도 AI 작업 타겟
- 검증 방법론: 동일한 47만 행의 코드 유적을 활용한 경향성 분석
2026년 7월 24일, Anthropic이 Claude Opus 5를 출시했습니다. 홍보 문구는 명쾌합니다. "Fable 5의 거의 모든 지능을 반값으로". 가격은 $5/$25(100만 토큰당, Opus 4.8에서 동결)로, Claude Max의 기본 모델 자리에 올랐습니다. Devin을 만드는 Cognition의 CEO는 "FrontierCode 1.1에서 Fable에 근접하는 성능을 반값에 제공한다. 특히 디버깅(Debugging)과 근본 원인 분석(Root Cause Analysis)에 강하다"라고 언급했습니다.
디버깅과 근본 원인 분석. 그것은 즉, 발굴하는 것입니다.
이 시리즈는 동일한 유적(Mifos 구버전, Struts 1.2의 47만 행)에 동일한 프롬프트(Prompt)를 계속해서 입력해 왔습니다. Fable 5에서 2회, Opus 4.8에서 1회, GPT-5.6 Sol에서 1회. 정답 확인표에는 4회 실행분의 발굴 결과가 새겨져 있으며, 높은 신뢰도의 유물만으로 50건이 넘는 합집합이 쌓여 있습니다. 새로운 모델이 나올 때마다 벤치마크(Benchmark)의 외부에서 확인할 수 있는 정점 관측소입니다. 오늘은 이곳에 Opus 5를 맞이합니다.
게다가 이번에는 이전에 없던 두 가지 비교가 가능합니다. 선대 Opus 4.8과의 세대교체 실측(동일한 유적·동일한 프롬프트 열이 이미 존재함)과, 동일 가격대 대결(Sol $5/$30 vs Opus 5 $5/$25)입니다.
미리 말씀드리자면, 이 두 가지는 모두 기사의 주인공이 되지 못했습니다. 예정에 없던 세 번째 결과가 가장 컸기 때문입니다.
Opus 5의 위치
가격은 $5/$25입니다. Opus 4.8에서 동결되었으며, Fable 5($10/$50)의 절반, Sol($5/$30)과 거의 비슷한 금액입니다.
포지셔닝이 흥미로운데, Anthropic 스스로가 "가장 똑똑한 것은 Fable 5"라고 명시한 상태에서, "경제적으로 가장 중요한 AI 작업은 중간 난이도에서 발생한다"라는 효율성을 주장하고 있습니다. Max의 새로운 기본 모델이자, Pro의 최상위 모델이라는 구성입니다.
성능 면에서는 복잡한 문제를 되돌아가는 과정 없이 진행하며, 자신의 작업을 검사하여 에러(Error)로부터 복구하는 등, Opus 4.8 대비 코딩(Coding) 능력이 향상되었다고 합니다.
제2회에서 OpenAI의 "비용 1/3"을 실측했던 것과 동일한 방식으로, 이 주장을 유적에서 확인하겠습니다.
검증 설계는 제2회와 동일
대상은 Mifos 구버전(약 47만 행), 신규 클론(Clone)의 콜드 스타트(Cold Start). 프롬프트는 제1회의 프롬프트 3(유물 발굴)을 토씨 하나 틀리지 않고 동일하게 사용합니다. 구성은 Claude Code를 사용하며, 메인이 Opus 5, 스캔 워커(Scanner Worker)는 Sonnet으로 고정합니다(모든 실행 공통). 채점은 제2회에서 확정된 정답 확인표 10개 항목과 고유 발견 건수로 판단합니다.
그리고 매번 쓰고 있는 주의사항을 이번에도 생략하지 않고 적어둡니다. 동일한 모델이라도 실행할 때마다 발견되는 내용은 달라집니다(제2회에서 실증됨. Fable 스스로도 자신의 주역급 발견을 재현하지 못했습니다). 따라서 열과 열 사이의 차이는 "모델의 차이 + 실행의 변동성"의 합이며, 단 1회의 실행으로 모델의 우열을 단정할 수는 없습니다. 이 표가 측정하고 있는 것은 단정이 아니라 경향입니다.
이번에는 이 주의사항이 기사의 주인공이 됩니다.
이번에만 구성에 2가지 차이점
솔직하게 말씀드리겠습니다. 과거 4회의 실행과 다른 점이 두 가지 있습니다.
첫 번째. 발굴을 수행한 것은 독립 세션이 아니라 Opus 5의 서브 에이전트(Sub-agent)입니다. 채점하는 쪽의 세션은 정답 확인표를 읽어버렸기 때문에, 그대로 /dig3를 입력하면 "정답을 알고 있는 상태에서의 발굴"이 되어, ○× 측정으로서 무효가 됩니다. 그래서 정답을 전혀 주지 않은 Opus 5에 dig3.md 본문을 토씨 하나 틀리지 않고 그대로 투입하고, 채점은 별도(정답을 알고 있는 쪽)가 실제 코드를 열어 확인하는 분리 방식을 취했습니다. 실행 중에는 정답을 포함한 파일(채점표, 이 기사의 초안, 실행 절차서, 키트의 zip)을 리포지토리(Repository) 외부에 대피시켜, 발굴 측에서 물리적으로 보이지 않는 상태로 만들었습니다.
두 번째. 이 구성으로는 세션 단위의 /cost를 측정할 수 없습니다. 그래서 비용만은 별도로 제2차 시도를 수행하여 실측했습니다. 신규 클론에서 RUNBOOK 대로의 독립 세션(메인이 Opus 5 본체, 워커가 Sonnet 고정), 동일한 프롬프트. 다른 4회의 실행과 조건이 완전히 일치하는 것은 이것입니다.
즉 이번에는 채점은 제1차 시도, 비용은 제2차 시도로 분담되었습니다. 제2차 시도는 정답을 모르는 독립 실행이므로, 겸사겸사 "동일 모델·동일 프롬프트로 2번 던졌을 때 발견 내용이 얼마나 바뀌는가"에 대한 추시 데이터도 되었습니다. 이것이 효과적입니다.
실행 로그
유적은 mifos/head 5f794ce8
(2019-02-04). Java 파일 3,319개, 470,162행, JSP 310개. 새로운 shallow clone의 콜드 스타트(Cold Start)입니다.
제1차 시도는 08:54:52부터 09:41:26까지, 46분 34초. 출토물은 49건(확신도 높음 25, 중간 17, 낮음 7)이며, 추가로 매장 유구(Burial features)가 15곳 327행입니다. legacy-scanner로의 위임은 9회, 거절(refusal)은 없었습니다.
Opus 4.8 때는 약 21분, 확신도 높음 10건이었습니다. 시간은 약 2.2배, 확신도 높음의 출토물은 2.5배입니다. 단순히 시간을 들여 양을 늘렸다는 이야기가 아닙니다. 내용을 보면 스캔(Scanning) 설계가 다릅니다.
위임한 9건의 내역을 Opus 5 스스로가 보고서의 부록에 작성해 왔습니다.
| 회차 | 스캔 내용 | 성과 |
|---|---|---|
| 1 | 예외 무시(Exception swallowing) 전수 조사 | catch 총 1,324건 중 101건을 분류 |
| ... | ||
| 「올림 모드(Rounding mode)를 세어보니 CEILING이 2건만 다른 것과 다르다」, 「부정어의 불일치를 43건 찾아내어, 거기서 Javadoc과 정반대인 구현을 추출한다」. 찾을 것을 정해놓고 파헤치는 것이 아니라, 분포를 파악한 뒤 이상치(Outlier)를 파헤치고 있습니다. 46분을 사용하는 방식이 여기에 나타나 있습니다. |
제2차 시도에서 주연급 유물이 바뀌었다
비용 측정을 위해 실행한 제2차 시도는 RUNBOOK에 따른 독립 세션입니다. 33분 22초에 $17.67, legacy-scanner로의 위임은 5건 병렬, 거절 없음. 보고서는 2,628행으로 제1차 시도(1,121행)의 두 배 이상입니다. 매장 유구는 17블록 443행(제1차 시도는 15곳 327행)입니다.
그리고 발굴된 것이 바뀌었습니다. 제2차 시도가 1순위로 놓은 것은 이것입니다.
// LoanBO.java:1437-1443 GLIM 조기 상환
else if (hasMemberAccounts() && !this.isGroupLoanAccount()) {
for (LoanBO memberAccount : this.memberAccounts) {
...
루프(Loop) 외부에서 전달된 공유 DTO를 매 회차마다 덮어쓰고 있습니다. 두 번째 회차에서는 「이미 나눈 후의 금액」을 다시 나눕니다. 멤버가 3명이라면 ((T/f1)/f2)/f3 입니다.
바로 위의 형제 분기(isGroupLoanAccountParent)는 멤버마다 new AccountPaymentDto(...)를 생성하고 있어 올바릅니다. 한쪽만 어긋난 전형적인 복사-붙여넣기(Copy-paste) 분기였습니다.
흥미로운 점은 여기서부터입니다. 제1차 시도는 같은 곳을 보고도 명시적으로 채택하지 않았습니다. 보고서의 방법론란에 이렇게 적혀 있습니다.
그룹 대출의 안분 계산
amount.divide(factor)는 얼핏 역산처럼 보이지만, calcFactorOfEntireLoan()이 부모/자식의 역수를 반환하기 때문에 올바름. 채택하지 않음
나눗셈의 방향만을 검산하여 「올바르다」고 결론짓고, DTO가 루프를 가로질러 살아남는다는 사실을 간과한 것입니다. 동일한 모델이 동일한 지점에서, 한쪽은 오탐(False positive)을 제거했고, 다른 한쪽은 한 단계 더 깊이 파고들었습니다.
그리고 채점을 해보니 더욱 까다로운 사실을 알게 되었습니다. 보고서의 양은 두 배, 비용은 실측 $17.67임에도 불구하고, 정답 확인표의 점수는 제1차 시도보다 낮습니다 (7.0 대 5.5). 다음 절에서 그 표를 보겠습니다.
채점표 v3, 4개 모델 6회 실행의 정점 관측
○는 자력 탐지, △는 인근까지 도달, ×는 미탐지입니다. 왼쪽 3열은 공개된 제2회의 확정값입니다. Opus 5는 제1차 시도(채점용)와 제2차 시도(비용 측정용)를 별도의 열로 구분했습니다. 여기가 이번에 가장 눈여겨봐야 할 표입니다.
| 유물 | Fable 5 | Opus 4.8 | Sol | Opus 5 제1차 시도 | Opus 5 제2차 시도 |
|---|---|---|---|---|---|
| 회계 전표의 계정 과목이 HashSet의 반복 순서에 따라 "랜덤"임 (Javadoc 공인) | ○ | × | × | × | × |
| 수수료 ID 미채번 시 hashCode()를 ID로 대용하여 지급 배분 (MIFOS-4517) | ○ | ○ | ○ | ○ | ○ |
| ... |
△를 0.5점으로 계산하면 다음과 같습니다.
| 실행 | ○ | △ | × | 환산 점수 |
|---|---|---|---|---|
| Fable 5 | 7 | 1 | 2 | 7.5 |
| ... |
동일한 모델의 두 시도가 7.0과 5.5로 갈렸습니다. 이 1.5점 차이는 Opus 5의 제1차 시도와 이전 세대 Opus 4.8의 차이(1.0점)보다 큽니다.
즉, 이 표 위에서 모델의 세대 차이보다 동일한 모델의 실행 시 발생하는 변동성(variability)이 더 컸던 셈입니다. 제2회부터 매번 써왔던 주의사항("열과 열의 차이는 모델의 차이와 실행 변동성의 합이다")이 처음으로 수치에 의해 뒷받침되었습니다. 심지어 변동성이 우세하다는 형태로 말입니다.
판정 방법
2단계로 진행했습니다. 먼저 보고서에 기재되어 있는지 확인하고, 그다음 유물의 실제 좌표를 직접 특정하여 해당 행을 열어 대조합니다. 좌표 특정은 legacy-scanner를 실행시켜 수행했으며, 최종 판정은 제가 직접 코드를 읽어 확인했습니다.
제1차 시도에서 ○(정답)로 판정한 6건은 모두 좌표가 일치합니다.
| 유물 | 도달 근거 |
|---|---|
| hashCode()를 ID로 대용 | 보고서 #18이 LoanScheduleEntity.java:582 (위약금)와 618 (수수료) 양측, 그리고 읽기 측인 LoanTrxnDetailEntity.java:159-179를 특정함. MIFOS-4517도 명시하며, "두 엔티티가 hashCode()를 오버라이드(override)하지 않았기에 우연히 작동하고 있을 뿐, 값 기반(value-based)으로 구현하는 순간 깨지게 될 시한폭탄"이라는 기제(mechanism)까지 도달 |
| ... |
360/365 건은 ○로 판정하기에 망설여졌습니다. "366일의 윤년을 걸러낸다"는 결론까지는 작성하지 않았기 때문입니다. 기제의 검출은 성립했으므로 ○로 처리했지만, 기술의 깊이 면에서는 미흡합니다.
△(부분 정답)로 판정한 2건은 모두 동일한 파일, 동일한 계통의 다른 결함에 도달했다가 멈춘 상태입니다. PAR 배치(batch)의 실체는 GroupPersistence.java:156-189이며, 문자열 결합을 이용한 생(raw) UPDATE가 2회 발생합니다. beginTransaction()은 존재하지만 성공 경로(success path)에 commit이 전혀 없고, 예외 경로(exception path)에만 rollback이 있으며, finally에는 closeSession()만 있는 형태입니다. 보고서 #1은 PAR 계통에 도달하여 "함께 PortfolioAtRiskCalculation.java:37도 확인 대상"이라고 지목했지만, commit 누락과 생 SQL(raw SQL)까지는 도달하지 못했습니다.
BigDecimal 건은 실체가 Money.java:77-78 (Money(MifosCurrency, Double)에서 new BigDecimal(double)을 사용하여 이진 표현이 부정확함)과 81-82 (String 버전을 사용하여 정확함)로 이어지는 이중 경로입니다. 보고서는 동일 파일 내의 double 경유 정밀도 저하(#22의 doubleValue()에 대해 "compareTo로 교체해야 함"이라고 제언)와 Money의 비대칭성(#46)을 언급하고 있지만, 생성자의 이중 경로 그 자체는 지적하지 못했습니다. 이 부분은 Opus 4.8의 ○에서 퇴보한 지점입니다.
×(오답)인 2건은 완전히 도달하지 못했습니다. HashSet 반복 순서의 실체는 BaseAccountingEntry.java:139-155이며, Javadoc에서 "return an account code chosen at random (determined by the implementation of the set's iterator)"라고 공인하고 있고, Set 생성 측인 COABO.java:245가 new HashSet<COABO>()입니다. 보고서에는 BaseAccountingEntry도 COABO도 GLcode도 등장하지 않습니다.
쌍둥이 클래스 건은 DecliningBalancePrincipalWithInterestGenerator.java:33의 dates.size() > 1과 DecliningBalanceEqualPrincipalWithInterestGenerator.java:36의 scheduledDates.size() > 2입니다. 주석의 오타 "chek"까지 동일한 쌍둥이입니다. 보고서에 PRORATE_RULE에 대한 언급은 전무합니다. "쌍둥이의 한 글자 차이"라는 관점 자체는 #26(AccountBO.java:940/956의 > vs >=)에서 파악하고 있었음에도, 이 유물에는 도달하지 못했습니다.
제2차 시도에서 맞춘 2건
제2차 시도에서 제1차 시도보다 점수가 떨어진 것은 2건입니다. 두 건 모두 "보지 않아서 틀린 것"이 아니라는 점이 가장 흥미로운 부분이었습니다.
PAR 배치(△→×). 제2차 시도 보고서에는 PortfolioAtRisk도 GroupPersistence도 createSQLQuery...
한 번도 나오지 않습니다. 제1차 시도가 찾아낸 「센터 PAR이 상수 0.2」에도 도달하지 못했습니다. PAR 계통을 통째로 지나쳐 버렸습니다.
360/365(○→×). 이쪽은 대조적으로, 제2차 시도는 연간 일수를 정의하는 AccountingRules.getNumberOfInterestDays()
(287-293)을 실제로 열어보고 있습니다. 다만 검증한 것은 「days != 365가 Short와 int의 비교에서 항상 true가 되는 것 아닌가?」라는 다른 가설 쪽이었으며, 「수치 승격 (Numeric Promotion)이 작동하므로 올바르게 비교된다」라고 결론짓고 오검출 (False Positive)로 기각했습니다. 연간 일수가 360/365로 고정되어 있는 건에 대해서는 보고하지 않았습니다.
같은 장소에 서서, 다른 가설을 없애고 돌아왔습니다. 제2차 시도의 「오검출을 정중하게 기각하는 행동」이 그대로 놓침 (Miss)이 된 형국입니다.
「Opus의 눈」의 유전은 절반만 성립했다
전대 Opus 4.8이 얻고 Fable/Sol이 놓친 3건(CEILING·권한 142·360/365) 중, 제1차 시도는 3건 모두 유지했으나, 제2차 시도는 360/365를 놓쳐 2건이었습니다. 두 시도를 통해 안정적으로 유전되었다고 말할 수 있는 것은 CEILING과 권한 142, 이 2건입니다.
두 시도 모두에서 안정적으로 얻은 유물은 5건(hashCode 대용·단수 면제·CEILING·권한 142·매장 87행)입니다. 이 중 단수 면제만이 4.8에서는 ×였으나 5에서는 ○였습니다. 세대를 통해 회수되었다고 말할 수 있는 유일한 유물입니다.
반대로 두 시도 모두 도달하지 못한 것이 3건입니다. HashSet 반복 순서, 쌍둥이 클래스 2회 vs 3회, 그리고 BigDecimal 이중 경로(둘 다 △에 그침). 앞의 2건은 Fable 5만이 얻은 유물로, Opus 계열은 2세대 3회 실행에 걸쳐 단 한 번도 파헤치지 못했습니다.
Opus 5의 고유 발견
이하는 제1차 시도의 결과입니다. 출토 49건 중 정답표에 대응하는 것은 8건(○ 6개와 △ 2개)입니다. 나머지 41건과 매장 유구 15곳 327행이 표 밖에 있었습니다. 제2차 시도는 더욱 다른 산(2,628행, 매장 유구 17블록 443행)을 쌓아 올리고 있습니다.
먼저 말씀드립니다. 「4회 실행의 합집합 50건 초과 중 몇 건이 추가되었는가」는 산출할 수 없었습니다. 과거 실행 보고서가 수중에 남아 있지 않아 (_dig가 모두 비어 있음), 합집합의 원본과 대조할 수 없기 때문입니다. 증분 숫자는 제시하지 않습니다.
엄선된 4건. 모두 확신도 「높음」이며, 실제 코드(Real Code)로 확인을 마쳤습니다.
1. 센터의 PAR이 문자열 리터럴 "0.2"로 반환됨 (CustomerDaoHibernate.java:744)
/**
* FIXME: THIS METHOD DOES NOT WORK. Specifically, the portfolioAtRisk calculation. Please see issue 2204.
*/
...
센터 상세 화면의 연체 채권 비율이 DB를 전혀 보지 않고 모든 센터가 동일한 값입니다. Javadoc이 「이 메서드는 작동하지 않는다」라고 자백한 상태입니다. Opus 5의 판정이 좋았습니다. 「업무가 의존하고 있다기보다, 업무가 포기하고 있는 패턴」이라고 짚었습니다. 그와 동시에 「계속 0.2였던 사실을 현장에서 눈치채지 못하고 있을 가능성이 있다」라는 코멘트를 덧붙였습니다.
2. isAnyPeriodicFeeActive()의 조건이 반전되어 있음 (CustomerBO.java:1428-1435)
/**
* @return true if at least one active and periodic fee is found, otherwise false
*/
...
Javadoc과 구현이 정반대입니다. 바로 위의 형제 메서드인 isAnyAccountActive()는 동일한 구조이며 부정(Negation)이 없습니다. 복사해서 붙여넣는 과정에서 !가 혼입된 것으로 보입니다. 이것이 가드(Guard)로 사용되고 있다면 실질적으로 「항상 true」인 상태이며, 가드가 작동하지 않는 상태로 운영되고 있다는 뜻입니다. 올바르게 수정하는 순간, 지금까지 통과되던 조작들이 갑자기 차단될 것입니다.
3. GLIM 자계좌의 입금 취소가 조건에 따라 「아무것도 하지 않고 성공」함 (LoanBO.java:4070, 4082)
모계좌라면 예외(Exception)를 던지는데, 자계좌는 예외도 로그도 없이 정상 종료됩니다. 코멘트는 MIFOS-5694에서 유래한 것으로 「자계좌에 입금이 없는 것은 2.4.0 이전의 입금을 의미할 수 있다」라고 되어 있습니다. 즉, 오래된 데이터의 경우 취소하려고 했으나 취소되지 않은 상태일 수 있습니다. Opus 5는 여기에 「회계상 좋지 않은 동작이므로 우선순위를 높여 확인할 것」이라는 주석을 달았습니다.
4. 이자 계상 배치(Batch)가 가공의 관리자 사용자로 동작함(SavingsIntPostingHelper.java:81-96)
private MifosUser createMifosAdminUser() {
Integer userId = Integer.valueOf(1);
String username = "mifos";
...
저축 이자의 일괄 계상이 DB를 조회하지 않고 이 사용자를 구성하여 SecurityContext에 올려서 실행됩니다. 여기서부터의 읽기가 핵심입니다. 이자 계상 분개의 created_by가 전건 「1」로 되어 있는데, 이 값이 사실상 「시스템 실행」의 마커(Marker)로서 기능하고 있을 가능성이 높습니다. 따라서 단순히 수정하면 과거 데이터의 재해석 매핑이 필요하게 된다는 것입니다.
또 하나, 프롬프트가 요구하지 않은 출력이 있었습니다. 보고서 말미에 「업무 부문 확인 사항 20문항」이 우선순위 순(최우선 6, 높음 6, 중간 8)으로 자동 편집되어 있습니다. "센터 상세 화면의 PAR, 현재 무엇에 사용하고 있습니까?", "완납 처리할 잔액의 임계값(Threshold)은 얼마입니까?"와 같은 내용입니다. 쇄신 킥오프(Kick-off) 시 그대로 사용할 수 있는 형태입니다. 프롬프트는 각 유물에 대해 「업무 부문에 무엇을 확인해야 하는가」를 쓰라고 지시했지만, 전건을 횡단하여 우선순위 순으로 다시 정렬하라고는 하지 않았습니다. 지시 범위를 벗어나 결과물의 형태를 정돈해 온 것입니다.
비용 비교
| API 환산 비용 | 소요 시간 | 단가(입력/출력) |
|---|---|---|
| Fable 5 스택(워커 포함) | $14.61 | 약 25분 |
| ... | 33분 22초 | $5/$25 |
Opus 5의 모델별 내역은 다음과 같았습니다.
| 모델 | 입력 | 출력 | 캐시 읽기 | 캐시 쓰기 | 비용 |
|---|---|---|---|---|---|
| claude-opus-5(메인) | 1.2k | 116.0k | 12.3m | 257.6k | $11.64 |
| ... | |||||
![]() |
자, 여기가 이번에 가장 중요한 수치입니다.
단가가 절반인 Opus 5가, Fable 5 스택보다 21% 더 높게 나왔습니다 ($17.67 vs $14.61).
내역을 보면 이유는 명확합니다. 스캔 워커(Scanner Worker)인 Sonnet에서만 $6.01를 사용하여 총액의 34%를 차지했습니다. Opus 5는 제1차 시도에서 9개, 제2차 시도에서 5개의 전역 스캔을 병렬로 던졌으며, 캐시 읽기는 두 모델 합쳐 19.0m 토큰입니다. 47만 행을 여러 번 각도를 바꿔가며 훑었습니다. 단가는 절반이 되었지만, 파헤치는 양이 늘어난 탓에 비용을 다 써버린 것입니다.
그럼 주장(Claim)을 대조해 보겠습니다.
먼저 「Fable 5의 거의 모든 지능을」. 좋은 결과가 나온 시도에서는 거의 성립했습니다. 제1차 시도는 7.0점으로, Fable 5(7.5점)와의 차이는 0.5점입니다. 게다가 내용이 뒤바뀌어 있어, Fable이 놓친 2건(CEILING·권한 142)을 Opus 5는 잡아냈고, Opus 5가 놓친 2건(HashSet·쌍둥이 클래스)을 Fable은 잡아냈습니다. 총량은 비슷한데 잡는 유물이 다릅니다.
다만 제2차 시도는 5.5점으로, Fable에 2.0점 차이로 뒤처졌습니다. 「거의 Fable 수준」이라고 말할 수 있을지가 실행 운(Gacha)에 의해 결정된다는 것이 솔직한 관측입니다.
다음으로 「절반 가격으로」. 단가는 절반, 업무 총액은 고가. 이것이 실측된 답입니다. 이 유적에서 이 프롬프트를 1회 던지는 작업에 한정하면, Opus 5는 Fable 5보다 1.21배 비싸고 스코어는 약간 낮습니다. 토큰 단가의 절반 감소가 곧바로 청구 금액의 절반 감소로 이어지지는 않았습니다.
물론 1회의 실행이므로, 이 또한 「모델의 차이 + 실행의 변동성」의 합입니다. 단정하지는 않겠습니다. 다만, "$5/$25니까 절반 가격으로 해결된다"는 식의 해석은 적어도 이 유적에서는 통하지 않았습니다. 이는 기록해 둘 가치가 있다고 생각합니다.
마지막으로 동일 가격 대결(vs Sol $5/$30). 성격이 정반대였습니다. Sol은 7분 38초 · $3.24로 ○3 △2 ×5였습니다. Opus 5는 33분 22초 · $17.67로 ○6 △2 ×2였습니다. 같은 $5 클래스에서 비용은 5.5배, 시간은 4.4배입니다. 한쪽은 빠르고 얕게, 한쪽은 느리고 깊게. 제2회차에서 Sol의 「비용 1/3」을 실측했을 때의 결론("저렴함은 속도로 사고 있는 것이다")이, 이렇게 나란히 놓고 보니 더욱 선명해집니다.
쇄신의 초기 진단에서 47만 행을 1회만 훑는다면, $17.67는 인간의 공수(Man-hour)에 비해 여전히 오차 범위 내입니다. 하지만 「$5 클래스니까 싸다」는 전제로 견적을 내면 5배나 차이가 납니다.
고찰
결론부터 말씀드리겠습니다. 이 시리즈가 4회에 걸쳐 쌓아온 「모델 비교」라는 프레임워크가, 이번 2회의 시도로 인해 근간부터 흔들렸습니다. 모델 간의 차이보다, 동일한 모델의 실행 차이가 더 컸기 때문입니다.
세대교체는 측정할 수 없었다
Opus 4.8(6.0점)에 대해, Opus 5는 7.0점과 5.5점이 나왔습니다. 이전 세대의 수치가 후속 모델의 2회 시도 결과값 정중앙에 끼어버렸습니다. 이런 배치로는 「세대교체로 강해졌다」라고도, 「변하지 않았다」라고도 말할 수 없습니다.
조금 더 세부적으로 살펴보면, Opus 4.8이 단독으로 획득했던 3건 중 제1시도는 3건을 유지했고, 제2시도는 2건을 유지했습니다. 회수했다고 말할 수 있는 유물은 단수 제외 1건뿐인데, 이는 두 시도 모두 ○이므로 비교적 신뢰할 수 있습니다. 반대로 double→BigDecimal은 두 시도 모두 △에 그쳤으며, 4.8의 ○에서 후퇴한 상태 그대로입니다.
요컨대, 10문항의 테스트는 세대 차이를 측정하기에는 너무 거칠었습니다. 1회 실행 시 1.5점씩 움직이는 잣대로는 1.0점의 차이를 측정할 수 없습니다.
변화가 일어난 곳은 표의 바깥쪽이었습니다. 확신도가 높은 출토 건수가 10건에서 25건으로 늘어났습니다. 46분의 사용 방식이 키워드 검색에서 분포를 파악한 뒤 이상치(Outlier)를 사냥하는 방식으로 바뀌었습니다. 반올림 모드를 세어 CEILING만 2건이라는 사실을 알아차리고, 부정어의 불일치를 43건 찾아낸 뒤 Javadoc과 정반대되는 구현을 끌어냅니다. 이러한 설계는 보고서의 부록에 스스로 작성해 왔던 내용들입니다.
「디버깅과 근본 원인 분석(Root Cause Analysis)에 강하다」라는 Cognition의 평가는 바로 이 「기제(Mechanism)까지 기술하는」 부분에서 드러난다고 생각합니다. hashCode 대용 항목에서 멈추지 않고 「오버라이드(Override)되지 않았기에 우연히 작동하고 있을 뿐, 값 기반(Value-based)으로 바꾸는 순간 터질 시한폭탄」이라는 결론까지 추적합니다. 유물을 찾아내는 능력이 아니라, 찾아낸 것의 인과관계를 끝까지 파헤치는 능력입니다.
지성은 반값으로, 청구는 더 비싸게
지성 측면은 대체로 성립했습니다. 다만 「Fable과 같은 것을 발굴할 수 있다」는 뜻은 아닙니다. 총량은 비슷하지만, 내용은 다릅니다.
빗나간 것은 가격 측면입니다. $17.67 대 $14.61. 단가가 절반인 모델이 동일한 작업에서 21% 더 높은 비용을 발생시켰습니다. 이유는 스캔 워커(Scanner Worker)인 Sonnet($6.01, 총액의 34%)과 캐시 읽기 19.0m 토큰이 보여주듯, Opus 5는 스스로 더 많이 파헤치는 쪽을 택했기 때문입니다.
여기에 일반화할 수 있는 교훈이 있다고 생각합니다. 에이전트의 청구 금액을 결정하는 것은 단가가 아니라, 모델이 스스로 결정하는 작업량입니다. 토큰 단가 비교표는 에이전트 용도에서는 견적을 내는 데 도움이 되지 않습니다. 파헤치는 양까지 포함하여 실측하지 않으면 5배의 오차가 발생합니다.
$5 클래스의 두 기종은 용도가 갈린다
Sol은 7분 38초·$3.24, Opus 5는 33분 22초·$17.67입니다. 비용은 5.5배, 시간은 4.4배 높지만, 채점 결과는 ○3△2에 대해 ○6△2입니다. 1차 스크리닝에는 Sol을, 본 조사에는 Opus 5를 사용하는 방식이 합리적이라고 생각합니다. 동일한 $5 클래스라는 분류는 실무에서는 거의 의미가 없습니다.
「한 번의 투입이 샘플링」이라는 가설은 6번째 실행에서 증명되었다
이것이 이번의 본론이 되어버렸습니다. 동일 모델·동일 프롬프트의 2회 시도를 나란히 놓았더니 이런 결과가 나온 것입니다.
정답 확인표의 스코어가 7.0과 5.5로 갈리며, 모델 간의 세대 차이인 1.0점보다 커졌습니다. 제1시도가 「정답이므로 채택하지 않음」이라며 버렸던 부분을 제2시도는 주역급 발견으로 만들어냈습니다. 반대로 제2시도는 연간 일수를 정의하는 메서드를 열어본 뒤 다른 가설을 기각하고 유물을 보고하지 않았습니다. 그리고 보고서의 양은 제2시도가 두 배(2,628행 vs 1,121행)임에도 불구하고 표의 스코어는 낮았습니다.
양과 스코어는 연동되지 않으며, 동일한 모델의 두 번의 실행이 같은 지점에서 서로 다른 결론을 내립니다. 발굴은 결정론적인 작업이 아니라 샘플링입니다.
실무적인 함의는 명확합니다. 모델 하나에 한 번 던지고 끝내서는 안 됩니다. $17.67를 두 번 돌려 합집합을 취하는 것이, $14.61를 한 번 돌리는 것보다 확실히 안전합니다. 쇄신 전 진단에서 사양화된 결함을 한 건 놓쳤을 때의 비용에 비하면, $35는 오차 범위에 불과합니다.
모델 선정으로 고민할 시간이 있다면, 차라리 같은 모델을 한 번 더 던지는 편이 낫습니다. 그것이 6번째 실행의 결론입니다.
그리고 정점 관측소로서의 설계도 재검토가 필요합니다. 표의 10문항은 이미 포화 상태에 가깝고(합집합에서는 모든 문항이 누군가에 의해 획득됨), 반면 표의 바깥쪽은 아직 고갈되지 않았습니다. 「표의 몇 퍼센트를 차지하는가」보다 「표의 바깥에 무엇을 쌓는가」, 그리고 「같은 모델을 두 번 던졌을 때 얼마나 흔들리는가」를 측정하는 축으로 바꿔야 합니다.
이번에도 변하지 않는 결론을 적어둡니다. 어떤 모델을 사용하든, 발굴된 "규격화된 결함 (specification-ized bug)" 후보가 정말로 업무 의존적인지를 판정하는 것은 인간의 몫입니다. 모델의 세대교체가 빠를수록, 발굴은 더 저렴하고 깊어집니다. 판정을 설계하는 측에게는 순풍이 점점 더 강해질 뿐입니다.
요약
동일한 모델의 2회 시도 결과가 7.0점과 5.5점으로 갈렸습니다. 이 1.5점의 차이는 Opus 5와 이전 세대인 Opus 4.8의 차이(1.0점)보다 큽니다. 4회에 걸쳐 쌓아온 비교표의 전제가 6회째 실행에서 무너진 셈입니다.
"지성을 반값으로"는, 지성은 대체로 성립되었으나(좋은 쪽의 시도가 7.0, Fable이 7.5) 가격이 어긋났습니다. $17.67로, 단가는 절반인데 Fable 5 스택($14.61)보다 21% 더 높습니다. 에이전트의 청구 금액을 결정하는 것은 단가가 아니라, 모델이 스스로 결정하는 작업량입니다.
다음 단계는 모델 선정보다 다회 시도입니다. $17.67를 2회 실행하여 합집합을 취하는 것이, $14.61를 1회 실행하는 것보다 안전합니다. 채점표 또한 "몇 할을 얻을 것인가"에서 "2회 던졌을 때 얼마나 흔들리는가"로 축을 바꿉니다.
다음 회차에서는 Anthropic이 공개한 공식 마이그레이션 가이드(official migration guide)와 스타터 키트(starter kit)를 이 유적에서 검증하겠습니다. 공식 방법론의 전제인 "심판을 준비하라"가, 빌드할 수 없는 레거시(legacy) 환경에서 어떻게 무너지고, 어떻게 메워질지 살펴보겠습니다.
과거 시리즈는 여기에서 확인하세요:
제1회 (방법론과 진단 프롬프트)
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기