Retort - 최적의 AI 코딩 스택
요약
Retort는 언어, 모델, 양자화, 에이전트 등 다양한 요소를 결합한 최적의 AI 코딩 스택을 실험하고 평가하는 도구입니다. 통과 비율(pass-proportion)이라는 엄격한 기준을 통해 실제 작업 수행 능력을 검증하고 최적의 구성을 제안합니다.
핵심 포인트
- 언어, 모델, 에이전트 등을 포함한 전체 스택을 통합적으로 평가
- 통과 비율(pass-proportion)을 기준으로 엄격한 성능 검증 수행
- 후보 선정부터 은퇴까지 체계적인 스택 라이프사이클 관리
- 단순 신기술이 아닌 비용, 지연 시간 등 실질적 우위를 기준으로 선정
새로운 실험이 완료됨에 따라 현재의 최적 스택에 대한 이 스냅샷은 계속해서 변화합니다. 만약 의견이 다르거나 다른 구성 또는 사용 가능한 모델이 있다면, Retort를 사용하여 직접 실험을 수행하고 풀 리퀘스트 (pull request)를 보내주세요...
https://github.com/adrianco/retort/blob/main/optimal-blog.md
도구를 통해 현재의 권장 사항을 직접 가져오고 싶다면 https://github.com/adrianco/retort/blob/main/optimal.json에 JSON 형식의 파일도 준비되어 있습니다.
살아있는 문서 — 최종 업데이트 2026-07-30 (최초 게시 2026-07-14). 이 문서는 오늘 무엇을 실행해야 하는지를 기록합니다: 선도적인 스택들과 각 스택에 필요한 정확한 구성입니다. 이것은 역사가 아닙니다. 대체된 스택과 거부된 구성은 여기서 다루지 않습니다; 그것들은 은퇴했으며, 은퇴가 목적입니다.
이 문서가 무엇인지
**스택 (stack)**은 단순히 모델만이 아니라, 실제로 배포하는 전체를 의미합니다:
언어 (language) × 모델 (model) × 양자화 (quantization) × 서빙 레이어 (serving layer) × 에이전트 (agent) × 컨텍스트 엔진 (context engine) × 샘플링 (sampling) × 프롬프트 (prompt)
Retort는 **통과 비율 (pass-proportion)**을 기준으로 스택의 점수를 매깁니다 — 실제 작업에 대해 스택을 N번 실행하고, 출력물이 사양을 완전히 구현한 비율을 계산합니다: 고정된 체크리스트의 모든 요구 사항, 실제로 실행되는 테스트, 그리고 독립적인 평가자에 의해 검증된 결과여야 합니다. 요구 사항 하나라도 놓친 실행은 0.9가 아니라 실패입니다. 이를 관리되지 않는 단일 실행이 완전히 정확하게 나올 확률로 이해하십시오.
이 엄격한 기준은 의도된 것입니다. 왜냐하면 이 수치가 스택을 관리 없이 작동하게 둘 수 있는지 여부를 결정하기 때문입니다.
라이프사이클: 스택이 여기에 도달하고 떠나는 방법
이 문서는 도구가 이미 실행하고 있는 라이프사이클의 인간이 읽을 수 있는 뷰(view)입니다. 각 단계는 Retort 명령이므로, 여기에 기재된 항목들은 취향에 의해 큐레이션된 것이 아니라 파생된 것입니다:
CANDIDATE ──► SCREENING ──► TRIAL ──► PRODUCTION ──► RETIRED
| 단계 | 의미 | 결정 방식 |
|---|---|---|
| Candidate (후보) | 새로운 모델, 에이전트 또는 설정이 나타남 | retort intake --factor model --level <new> 명령이 기존 설계를 재시작하는 대신 확장함 |
| ... |
게이트(Gates)는 의견이 아닌 설정(Configuration)입니다. 이는 각 workspace.yaml 파일에 정의되어 있습니다:
promotion:
screening_to_trial: { p_value: 0.10 }
trial_to_production: { posterior_confidence: 0.80 }
스택(Stack)은 개발자가 실제로 선택한 축(Axis) — 언어, 작업 크기, 비용 또는 지연 시간(Latency) 예산 — 에서 우위를 점할 때만 이곳에 자리할 수 있습니다. 단순히 새롭다는 것은 자격 요건이 아닙니다. 어떤 축에서도 우위를 점하지 못하면, retort report pareto가 해당 스택이 도태되었음을 보여주며 스택에서 제외됩니다. 목록을 의도적으로 짧게 유지하는 이유입니다.
스택의 성능을 확실히 저하시키는 설정은 즉시 제거되며 금지된 설정 (forbidden settings) (아래 참조)으로 기록됩니다. 새로운 모델 출시(Frontier 모델 및 로컬 모델 모두 포함)는 재자격 검증(Re-qualification) 과정을 트리거하므로, 이 문서는 계속해서 업데이트될 예정입니다.
시작하기: 각 셀을 통과하는 가장 저렴한 (모델 × 사고 수준 (thinking level))
스택은 모델 그리고 사고 수준 (thinking level)의 조합입니다. 4개의 Claude 버전 × 5개의 노력 수준(Effort levels)에 걸쳐 하나의 셀을 기준으로 측정했을 때, 21개의 모든 조합이 통과되었습니다. 이때 비용은 동일한 출력물에 대해 $0.42에서 $6.75까지 16배의 차이가 났습니다. 비용을 결정하는 것은 모델 버전보다 사고 수준(Thinking level) 조절이며, 이 조절은 결과에는 전혀 영향을 미치지 않습니다. 따라서 권장 사항은 단일 모델이 아닌 항상 '쌍(Pair)'으로 제공됩니다.
아래 표의 기계 판독 가능(Machine-readable) 형태는 optimal.json 에 커밋됩니다 (retort report optimal --routing-json optimal.json으로 재생성). 이를 통해 메타하네스 라우터(Metaharness router), CI, 또는 사용자의 자체 스크립트와 같은 다른 도구들이 텍스트를 스크래핑할 필요 없이 라우팅 결정(Routing decision)을 직접 사용할 수 있습니다.
| 언어 | Routine → cloud | 통과 (pass) | $ | Routine → local | Hard → cloud | 통과 (pass) | $ |
|---|---|---|---|---|---|---|---|
| c | Opus 4.8 @ default n=1 | 1.00 | $1.28 | — | Fable 5 @ default n=1 | 1.00 | $10.59 |
| ... |
effort컬럼 읽기. 거의 모든 셀이default라고 표시되어 있는데, 이는 권장 사항이라기보다 정직한 상태 기술입니다. 사고 수준 (thinking level)이 변경된 셀은 단 하나뿐입니다 (python × bookshop, exp-49). 그 외의 모든 곳에서 코퍼스 (corpus)는 정확히 하나의 측정된 수준을 가지고 있으므로, 라우터 (router)는 해당 실행에서 실제로 사용된 수준을 보고할 뿐, 아무도 수행하지 않은 비교를 암시하지 않습니다. 수치를 조절했을 때의 결과는 일관되었습니다.low비용은 동일한 신뢰도에서 CLI 기본값보다 약 1.6배 저렴했으며, 기본값은 저렴한 축에 속하지 않습니다. 조절 범위가 넓어짐에 따라 이 수치들은low쪽으로 이동할 것으로 예상됩니다.
null은 해당 셀의 기준을 통과하는 측정값이 없음을 의미합니다 —
신뢰성(Reliability), 비용(Cost), 시간(Time)은 모두 작업 규모(task size)별로 보고됩니다. 루틴(routine) 작업과 어려운(hard) 작업은 서로 다른 업무이며, 루틴 작업에서 저렴하고 확실한 스택이 어려운 작업에서는 그렇지 않을 수 있습니다. 여기서 루틴 신뢰성(routine reliability)은 여러 언어가 혼합된 수치이며, 이 문서에서 가장 유용성이 낮은 숫자입니다 — 이는 특정 스택의 강점인 언어 뒤에 약점인 언어를 숨깁니다 (예: 로컬 Qwen은 Python/Go는 통과하지만 Rust는 통과하지 못함; Opus는 Java에서 4.8로 하락). 이를 대략적인 분류 용도로만 사용하십시오. 실제로 결정할 때 사용해야 할 수치는 아래의 언어별 성공률 매트릭스(per-language success-rate matrix)입니다. (어려운 작업 신뢰성은 단일 작업 기준이며, Python/Go로 측정되었습니다.)
| 스택 (Stack) | 신뢰성 (routine · hard) | 비용 (routine · hard) | 시간 (routine · hard) |
|---|---|---|---|
| Claude Opus 5 | 1.00 · 1.00 | $3.23 · $21.67 | 546 s · 2630 s |
| ... | |||
(Table generated from master.db by retort report optimal — do not hand-edit between the markers.) 각 로컬 스택의 루틴 수치는 해당 스택이 **권장(recommended)**되는 언어 범위 내로 한정됩니다 (35B: Python/Go; 80B: Python/Go/TypeScript). 실패하는 언어를 포함한 언어별 전체 진실은 아래 매트릭스에 있습니다. 어려운 작업(hard task)에서 로컬 모델들은 현재 측정되었으며 둘 다 성능이 저조합니다 — 35B는 0.25, 80B는 0.00입니다 (각 스택별 불렛 포인트 참조). 로컬 Rust는 자격 미달입니다 (80B 0.33, 근소한 차이). |
⚠️ 로컬 + 어려운 작업: 무인 상태에서는 벽에 부딪히지만, 복구 루프(repair loop)를 통하면 돌파 가능
아래의 0.00은 무인 상태에서의 첫 번째 시도 (unattended, first-attempt) 수치이며 이는 변하지 않습니다 — exp-50을 재실행한 결과 첫 번째 시도에서 0/6을 기록했으며, 이는 exp-39와 정확히 일치합니다.
exp-50이 추가로 보여주는 점: retort의 자가 복구 두 번째 기회 (self-repair second chance) — 즉, 자신의 코드와 평가(evaluation)의 비판(critique)을 결합하여 셀을 다시 시드(re-seed)하는 방식 — 를 통해 80B 모델은 6번의 실행 중 3번에서 요구 사항을 완전히 충족(full req-coverage)했습니다. 모든 통과(pass)는 두 번째 시도였으며, 무인 상태(unattended)에서의 통과는 없었습니다. 발표된 0.00과 비교했을 때, 두 번째 시도 통과에 대해 절반의 점수를 부여하면 통과 비율(pass-proportion)은 0.25가 됩니다.
이를 다음과 같이 해석할 수 있습니다: 80B 모델은 12개의 능력 중 약 11개를 안정적으로 수행하지만, 마지막 하나는 혼자서는 해결할 수 없습니다. 하지만 무엇이 누락되었는지 알려주면 약 절반의 확률로 이를 해결합니다. 무인 사용 시
- Fable 5는 13개 언어 모두에서 어려운 작업(hard task)을 매번(1.00) 완수합니다. 사람이 개입하지 않는 상태에서 다중 역량이 필요한 어려운 작업이 반드시 정확해야 한다면, 이것이 정답입니다 — 실행당 약 $10.47 및 약 18분이 소요되며, 당신이 구매하는 것은 바로 그 확실성입니다.
- Opus 5 또한 13개 언어 모두에서 어려운 작업 1.00을 달성하지만, 비용은 약 $21.67, 시간은 약 44분이 소요됩니다 — 동일한 결과물을 얻기 위해 비용은 두 배, 시간은 2.4배가 더 듭니다. 이 모델은 13개 언어 전체를 대상으로 측정된 유일한 스택이라는 강점 덕분에 잠시 이 자리를 차지했으나, Fable 5가 누락되었던 9개 언어에서도 실제로 실행되자 그 차별점은 사라졌습니다. Opus 5가 반드시 선택되어야 하는 언어는 여기 없습니다.
- Sonnet 5는 Fable보다 비용은 약 15% 저렴하고 시간은 비슷하면서, 어려운 작업에서 0.93을 기록했습니다 — 약 14번 중 1번 정도의 실패가 허용 가능한 경우, 비용 효율적인 어려운 작업용 선택지입니다.
- Opus 4.8은 어려운 작업이 가능한(hard-capable) 클라우드 스택 중 가장 저렴하지만, 어려운 작업에 대한 신뢰도는 약 0.59 — 즉 동전 던지기 수준이므로 검토 및 재시도(review-and-retry)를 위한 예산을 고려해야 합니다. 일상적인(routine) 작업에서는 약 1.00의 성능을 보이며 저렴합니다; 이것이 이 모델의 진정한 틈새시장입니다.
- Opus 4.7은 훌륭하고 저렴한 일상적(routine) 스택(1.00, 약 $0.97)이지만, **어려운 작업에는 취약(0.40)**합니다 — 어려운 작업을 이 모델에 맡기지 마세요.
- Qwen 35B local은 $0의 비용으로 일상적인(routine) Python / Go 작업을 각각 0.85로 수행합니다 — 이것이 이 모델의 진정한 틈새시장입니다. 이 모델의 대표 수치(0.78)는 두 언어보다 낮은데, 이는 이제 혼합 데이터에 Rust와 TypeScript 실행 결과가 포함되었기 때문입니다. 이 두 언어는 0.00을 기록했습니다 — 이는 왜 평균이 아닌 언어별 매트릭스를 읽어야 하는지를 보여주는 이 문서의 가장 명확한 사례입니다. **어려운 작업(hard task)에서는 0.25(12개 중 3개)**를 기록합니다 — 가끔 12개 역량을 모두 맞추기도 하지만, 신뢰할 수는 없습니다. Rust와 TypeScript는 자격 미달입니다.
- Qwen 80B local (
Qwen3-Coder-Next) — _Python, Go, TypeScript_를 위한 최고의 로컬 스택 (context_threshold: 0.9, "full context"). 위에서 언급된 주요 수치들은 이제 0.9 기준, 즉 깨끗한 9개 언어 기준선(exp-38, n=3/language)에서 다음과 같습니다: Python 1.00, Go 1.00, TypeScript 1.00 — 세 언어 모두 신뢰할 수 있으며, 비용은 모두 $0입니다.
TypeScript는 핵심적인 열쇠(unlock)입니다: ctx 0.35/0.7에서 0.33을 기록했으며, 압축(compaction)을 전체 컨텍스트(full context)로 높이면 3/3을 통과합니다. 35B 모델보다는 느립니다 (600초 루틴). Rust는 0.33 (1/3) → 클라우드(cloud) — 하지만 2번의 실패는 _아슬아슬한 실패(near-misses)_였다는 점에 주목하십시오 (요구사항 충족률(req-coverage) 0.92/0.92; 코드는 컴파일되며 테스트도 100% 통과하지만, 단지 12개의 사양 요구사항을 놓친 것뿐입니다). 이는 과거 사례처럼 벽에 부딪혀 멈춰버리는(thrash-to-the-wall stalls) 현상이 아닙니다 (retort diagnose+rescore+reevaluate를 통해 확인되었으며, 이를 스코어러 툴링의 오탐(false-failures)으로 잡아내어 실제 아슬아슬한 실패 점수를 복구했습니다). 나머지 5개 언어는 → 클라우드: java/erlang은 아슬아슬한 실패(0/3)이며, clojure/csharp/elixir는 진정한 0.00을 기록했습니다 — 이들은 작동하는 코드를 전혀 생성하지 못합니다 (harness가 아닌 GENUINE으로 진단됨). 어려운 작업(hard task)에서 0.00을 기록하며, 이는 이제 설정 불변성(config-invariant)이 검증되었습니다 — 전체 컨텍스트로 재실행(exp-39, brazil at 0.9)해도 여전히 0/6이며, 이는 0.7(exp-31)과 동일합니다: Python은 11/12까지 근접하지만 12개를 모두 채우지는 못하며, Go는 실제로 _퇴보(regresses)_합니다 (완료하지 못하는 모든 실행에서 발생하는 것과 동일한 후기 압축(late-compaction)의 단점으로 인한 정체). 따라서 전체 컨텍스트는 엄격하게 쉬운 언어들을 위한 것이며, 어려운 작업의 한계치(ceiling)를 높여주지는 않습니다. 규칙: 로컬 Python, Go, TypeScript는 80B 사용 (context_threshold: 0.9 적용); Rust, 니치(niche) 언어, 그리고 어려운 작업은 → 클라우드.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기