Coalescing the Stream

개요

claude-code-router (ccr)는 Anthropic API 또는 서드파티 제공업체를 가리킬 수 있는 자체 호스팅 프록시로, 토큰당 스트리밍 이벤트가 많을 때 발생하는 지연 문제를 해결하기 위해 이벤트 병합 미들웨어를 도입했습니다.

주요 내용

* 문제점: 기존 방식은 토큰당 하나의 스트리밍 이벤트가 발생하고, VS Code 확장 프로그램이 이를 빠르게 처리하지 못하며, CLI 제어 메시지가 지연을 유발했습니다.
* 해결책: 이벤트 스트림을 청크(chunk) 단위로 병합하는 미들웨어를 개발하고, 이를 라우터 프로세스에 성공적으로 배포했습니다.
* 미들웨어 규칙: 동일한 블록 인덱스와 델타 타입(텍스트, 생각, 부분 JSON)을 가진 연속적인 content_block_delta 이벤트만 병합하며, 다른 이벤트가 발생하면 즉시 플러시(flush)합니다.
* 안정성 확보: 미들웨어는 대화 내용을 이해하지 않고, 증명 가능한 상호 교환 가능한 항목만 결합하여 프로토콜 의미를 유지합니다.
* 설정: CCR_SSE_COALESCE_MS와 같은 전역 설정을 통해 병합 창 크기를 조절하며, CCR_SSE_COALESCE_THINKING_MS, CCR_SSE_TEXT_MS 등으로 타입별 설정을 추가했습니다.
* 전송 계층 고려: 병합된 바디는 content-length 헤더를 무효화하며, 압축된 응답은 처리하지 않고 통과시킵니다.
* 배포 과정: 미들웨어를 라우터 컨테이너에 배포하는 과정에서 globalThis.fetch 패치 실패, undici 디스패처 사용, 다중 프로세스 문제, NODE_OPTIONS 활용, 생성된 파일 수정의 함정 등을 겪었습니다.
* 최종 배포: /data/.claude-code-router/sse-coalesce.cjs 경로에 자체 파일을 마운트하고, NODE_OPTIONS로 모든 Node.js 프로세스에서 로드 및 자동 설치되도록 구성했습니다.
* 검증: 9개의 유닛 테스트를 작성하고, DeepSeek를 통해 실제 트래픽에서 200 토큰 응답을 85개에서 11개 이벤트로 줄이는 등 효과를 검증했습니다.
* 성능 개선: 미들웨어 도입 후 1시간 이상 걸리던 지연이 3분으로 감소했으며, 이벤트당 렌더링 비용을 고려하여 타입별 병합 창 시간을 최적화했습니다.
* 지속적인 문제: 미들웨어 적용 후에도 렌더링 지연이 남아 있으며, 이는 upstream에서 해결이 필요합니다.

시사점

미들웨어를 개발하고 배포하는 과정은 단순히 코드를 작성하는 것을 넘어, 대상 시스템의 실제 동작 방식, 프로세스 간 상호 작용, 그리고 배포 및 실행 환경에 대한 깊은 이해를 요구하며, 실질적인 성능 개선은 코드 실행이 보장될 때 비로소 이루어집니다.

원문 읽기 →
원문을 불러오는 중...

댓글

GitHub Discussions