pxpipe 소개
pxpipe는 Claude Code가 API로 보내는 요청에서 부피가 큰 텍스트 컨텍스트를 PNG 이미지로 렌더링해 입력 토큰을 줄이는 로컬 프록시입니다. 시스템 프롬프트, 도구 문서, 오래된 대화 이력처럼 매 요청마다 반복 전송되는 큰 덩어리를 요청이 사용자의 머신을 떠나기 전에 압축된 이미지 페이지로 치환합니다. TypeScript로 작성되어 있고 npx 명령 한 줄로 실행할 수 있으며, 응답 스트리밍은 그대로 유지됩니다.
핵심 아이디어는 이미지의 토큰 비용이 담긴 텍스트 양이 아니라 픽셀 크기로 고정된다는 점입니다. 실제 Claude Code 트래픽 기준으로 코드, JSON, 도구 출력 같은 밀도 높은 콘텐츠는 텍스트로 보내면 토큰당 약 1자에 그치지만, 이미지로 보내면 토큰당 약 3.1자를 담을 수 있습니다. 읽는 쪽은 Anthropic의 컴퓨터 사용(Computer Use)이 스크린샷을 읽을 때 쓰는 것과 같은 비전 채널입니다. 저자는 현재 Fable 5 가격 기준으로 전체 청구액이 "약 59~70% 낮아진다" 는 측정 결과를 제시하면서도, 가격과 워크로드가 계속 변하므로 오래 유효한 수치는 ~/.pxpipe/events.jsonl 에 요청 단위로 기록되는 토큰 절감량 자체라고 설명합니다 (README 도입부).
다만 이 변환은 무손실이 아닙니다. ID나 해시처럼 바이트 단위로 정확해야 하는 값은 이미지에서 잘못 읽힐 수 있고, 그 실패는 오류가 아니라 그럴듯한 오독으로 나타납니다. 그래서 pxpipe는 최근 턴을 항상 텍스트로 남기고, 계산상 이득이 있는 요청에만 이미지를 적용하는 수익성 게이트를 두며, 기본적으로 렌더 판독 성능이 검증된 모델(Fable 5, GPT 5.6)에만 동작합니다.
위 그림은 실제 transformRequest 출력 예시로, 약 48,000자 분량의 시스템 프롬프트와 도구 문서가 한 장의 밀집 페이지로 재배치된 모습입니다. 같은 내용을 텍스트로 보내면 약 25,000 토큰이 들지만 이 이미지 한 장은 약 2,700 이미지 토큰에 해당한다고 저자는 밝힙니다 (README 도입부).
pxpipe의 동작 방식
tool_result string ──► wrap at 1928px-wide columns ──► pack ~92,000 chars/page ──► PNG[]
프록시는 /v1/messages 요청을 가로채 압축 대상이 되는 큰 블록을 이미지 블록으로 다시 쓰고, 정적 프리픽스를 보존해 프롬프트 캐싱이 계속 동작하도록 이어붙인 뒤 원래 API로 전달합니다. 1928×1928 크기의 이미지 한 장은 약 4,761 비전 토큰으로 약 92,000자를 담으므로, 텍스트가 유리해지는 구간은 토큰당 약 19자를 넘는 성긴 산문뿐입니다. 실측된 Claude Code 트래픽은 토큰당 약 1.91자(N=391)로 그 기준을 크게 밑돕니다 (README §How it works).
이미지로 변환되는 대상은 세 종류의 입력 블록이며, 각각 수익성 게이트를 거칩니다 (README §FAQ).
- 약 6,000자 이상의 토큰 밀도가 높은 대형
tool_result본문 (파일 읽기, 명령 출력, 로그) - 오래된 대화 이력: 최근 턴 뒤로 밀려난 턴들을 이미지 페이지로 재렌더링 (최근 턴은 항상 텍스트 유지)
- 정적인 시스템 프롬프트 + 도구 문서 덩어리
그 밖의 모든 것, 즉 사용자 메시지와 최근 턴, 모델의 출력, 성긴 산문, 압축해도 이득이 없는 작은 블록은 바이트 그대로 통과합니다. 허용 목록 밖의 모델로 가는 요청도 전부 그대로 통과합니다.
pxpipe 데모 영상
아래 두 영상은 같은 작업을 좌우로 나눠 A/B 로 비교합니다. 왼쪽이 pxpipe 없이 그냥 텍스트로 보낸 세션, 오른쪽이 pxpipe를 거친 세션 입니다.
첫 번째 영상은 기본값이자 렌더 판독 성능이 100/100 인 Fable 5 입니다. pxpipe를 켠 쪽은 이미지로 렌더링된 39개 파일에서 특정 토큰의 등장 횟수를 10/10 으로 정확히 세어 grep 결과와 한 줄도 어긋나지 않았고, 여러 단계에 걸친 장부 계산도 맞혔습니다. 세션이 끝났을 때 켠 쪽은 컨텍스트를 73.5k/1M 만 쓰고 약 6.06달러로 마친 반면, 끈 쪽은 컨텍스트가 96%까지 차오르며 약 42.21달러가 나왔습니다. 다만 한 가지 한계도 영상에 그대로 담겨 있습니다. pxpipe를 켠 쪽은 요청한 "한 줄 출력" 형식을 맞추는 데 한 번의 추가 지시가 필요했습니다.
두 번째 영상은 기본값에서 제외된 Opus 4.8 입니다. 텍스트로 심어둔 값은 양쪽 모두 잘 읽어냈지만, 이미지로 렌더링된 문구의 등장 횟수는 Opus 쪽에서 제대로 읽히지 않았습니다. 중요한 점은 이때 pxpipe가 그럴듯한 숫자를 지어내지 않고 "읽을 수 없다" 고 그대로 말한다는 것입니다. 바로 이 오독률 때문에 Opus는 기본 활성화 목록에서 빠져 있고 사용자가 직접 켜야 합니다.
pxpipe의 한계와 벤치마크
pxpipe의 README는 The honest part 섹션에서 손실 특성을 수치로 공개합니다. 밀집 렌더 안의 12자 16진수 문자열을 그대로 회상하는 테스트에서 Fable 5는 15개 중 13개, Opus 4.8은 15개 중 0개를 맞혔고, 틀린 경우는 오류가 아니라 조용한 허구(confabulation)로 나타났습니다. 그래서 ID, 해시, 시크릿 같은 바이트 정확성이 필요한 값은 텍스트로 남겨야 하며, 허용 목록 밖 모델을 쓰는 서브에이전트로 우회하는 탈출구도 안내합니다 (예: CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6 을 지정하거나 에이전트 frontmatter에 model: sonnet 을 두면 그 작업은 이미지 변환 없이 텍스트 그대로 전달됩니다). Opus 4.7/4.8과 GPT 5.5는 렌더 오독률이 높아 기본값에서 제외되어 있고, PXPIPE_MODELS 환경 변수나 대시보드에서 직접 켜야 합니다.
모델이 암기했을 수 없는 무작위 숫자 문제로 측정한 벤치마크는 다음과 같습니다 (README §Benchmarks).
| 테스트 | N | 텍스트 | pxpipe (이미지) | 토큰 |
|---|---|---|---|---|
신규 산술 문제, claude-fable-5 |
100 | 100% | 100% | −38% |
신규 산술 문제, claude-opus-4-8 |
100 | 100% | 93% | −38% |
| 요지 회상 A/B (결정·값·경로·이름·부정, 방해 요소 포함, 15k~45k자 세션), Fable 5 | 98/조건 | 98/98 | 98/98 | - |
| 상태 추적 (값 3회 변경 후 최종·최초·횟수 질의), Fable 5 | 18/조건 | 18/18 | 18/18 | - |
| 언급된 적 없는 사실의 허구 생성 (낮을수록 좋음), Fable 5 | 16/조건 | 0/16 | 0/16 | - |
| 12자 16진수 원문 회상 (밀집 렌더), Opus | 15 | 15/15 | 0/15 | - |
| 12자 16진수 원문 회상 (밀집 렌더), Fable 5 | 15 | - | 13/15 | - |
실제 코딩 작업에서는 SWE-bench Lite 파일럿에서 두 조건 모두 10/10을 유지하며 요청 크기를 65% 줄였고, SWE-bench Pro에서는 켠 쪽 14/19 대 끈 쪽 15/19로 요청 크기 60% 절감에 판정 일치 18/19를 기록했습니다. 저자는 표본이 작다는 점을 명시하며 원자료를 저장소의 eval/ 디렉토리와 FINDINGS.md에 공개해 두었습니다 (README §The honest part).
그 밖의 알려진 한계도 README에 명시되어 있습니다. 이미지 변환은 큰 요청이 머신을 떠나기 전에 PNG 인코딩 시간을 더하고, 문자 지원은 ASCII/라틴 문자권이 가장 충분히 검증되어 있으며 CJK(한국어·중국어·일본어)는 동작하지만 보수적으로 처리 됩니다. 저자는 2026년 7월 5일 기준으로 렌더링 자체를 개선하려는 연구는 일단 보류했다고 밝혔는데, 원문 회상 실패가 폰트나 색·레이아웃 같은 표현 방식의 문제가 아니라 수익이 나는 밀도에서는 모델의 판독 용량 자체가 부족한 문제(capacity-bound)이기 때문입니다. 다만 모델이 새로 나올 때마다 해상도 스윕을 다시 돌리는 것을 관찰 조건으로 두었고, 판독 가능한 밀도가 Opus 4.8에서 Fable 5로 오면서 글리프 면적 기준 약 4배 넓어진 만큼 판독률이 100%에 가까워지면 절감폭은 자연히 커집니다. 이미지로 압축한 컨텍스트가 실질 컨텍스트 창을 약 2배로 넓혀주는지, 활성 컨텍스트가 작아질 때 긴 작업의 정확도가 오르는지는 아직 검증할 열린 질문으로 남겨두었습니다 (README §Limitations, §Roadmap).
pxpipe 설치 및 사용 방법
README가 안내하는 시작 방법은 두 줄입니다. 프록시를 띄우고 Claude Code가 그 주소를 바라보게 하면 끝입니다.
npx pxpipe-proxy # proxy on 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude # point Claude Code at it
프록시를 띄우면 http://127.0.0.1:47821/ 에서 대시보드가 열립니다. 절감된 토큰, 텍스트에서 이미지로 바뀐 변환 내역의 좌우 비교, 킬 스위치, 모델별 활성화 칩을 제공합니다. 프록시 없이 라이브러리로도 쓸 수 있습니다 (README §Library use).
import { renderTextToImages, transformAnthropicMessages } from "pxpipe-proxy";
const { pages } = await renderTextToImages(toolResultText); // pages[i].png: Uint8Array
const { body, applied, info } = await transformAnthropicMessages({
body: requestBytes,
model: "claude-fable-5",
});
런타임은 순수 JavaScript로 Node와 엣지/Workers 환경에서 동작하고, @napi-rs/canvas 는 빌드 시점에만 필요합니다. 모델 비전이 OCR이 아니라 패치 임베딩이라는 점, 그래서 오독이 조용한 허구로 나타나는 메커니즘은 저장소의 docs/NOT-OCR.md에 정리되어 있습니다.
pxpipe의 라이선스
pxpipe는 MIT 라이선스로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다.
pxpipe 프로젝트 GitHub 저장소
더 읽어보기
이 글은 GPT 모델로 정리한 글을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 덧글로 알려주시기를 부탁드립니다. ![]()
파이토치 한국 사용자 모임
이 정리한 이 글이 유용하셨나요? 회원으로 가입하시면 주요 글들을 이메일
로 보내드립니다! 텔레그램(Telegram)이나 Slack/Discord/Teams/Dooray/GoogleChat 등으로도 새 글 알림을 받으실 수 있습니다. ![]()
아래
쪽에 좋아요
를 눌러주시면 새로운 소식들을 정리하고 공유하는데 힘이 됩니다~ ![]()

