Playwright MCP 토큰 절감: playwright-optimizer 미들웨어 도입 가이드
Playwright MCP가 페이지 이동마다 토큰을 과다 소모하는 근본 원인 분석과 playwright-optimizer 미들웨어 도입 실전 가이드. Claude Code 연동 설정 예시, 브라우저 자동화 MCP 서버 운영 관점의 토큰 40~60% 절감 실측 전략 정리.
브라우저 AI 자동화를 실제 프로덕션에 올려보면 Playwright MCP가 얼마나 빠르게 토큰을 태우는지 체감하게 됩니다. 우리 팀도 고객사 데이터 수집 워크플로에 Playwright MCP를 붙이자마자, 페이지 하나 이동할 때마다 DOM 스냅샷이 통째로 컨텍스트에 들어와 하루 수십만 토큰이 사라지는 걸 목격했습니다. 이 글은 이 문제의 원인을 뜯어보고, 최근 공개된 playwright-optimizer 미들웨어를 실제로 붙여본 과정을 Claude Code Playwright 연동 설정 예시와 함께 정리한 것입니다.
왜 Playwright MCP는 토큰을 빠르게 소모하는가
기본 동작을 먼저 짚고 가야 합니다. 공식 Playwright MCP 서버는 LLM이 브라우저를 조작할 수 있도록 `browser_snapshot`, `browser_navigate`, `browser_click` 같은 툴을 노출합니다. 문제는 대부분의 툴이 액션 직후 접근성 트리(accessibility tree) 전체를 문자열로 반환한다는 점입니다.
실제 사이드 프로젝트 페이지 한 장을 찍어봤더니 스냅샷이 4,200토큰 가까이 나왔습니다. 이게 페이지 한 번이고, 폼을 찾아 클릭하고 다음 페이지로 넘어가는 3단계 플로우면 단순 탐색만으로 1.2만 토큰이 컨텍스트에 쌓입니다. 여기에 모델이 이전 스냅샷까지 맥락으로 계속 들고 가려 하면 대화 하나가 10만 토큰을 넘기는 건 금방입니다.
원인을 요약하면 세 가지입니다.
- 페이지 전체 DOM을 요약 없이 직렬화: 광고, footer, 숨겨진 메뉴, 아무도 클릭하지 않을 약관 링크까지 모두 트리에 포함됩니다. 상용 사이트일수록 꼬리가 길어지는 구조입니다.
- 액션마다 전체 스냅샷 재전송: 변화한 부분만 보내는 diff 개념이 기본 동작에는 없습니다. 모델은 매 단계 처음 보는 페이지처럼 전체 구조를 다시 읽어야 합니다.
- 반복 플로우의 누적 효과: 에이전트가 "폼을 찾으세요" 류 작업을 하면 N개의 페이지를 오가며 N배의 컨텍스트를 먹습니다. 토큰 사용량이 O(페이지×세션) 으로 늘어나는 셈입니다.
더 고약한 건 이 문제가 개발 단계에선 잘 드러나지 않는다는 점입니다. 혼자 한두 페이지를 시험할 땐 체감되지 않다가, 자동화 스크립트를 스케줄러에 올려 하루 수백 번 돌리면 월 단위 청구서에서 처음 모습을 드러냅니다.
playwright-optimizer는 어떻게 동작하는가
최근 Dion Nam이 공개한 playwright-optimizer는 위 문제를 MCP 서버 바깥에서 해결하는 접근입니다. 즉 Playwright MCP의 응답을 모델이 받기 직전에 한 번 가로채, 지금 액션에 필요한 정보만 남기고 나머지를 잘라내는 경량 미들웨어 역할을 합니다.
동작을 단순화하면 이렇습니다.
- Playwright MCP가 액세시빌리티 트리를 반환
- optimizer가 현재 액션 타입(클릭/입력/네비게이션)을 읽고, 관련 서브트리만 남기는 규칙을 적용
- 남은 노드들을 더 짧은 구조화된 요약으로 재작성해 LLM에 전달
예컨대 `browser_click` 직후에는 "방금 클릭한 요소의 형제·부모 영역"과 "새로 나타난 토스트/모달" 같은 변경분만 유지하고, 바뀌지 않은 헤더·푸터는 `[unchanged: header]` 같은 짧은 플래그로 대체합니다. 모델 입장에선 '지금 무엇이 바뀌었고 다음 후보 액션이 무엇인지'를 훨씬 적은 토큰으로 보게 됩니다.
원리 자체는 Model Context Protocol 생태계에서 자주 보이는 패턴입니다. MCP 서버가 반환하는 원본 페이로드에 파이프라인 성격의 미들웨어를 끼워, 모델에 닿기 전에 한 번 더 축약·재구조화하는 것이죠. Playwright 쪽에서 이 패턴을 먼저 패키지화한 것이 playwright-optimizer라고 이해해도 됩니다.
Claude Code Playwright 연동 설정 예시
Claude Code에서 기본 Playwright MCP를 쓰던 상태라면, optimizer는 MCP 서버 프로세스를 한 번 감싸는 형태로 붙입니다. `~/.claude/mcp_servers.json` 혹은 프로젝트 루트의 `.claude/mcp.json`을 아래처럼 수정하면 됩니다.
```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"-y",
"playwright-optimizer",
"--",
"npx",
"@playwright/mcp",
"--headless"
],
"env": {
"PWOPT_MAX_TREE_TOKENS": "1500",
"PWOPT_STRIP_HIDDEN": "true"
}
}
}
}
```
실행 흐름은 `claude mcp list`로 확인할 수 있고, optimizer가 제대로 붙었다면 응답 JSON에 `"optimizer": "playwright-optimizer"` 같은 필드가 한 번 섞여 나옵니다. 만약 스냅샷 품질이 너무 짧다고 느껴지면 `PWOPT_MAX_TREE_TOKENS`를 3,000 수준으로 올리면서 타협점을 찾는 것을 권장합니다. 우리는 1,500에서 시작해 2,000에 고정했을 때 플로우 정확도가 안정적이었습니다.
도입 전후 토큰 사용량 비교 관점
숫자는 워크플로마다 편차가 크지만, 브라우저 자동화 MCP 서버를 평가할 때 측정해야 할 지표는 공통적입니다.
| 지표 | 최적화 전 관찰 | 최적화 후 기대치 |
| 스냅샷 1회 평균 토큰 | 3,500 ~ 5,000 | 800 ~ 1,500 |
| 3페이지 탐색 플로우 누적 | 10,000+ | 3,000 ~ 4,000 |
| 동일 작업 재시도율 | 높음(컨텍스트 포화) | 낮음(모델이 핵심만 기억) |
정확한 수치는 자기 데이터로 반드시 찍어봐야 합니다. 사이트 DOM 구조가 깊거나 SPA 리렌더가 잦은 경우, optimizer의 diff 규칙이 예상보다 크게 동작하거나 반대로 거의 효과가 없을 수 있습니다. 우리 내부 기준은 "3단계 플로우 기준 누적 토큰 60% 이하"를 충족하지 못하면 룰을 다시 조정한다는 것입니다.
비용 관점에서 한 가지 더 덧붙이면, 토큰 절감은 단순히 청구액 감소로 끝나지 않습니다. 컨텍스트가 짧아지면 동일한 모델이 현재 과업에 더 집중하게 되어, 같은 플로우에서 실패·재시도가 줄어듭니다. 우리 팀 기준으로 optimizer 투입 후 가장 크게 달라진 건 '스크립트가 엉뚱한 버튼을 누르고 다시 복구하는' 실수의 빈도였습니다. 즉 토큰 절감과 정확도 개선이 같은 방향으로 움직입니다.
대안: 수동 스냅샷 파싱 vs 커스텀 MCP 서버
optimizer가 아니라도 같은 문제를 풀 수 있는 선택지는 두 가지 더 있습니다.
- 수동 스냅샷 파싱: 에이전트 쪽 프롬프트에서 "필요 없는 노드를 버리고 요약해서 기억하라"고 지시하는 접근입니다. 단기간에 쓰기엔 편하지만, 모델이 규칙을 매번 지키지 않아 장기 운영엔 불안정합니다. 프롬프트로 불확실성을 해결하는 전략은 실험 단계에 적합합니다.
- 커스텀 MCP 서버: Playwright 위에 직접 서버를 래핑해 내부에서부터 요약 스키마를 설계하는 방법입니다. 제어권은 최대한 확보되지만 구현·유지비가 큽니다. 9명 이하 팀이라면 옵션으로 두되, 먼저 optimizer 같은 미들웨어를 붙여 병목을 측정한 뒤 내재화 여부를 결정하는 순서를 권장합니다. 우리 팀도 내부 포크 대신 먼저 외부 미들웨어를 붙여 지표부터 확보하는 방향으로 움직이고 있습니다.
- 하이브리드: optimizer로 1차 축약을 걸고, 특정 사이트 전용 룰(예: 회사 내부 어드민 화면)만 따로 작은 플러그인으로 덧붙이는 구성도 가능합니다. 일반 규칙은 검증된 오픈소스에 맡기고, 사이트 특수 규칙만 우리가 유지하는 분업이 유지 비용 면에서 가장 합리적이었습니다.
실제 운영해보니 Playwright MCP 설정은 "서버를 더 잘 만드는 것"보다 "응답을 얼마나 잘 줄이느냐"의 문제에 가까웠습니다. 미들웨어 한 겹을 끼우는 것만으로 동일한 모델·동일한 태스크에서 토큰 비용 곡선이 눈에 띄게 완만해집니다.
다음 단계
Playwright MCP를 이미 돌리고 있다면 이번 주 안에 할 일은 두 가지입니다. 첫째, 지금 워크플로에서 스냅샷 한 번당 평균 토큰을 로그로 남기고 실제 분포를 확인하는 것. 둘째, optimizer를 스테이징 환경에만 먼저 붙여 플로우 정확도가 떨어지지 않는지 한 사이클 돌려보는 것입니다.
우리 팀은 같은 접근을 데이터 수집·QA 자동화·고객사 온보딩 스크립트 세 군데에 나눠 붙이고 있습니다. 세 영역 모두 공통적으로 "모델이 오래 작업할수록 품질이 떨어지는" 문제가 있었는데, 스냅샷 경량화가 거의 그대로 대화 수명 연장으로 이어졌습니다. 비슷한 구조의 AX 자동화를 고민 중이라면 모델을 바꾸거나 프롬프트를 새로 쓰기 전에, 지금 쓰는 MCP 응답이 얼마나 뚱뚱한지부터 한 번 찍어보는 걸 권합니다. 관련 케이스와 MCP 도구 비교는 treesoop.com/blog에 계속 정리 중이니, 브라우저 자동화 MCP 서버를 실무에 붙일 계획이 있다면 거기서 더 자세한 실측 데이터를 참고할 수 있습니다.