AI 에이전트 QA 자동화 — 토큰 경제 분석

"QA용 MCP를 따로 빼는 게 이득인가, 스킬로 처리하는 게 이득인가, 서브에이전트로 격리하는 게 이득인가?" 세 옵션을 토큰 비용 모델로 직접 계산해 비교한다.

Seobway · · 10분


0. 비교 결과 한눈에 보기

지표 (QA 3회 + 이후 일반작업 20턴 기준) A: MCP 직접 B: 스킬만 C: 서브에이전트
메인 최종 컨텍스트 크기 119,550 121,050 20,400
QA 중 메인 빌링 input 2,320,500 2,370,000 56,400
QA 후 20턴 빌링 input 2,391,000 2,421,000 408,000
메인이 부담하는 총 빌링 4,711,500 4,791,000 464,400

세 선택지는 경쟁 관계가 아니라 서로 다른 레이어다. 그래서 "택1"이 아니라 "조합"이 정답이다.


1. 왜 같은 층위 비교가 아닌가

선택지 실제 역할 토큰에 영향 주는 지점
MCP 따로 빼기 도구 전송층 — 브라우저를 어떻게 조종하나 도구 스키마 로딩 비용
스킬 절차/지시 — QA를 무슨 순서로 하나 절차 텍스트 1회 로딩 + 계획 재추론 절감
서브에이전트 컨텍스트 격리 경계 — 노이즈가 어디에 쌓이나 누적 출력 격리 (지배적 변수)

이 셋 중 토큰을 좌우하는 절대 변수는 "QA가 만들어내는 더러운 중간 산출물이 어느 컨텍스트에 누적되느냐" 다. 그건 오직 서브에이전트(격리)만 해결한다.


2. 핵심 원리 — LLM 비용은 준2차(quasi-quadratic)다

LLM은 매 턴 컨텍스트 전체를 input으로 다시 전송한다.

턴 t의 빌링 input = (그 시점까지 누적된 컨텍스트 크기)
세션 총 빌링 input = Σ_{t=1..N} (컨텍스트_at_t)

컨텍스트가 매 턴 커지면 비용은 선형이 아니라 누적합(준2차)으로 증가한다. 한 번 들어온 노이즈는 그 턴만 비싼 게 아니라 이후 모든 턴에서 계속 재청구된다. 이게 "QA 출력을 메인에 떨구면 안 되는" 진짜 이유다.


3. 모델 가정 — 계산에 사용한 파라미터

3.1 Playwright 단일 호출 출력 토큰 (실측 근사, char/4)

도구 호출 min max 비고
browser_navigate 300 800 ack + 상태
browser_snapshot 3,000 15,000 접근성 트리 — DOM 규모에 비례, 최대 변수
browser_click 200 600
browser_type / fill 200 600
browser_console_messages 200 2,000
browser_network_requests 500 5,000
browser_take_screenshot 1,000 1,500 이미지 토큰
browser_wait_for 100 400

3.2 대표 QA 플로우 1회 = 10 스텝

navigate → snapshot → click → snapshot → type → click
        → snapshot → console → network → screenshot

플로우 1회 도구 출력 누계: 최소 11,600 토큰, 평균 33,850 토큰, 최대 56,100 토큰.

3.3 기타 상수

변수 의미
BASE_MAIN 18,000 메인 에이전트 베이스 (시스템 프롬프트 + CLAUDE.md + 전역 룰 + 대화)
BASE_SUB 9,000 서브에이전트 베이스 (qa.md + 도구 일부, 슬림)
SKILL 1,500 스킬 절차 텍스트
REPORT 800 서브 → 메인 최종 리포트
RUNS 3 QA 실행 횟수
POST_TURNS 20 QA 종료 후 메인에서 이어지는 일반 개발 턴 수

4. 옵션별 계산

계산 코드(요지):

def billed(base, outs):          # 한 플로우의 준2차 빌링
    ctx = base; tot = 0
    for o in outs:
        tot += ctx               # 이번 턴 컨텍스트 전체 재전송
        ctx += o                 # 도구 출력이 컨텍스트에 누적
    tot += ctx
    return tot, ctx

옵션 A — MCP를 메인 에이전트가 직접 호출 (격리 X)

QA 노이즈(평균 33,850/회)가 메인 컨텍스트에 그대로 누적되고, 이후 모든 턴에서 재청구된다.

항목
메인 최종 컨텍스트 119,550
QA 중 메인 빌링 2,320,500
QA 후 20턴 빌링 2,391,000
총 빌링 4,711,500

QA가 끝나고 일반 작업으로 돌아가도, 부풀어 오른 119k 컨텍스트를 매 턴 계속 끌고 다닌다. 세션이 길수록 손해가 복리로 커진다.

옵션 B — 스킬만 (메인에서 실행)

절차는 고정되지만(신뢰성↑), 도구 출력은 여전히 메인에 떨어진다. 토큰 문제는 풀지 못한다.

항목
메인 최종 컨텍스트 121,050
QA 중 메인 빌링 2,370,000
QA 후 20턴 빌링 2,421,000
총 빌링 4,791,000

스킬은 토큰 절감 수단이 아니라 절차 일관성 수단이다.

옵션 C — 서브에이전트 (격리)

노이즈(평균 33,850/회)는 서브에이전트의 격리된 컨텍스트에서 살다가 종료 시 폐기된다. 메인은 최종 리포트(800)만 수령한다.

항목
메인 최종 컨텍스트 20,400
QA 중 메인 빌링 56,400
QA 중 서브 빌링 (폐기·병렬) 906,450
QA 후 20턴 빌링 408,000
총 빌링 (서브 포함) 1,370,850
메인 부담 총 빌링 (서브 제외) 464,400


5. 결과 비교

지표 A C 차이
메인 최종 컨텍스트 119,550 20,400 5.9배
QA 중 메인 빌링 2,320,500 56,400 41.1배
QA 후 20턴 빌링 2,391,000 408,000 5.9배
총 빌링 (서브 포함) 4,711,500 1,370,850 3.4배
메인 부담 총 빌링 4,711,500 464,400 10.1배
메인 부담 총 빌링 (서브 격리 비용 제외):
A  ████████████████████████████████████████  4,711,500
B  ████████████████████████████████████████  4,791,000
C  ████                                         464,400   (A의 1/10)

해석은 세 가지다.

  1. 메인 컨텍스트 오염 5.9배 — 추론 품질에 직접 영향을 준다. QA 후에도 부푼 컨텍스트를 계속 끌고 다닌다.
  2. QA 중 메인 빌링 41배 — QA를 자주 돌릴수록 격차가 폭발적으로 커진다.
  3. 세션이 길수록 C 우위 확대POST_TURNS(QA 후 작업 턴)가 늘면 A는 큰 컨텍스트를 매 턴 재청구하고, C는 작은 컨텍스트만 유지한다.

6. "MCP 따로 빼기"가 이 환경에선 거의 의미 없는 이유

이 환경의 MCP 도구는 deferred(지연 로딩) 상태다.[1]

The following deferred tools are now available via ToolSearch.
Their schemas are NOT loaded — ... Use ToolSearch ... before calling.

Playwright MCP(약 25개 도구)가 연결돼 있어도 스키마가 컨텍스트에 올라오지 않는다. 이름 한 줄(약 10토큰)만 차지한다. 실제로 쓸 때는 ToolSearch로 그 도구만 on-demand 로딩한다.

→ "QA용 MCP를 별도 서버로 분리"해서 얻는 스키마 절감 이득이 사실상 0이다.


7. 권장 구성 — 세 가지를 레이어로 합친다

세 개를 대체재로 보지 말고 레이어로 합친다.

오케스트레이터(메인)
   └─ 서브에이전트(qa) 스폰  ← 격리 경계 (토큰 절감의 본질)
        ├─ 절차: qa 스킬/qa.md 로 QA 순서 고정  ← 계획 재추론 절감
        └─ 도구: Playwright MCP를 내부에서 on-demand fetch  ← 스키마 0 (deferred)
   ← 받는 것: _workspace/03_qa_report.md (요약 ~800토큰) 만

이 구성의 토큰 효과는 다음과 같다.

서브에이전트를 활용한 작업 분리에 대한 더 자세한 내용은 Context Engineering — 프롬프트, Rules, 메모리, Skill 시스템 → 글에서 다뤘다.


8. 부록 — 계산 재현

PYTHONIOENCODING=utf-8 python 로 3장 파라미터와 4장 billed() 함수를 사용, RUNS=3 / POST_TURNS=20으로 산출했다.

파라미터(snapshot 출력 크기, POST_TURNS)를 바꾸면 절감 배수는 달라지지만, C가 A·B를 항상 압도하는 방향성은 불변이다. 노이즈가 클수록, 세션이 길수록 격차는 더 벌어진다.

참고

  1. [1] Claude Code Docs — Connect Claude Code to tools via MCP
  2. [2] Claude Code Docs — Subagents

관련 글