OmniRoute 压缩引擎全指南:Caveman、RTK、LLMLingua-2 与 Stacked 管线架构与配置实战
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
本文系统拆解 OmniRoute 的上下文压缩体系:从"模式(Mode)—引擎(Engine)—管线(Pipeline)"的分层模型出发,逐一剖析 Caveman 语义压缩、RTK 命令输出压缩、LLMLingua-2 语义剪枝、OmniGlyph 图像化压缩以及 CCR / headroom / ionizer / session-dedup 等结构化无损引擎的契约、配置与适用场景。你将理解引擎注册表的统一接口、Stacked 组合管线的收益叠加公式、MCP 可访问性树后置过滤器、压缩组合(Compression Combos)与 API/MCP 暴露面,并学会用源码级证据排查"引擎为何没有生效"这类实战问题。
模式(Modes):单引擎直跑与确定性管线
OmniRoute 的压缩体系围绕"引擎契约"构建:一种模式(mode)可以直接运行某个引擎(如caveman、rtk),也可以运行一条按顺序执行多个引擎的确定性 Stacked 管线。运行期由 open-sse/services/compression/strategySelector.ts 的selectCompressionPlan()依据配置解析最终计划,再交给applyCompression()/applyCompressionAsync()执行。
从 types.ts 的类型定义可见完整的CompressionMode集合:
| Mode | 引擎路径 | 面向的输入 |
|---|---|---|
off | 无 | 精确保留原始 prompt |
lite | Caveman lite 辅助规则 | 低风险的常开清理 |
standard | Caveman | 自然语言 prompt 凝练 |
aggressive | Caveman + 历史/工具总结器 | 长对话会话 |
ultra | Caveman + 剪枝辅助 | 上下文超限后的恢复 |
rtk | RTK | 终端、shell、构建、测试、git 输出 |
omniglyph | OmniGlyph | 以"上下文即图像"形式直连原生 provider 线路 |
stacked | 管线,默认rtk -> caveman | 混合工具日志 + 散文,追求最大节省 |
关键实现细节:strategySelector.ts中的计划解析遵循严格的优先级(见resolveBasePlan):主开关config.enabled置为false时是"硬性关闭"(任何请求头都无法再打开压缩);其次是路由组合覆盖、显式命名档案、自动触发(autoTriggerTokens),最后才落到由每引擎开关地图派生的默认计划。chatCore.ts在解析压缩设置后、任何引擎运行前执行排除检查(见下文"范围与排除"),一旦命中即视为全局关闭,保证请求体逐字节不变。
模式即"启用信号"
源码中一个容易误解的点:当用户在界面上选中standard/rtk/lite/aggressive/ultra模式时,选择行为本身就是启用信号——引擎会无视 per-engine 的enabled开关直接运行(该开关只用于约束 stacked 步骤内的行为)。例如runCompression()对rtk分支的处理就是:
if (mode === "rtk") { return applyRtkCompression(body, { config: { ...(options?.config?.rtkConfig ?? {}), enabled: true }, }); }这一点在排查"我开了 rtk 但 RTK 配置里的 enabled=false 为什么还生效"时非常关键。
引擎注册表(Engine Registry)
所有引擎共享一套统一的对外契约,注册表实现位于 open-sse/services/compression/engines/registry.ts。引擎接口定义在 open-sse/services/compression/engines/types.ts:
id:稳定的引擎标识,如caveman、rtk;apply(text, config):遗留执行路径,供 stacked 管线使用;compress(input, config):主执行路径,返回文本 + 统计(CompressionResult,含body/compressed/stats);getConfigSchema():返回类 JSON-Schema 的合法配置形状(字段类型为 boolean/number/string/select/multiselect);validateConfig(config):返回{ valid, errors[] };- 可选扩展字段:
targets(messages/tool_results/code_blocks)、stackable、stackPriority、sampling(声明为有意有损的采样引擎,保真门会跳过它)、metadata.executionStages(pre-translation/post-translation,缺省即只支持 pre-translation),以及异步变体applyAsync(worker 线程模型引擎必须把apply保留为安全的同步透传)。
注册流程使用registerCompressionEngine(engine)(进阶可用registerEngine,可携带defaultConfig)。从 registry.ts 源码可见,注册时先调用assertValidEngine()校验契约完整性,再调用validateConfig(defaultConfig)校验默认配置,任一环节失败都会抛错拒绝注册。运行期可用unregisterCompressionEngine(id)移除引擎,getEngine(id)按 id 取回引擎,listEngines()枚举全部注册项,setEngineEnabled(id, enabled)可整体开关某个引擎(stacked 循环会尊重该标志跳过已禁用引擎,无需改动每条管线)。
内置引擎的注册统一在 engines/index.ts 的registerBuiltinCompressionEngines()中完成(带registered闩锁,且测试clearCompressionEngineRegistry()后可自动恢复),注册的引擎包括:lite、caveman、aggressive、ultra、rtk、codex-responses、session-dedup、headroom、ccr、llmlingua、ionizer、relevance、llm、read-lifecycle、omniglyph。strategySelector.ts 在压缩运行前调用该函数注册内置引擎,使得预览、运行期压缩、stacked 模式、测试与未来的引擎共享同一条执行路径。
相关的 MCP 描述压缩
另有一个独立的注册表在"注册表级别"压缩 MCP 工具描述元数据——实现位于 open-sse/mcp-server/descriptionCompressor.ts,详见 docs/frameworks/MCP-SERVER.md。它复用 Caveman 规则,但作用对象是工具元数据而非请求载荷,与正文压缩互不干扰。
内置结构化/无损引擎:CCR、headroom、ionizer、session-dedup
在 Caveman、RTK、LLMLingua-2 之外,注册表还提供若干面向 stacked 管线、Playground 与测试的专用无损/结构化引擎(实现同样位于open-sse/services/compression/engines/):
| 引擎 | Id | 作用 |
|---|---|---|
| CCR | ccr | Content-Compress-Retrieve(H4):把大段连续文本替换为内容寻址引用,重复/超大块只发送一次,之后用引用代替。 |
| headroom | headroom | SmartCrusher(H3 + N5):对同质 JSON 数组载荷做无损表格化压缩,折叠为列式[N rows]形态。 |
| ionizer | ionizer | 对超大同质块做头/中/尾行采样,被剔除的中间段以 CCR 内容寻址引用保存。 |
| session-dedup | session-dedup | 内容寻址的跨轮去重(受 TokenMizer 启发):剔除同会话前序轮次已出现过的文本。 |
CCR 检索协议注入(#8033)
CCR 首次在同一请求中替换 ≥1 个文本块时,会在请求前注入一条幂等的system消息(以[CCR protocol]哨兵开头),向调用方传授"标记 → 工具"契约。实现见 engines/ccr/protocolInstruction.ts:
- 它向模型说明
[CCR retrieve hash=<24hex> chars=N]标记的含义、hash 必须逐字符复制全部 24 位十六进制(误抄 hash 是 "block not found" 未命中最可能的原因),以及[dedup:ref sha=...]表示"回看历史"而不是"调用工具"; - 注入仅当调用方对外声明的
tools[]证明它能真正触达omniroute_ccr_retrieve时发生(callerSupportsCcrRetrieve()会同时识别 OpenAI 嵌套形态{type:"function",function:{name}}、扁平形态与 Claude 形态)——纯 OpenAI-compatible 调用方没有该工具,就绝不会收到"去调用一个够不着的东西"的指令; - 幂等性通过先扫描消息历史是否已含哨兵保证:多轮请求会重放前序消息,若不检查,每轮都会叠一条说明。
Caveman:自然语言的语义凝练
Caveman 模式聚焦于普通散文的语义化压缩:
- 保留代码块、URL、JSON、路径与结构化数据;
- 移除填充词、犹豫表达、重复上下文与冗长连接性措辞;
- 支持语言感知的文件规则包,规则目录见 open-sse/services/compression/rules/;
- 继续通过遗留的
standard、aggressive、ultra模式开放使用。
Caveman 的单条规则在 types.ts 中被建模为CavemanRule:每条规则含pattern、replacement、生效context(all/user/system/assistant)、preservePatterns、category(filler/context/structural/dedup/terse/ultra)与minIntensity。规则包按语言目录组织,例如en/下含context.json、filler.json、structural.json、dedup.json、ultra.json五类;_schema.json定义规则格式。
关于上游数据(非本项目测量):Caveman 上游报告"输出 token 减少约 75%"、基准中"平均输出节省 65%、区间 22–87%",并提供约 46% 的输入侧压缩工具。OmniRoute 在文档化 stacked prompt/context 节省时采用 Caveman 输入侧数字;Caveman 的"输出模式"仍是独立的响应行为特性,不要与输入压缩混为一谈。
规则集的分语言覆盖有明确维护状态(见下文"已知限制"),在配置standard/aggressive/ultra前建议确认所选语言包完整性。引擎单测与集成用例可参考tests/unit/compression/与tests/integration/compression-pipeline.test.ts。
RTK:命令与工具输出压缩
RTK 模式专注命令/工具输出,是 Coding Agent 会话中最常用的输入压缩器之一:
- 可识别
git status、git branch、git diff、Vitest/Jest/Pytest、Cargo/Go 测试、TypeScript/Vite/Webpack 构建、ESLint、npm audit/install、Docker 日志、shellfind/grep、堆栈跟踪与泛化日志等输出类别; - 应用按命令类型组织的 JSON 过滤器集合(文档维护时统计为 49 个,全部过滤器清单在 engines/rtk/filters/);
- 支持 RTK 风格声明式管线:ANSI 剥离、替换、match-output 短路、strip/keep 行、逐行截断、head/tail/max-line 截断、on-empty 回退;
- 支持受信任门控的项目过滤器
.rtk/filters.json与全局过滤器DATA_DIR/rtk/filters.json; - 剥离 ANSI 序列、进度噪音、重复行与无益样板;
- 保留可操作的失败、警告、摘要、变更文件与尾部上下文;
- 可选地通过鉴权管理路由保留脱敏原始输出用于恢复/排障。
一个真实过滤器示例 filters/docker-logs.json 展示其 JSON Schema 形态:match声明命中条件(输出类型、命令正则、内容模式),rules声明处理动作(stripAnsi、dropPatterns、includePatterns、collapsePatterns、deduplicate、maxLines、headLines、tailLines),preserve声明必须保住的行模式,tests内置可回放的样本用例。这类过滤器自带测试的结构让"改完即可验证"成为可能。
RTK 内部管线顺序(见 engines/rtk/index.ts 的processRtkText)为:命令类型探测 → 过滤器匹配与应用 → 可选语义渲染器(enableRenderers,默认关)→ 可选代码块内压缩/代码剥离(applyToCodeBlocks)→ 重复行去重(deduplicateThreshold)→ 可选相似行分组(enableGrouping,默认关)→ 基于优先级模式(error/failed/exception/traceback/TS\d{4} 等)的smartTruncate硬截断。行数预算会按强度缩放(effectiveMaxLines:aggressive×0.5、minimal×1.5),但错误/失败行在任何强度下都通过 priorityPatterns 存活。
值得注意的工程细节:
- 缓存断点保护:携带
cache_control的内容块是 provider 的显式 prompt-cache 断点,RTK 会对其逐字节保留(#3936),避免每轮都打爆 provider 缓存; - 命令来源追踪:引擎从 assistant 消息构建
tool_call_id → {toolName, command}查找表(同时支持 OpenAI 嵌套tool_calls与 Anthropictool_use),并仅在工具名匹配 bash/shell/terminal 等(见SHELL_TOOL_NAME_RE)时才应用命令感知过滤器,防止read/grep读回的内容被误判为构建日志而截断; - 文档读取保护(#4559):当 RTK 未识别出命令、类型为 unknown 且无错误标记时,按"文档读取"处理,跳过泛化过滤器和末尾硬上限,避免误删代码/散文文件的中间段;
- 原始输出保留(#10659):
rawOutputRetention支持never/failures/always,配合rawOutputMaxBytes/rawOutputMaxFiles/rawOutputMaxAgeDays做有界保留与节流清理,绝不在热路径阻塞。
RTK 默认配置可在 types.ts 的DEFAULT_RTK_CONFIG看到全貌:intensity: "minimal"、默认只作用于工具结果(applyToToolResults: true)、maxLinesPerResult: 120、maxCharsPerResult: 12000、deduplicateThreshold: 3、customFiltersEnabled: true、trustProjectFilters: false、rawOutputRetention: "never"。
关于上游数据:RTK 上游报告命令输出压缩可节省 60–90%;其 README 示例显示一段 30 分钟的 Claude Code 会话从约 118,000 tokens 降至约 23,900 tokens(节省 79.7%)。自定义过滤器、信任门控、校验与原始输出恢复的操作细节,详见 docs/compression/RTK_COMPRESSION.md。
LLMLingua-2:基于语义剪枝的 prose 压缩
LLMLingua-2 模式使用小型 ONNX token 分类器对散文做语义 token 剪枝,与基于规则的 Caveman/RTK 互补:
- 只压缩非 system 消息中的散文;围栏代码块及其他受保护结构绝不改动;
- 运行
@atjsh/llmlingua-2后端(经@huggingface/transformers的 ONNX),且在工作线程中执行——模型推理不会阻塞请求事件循环; - 可堆叠(
stackPriority: 35):在 stacked 管线中,它运行在结构化引擎(CCR、session-dedup、headroom、Caveman)之后、ultra之前,因为语义剪枝对"已完成结构压缩"的文本最有效——例如rtk -> caveman -> llmlingua; - 任何错误都 fail-open(可选依赖缺失、worker 生成失败、模型加载失败、推理失败或超时)→ 原样返回文本,绝不抛错。
引擎位置:open-sse/services/compression/engines/llmlingua/(含worker.ts、modelStore.ts、onnxWorker.ts、constants.ts等)。
模型选择
- 默认模型TinyBERT(
atjsh/llmlingua-2-js-tinybert-meetingbank,约 57 MB,速度快); - 更高精度的BERT-base模型(
Arcoldd/llmlingua4j-bert-base-onnx,约 710 MB)可通过引擎配置model字段启用; @huggingface/transformers在首次调用时把所选模型懒下载到${DATA_DIR}/models/llmlingua(见modelStore.ts);- 离线 / 隔离(air-gapped)安装可改用
modelPath配置指向本地模型副本。
可选依赖与按需安装
可剪枝的 LLMLingua 运行期 peer 栈是可选的。两个包在package.json中以optionalDependencies声明,并由生产构建保持external(scripts/build/prepublish.ts 不打进 bundle):
| 包 | 版本(pin) | 说明 |
|---|---|---|
@atjsh/llmlingua-2 | 2.0.5 | 入口包;把其余声明为 peers |
js-tiktoken | ^1.0.20 | Tokenizer |
@huggingface/transformers固定在^4.2.0(与本地 embedding 路径共享);@atjsh/llmlingua-2@2.0.5以"^3.5.2 || ^4.0.0"依赖它,因此 Transformers.js v3/v4 都支持。自 2.0.4 起@atjsh/llmlingua-2不再需要@tensorflow/tfjs,移除了 SLM 栈里最大的单个体积贡献者(约 800 MB)。注意:只有上述两个包是"可剪枝的 SLM peers";标准npm install(开发环境)默认自动安装可选栈(除非你显式跳过 optional)。
为何按需安装:npm 发布包、standalone bundle 与 Docker 镜像默认都不携带这些依赖以保持精简。缺失时 worker 的依赖门(worker.ts中一次@atjsh/llmlingua-2resolve 探测)会失败并静默 fail-open——此时选中 LLMLingua 等于空操作(文本原样返回,无任何错误日志)。要在精简环境中激活它,请安装可选栈:
# 固定到 package.json optionalDependencies 声明的版本 npm install @atjsh/llmlingua-2@2.0.5 js-tiktoken@tensorflow/tfjs移除(2.0.4+)后,剩余体积主要是 transformers.js + onnxruntime-node 运行期,外加首次使用时下载的 TinyBERT 模型(约 57 MB,不走 npm)。
分环境的激活方式:
- Dev /
npm install—— 默认自动安装(除非传了--omit=optional/--no-optional),无需操作; - 全局 npm(
npm i -g omniroute)/ standalone—— 在已安装的包目录内执行上面的安装命令,或在不省略 optional 的前提下重装; - Docker—— 在派生镜像层里追加安装命令;官方镜像刻意保持精简;
- VPS(PM2)—— 安装进应用的
node_modules后重启进程,让 worker 重新探测门; - 裸 Next standalone(
npm run build→.build/next/standalone/server.js)—— standalone trace 既不携带 worker 也不携带 optional 依赖,引擎会静默 fail-open。scripts/build/colocate-standalone.mjs 会在每次构建后自动把两者(worker esbuild + optional-dep 闭包)重新应用到 standalone 树中;它通过postbuildnpm 钩子自动运行,幂等,依赖缺失时 fail-soft。
验证它真的激活了:选中 LLMLingua 后,真实散文确实变短(引擎不再 fail-open),且首个请求会触发模型下载到${DATA_DIR}/models/llmlingua。注意门的探测只探测@atjsh/llmlingua-2——其余 peers 是纯 ESM,require.resolve即便包存在也会抛错——所以若任一 peer 在import()时才真正缺失,worker 仍会 fail-open。
Stacked 管线:确定性多引擎流水线
Stacked 模式按顺序执行管线步骤,默认管线为:
rtk -> caveman适合 Coding Agent 会话——这类 prompt 往往混有命令输出与人话/助手散文:RTK 先削减嘈杂工具日志,Caveman 再压缩剩余自然语言。
管线步骤通过压缩设置里的stackedPipeline或压缩组合(compression combos)配置。实现上,strategySelector.ts 的resolveStackSteps()会先尊重显式配置的管线,其次回退到由每引擎开关地图派生出的管线,最后才是历史默认[{engine:"rtk"},{engine:"caveman"}]——避免了"外部调用方只转发持久化配置、却悄悄无视用户开关的引擎而走内置默认"的陷阱(#6463)。
执行循环支持同步applyStackedCompression()与异步applyStackedCompressionAsync()双路径(引擎暴露applyAsync时被 await,纯同步引擎内联执行,两条路径行为一致)。每步引擎执行前会依次检查:引擎是否已注册、是否符合当前compressionStage(post-translation 阶段只放行声明支持该阶段的引擎)、注册表中是否被禁用、管线级熔断器(circuit-breaker,T02)是否打开;执行后按 min-gain 决策(TV1 bail-out)与保真门(fidelity gate)决定是否真正提交该步结果。可选步骤还包括硬预算后处理(targetTokens/targetRatio)与聚合膨胀守卫(applyStackedInflationGuard),并提供onEngineStep逐引擎流式进度回调。
当两个引擎削减同一批可减载荷时,节省复利叠加:
combined = 1 - (1 - RTK savings) * (1 - Caveman input savings) average = 1 - (1 - 0.80) * (1 - 0.46) = 89.2% range = 1 - (1 - 0.60..0.90) * (1 - 0.46) = 78.4-94.6%其中 0.46 为 Caveman 上游报告的输入侧压缩率、0.60–0.90 为 RTK 命令输出压缩区间——该式只是说明"同源可减载荷上节省叠加"的估算模型,实际收益取决于载荷构成。
OmniGlyph 压缩画像
omniglyph引擎(npm 包omniglyph,1.4.0+)接受一个具名语义画像(profile),可通过压缩设置的omniglyph.profile全局设置,也可在 stacked 管线步骤配置中逐步骤指定:
| 画像 | 边界(Boundary) |
|---|---|
aggressive | 默认。发布 receipts 所测量的策略——images system、工具文档与稠密历史 |
balanced | 保持实时状态原生,保护最近 8 轮,折叠更早的已关闭历史 |
coding-safe | 保持 authority、工具 schema 与实时工具输出原生,保护最近 12 轮 |
passthrough | 不做变换直接路由;引擎被跳过 |
画像是一个上限(ceiling)而非下限(floor):包内mergeCompressionProfileOptions拒绝让调用方重新打开画像已关闭的有损通道——因此逐步骤设置preserveSystemPrompt: false也无法在coding-safe下重新启用系统压缩。
本代码库内的测量结论:coding-safe与balanced会把minCompressChars抬到最大值,并保持 system、工具 schema 与工具结果原生——尚未积累历史的会话会停在below_min_chars,引擎什么都不变换。这正是默认值选aggressive(而非最安全的画像)的原因。包会自行从环境配置解析模型范围与画像;OmniRoute 从不把决定权下放——适配器把模型门固定到包内最严格的 scope,宿主环境设置只能收窄允许列表,无法放宽到超过 OmniRoute 测量过的 receipts 之外。
MCP 可访问性树过滤器
MCP accessibility-tree 智能过滤器是一个执行后(post-execution)压缩层,作用对象是 MCP工具结果而非 prompt/上下文。它专门对付 Playwright、computer-use、浏览器自动化类 MCP 服务返回的冗长可访问性树与浏览器快照载荷。
做了什么
- 噪音剥离——移除空 generic/text 条目(
- generic:、- text: ""); - 兄弟节点折叠——当 ≥
collapseThreshold(默认 30)个连续行是结构重复时,折叠为前collapseKeepHead(默认 10)行 + 计数摘要 + 最后collapseKeepTail(默认 5)行; - 引用保留——Playwright/computer-use 所需的
[ref=eXX]锚点永不触碰; - 硬截断——折叠后仍超过
maxTextChars(默认 50,000)时截断并附导航提示,让 agent 能继续工作。
引擎位置
open-sse/services/compression/engines/mcpAccessibility/ index.ts ← smartFilterText() 入口 collapseRepeated.ts ← 兄弟折叠算法 constants.ts ← DEFAULT_MCP_ACCESSIBILITY_CONFIG配置
由全局设置中的compression.mcpAccessibility控制(迁移 056)。默认配置与常量定义一致(见 engines/mcpAccessibility/constants.ts):
{ "enabled": true, "maxTextChars": 50000, "collapseThreshold": 30, "collapseKeepHead": 10, "collapseKeepTail": 5, "minLengthToProcess": 2000 }过滤器只作用于type为"text"、且长度超过minLengthToProcess的工具结果载荷;不影响 prompt 压缩或请求载荷。clampMcpAccessibilityConfig()会把持久化配置收敛到安全值域(如maxTextChars低于MCP_ACCESSIBILITY_MIN_MAX_TEXT_CHARS会回退默认),保证 DB 规范化器与 MCP server 实时读路径口径一致。
预期节省与复杂度
浏览器快照工具结果通常可节省 60–80%(取决于页面复杂度);折叠算法对行数 O(n),延迟可忽略。
与上述压缩引擎的区别
| 维度 | Caveman / RTK / Stacked | MCP accessibility 过滤器 |
|---|---|---|
| 目标 | 请求 prompt / 上下文 | MCP 工具结果 |
| 触发 | 压缩模式设置 | compression.mcpAccessibility.enabled |
| 范围 | 所有 SSE 消息 | 仅工具结果 |
| ref 锚点 | 不适用 | 无条件保留 |
压缩组合(Compression Combos)
压缩组合是具名压缩画像,可被指派给路由组合(routing combos):
compression_combos:存储模式、管线、RTK 配置、语言配置与默认标记;compression_combo_assignments:把压缩组合映射到路由组合;- 运行期集成在泛化组合覆盖之前解析已指派的压缩组合;
- 分析数据包含
compression_combo_id与engine。
从 strategySelector.ts 源码可看到其优先级定位:路由组合覆盖(route-scoped 最具体)> 显式活动命名档案(manual operator choice,胜过自动触发)> 自动触发 > 派生默认;checkComboOverride()与buildNamedComboLookup()分别处理路由级与命名级覆盖。面板入口:Dashboard → Context & Cache → Compression Combos。
API Surface
| 路由 | 用途 |
|---|---|
/api/settings/compression | 全局压缩设置(含mcpAccessibility配置) |
/api/compression/preview | 预览任意压缩模式 |
/api/compression/language-packs | 列出可用 Caveman 语言包 |
/api/context/caveman/config | Caveman 设置别名 |
/api/context/rtk/config | RTK 默认值与设置 |
/api/context/rtk/filters | RTK 过滤器目录 |
/api/context/rtk/test | RTK 预览/测试端点 |
/api/context/rtk/raw-output/[id] | 鉴权的脱敏原始输出恢复 |
/api/context/combos | 压缩组合 CRUD |
/api/context/combos/[id]/assignments | 路由组合指派 CRUD |
/api/context/analytics | 压缩分析别名 |
管理类路由需要管理鉴权或 API-key 策略检查。
MCP 工具
压缩能力对外暴露五个 MCP 工具:
| 工具 | 作用域 | 用途 |
|---|---|---|
omniroute_compression_status | read:compression | 设置、分析、缓存统计 |
omniroute_compression_configure | write:compression | 更新全局设置 |
omniroute_set_compression_engine | write:compression | 设置模式及可选管线 |
omniroute_list_compression_combos | read:compression | 列出压缩组合 |
omniroute_compression_combo_stats | read:compression | 读取组合/引擎分析 |
范围与排除(Scope & Exclusions)
Embedding 永不压缩
open-sse/handlers/embeddings.ts从不调用任何压缩引擎——请求/响应体原样直通 executor。这当前是结构性的(embeddings 与 chat completions 是互不相交的 handler),而非运行期检查;但它意味着 #8034 中关于向量失真的担忧在 embeddings 路径上没有暴露面。
按模型/端点排除过滤器(#8034)
对 chat completions,运维者可点名绝不能被压缩的模型 id /provider/model目标——这是压缩未来若被接得更靠近 embedding 邻近路径时的护栏,也普遍适用于任何要求 prompt 逐字节精确的模型(确定性 evals、缓存敏感前缀等)。
- 设置字段:全局压缩配置上的
exclusions?: string[](GET/PUT /api/settings/compression),通过既有key_value压缩命名空间持久化(见 src/lib/db/compression.ts),不建新表; - 面板:Dashboard → Compression → Exclusions(
/dashboard/compression/exclusions); - 模式语法:
*是唯一通配符,其余所有正则元字符在匹配前都被转义——所以gpt-5.6只匹配字面量,绝不会命中gpt-5x6(ReDoS 安全、有界、无嵌套量词)。模式对裸模型 id 与provider/model复合串做大小写不敏感匹配——gpt-5-6、openai/gpt-5-6、openai/*都有效,单独一个*则排除全部模型; - 匹配逻辑:
isCompressionExcluded()/normalizeCompressionExclusions()位于 open-sse/services/compression/exclusions.ts。normalizeCompressionExclusions会把原始设置值归一化为小写、去重、有界(上限 200 条)的模式列表,杜绝病态配置拖慢每次请求;chatCore.ts在解析压缩设置后、任何引擎运行前检查命中目标,命中时与全局关闭压缩完全等价——请求体可证明逐字节一致。跳过会通过writeCompressionSkip(..., "excluded")记入分析可见; - 默认行为(空/缺省列表):与 #8034 之前完全相同——什么都不排除。
已知限制
- LLMLingua-2(SLM)要求共置可选依赖。worker 只有在生产构建中
@atjsh/llmlingua-2+ peers 被共置进dist/node_modules时才运行(见 scripts/build/colocateOptionals.mjs,#4286);缺失时引擎 fail-open(原样返回)。worker 解析不再依赖import.meta.url(在 standalone bundle 里会失效),而是锚定运行期 cwd /argv[1]; - Caveman 语言包
de/fr/ja标注为部分覆盖。维护说明指出它们只发布context+filler+structural规则,不带dedup/ultra包,因此这些语言下ultra强度并不强于full(它们只用自身规则——不会静默回退英文dedup/ultra规则去破坏外语文本);en/es/id/pt-BR完整。需要注意:当前仓库rules/目录中de/fr/ja等语言已可见dedup.json/ultra.json文件,说明语言包内容仍在持续演进,实际以你所安装版本提供的包为准;文档亦欢迎为部分包贡献dedup.json+ultra.json; - Stacked 遥测只列出真正压缩过的引擎。stacked 管线中某步引擎执行了但节省为 0% 时返回
stats:null,从而不会出现在engineBreakdown里——与"被跳过"不可区分。若要区分"跑了但 0%"与"跳过"需要改动 breakdown 模型,此项已推迟。
验证(Validation)
本区域的聚焦质量门可直接运行:
node --import tsx/esm --test tests/unit/compression/rtk-*.test.ts tests/unit/compression/pipeline-integration.test.ts tests/unit/compression/context-compression-api.test.ts node --import tsx/esm --test tests/unit/compression/*.test.ts tests/golden-set/*.test.ts tests/integration/compression-pipeline.test.ts tests/unit/api/compression/compression-api.test.ts node --import tsx/esm --test tests/unit/compression/mcpAccessibility*.test.ts npm run typecheck:core总结:如何为你的会话选择压缩路径
把上面各引擎放到一个决策面上:
- Prompt 以散文为主、追求无损语义保留→
standard(Caveman)起步,长会话升aggressive,逼近上下文上限再用ultra; - Prompt 以终端/工具输出为主(git diff、构建日志、测试输出、docker logs)→
rtk,需要时可下放项目级.rtk/filters.json并打开trustProjectFilters; - 两者混合的 Coding Agent 会话→
stacked(默认rtk -> caveman),追求最大节省可追加 LLMLingua-2 语义剪枝步骤; - 对逐字节保真有硬要求的模型/端点→ 使用压缩排除列表
exclusions(配provider/model复合匹配)绕过全部引擎; - Playwright/浏览器自动化工具返回可访问性树→ 依赖
compression.mcpAccessibility后置过滤器,而不是改变请求压缩模式。
配置入口统一收敛到 Dashboard → Context & Cache 面板与/api/settings/compression,引擎级开关通过注册表统一管理,验证命令即上文所示的质量门。这套"契约化引擎 + 确定性管线 + 排除护栏 + 后置结果过滤器"的结构,正是 OmniRoute 在保持逐字节保真可证明的前提下实现高压缩收益的关键设计。
【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考