YouMind
로그인

비용을 80% 절감하는 코딩 에이전트 구축법: Jev + Opus 5.5 (전체 아키텍처)

@cyrilXBT
영어2026년 10월 09일
241K
200
25
11
306

TL;DR

이 가이드에서는 복잡한 추론에는 Opus 5.5를, 컨텍스트 선택 및 오류 복구와 같은 일상적인 의사 결정 작업에는 Jev를 사용하는 코딩 에이전트를 위한 하이브리드 아키텍처를 자세히 설명합니다. 이를 통해 상당한 비용 절감을 달성할 수 있습니다.

당신의 코딩 에이전트는 객관식 문제를 풀기 위해 프런티어 모델 가격을 지불하고 있습니다.

어떤 노트를 로드해야 할까? 이 단계는 대형 모델로 가야 할까, 소형 모델로 가야 할까? 방금 도구가 실패했다. 재시도할까, 수정할까, 포기할까? 어떤 테스트를 먼저 실행해야 할까?

이 모든 질문은 네다섯 가지 가능한 답변 중 하나를 고르는 문제입니다. 그리고 오늘날 대부분의 에이전트 구성에서는, 이런 질문 하나하나가 당신이 가진 가장 비싼 모델에 의해 처리됩니다. 사고(thinking) 기능이 켜진 상태로 전체 컨텍스트를 읽고, 결정을 내리기 전에 한 문단을 통째로 작성하면서 말이죠.

바로 이것이 비용이 새어나가는 구멍입니다.

이 글에서는 그 구멍을 막는 방법을 알려드립니다. Opus 5.5 는 계획 수립, 코드 작성, 디버깅 같은 어려운 추론 작업을 계속 담당합니다. Jev 는 거의 모든 단계에서 발생하는 네 가지 의사결정을 맡습니다. 당신의 하니스(harness)는 선택지를 준비하고, 답변을 확인하며, 최종 결정을 내립니다.

아래의 실제 적용 예시에서는 하나의 기능 개발 세션 비용이 $6.42 에서 $2.00 로 떨어집니다. 무려 69% 저렴해진 것이며, 이 글에는 계산 과정의 모든 줄이 포함되어 있어 당신의 실제 수치와 비교해 볼 수 있습니다.

이 글은 Claude Code, API 위에서 직접 만든 하니스, 또는 그 사이의 어떤 형태로든 실제 업무에 코딩 에이전트를 돌리고 있는 모든 사람을 위해 쓰였습니다. 에이전트를 처음부터 다시 작성할 필요는 없습니다. 이 글에 나온 모든 요소는 기존 루프에 함수 호출 하나로 끼워 넣을 수 있으며, 끄고 켤 수 있는 플래그도 함께 제공됩니다. 제가 쓴 Jev + Claude Code 글을 읽어보셨다면, 이번 글은 그 업그레이드 버전입니다. 핵심 아이디어는 같지만 더 최신 추론 모델을 사용하며, 일반적인 원칙 대신 네 가지 구체적인 의사결정을 다룹니다.

Jev API 키, Anthropic API 키, 그리고 비교 측정을 위한 약 일주일 치의 에이전트 로그가 필요합니다.

한번 만들어 봅시다.

CyrilXBT - inline image

opus 가 추론하고 jev 가 결정한다.

문제: 두 가지 일을 하는 하나의 모델

코딩 에이전트가 작업하는 모습을 10 분만 지켜보면, 완전히 다른 두 종류의 일을 하고 있다는 것을 알 수 있습니다.

첫 번째 일은 추론입니다. 기능을 계획하고, 함수를 작성하고, 스택 트레이스를 읽으며 윤년일 때 날짜 파서가 왜 깨지는지 파악하는 일입니다. 이 작업은 끝이 열려 있습니다. 정답이 목록에 있지 않습니다. 여기에는 당신이 감당할 수 있는 가장 똑똑한 모델이 필요하며, Opus 5.5 는 이 일에 아주 뛰어납니다.

두 번째 일은 결정입니다. 40 개의 프로젝트 노트 중 중요한 3 개를 골라내는 일, 이름 변경(rename) 작업은 저렴한 모델로 넘겨도 된다고 판단하는 일, npm test 가 타임아웃된 후 무엇을 할지 선택하는 일, 전체 1,400 개 중 먼저 실행할 12 개의 테스트 파일을 고르는 일입니다. 이 답변들은 목록에 있습니다. 목록은 짧습니다. 그리고 당신의 코드는 그 답변을 받아 즉시 행동할 수 있습니다.

대부분의 에이전트는 기본값이 그렇다는 이유로 두 가지 일을 모두 같은 모델에 맡깁니다. 루프가 Opus 를 호출하고, Opus 가 생각하고, Opus 가 답하면 루프가 계속됩니다.

작동은 합니다. 하지만 쉽게 놓치기 쉬운 방식으로 느리고 비쌉니다. 결정용 호출은 하나씩 떼어놓고 보면 비싸 보이지 않기 때문입니다. "어떤 노트가 필요할까?"라는 단일 호출은 아마 1 센트 정도일 겁니다. 하지만 모든 단계에서 발생하고, 매번 전체 컨텍스트를 통째로 끌고 갑니다.

그리고 훨씬 더 쉽게 놓치는 두 번째 비용이 있습니다. 에이전트가 무엇을 로드할지 결정하지 못하면, 모든 것을 로드해 버립니다. 모든 프로젝트 노트, 모든 컨벤션 문서, 모든 과거 결정이 모든 호출에 쑤셔 넣어집니다. Opus 5.5 는 캐시 읽기를 백만 토큰당 $0.20 로 저렴하게 만들었지만, "저렴한 가격 × 60 단계 × 노트 폴더 전체"는 여전히 쌓이면 큰 금액이 됩니다.

해결책: Opus 는 추론하고, Jev 는 결정하며, 하니스가 통제한다

Jev 는 TypeSafe 에서 정확히 이 두 번째 일을 위해 만든 모델입니다. 텍스트를 작성하지 않습니다. 컨텍스트와 고정된 선택지 집합을 가진 타입 지정 질문을 주면, 각 선택지에 대한 확률을 반환합니다. 밀리초 단위로 응답하며, 입력 비용은 백만 토큰당 $0.042 이고 출력은 무료입니다.

덕분에 아키텍처를 설명하기가 매우 간단해집니다.

Opus 5.5 는 추론을 담당합니다. 계획, 코드, 디버깅 등 정답이 목록에 없는 모든 작업입니다.

Jev 는 작은 결정을 내립니다. 하니스가 미리 준비한 선택지 중에서 고릅니다.

하니스가 주도권을 유지합니다. 선택지 목록을 만들고, 확률을 읽고, 임계값을 적용하며, Jev 가 확신하지 못할 때 Opus 로 폴백합니다.

사람들이 자주 건너뛰는 것이 바로 세 번째 줄이며, 이 구조 전체를 안전하게 만드는 것도 이 부분입니다. Jev 는 절대 선택지를 지어내지 않습니다. 되돌릴 수 없는 일에 대해 Jev 가 최종 발언권을 갖는 일은 결코 없습니다. "충분히 확실하다"의 기준은 당신의 코드가 결정합니다.

이 글의 나머지 모든 내용이 기반하는 헬퍼 함수는 다음과 같습니다.

from dataclasses import dataclass

@dataclass

class Decision:

answer: str

prob: float

probs: dict

confident: bool

def jev_choice(context: str, question: str, options: list[str]):

여기에 Jev 클라이언트를 연결하세요: TypeSafe SDK, Vercel AI Gateway,

또는 LangChain 패키지. 전달한 모든 선택지에 대해 {option: probability} 를

반환해야 합니다.

raise NotImplementedError

def decide(context: str, question: str, options: list[str], threshold: float):

probs = jev_choice(context, question, options)

answer = max(probs, key=probs.get)

return Decision(answer, probs[answer], probs, probs[answer] >= threshold)

여기에 무엇이 빠져 있는지 주목하세요. Jev 에게 자신이 얼마나 확신하는지 묻는 질문이 없습니다. 대신 반환된 확률을 읽습니다. 어떤 모델에게든 "확실해?"라고 물으면 거의 매번 "응"이라는 대답이 돌아옵니다. 확률만이 정직한 신호입니다.

이제 네 가지 결정을 살펴보겠습니다.

CyrilXBT - inline image

에이전트 단계 내부의 네 가지 결정

결정 1: 컨텍스트 로드 전 관련 프로젝트 노트 선별하기

이것이 가장 큰 단일 레버리지이며, 거의 아무도 구축하지 않은 부분입니다.

당신의 에이전트에는 노트 폴더가 있습니다. AGENTS.md, 아키텍처 문서, 컨벤션, 과거 결정들, "마이그레이션 없이 결제 모듈 절대 건드리지 말 것" 같은 경고문. 아마 30,000 토큰 정도 될 것입니다. 대부분의 에이전트는 중요한 노트를 빠뜨린 사람이 되고 싶지 않아서 매 호출마다 이를 전부 로드합니다.

따라서 모든 것을 로드하는 대신, 각 노트에 대해 간단한 질문을 병렬로 Jev 에게 던집니다. 이 작업에 이 노트가 필요한가?

먼저 노트를 제목 기준으로 청크(chunk)로 나눕니다. AGENTS.md 의 각 섹션은 자체 청크가 되고, 각 아키텍처 문서는 하나 이상의 청크가 됩니다.

import re

def chunk_notes(markdown: str, source: str):

parts = re.split(r"
(?=## )", markdown)

return [{"source": source, "text": p.strip()} for p in parts if p.strip()]

그런 다음 현재 작업과 비교하여 모든 청크에 점수를 매깁니다.

from concurrent.futures import ThreadPoolExecutor

def pick_notes(task: str, notes: list[dict], keep: int = 6, floor: float = 0.55):

def score(note):

probs = jev_choice(

context=f"TASK:
{task}

NOTE ({note['source']}):
{note['text']}",

question="Would an engineer need this note to do the task correctly?",

options=["needed", "not_needed"],

)

return probs["needed"], note

with ThreadPoolExecutor(max_workers=16) as pool:

scored = sorted(pool.map(score, notes), key=lambda s: s[0], reverse=True)

picked = [n for p, n in scored[:keep] if p >= floor]

return picked or [n for _, n in scored[:2]]

여기서 세 가지 세부 사항이 중요합니다.

타협 불가 항목은 항상 로드하세요. 보안 규칙, "절대 force push 금지", 어떤 데이터베이스가 프로덕션인지 알려주는 한 줄 같은 노트는 무슨 일이 있어도 모든 호출에 포함되어야 합니다. 이런 항목에는 always 태그를 달고 점수 평가를 건너뛰세요.

최소 기준선과 폴백을 유지하세요. 0.55 를 넘는 것이 없더라도 상위 2 개는 로드합니다. 컨텍스트가 전혀 없는 에이전트는 약간 과도한 에이전트보다 훨씬 못합니다.

무엇이 제외되었는지 로그에 남기세요. 에이전트가 실수를 했을 때 가장 먼저 확인할 것은, 그 실수를 막아줄 노트가 점수 평가에서 탈락했는지 여부입니다. 이 로그가 keep 과 floor 값을 튜닝하는 근거가 됩니다.

실제 적용 예시에서 이 단일 변경만으로 각 호출의 노트 부분이 30,000 토큰에서 6,000 토큰으로 줄었습니다. 이것만으로도 세션 비용이 약 24% 절감됩니다.

결정 2: 적합한 작업을 더 빠른 워커로 라우팅하기

모든 단계에 Opus 가 필요한 것은 아닙니다.

8 개 파일에 걸쳐 함수 이름을 바꾸는 작업에는 필요 없습니다. 이미 비슷한 필드가 9 개 있는 폼에 필드 하나를 추가하는 데도 필요 없습니다. import 경로를 업데이트하는 데도 필요 없습니다. 이들은 코드베이스에 이미 존재하는 패턴을 따르는 편집 작업입니다.

따라서 각 단계가 실행되기 전에 Jev 가 단계를 분류하고, 하니스가 해당 클래스를 워커에 매핑합니다.

ROUTES = {

"rename_or_move": "fast",

"small_edit_following_existing_pattern": "fast",

"new_logic": "opus",

"debugging": "opus",

"design_decision": "opus",

}

def route(step: str, recent_diff: str):

d = decide(

context=f"STEP:
{step}

RECENT CHANGES:
{recent_diff}",

question="What kind of work is this step?",

options=list(ROUTES),

threshold=0.8,

)

if not d.confident:

return "opus"

return ROUTES[d.answer]

선택지가 어떻게 작성되었는지 보세요. "쉬움"과 "어려움"이 아니며, 당연히 "작은 모델이 처리할 수 있을까?"도 아닙니다. 코드가 액션으로 매핑할 수 있는 구체적인 작업 유형들입니다. 이것이 모든 Jev 질문의 규칙입니다. 모든 선택지는 하니스가 어떻게 행동해야 할지 아는 것이어야 합니다.

그리고 기본값을 주목하세요. 0.8 미만이면 단계는 Opus 로 넘어갑니다. 여기서 라우팅 실수는 한 방향으로만 발생합니다. 어려운 작업을 빠른 워커에 보내면 단계 실패와 재시도 비용이 들지만, 쉬운 작업을 Opus 에 보내면 약간의 추가 비용만 듭니다. 따라서 확신이 없으면 위로 올리세요.

빠른 워커로는 입력 백만 토큰당 $1, 출력 백만 토큰당 $5 인 Haiku 4.5 를 사용합니다. 실제 적용 예시에서는 36 개의 실제 작업 단계 중 12 개가 이곳으로 향합니다.

결정 3: 도구 실패 시 복구 경로 선택하기

도구는 끊임없이 실패합니다. 테스트가 타임아웃됩니다. 파일 경로가 잘못됩니다. 패키지가 설치되지 않았습니다. 셸 명령이 권한 오류에 부딪힙니다. 린터가 전혀 상관없는 것에 대해 불평합니다.

대부분의 에이전트는 가능한 가장 비싼 방식으로 이를 처리합니다. 오류 전체를 대형 모델에 다시 넘기고 무엇을 할지 생각하게 둡니다. 가끔은 그것이 맞습니다. 하지만 종종 답은 뻔한데도, Opus 는 ENOENT 가 파일이 없다는 뜻임을 재발견하는 데 1,500 토큰을 소모합니다.

더 나쁜 것은, 에이전트가 루프에 갇힌다는 점입니다. 재시도, 실패, 재시도, 실패. 매번 완전한 추론 단계 비용을 지불합니다.

그래서 고정된 복구 경로 집합과 함께 실패 정보를 Jev 에게 넘깁니다.

from collections import deque

def tail(text: str, n: int = 4000):

return "".join(deque(text, maxlen=n)) # 오류의 마지막 n 문자

def recover(tool: str, command: str, error: str, attempt: int):

if attempt >= 3:

return "stop_and_report"

d = decide(

context=f"TOOL: {tool}
COMMAND: {command}
ATTEMPT: {attempt}
ERROR:
{tail(error)}",

question="What is the best next move after this failure?",

options=RECOVERY,

threshold=0.8,

)

return d.answer if d.confident else "escalate_to_opus"

text
1RECOVERY = [
2 "retry_unchanged", # 불안정한 네트워크 또는 타임아웃
3 "retry_after_install", # 누락된 패키지 또는 도구
4 "fix_path_and_retry", # 잘못된 파일 경로 또는 cwd
5 "switch_tool", # 이 도구로는 안 되지만 다른 도구로는 가능
6 "escalate_to_opus", # 진짜 디버깅이 필요함
7 "stop_and_report", # 사람의 개입이 필요함
8]

시도 횟수의 하드 캡은 모델이 아닌 코드에 존재합니다. 아무리 저렴한 모델이라도 영원히 재시도하도록 놔둬서는 안 됩니다.

각 복구 경로는 하니스의 작은 함수에 매핑됩니다. retry_after_install 은 정규식으로 오류 메시지에서 누락된 패키지를 읽어 설치합니다. fix_path_and_retry 는 존재하는 경로를 확인하고 가장 유사한 것을 제안합니다. escalate_to_opus 만 실제 비용을 소모하며, 실패가 정말로 사고를 요구할 때만 발동합니다.

실제 적용 예시에서, 이는 세션에서 낭비되는 6 개의 재시도 단계를 제거합니다.

결정 4: 전체 테스트 스위트 전 집중 검사 실행하기

이것은 돈보다 시간을 절약해주며, 시간이야말로 에이전트를 빠르게 느끼게 만드는 요소입니다.

변경 후 대부분의 에이전트는 전체 테스트 스위트를 실행합니다. 스위트에 4 분이 걸린다면, 에이전트는 매 편집 후 4 분을 기다리며 보낸 뒤, 수백 줄의 출력을 훑어보며 중요한 단 하나의 실패를 찾습니다.

해결책은 노트와 동일한 패턴입니다. diff 와 비교해 각 테스트 파일에 점수를 매기고, 가장 관련성 높은 것을 먼저 실행한 뒤, 집중 검사를 통과했을 때만 전체 스위트를 실행합니다.

text
1def pick_tests(diff: str, test_files: list[str], keep: int = 12):
2 def score(path):
3 probs = jev_choice(
4 context=f"DIFF:\n{diff[:12000]}\n\nTEST FILE: {path}",
5 question="Could this change break tests in this file?",
6 options=["likely", "unlikely"],
7 )
8 return probs["likely"], path
9
10 with ThreadPoolExecutor(max_workers=16) as pool:
11 scored = sorted(pool.map(score, test_files), key=lambda s: s[0], reverse=True)
12 return [p for _, p in scored[:keep]]
13
14def check(diff: str, test_files: list[str]):
15 focused = pick_tests(diff, test_files)
16 if not run_tests(focused):
17 return False # 빠르게 실패시키고, 다른 것보다 먼저 수정
18 return run_tests(test_files) # 전체 스위트가 여전히 커밋의 관문 역할

마지막 줄을 두 번 읽어보세요. 전체 스위트는 여전히 무언가 커밋되기 전에 실행됩니다. 집중 검사는 대체재가 아니라 조기 경보입니다. 대부분의 오류를 몇 분이 아닌 몇 초 만에 잡아내면서도, 전체 스위트였다면 잡아냈을 무언가를 배포하는 일은 결코 없습니다.

저렴한 검사도 먼저 추가하세요. 변경된 파일에 대해서만 타입 체크와 린트를 수행합니다. 1 초밖에 걸리지 않지만 테스트가 실행되기도 전에 놀랄 만큼 많은 실수를 잡아냅니다.

통합하기: 하니스 루프

루프의 한 단계 안에 네 가지 결정이 자리 잡는 방식은 다음과 같습니다.

def run_step(task: str, step: str, state):

1. context: 이 단계에 필요한 노트만 로드

notes = state.always_notes + pick_notes(step, state.notes)

2. routing: 이 단계를 위한 워커 선택

worker = state.workers[route(step, state.recent_diff())]

result = worker.run(step, notes=notes, history=state.history)

3. recovery: 이 단계의 도구 실패 처리

for failure in result.failures:

action = recover(failure.tool, failure.command, failure.error, failure.attempt)

state.apply_recovery(action, failure)

4. checks: 집중 테스트 우선, 커밋 전 전체 스위트

if result.diff:

state.log_check(check(result.diff, state.test_files))

그리고 Opus 쪽은 다음과 같습니다. 평소의 Opus 5.5 호출과 동일합니다. 안정적인 컨텍스트(시스템 프롬프트, 도구 정의, "always" 노트)를 먼저 배치하여 단계 간 캐시가 유지되도록 하고, 단계별 특정 자료는 마지막에 배치하세요.

import os

import anthropic

client = anthropic.Anthropic()

OPUS = os.environ["OPUS_MODEL"] # 당신의 Opus 5.5 모델 ID

def opus_step(system: str, notes: list[dict], history: list, step: str):

notes_text = "

".join(n["text"] for n in notes)

return client.messages.create(

model=OPUS,

max_tokens=8000,

system=[{"type": "text", "text": system, "cache_control": {"type": "ephemeral"}}],

messages=history + [{"role": "user", "content": f"NOTES:
{notes_text}

STEP:
{step}"}],

)

특별할 것 없습니다. 비용 절감은 영리한 프롬프트가 아니라, Opus 에 보내지 않게 된 것들에서 나옵니다.

단일 단계 추적

네 가지 결정이 모두 활성화되었을 때 로그에 나타나는 단일 단계의 모습입니다. 작업: 공개 가입 엔드포인트에 속도 제한(rate limiting) 추가하기. 이 추적은 예시를 위한 것이지만, 당신 자신의 로그에서도 이와 같은 형태를 보게 될 것입니다.

step 14 "add a per IP rate limit to POST /signup"

[notes] 41 개 청크를 병렬로 평가

kept: api/middleware.md (0.94), conventions/errors.md (0.88),

infra/redis.md (0.81), decisions/2025_auth.md (0.62)

dropped: 결제, 이메일 템플릿, CI 등을 포함한 37 개 청크

[route] new_logic (0.91) → opus

[opus] 변경 사항을 계획하고 미들웨어 + 설정 + 핸들러 편집 코드 작성

[tool] npm test FAILED "Cannot find module 'bottleneck'"

[recover] retry_after_install (0.97) → npm install 후 재실행

[checks] 변경된 파일 타입체크: 통과

focused tests (1,388 개 중 12 개): 통과

full suite: 통과

위에서 아래로 읽으면서, 저 줄들 중 몇 개가 예전에는 완전한 Opus 호출이었는지 세어보세요. 노트 선별: 거대한 호출 1 회, 아니면 아예 선별 없이 30,000 토큰의 노트를 눈 감고 로드. 라우팅: 없음, 모든 단계가 Opus 로 감. 누락된 패키지: "모듈이 없다"는 것이 "모듈을 설치하라"는 뜻임을 알아내기 위한 완전한 추론 단계 1 회. 테스트 선택: 없음, 매 편집마다 전체 스위트 실행.

이제 저 추적에서 Opus 를 쓰는 줄은 단 하나뿐이며, 그것도 실제로 프런티어 모델이 필요했던 줄입니다. 속도 제한 장치를 계획하고 작성하는 일이죠.

이것이 한눈에 보는 핵심 아이디어입니다. 비싼 모델은 오직 자신만이 할 수 있는 작업 부분에 시간을 쏟습니다.

실제 적용 예시: 69% 절감의 산출 근거

하나의 기능 개발 세션에 대한 전체 계산입니다. 에이전트 60 단계와 전형적인 에이전트가 중간중간 쌓아가는 6 회의 낭비된 재시도를 포함합니다. 모든 가격은 현재 공개된 정가 기준입니다.

이전: Opus 5.5 가 모든 것을 처리

매 단계마다 70,000 토큰의 컨텍스트를 로드합니다. 시스템 프롬프트와 도구에 15,000, 노트 폴더 전체에 30,000, 지금까지의 대화에 25,000 입니다. 그중 80% 가 캐시 히트라고 가정합니다. Opus 5.5 에서는 thinking 이 항상 켜져 있으므로 매 단계 약 1,500 출력 토큰이 생성됩니다.

cache reads: 56,000 × $0.20/M = $0.0112

fresh input: 14,000 × $4.00/M = $0.0560

output: 1,500 × $20.00/M = $0.0300

per step = $0.0972

66 steps × $0.0972 = $6.42

이후: 결정 레이어 도입

Jev 가 30,000 토큰 전체를 로드하는 대신 6,000 토큰의 노트를 선별하므로 컨텍스트가 단계당 46,000 토큰으로 줄어듭니다. 24 개의 순수 결정 단계는 Jev 로 이동합니다. 6 개의 재시도 루프는 사라집니다. 그리고 남은 36 개의 작업 단계 중 12 개는 Haiku 4.5 로 향합니다.

Opus 5.5: 24 steps × $0.0742 = $1.78

Haiku 4.5: 12 steps × $0.0169 = $0.20

Jev: 102 calls × 5,000 tokens

× $0.042/M, output free = $0.02

total = $2.00

$6.42 에서 $2.00 으로. 동일한 기능에 대해 68.8% 저렴해진 것입니다.

CyrilXBT - inline image

잘못된 답변의 비용에 따라 임계값을 설정하라

그리고 각 레버리지가 기여하는 바를 순서대로 누적하면 다음과 같습니다.

notes selection only $4.89 23.7% saved

  • decisions moved to Jev $3.13 51.2% saved
  • recovery paths $2.69 58.1% saved
  • routing to a fast worker $2.00 68.8% saved

이 계산에 대해 솔직하게 짚고 넘어갈 두 가지가 있습니다.

첫째, 이는 명시적 가정에 기반한 모델링 수치이지 당신의 스택을 측정한 값이 아닙니다. 컨텍스트 크기, 캐시 히트율, 결정 횟수는 다를 것입니다. 모든 줄을 보여주는 이유는 당신이 직접 수치를 대입해 볼 수 있게 하기 위함입니다. 실제 적용 전후를 측정한 후에는 제 숫자가 아닌 당신의 숫자를 사용하세요.

둘째, 돈이 실제로 어디로 가는지 보세요. Jev 의 102 회 호출 비용은 총 2 센트입니다. 절감 효과는 Jev 가 호출당 저렴해서 나오는 것이 아닙니다. Jev 가 결정을 내림으로써 발생하지 않게 되는 모든 것, 즉 비대해진 컨텍스트, 객관식 문제를 위한 완전한 추론 단계, 재시도 루프, 이름 변경 작업에서의 대형 모델 호출이 사라지기 때문에 나옵니다.

결정에 그냥 Haiku 를 쓰면 안 될까?

타당한 질문입니다. Haiku 4.5 는 저렴하고 빠릅니다. 굳이 새 모델을 추가할 이유가 있을까요?

세 가지 이유가 있습니다.

여전히 텍스트를 작성합니다. Haiku 는 텍스트로 답합니다. 당신의 선택지 중 하나로 답하도록 프롬프트를 작성하고, 답을 파싱하고, 설명을 덧붙이거나 목록에 없는 것을 고르거나 답을 문장으로 감싸는 경우를 처리해야 합니다. Jev 는 당신이 전달한 모든 선택지에 대한 확률을 반환합니다. 파싱할 것도 없고 목록 밖의 답도 없습니다.

단순한 답변이 아닌 전체 분포를 얻습니다. Jev 가 needed: 0.52, not_needed: 0.48 이라고 하면, 동전 던지기 수준이라는 것을 알 수 있고 하니스가 에스컬레이션할 수 있습니다. 반면 텍스트 모델이 "needed"라고 하면, 그것이 확신한 것인지 알 길이 없습니다. 임계값은 확률을 볼 수 있을 때만 작동합니다.

비용 계산이 다릅니다. Jev 의 출력은 무료이고 입력은 백만 토큰당 $0.042 입니다. 매 단계 41 개의 노트 청크를 평가한다는 것은 단계당 41 번의 작은 호출을 의미합니다. Jev 로는 1 센트의 일부에 불과합니다. 하지만 저렴한 텍스트 모델이라 해도, 그것은 각각의 출력 비용과 지연 시간을 수반하는 41 번의 생성입니다.

Haiku 는 실제로 코드를 작성해야 하는 작은 편집에 사용하세요. Jev 는 목록에서 고르는 데 사용하세요. Opus 는 사고하는 데 사용하세요. 각 모델이 본연의 역할을 수행하게 하십시오.

아무것도 망가뜨리지 않고 롤아웃하는 방법

네 가지 결정을 한꺼번에 켜지 마세요. 제가 권장하는 순서는 다음과 같습니다.

1 주차: 섀도우 모드. 현재 에이전트를 그대로 유지하세요. 에이전트가 내리는 모든 결정에 대해 Jev 에게도 같은 질문을 던지고, 두 답변과 Jev 의 확률을 모두 로그에 기록하세요. Jev 의 답변에 따라 실제로 행동하지는 마세요.

text
1def shadow(decision_name, context, question, options, current_answer):
2 probs = jev_choice(context, question, options)
3 jev_answer = max(probs, key=probs.get)
4 log_row(
5 decision=decision_name,
6 current=current_answer,
7 jev=jev_answer,
8 prob=probs[jev_answer],
9 agree=(jev_answer == current_answer),
10 )

2 주차: 불일치 읽기. Jev 와 현재 에이전트가 의견이 갈린 행만 보세요. Jev 의 확률 기준으로 정렬하세요. 보통 명확한 기준선이 보입니다. 특정 확률 이상에서는 Jev 가 Opus 만큼이나 자주 맞는 답을 냅니다. 그 선이 당신의 임계값입니다. 또한 이 불일치 행들은 실제 트래픽에서 공짜로 만들어진 테스트 세트가 됩니다.

3 주차: 노트 선별 켜기. 가장 큰 레버리지이면서 되돌리기도 가장 쉽습니다. 누락된 노트는 로그에 금방 나타나기 때문입니다.

4 주차: 복구 및 테스트 켜기. 둘 다 코드에 하드 캡과 폴백이 있으므로, 최악의 경우에도 오늘 하고 있는 방식으로 돌아가는 것뿐입니다.

마지막: 라우팅. 라우팅 실수는 사용자에게 가장 잘 드러납니다. 어려운 작업이 빠른 워커로 가면 엉망인 코드가 나오기 때문입니다. 보수적인 임계값으로 가장 마지막에 켜고, 빠른 워커 단계의 실패율을 주시하세요.

모든 결정 뒤에 온/오프 플래그를 두어 한 줄로 되돌릴 수 있게 하세요.

리스크에 따른 임계값 설정

모든 것에 단일 임계값을 적용하는 것은 실수입니다. 답변이 틀렸을 때 벌어지는 일에 따라 설정하세요.

CyrilXBT - inline image

하나의 기능 세션, 동일한 결과 $6.42 에서 $2.00 로

낮은 위험, 되돌리기 쉬움: 0.55 ~ 0.65. 노트 선별. 테스트 순서 지정. 잘못된 답변은 약간의 컨텍스트나 몇 초의 시간만 낭비합니다.

중간 위험: 0.8. 라우팅 및 복구. 잘못된 답변은 단계 실패를 초래하지만, 하니스가 이를 잡아냅니다.

높은 위험, 되돌리기 어려움: 0.9 또는 절대 위임 금지. 파일 삭제. Force push. 프로덕션 설정 변경. 마이그레이션 실행. 솔직한 조언을 하자면, 어떤 모델도 이런 결정을 혼자 내리게 하지 마세요. 사람에게 라우팅하거나, 최소한 확인 단계를 거친 Opus 에게 넘기세요.

임계값 미만의 모든 것은 사다리를 타고 올라갑니다. 추론이 필요하면 Opus 로, 판단이 필요하면 사람에게로 갑니다.

이 방법이 통하지 않는 경우

이 아키텍처가 모든 워크로드에 마법 같은 승수를 제공하는 것은 아닙니다.

순수 생성 워크로드는 거의 변하지 않습니다. 에이전트가 대부분의 시간을 명확한 명세로부터 방대한 양의 새 코드를 작성하는 데 쓴다면, 옮길 결정이 많지 않습니다. 노트 선별로 인한 절감은 얻겠지만 그 외에는 별로 없습니다.

작은 프로젝트에는 필요 없습니다. 노트 폴더 전체가 2,000 토큰이고 스위트가 8 초 만에 끝난다면, 이를 구축하는 오버헤드는 아직 가치가 없습니다.

Jev 는 단독으로 최종 결정을 내리는 데 뛰어나지 않습니다. 무언가를 알아채고 짧은 목록에서 고르는 데는 훌륭합니다. "이 PR 을 머지할 준비가 되었는가?"를 단일 질문으로 결정하게 하고 싶은 모델은 아닙니다. 큰 질문을 작은 질문으로 쪼개고, 각각에 점수를 매긴 뒤, 당신 코드에서 당신만의 가중치로 결과를 결합하세요.

고정된 질문에 대한 레이블 데이터가 이미 있다면, 직접 호스팅하는 소형 모델이 가격 면에서 Jev 를 이길 수 있습니다. Jev 는 질문이 계속 바뀌고 학습 데이터가 없을 때 빛을 발하는데, 이는 대부분의 코딩 에이전트에 해당하는 상황입니다.

피해야 할 실수들

모델이 선택지 목록을 작성하게 두는 것. 전체 아키텍처는 코드가 행동할 수 있는 선택지에 의존합니다. 모델이 선택지를 생성하면 자유 텍스트 파싱의 늪으로 돌아갑니다.

Jev 에게 확신하는지 묻는 것. 대신 확률을 읽으세요. 자기 보고(self-report)는 거의 항상 "yes"입니다.

폴백 없음. 모든 Jev 결정에는 "확실하지 않음"을 위한 경로가 필요하며, 그 경로는 Opus 나 사람이어야지 절대 찍어맞추기가 되어서는 안 됩니다.

코드 대신 프롬프트에 재시도 제한을 두는 것. "3 번만 재시도해"라는 지시를 받은 모델은 이따금 30 번을 재시도합니다. 코드는 그렇지 않습니다.

전체 테스트 스위트를 없애는 것. 집중 검사는 속도를 높여줍니다. 전체 스위트는 정확성을 지켜줍니다. 둘 다 유지하세요.

아무것도 측정하지 않는 것. 시작하기 전에 세션당 비용을 기록해 두지 않으면, 20% 를 아꼈는지 70% 를 아꼈는지 절대 알 수 없습니다. 먼저 평소처럼 일주일간 작업한 사용량을 뽑아보세요. 10 분이면 충분하며, 이것이 유일하게 중요한 숫자입니다.

이번 주에 해야 할 일

전체 과정을 체크리스트로 정리했습니다.

  1. 일주일간의 에이전트 세션을 기록합니다: 단계, 토큰, 비용, 실패 건수.
  2. 루프 안에 숨어 있는 의사결정 지점을 찾습니다: 노트, 라우팅, 복구, 테스트.
  3. 각 항목을 고정된 선택지가 있는 질문 형태로 작성합니다.
  4. 일주일 동안 현재 사용 중인 에이전트 옆에서 Jev 를 섀도 모드로 실행합니다.
  5. 불일치 로그를 바탕으로 위험도에 따라 임계값을 설정합니다.
  6. 노트 선택부터 켜고, 그다음 복구와 테스트, 마지막으로 라우팅을 활성화합니다.
  7. 적용 전후의 세션당 비용을 비교합니다. 그것이 바로 여러분이 찾는 숫자입니다.

Opus 5.5 는 제가 코드 작업에 사용해 본 최고의 추론 모델입니다. 하지만 다른 모든 작업까지 맡기는 것이 실수입니다.

Opus 에게는 생각하게 하세요. 결정은 Jev 가 내리게 하세요. 그리고 여러분의 코드가 지배하게 하세요.

이 글이 도움이 되었다면 @cyrilXBT 를 팔로우해 주세요. 매주 최신 AI 모델로 구축하는 방법을 실제 수치와 함께 자세히 풀어냅니다.

나중에 직접 구축할 때 바로 참고할 수 있도록 이 글을 북마크해 두세요.

원클릭 저장

YouMind로 바이럴 글을 AI 심층 읽기

소스를 저장하고, 핵심 질문을 던지고, 주장을 요약해 바이럴 글을 다시 활용할 수 있는 노트로 바꾸세요. 하나의 AI 워크스페이스에서 모두 할 수 있습니다.

YouMind 둘러보기
크리에이터를 위해

당신의 Markdown을 깔끔한 𝕏 글로

직접 쓴 장문을 올릴 때 이미지, 표, 코드 블록을 𝕏에 맞게 정리하는 일은 번거롭습니다. YouMind는 전체 Markdown 초안을 깔끔하고 바로 게시할 수 있는 𝕏 글로 바꿔 줍니다.

Markdown → 𝕏 사용해 보기

분석할 패턴 더 보기

최근 바이럴 아티클

더 많은 바이럴 아티클 보기