ctxtrim: 코딩 에이전트에게 300줄짜리 로그를 계속 먹이지 마세요
요약
ctxtrim은 코딩 에이전트가 처리하는 컨텍스트 창의 과부하 문제를 해결하는 명령줄 도구입니다. 대용량 로그, 테스트 결과 등 불필요한 데이터를 기계적으로 자르거나(Press), 필요시 모델을 이용해 요약하여 핵심 정보만 남깁니다. 이는 에이전트에게 중요한 정보를 밀어내는 것을 방지합니다.
핵심 포인트
- 대용량 로그나 파일 덤프를 자동으로 트리밍하는 기능 제공
- 기계적 자르기(Press)와 선택적 모델 기반 요약(Gloss)을 결합
- 세션 노트 기능을 통해 결정사항만 간결한 원장으로 관리
- 명령줄 도구 및 MCP 서버 형태로 에이전트 워크플로우에 통합 가능
Repo: 👉 github.com/bayuh85/ctxtrim (MIT, Node.js 20+)
문제점
Claude Code, Cursor, Cline과 같은 코딩 에이전트는 좋지만 컨텍스트 창(context window)이 불필요한 데이터로 가득 차는 문제가 있습니다. 테스트 실행만 해도 수백 줄의 로그가 남습니다. 서버 로그는 동일한 시작 메시지를 반복합니다. 에이전트가 특정 필드를 확인하기 위해 대용량 JSON 파일을 cat 할 수도 있습니다. 이 모든 것이 컨텍스트에 쌓이고, 매 턴마다 다시 읽히면서 실제로 중요한 정보—예를 들어 20분 전에 결정했던 내용—를 밀어내 버립니다.
일반적인 해결책은 수동적입니다: | tail -50, grep ERROR 등을 사용하거나 에이전트에게 "파일 전체를 읽지 마세요"라고 지시하는 식입니다. 하지만 이런 방법들은 결국 한계에 부딪힙니다.
ctxtrim의 기능
ctxtrim은 코딩 에이전트가 읽는 컨텍스트 데이터를 줄여줍니다:
- Press: 대용량 로그, 테스트 실행 결과, 파일 덤프 등을 기계적으로 자릅니다—네트워크 연결이나 키가 필요 없습니다.
- Gloss (선택 사항): 잘라낸 결과물도 여전히 크다면, 저렴한 OpenAI 호환 모델이 이를 요약합니다 (기본값:
zai/glm-5.3). - 세션 노트(Session notes): 결정사항이나 발견된 내용은 늘어나는 전체 기록 대신 간결한 세션 원장(ledger)에 저장됩니다.
이는 **명령줄 도구(command-line tool)**와 MCP 서버 두 가지 형태로 제공되며, 둘 다 동일한 기능을 노출합니다.
빠른 시작하기 (Quickstart)
Node.js 20 이상이 필요합니다.
git clone https://github.com/bayuh85/ctxtrim.git
cd ctxtrim
npm install
...
Press 기능은 키가 전혀 필요 없습니다. 모델 요약을 사용하려면 API 키를 설정하세요:
cp .env.example .env
# CTXTRIM_API_KEY=your-key
이제 노이즈가 많은 데이터를 파이프(|)로 전달해 보세요:
export CTXTRIM_API_KEY=your-key
# 선택 사항; 이들은 이미 기본값입니다.
export CTXTRIM_BASE_URL=https://atmorouter.dev/v1
...
결과는 stdout으로 전송되어(계속 파이프 연결할 수 있음) 사용하고, 한 줄 요약된 영수증은 stderr로 전송됩니다. README의 예시처럼, 세 개의 연결 오류와 하나의 경고가 포함된 300줄짜리 로그를 Press하면 다음과 같은 보고서가 출력됩니다:
ctxtrim · log · press · 12578 → 1299 bytes · kept 10%
간결한 로그는 반복되는 시작 라인(ready ×3), 오류, 경고, 그리고 시작 부분과 끝부분만 유지합니다. 조용한 중간 내용은 단일 생략 라인이 됩니다.
이 기록을 통해 어떤 경로가 취해졌는지 알 수 있습니다:
passthrough: 입력 자체가 이미 작았음press: 기계적 트리밍(mechanical trim)gloss: 모델 요약(model summary)cache: 동일한 텍스트와 모델에 대해 재사용된 요약(gloss)
에이전트 설정하기 (MCP)
먼저 빌드(npm run build)를 수행한 다음, 클라이언트를 node /absolute/path/to/ctxtrim/dist/cli.js serve로 지정합니다.
Claude Code
프로젝트의 .mcp.json (또는 사용자 설정)에 추가합니다:
{
"mcpServers": {
"ctxtrim": {
...
또는 셸에서 다음 명령어를 사용합니다:
claude mcp add ctxtrim --env CTXTRIM_API_KEY=your-key -- node /absolute/path/to/ctxtrim/dist/cli.js serve
Cursor
프로젝트의 .cursor/mcp.json에 동일한 mcpServers.ctxtrim 블록을 넣거나, Cursor Settings → MCP를 통해 추가합니다.
Cline
동일한 항목을 Cline의 MCP 설정 파일에 추가합니다:
- Linux:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json - macOS:
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json - Windows:
%APPDATA%\Code extbackslash User extbackslash globalStorage extbackslash saoudrizwan.claude-dev extbackslash settings extbackslash cline_mcp_settings.json
(VS Code Insiders 및 기타 포크는 자체 User/globalStorage 디렉토리를 사용합니다.) Cline은 저장 시 파일을 읽어옵니다.
에이전트가 얻게 되는 도구들
| Tool | Use it when |
|---|---|
shrink | 결과물이 너무 커서 유지할 수 없을 때. mode는 auto(기본값), gloss, 또는 offline입니다. |
| ... |
MCP 클라이언트를 재시작한 후의 실질적인 습관은 다음과 같습니다: 에이전트에게 부피가 큰 도구 출력물에 대해 shrink를 호출하고, 긴 작업을 시작할 때 recall을 요청하는 것입니다. 이는 CLAUDE.md, Cursor 규칙 또는 Cline 사용자 지정 지침에 포함시킬 수 있습니다.
shrink 작동 방식
- 감지(Detect).
auto는 입력이 로그인지, 테스트 실행 결과인지, 파일 덤프(소스 또는 JSON)인지, 아니면 일반 텍스트인지를 분류합니다.--kind로 재정의할 수 있습니다. - 압축(Press). 중복된 줄은 병합됩니다. 로그는 오류, 경고, 그리고 시작 부분과 끝 부분을 유지합니다. 테스트 출력 결과는 실패 내용, 근처 프레임, 요약본을 유지합니다. 소스 코드는 가져오기(imports)와 선언(declarations)의 개요를 유지합니다. JSON은 그 구조에 대한 짧은 설명을 만듭니다. 여전히 너무 큰 내용은 문자 제한까지 잘립니다.
- 요약(Gloss). 압축된 내용이 여전히 크고
CTXTRIM_API_KEY가 설정되어 있으면, ctxtrim은 **원본 데이터 덩어리(original blob)가 아닌 압축본(the press)**을POST {CTXTRIM_BASE_URL}/chat/completions으로 전송하고CTXTRIM_TARGET_CHARS에 따라 일반 텍스트 요약본을 요청합니다. 비어 있거나 압축본보다 긴 요약본은 버려집니다. 결과는CTXTRIM_HOME아래에 캐시됩니다.
알아두면 좋은 몇 가지 동작 방식:
--offline은 모델을 호출하지 않습니다.--gloss는 키를 필요로 하며, 누락된 경우 상태 2로 종료됩니다.- 제공자 오류(Provider errors)는
--gloss를 명시적으로 요청하지 않은 한 압축본으로 폴백합니다. - 이진 입력은 확장되지 않으며, 원래 크기와 한 줄짜리 스텁을 받게 됩니다.
분할의 아이디어는 간단합니다. 기계적인 압축(press)은 무료이고 결정론적이며, 저렴한 모델은 이미 잘린 텍스트만 보기 때문에 요약 단계가 주요 코딩 모델이 원본 출력을 읽는 것보다 훨씬 저렴하게 유지됩니다.
세션 기록부 (The session ledger)
노트는 $CTXTRIM_HOME/sessions/ (기본값 ~/.ctxtrim)에 JSON 형태로 세션별로 저장되며, 노트당 한 개의 간결한 줄을 사용하고, decision, blocker 또는 파일 이름의 접미사 같은 선택적 태그를 가집니다. 활성 노트가 CTXTRIM_NOTE_BUDGET을 초과하면, 가장 오래된 줄들이 다이제스트(digest)로 묶여 세션이 프롬프트에 다시 붙여넣기 할 수 있을 만큼 작게 유지됩니다.
recall은 축소된 총량(입력 바이트, 출력 바이트, 보존된 양)과 다이제스트, 그리고 현재 노트를 출력합니다. 줄어든 요약본 자체가 기록부에 복사되는 것은 아니므로, 에이전트가 결론을 기억하게 하려면 노트를 작성해야 합니다.
튜닝 (Tuning)
모든 것이 환경 변수입니다. 주요 조정 가능한 부분은 다음과 같습니다:
크레딧
이 개념은 mksglu의 context-mode에서 영감을 받았습니다. ctxtrim은 별도의 프로젝트이며, 그것과는 제휴되지 않았습니다. 이 분야를 탐색하고 있다면 context-mode도 확인해 보세요.
AtmoRouter 소개 (기본 모델 엔드포인트)
별도로 사용할 경우, ctxtrim은 zai/glm-5.3을 사용하여 AtmoRouter로 요약된 내용을 전송합니다. AtmoRouter는 OpenAI 및 Anthropic과 호환되는 게이트웨이이며, 토큰당 지불 방식, QRIS 및 USDC를 통한 결제, 그리고 최첨단 모델에 대한 저렴한 접근성을 제공하여 '요약 단계 비용을 코딩 모델보다 저렴하게 유지한다'는 아이디어에 적합합니다.
하지만 이것은 필요하지 않습니다. ctxtrim은 messages, model, temperature, max_tokens를 포함하는 POST /chat/completions만 의존하므로, 어떤 OpenAI 호환 제공업체라도 작동합니다:
export CTXTRIM_BASE_URL=https://your-provider.example/v1
export CTXTRIM_API_KEY=your-key
export CTXTRIM_MODEL=your-cheap-model
그리고 키를 완전히 건너뛰어도 네트워크 호출 없이 기계적인 압착기(mechanical press)는 여전히 작동합니다.
사용해 보기
에이전트가 테스트 출력과 로그에 계속 빠져드는 경우, 한번 시도해 보세요:
압착기 휴리스틱(press heuristics)에 대한 피드백은 특히 환영합니다. 만약 처리하기 어려운 로그나 테스트 형식이 있다면, 샘플과 함께 이슈를 제기해 주시는 것이 가장 유용할 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기