콘텐츠로 이동
OmniRoute source

RTK Compression (한국어)

RTK는 압축의 공격성과 안전성 사이에서 균형을 조절하는 3가지 강도 수준을 지원합니다. 수준은 엔진 구성의 config.intensity를 통해 설정합니다.

수준 잘라내기 임계값 토큰 절감률 위험도 적합한 용도
minimal 섹션당 24줄 ~20-40% 매우 낮음 중요한 컨텍스트가 있는 프로덕션
standard (기본값) 섹션당 24줄 ~50-70% 낮음 일상적인 코딩 세션
aggressive 섹션당 16줄 ~70-90% 중간 긴 세션, 최대 절감

잘라내기 임계값은 lineFilter.ts에 영향을 줍니다.

// open-sse/services/compression/engines/rtk/index.ts:329-330에서 발췌
config.intensity === "aggressive" ? 16 : 24,
config.intensity === "aggressive" ? 16 : 24,

각 섹션의 앞부분과 뒷부분은 모두 보존되며, 잘라내기가 시작되면 중간 콘텐츠가 제거됩니다.

콘텐츠 minimal standard aggressive
오류 / 스택 추적 ✅ 보존 ✅ 보존 ✅ 보존
테스트 실패 ✅ 보존 ✅ 보존 ✅ 보존
빌드 오류 ✅ 보존 ✅ 보존 ✅ 보존
테스트 통과(상세 출력) ✅ 보존 🟡 축약 🟡 축약
일반 출력(정보 로그) 🟡 축약 🟡 축약 ❌ 제거
진행률 표시줄 🟡 축약 ❌ 제거 ❌ 제거
배너 / ASCII 아트 🟡 축약 ❌ 제거 ❌ 제거
컨텍스트 손실이 치명적인가?
│
┌───────────┼───────────┐
│ │ │
예 아니요 확실하지 않음
│ │ │
▼ │ │
minimal │ │
│ │ │
│ ▼ ▼
│ 처리량이 얼마나 먼저 `standard` 시도
│ 중요한가? (사례의 80%에서
│ │ 효과적)
│ ┌────┴────┐
│ │ │
│ 낮음 높음
│ │ │
│ ▼ ▼
│ standard aggressive
│ │ │
└──────┴─────────┘

콤보별(콤보 구성 내):

{
"combo": "my-coding-combo",
"routing": {/* ... */},
"compression": {
"engine": "rtk",
"intensity": "aggressive"
}
}

프로그래밍 방식:

rtkEngine (@omniroute/open-sse/services/compression/engines/rtk)은 CompressionEngine이며 updateConfig 메서드가 없습니다. 대신 레지스트리 헬퍼를 통해 엔진 구성을 업데이트하세요.

import { updateEngineConfig } from "@omniroute/open-sse/services/compression/engines/registry";
updateEngineConfig("rtk", { intensity: "aggressive" });

검증 게이트(아래 참조)를 사용하여 선택한 강도에서 필터가 안전한지 확인하세요.

import { runRtkFilterTests } from "omniroute/compression/engines/rtk/verify";
const result = runRtkFilterTests({ intensity: "aggressive" });
if (!result.passed) {
console.error("공격적 강도에서 필터 실패");
}

engines/rtk/filters/ 디렉터리에는 49개 이상의 기본 제공 필터 JSON 파일이 포함되어 있습니다. 기본 필터에서 지원하지 않는 사용자 지정 도구의 출력을 압축하려면 자체 필터를 추가할 수 있습니다.

{
"id": "string", // 필수. 필터 식별자(kebab-case, 예: "python-traceback")
"label": "string", // 필수. 사람이 읽을 수 있는 필터 이름
"description": "string", // 선택 사항(기본값: ""). 필터가 수행하는 작업에 대한 간단한 설명
"category": "git|test|build|shell|docker|package|infra|cloud|generic",
"priority": number, // 선택 사항(0-100, 기본값: 50). 실행 순서(값이 높을수록 먼저 실행)
"match": {
"commands": ["string"], // 일치시킬 명령어 이름(예: "python", "pytest")
"patterns": ["string"], // 출력과 일치시킬 정규식 패턴
"outputTypes": ["string"] // 감지된 출력 클래스(예: "test-failure")
},
"rules": {
"stripAnsi": boolean, // 선택 사항(기본값: false). ANSI 색상 코드 제거
"replace": [ // 찾기 및 바꾸기 규칙(기본값: [])
{ "pattern": "regex", "replacement": "..." }
],
"matchOutput": [ // 패턴이 일치하면 즉시 처리 종료(기본값: [])
{
"pattern": "regex",
"message": "short summary",
"unless": "regex" // 이 패턴이 일치하면 건너뜀
}
],
"includePatterns": ["string"], // 유지할 줄(정규식 패턴, 기본값: [])
"dropPatterns": ["string"], // 제거할 줄(정규식 패턴, 기본값: [])
"collapsePatterns": ["string"], // 하나의 항목으로 축약할 줄(기본값: [])
"deduplicate": boolean, // 선택 사항(기본값: false). 중복된 줄 제거
"truncateLineAt": number, // 선택 사항(기본값: 0). 줄을 최대 문자 수로 자름
"maxLines": number, // 선택 사항(기본값: 0). 전체 줄 수의 절대 상한
"headLines": number, // 선택 사항(기본값: 20). 일치한 출력의 처음 N개 줄 유지
"tailLines": number, // 선택 사항(기본값: 20). 일치한 출력의 마지막 N개 줄 유지
"onEmpty": "string", // 선택 사항(기본값: ""). 모든 줄이 필터링된 경우 사용할 대체 메시지
"filterStderr": boolean // 선택 사항(기본값: false). stderr 출력도 필터링
},
"preserve": {
"errorPatterns": ["string"], // 항상 보존해야 하는 패턴(기본값: [])
"summaryPatterns": ["string"] // 최종 요약 줄의 패턴(기본값: [])
},
"tests": [ // 검증용 인라인 테스트(기본값: [])
{
"name": "string", // 필수. 테스트 이름
"input": "sample output", // 필수. 샘플 입력 텍스트
"expected": "expected output", // 필수. 예상 압축 출력
"command": "optional command" // 선택 사항. 명령어 컨텍스트
}
]
}
{
"id": "python-traceback",
"label": "Python Traceback Filter",
"description": "Compresses Python tracebacks to essential file/line locations and error type",
"category": "test",
"priority": 60,
"match": {
"commands": ["python", "python3", "pytest", "uv", "poetry"],
"patterns": ["Traceback \\(most recent call last\\)", "Error", "Exception"],
"outputTypes": ["error-traceback"]
},
"rules": {
"stripAnsi": true,
"includePatterns": [
"Traceback \\(most recent call last\\)",
"^\\s*File \".+\", line \\d+",
"^\\s*[A-Z][a-zA-Z]+Error:",
"^\\s*[A-Z][a-zA-Z]+Exception"
],
"dropPatterns": ["site-packages/", "^\\s+[a-z_]+\\([^)]*\\)$"],
"headLines": 5,
"tailLines": 3,
"maxLines": 25,
"filterStderr": true
},
"preserve": {
"errorPatterns": ["Error:", "Exception:", "Traceback"],
"summaryPatterns": ["^[A-Z][a-zA-Z]+(?:Error|Exception):"]
},
"tests": [
{
"name": "preserves-error-type-and-location",
"input": "Traceback (most recent call last):\n File \"app.py\", line 42, in main\n do_thing()\n File \"lib/utils.py\", line 17, in helper\n return 1 / 0\nZeroDivisionError: division by zero",
"expected": "Traceback (most recent call last):\n File \"app.py\", line 42, in main\n File \"lib/utils.py\", line 17, in helper\nZeroDivisionError: division by zero",
"command": "python app.py"
}
]
}

파일을 인식되는 위치에 배치합니다.

~/.omniroute/rtk/filters/my-filter.json # 사용자 수준
<project>/.rtk/filters/my-filter.json # 프로젝트 수준

필터는 시작 시 open-sse/services/compression/engines/rtk/filterLoader.ts의 loadRtkFilters()를 통해 자동으로 로드됩니다. 로더는 다음 위치에서 필터를 검색합니다.

  • 기본 제공 카탈로그: open-sse/services/compression/engines/rtk/filters/
  • 사용자 디렉터리: ~/.omniroute/rtk/filters/
  • 프로젝트 디렉터리: <project>/.rtk/filters/

프로그래밍 방식으로 필터를 로드하려면 다음을 사용합니다.

import { loadRtkFilters } from "@omniroute/open-sse/services/compression/engines/rtk/filterLoader";
// 옵션: customFiltersEnabled(사용자/프로젝트 필터 로드, 기본적으로 활성화),
// trustProjectFilters, refresh.
const filters = loadRtkFilters({ customFiltersEnabled: true });

필터를 로드할 때 Zod 스키마를 기준으로 유효성을 검사합니다. 구조가 잘못된 필터는 로드되지 않으며 오류가 기록됩니다.

RTK_FILTER_LOADER: 필터 "my-filter"의 유효성 검사 실패:
- rules.replace.0.pattern: 잘못된 정규식
- match.commands: 비어 있으면 안 됨

설치된 모든 필터의 유효성을 검사하려면 open-sse/services/compression/engines/rtk/verify.ts에서 내보내는 runRtkFilterTests()를 호출합니다.

  1. 항상 tests[]를 포함하세요 — 필터가 제대로 작동함을 입증하고 회귀를 방지합니다
  2. 단축 처리에는 matchOutput을 사용하세요 — 한 줄만으로 충분히 설명된다면 전체 블록을 대체하세요
  3. strip보다 keep을 우선하세요 — 명시적인 “항상 보존” 규칙이 “항상 제거” 규칙보다 안전합니다
  4. 3가지 강도 수준 모두에서 테스트하세요 — minimal은 아무 작업도 하지 않아야 하며, aggressive에서도 오류는 보존되어야 합니다
  5. unless 필드를 사용하세요 — “X가 있으면 트리거하지 않음” 조건으로 단축 처리를 보호하세요

RTK가 출력을 강하게 압축할 때 디버깅, 감사 또는 재실행을 위해 원본 텍스트를 복구할 수 있습니다.

원본 출력(10K 토큰)
│
▼
RTK 압축(rawOutput.enabled=true)
│
├─▶ 압축된 출력(2K 토큰) ──▶ LLM으로 전달
│
└─▶ 원본 출력(10K 토큰) ──▶ DB에 저장
(request_id로 연결)

요청별 설정(combo 구성에서):

{
"compression": {
"engine": "rtk",
"intensity": "aggressive",
"rawOutput": {
"enabled": true,
"maxBytes": 1048576 // 1MB 제한
}
}
}

기본값: rawOutput.enabled: false(저장 공간 절약).

요청당 1MB 제한 10MB 제한
평균 압축 출력 ~5KB ~5KB
저장된 원시 출력 ~50-500KB ~500KB-5MB
일일 요청 1000건 기준 50-500MB/일 500MB-5GB/일

권장 사항: 원시 출력은 항상 활성화하지 말고 디버깅 세션 또는 샘플링된 감사에만 활성화하세요.

import { readRtkRawOutput } from "omniroute/compression/engines/rtk/rawOutput";
const raw = readRtkRawOutput(pointerId); // 압축 통계의 pointerId
if (raw) {
console.log("원본 출력:", raw);
}

pointerId는 압축 후 CompressionStats.rtkRawOutputPointers[]에 반환됩니다. 함수 시그니처는 open-sse/services/compression/engines/rtk/rawOutput.ts:102를 참조하세요.

RTK 필터 검증(open-sse/services/compression/engines/rtk/verify.ts)은 모든 필터를 해당 tests[]에 대해 검증하고, 세 가지 강도 수준 모두에서 동작이 올바른지 확인합니다.

검증을 실행하려면 runRtkFilterTests()를 호출하세요:

import { runRtkFilterTests } from "open-sse/services/compression/engines/rtk/verify";
const result = runRtkFilterTests();
console.log(`통과: ${result.outcomes.filter((o) => o.passed).length}`);
console.log(`실패: ${result.outcomes.filter((o) => !o.passed).length}`);
if (!result.passed) {
console.error("필터가 검증에 실패했습니다");
result.outcomes
.filter((o) => !o.passed)
.forEach((o) => {
console.error(
` - ${o.filterId} / ${o.testName}: 예상값 "${o.expected}", 실제값 "${o.actual}"`
);
});
}

검증 항목:

  1. 모든 필터가 로드되고 스키마 검증을 통과하는지 확인
  2. 모든 tests[] 항목이 예상 출력을 생성하는지 확인
  3. minimal 강도가 아무 작업도 하지 않는지 확인(원본을 보존하고 구조적 필터만 적용)
  4. aggressive 강도가 오류, 테스트 실패 및 스택 추적을 보존하는지 확인
  5. 압축된 출력이 원본 입력보다 절대 크지 않은지 확인
  • 소스: open-sse/services/compression/engines/rtk/(63개 파일, ~70KB)

  • 필터 변경 사항을 병합하기 전 — 항상 테스트 통과 여부 확인

  • RTK 엔진을 업그레이드한 후 — 스키마가 변경되었을 수 있음

  • 모니터링 중 정기적으로 — 테스트 픽스처의 드리프트 방지

  • 새로운 도구/명령 계열을 추가할 때 — 새 필터의 정상 작동 입증



OmniRoute 소스 코드 (a58000c7685f)

HagiCode

HagiCode는 구조화된 워크플로, 다중 에이전트 실행, Hero Dungeon 뷰를 갖춘 에이전트 코딩 작업 공간입니다.

더 스마트하고 빠르며 즐거운 에이전트 워크플로로 유용한 소프트웨어를 만드세요.

HagiCode 라이트 테마 메인 화면
  • Smart구조화된 워크플로는 의도를 아이디어부터 배포까지 실행 가능한 경로로 바꿉니다.
  • Efficient다중 에이전트 워크플로로 조사, 구현, 검토를 병렬로 진행합니다.
  • FunHero Dungeon은 긴 코딩 세션을 시각적이고 협업적인 경험으로 만듭니다.
HagiCode 방문