面向 AI 上下文的本地、确定性证据筛选器。 从日志、命令输出、diff 和错误堆栈中,按当前问题逐行保留相关证据,删除低价值噪声。保留内容不重写,运行过程不联网,第三方 crate 依赖为零。
Local, deterministic, query-aware context compression for logs and command output.
Keep the lines that matter; leave the rest behind. Verbatim output, offline by default, zero dependencies.
快速开始 · 工作原理 · CLI 参考 · 本地记忆库 · 记忆治理 · 质量与证据 · 贡献与安全
把一大段日志直接塞进模型上下文,既昂贵又容易淹没关键行。通用摘要器会改写内容,抽样器可能恰好丢掉根因,向量检索则不适合逐行保留原始证据。
scx 选择另一种约束:先确定证据,再分配预算;只删除整行,不改写原文。
- 证据优先:查询命中的证据行及其最小可读邻域无条件保留,
--ratio只能约束可选内容,不能挤掉证据。 - 原文可追溯:筛选模式只删整行;
--lineno 1为保留行附加原始行号,--force可锁定必须保留的片段。 - 本地且确定:无网络请求、无随机源、无第三方运行时依赖;相同输入、查询和配置产生相同输出。
- 面向 Agent 工作流:同时提供 CLI、Rust 库、JSON 统计和跨平台自举入口,便于接到脚本、Agent 或本地工具链。
- 失效可解释:小输入、无查询信号或无可用内容时回退原文,并明确报告
mode,不会静默返回空结果。 - 可选经验复用:内置可关闭的本地 case memory,通过
--store、--recall、--rate沉淀并召回排障经验。
scx 不是通用摘要器、日志平台、向量数据库或 DLP 系统。它解决的是更窄但高频的问题:在有限上下文中,尽可能完整地保留与当前问题相关的原始行。
- Rust 1.82 或更高版本(含 Cargo)
- macOS、Linux 或 Windows
- 无外部 crate;若尚未安装 Rust,需要先联网获取工具链;
scx本身不联网
git clone https://github.com/spapient/scx.git
cd scx
./tools/scx --versionUnix 入口会在二进制缺失或源码更新时自动执行 release 构建,然后转发参数。若文件系统丢失了执行位,使用 sh tools/scx --version。
Windows PowerShell:
git clone https://github.com/spapient/scx.git
Set-Location scx
.\tools\scx.cmd --version也可以直接构建独立二进制:
# macOS / Linux / WSL
cargo build --release --locked
./target/release/scx --version# Windows
cargo build --release --locked
.\target\release\scx.exe --version# crates.io(推荐,通用)
cargo install scx
# macOS Homebrew(tap 实测通过)
brew tap spapient/scx && brew install scx
# Node ≥18 环境(含 MCP 入口,包内置三平台二进制)
npx -y @spapient/scx
# Windows(Scoop 自建 bucket 即时可用 / winget PR 合入后可用)
scoop bucket add scx https://github.com/spapient/scoop-scx
scoop install scx/scx
winget install Spapient.Scx # 待 microsoft/winget-pkgs PR #466131 合并完整发布渠道矩阵与各平台接入状态(豆包/千问办公等)见 docs/install-plan.md。
scx 内置 MCP stdio server(零第三方 crate、无条件编译进主二进制)。三条命令完成注册:
./tools/scx install # 或把 release 二进制放进 PATH(scx)
scx setup # 一键注册到 Claude / Codex / Cursor
scx mcp # 手动进入 stdio server 模式(agent 会以子进程方式拉起)scx setup 行为契约:
- 注册名统一小写
scx,命令为当前二进制绝对路径 +mcp子命令(stdio)。 - Claude:优先
claude mcp add scx -- <scx> mcp;CLI 不可用或失败时兜底写~/.claude.json的mcpServers.scx。 - Codex:优先
codex mcp add scx -- <scx> mcp;兜底写~/.codex/config.toml的[mcp_servers.scx]。 - Cursor:写
~/.cursor/mcp.json的mcpServers.scx;--project-cursor改写当前项目.cursor/mcp.json。 - 幂等:已存在
scx条目则更新 command/args,绝不重复追加;配置内容未变时跳过写入。 - 写前备份:原配置复制为
<path>.scx.bak(每次覆盖最新一份,可回滚)。 - 写后自检:每个 agent 注册后 spawn
scx mcp做 initialize + tools/list 握手,验证compress_context存在并打印结果。 - 细粒度:
--claude/--codex/--cursor只注册指定 agent。
只注册某个 agent:
scx setup --cursor # 只写 Cursor 配置
scx setup --claude --codex # 只注册 Claude 与 Codex验证(不依赖配置,直接握手):
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | scx mcpserverInfo.name 为 scx,工具为 compress_context / connect_account / usage_summary。
仓库同时包含 SKILL.md。将仓库放入技能目录后,Codex 可以在处理长日志或大文件时自动发现并使用它:
git clone https://github.com/spapient/scx.git \
"${CODEX_HOME:-$HOME/.codex}/skills/scx"tools/scx install 构建 release 二进制并软链到 ~/.local/bin/scx(零第三方 crate,
--locked 离线可构建;目标目录可用 SCX_BIN_DIR 覆盖):
# macOS / Linux / WSL
sh tools/scx install # 构建 + 安装到 ~/.local/bin/scx
export PATH="$HOME/.local/bin:$PATH"# Windows PowerShell:复制 release 二进制到用户工具目录
New-Item -ItemType Directory -Force "$HOME\bin" | Out-Null
Copy-Item target\release\scx.exe "$HOME\bin\scx.exe"
$env:Path = "$HOME\bin;" + $env:Path或直接使用自举入口(无需安装,按需自动构建):
./tools/scx --version # macOS / Linux / WSL
.\tools\scx.cmd --version # WindowsCodex、Claude Code 与 PATH 入口应指向同一版本;副本漂移是“技能存在但实际不可用”的常见原因:
"${CODEX_HOME:-$HOME/.codex}/skills/scx/tools/scx" --version
"$HOME/.claude/skills/scx/tools/scx" --version # 安装到 Claude Code 时
scx --version # 已将入口加入 PATH 时三条命令都应输出版本号(当前为 scx 0.11.0)。若 Claude Code 入口报 permission denied,说明副本过旧或执行位丢失,请更新该副本后重试;版本相同但行为不一致时,用 git -C <技能目录> rev-parse HEAD 检查两份副本是否在同一提交。
只对实际安装过的入口执行上述检查;未安装的路径报“不存在”不代表工具本身异常。
some-noisy-command > /tmp/scx-input.log 2>&1
./tools/scx \
--query "database timeout connection pool" \
--ratio 0.35 \
--lineno 1 \
/tmp/scx-input.logstdout 是筛选后的正文,末尾附一行统计。典型输出形状如下:
42: 2026-10-24T10:31:08Z ERROR db timeout waiting for connection
43: at Pool.acquire(Pool.java:214)
...
compressed: kept=13/98 lines chars=4950->802 (83.8% cut) dup=84 seeds=4 evidence=4 risk=LOW guarded=0 regions=2 window=2 terms=3 forced=0 mode=sieve ser_b=1562
kept/total是保留行数与输入行数。seeds与evidence是结构性不变量,二者始终相等。ser_b是实际序列化响应大小:--json渲染载荷(render())的 UTF-8 字节数,MCP/脚本层按此计真实载荷,而非字符/估算 token。mode=sieve表示实际执行了筛选;passthrough 或 fail-open 模式返回原文。- 统计行属于 stdout;管道消费正文时加
--no-stats,需要机器可读统计时加--json。
--evidence SUBSTR|N(可重复)声明的证据行强制整行保留并跳过行内 trim:
证据是问答硬锚,字符级裁剪会摘掉证据 marker 导致正文丢失而报告仍称"全部保留"
(v0.9.x 缺陷,P12.6 修复)。--json 中 ev_total 是声明证据条数、
ev_retention 是实际保留率(0..=1),二者配合给出真实"保留/丢失"口径。
每次压缩后,终端会额外输出一张「SCX 压缩召回」效果卡(stderr,不影响 stdout 管道契约), 把"原始多大 → 压缩后多大 → 省了多少 → 召回多少证据 → 做了什么 → 风险如何"讲给普通人听:
✦ SCX 压缩召回 ✦
📌 查询 database connection failed
⚙️ 模式 sieve 智能筛选 · 按问题逐行召回证据
📥 原始 60 行 · 3,318 字符 · 约 830 token
📤 压缩后 45 行 · 2,710 字符 · 约 678 token
💾 省下 15 行 · 608 字符 · 约 151 token(-18.3%)
🎯 证据召回 12 条关键证据全部保留 · 0 丢失
🔁 去重 28 行重复内容已折叠
✂️ 裁剪 11 段无关内容已移除
🛡️ 风险 低
- 小输入(<40 行且 <400 token)与查询零命中时同样出卡:结论分别是 「小输入透传 · 无需压缩」与「无命中保护 · 零丢失」,附一句人话说明为什么没有压缩。
- token 为 scx 内部估算口径(
terms::estimate:ASCII 约 4 字符/token,中文约 0.6 token/字), 数字带"约"字;行/字符/token 三口径同时给出,中文日志时三者的缩减率独立计算。 --json的机器字段同步扩展(向后兼容):tokens_in/tokens_out/token_cut_pct, MCPcompress_context的返回 JSON 同样携带,AI 侧可直接转述"省了多少 token"。- MCP 单 content(v0.6.6+):
compress_context返回一块 text,效果卡在上、机器 JSON 在下—— 效果卡就是上面这张「SCX 压缩召回」(豆包/千问/Codex/Cursor/Claude 对话直接原样可见), JSON(tokens_in等完整字段)紧随其后供 AI 精确转述。实测豆包对多 content 仅渲染 JSON 转述、效果卡不可见,故自 0.6.6 起合并为单块;0.6.5 的双 content 行为已废弃。
常用调节方式:
# 更紧的可选预算;证据及其 ±1 行邻域仍不会被挤掉
./tools/scx --query "panic overflow index" --ratio 0.15 app.log
# 针尖模式:不填充可选内容
./tools/scx --query "panic overflow index" --context 0 app.log
# 强制保留指定子串(可重复或使用 | 分隔;大小写不敏感)
./tools/scx --query "deploy failed" --force "rollback" --force "Region=eu-west-1" app.log
# 正则子集:re: 前缀进入有限正则(交替/字符类/量词,Thompson NFA,无回溯灾难)
./tools/scx --query "oom crash" --force "re:ERROR|FATAL" --force "re:panic in|assert in" app.log
# 硬 token 上限:证据地板优先,超限如实报告 overflow:evidence/fill,绝不静默丢证据
./tools/scx --query "db timeout" --max-tokens 2000 app.log
# 结构感知邻域:fence 代码块 / import/use 块 / 堆栈 at 链整体并入(默认关,显式开启)
./tools/scx --query "conn broken" --structure 1 app.log
# 策略文件覆盖默认值:CLI 显式参数 > 文件 > DEFAULT
./tools/scx --query "oom crash" --policy-file policy.toml app.logscx wrap 包装任意命令,把其 stdout+stderr 合并后按需压缩——省去手动落盘再接管道:
# 构建/测试输出自动压缩,只保留与问题相关的行;退出码沿用被包装命令
scx wrap --query "compile error" -- cargo build
scx wrap --query "db timeout" --preserve errno -- make test小输出由内核自动 passthrough(原样透传),大输出按 --query/--force/--preserve 筛选,正文写 stdout、效果卡写 stderr。等价于 CMD > /tmp/out 2>&1 && scx --query "..." /tmp/out,但一条命令完成且退出码正确透传。
完全自动的「工具输出拦截」(无需模型主动调用)需在宿主 Agent 配 hook:思路是在 PostToolUse hook 里把大
tool_response交给scx wrap(或直接scx)压缩后再回填, 具体脚本取决于宿主当前的 hook 协议(见docs/automatic-interception.md的模板)。
query + input
│
├─ 1. 计算 IDF 加权词面命中,确定证据行
├─ 2. 无条件保留证据行及其 ±context 邻域
├─ 3. 可选:--structure 1 把 fence 代码块 / import/use 块 / 堆栈 at 链
│ 作为结构区间整段并入邻域(默认关,关闭时与 v0.4.1 逐字节一致)
├─ 4. 只在种子邻域内,用剩余预算填充可选行
├─ 5. --max-tokens N 硬上限:证据地板优先,超限报 overflow:evidence/fill
├─ 6. HIGH 风险时启用错误行 / 事故标记守卫
└─ 7. 输出原文行子集与统计,不重写、不截断保留行
核心参数:
| 参数 | 默认值 | 语义 |
|---|---|---|
--ratio |
0.35 |
可选内容的 token 估算预算比例,范围 0.02..=1.0 |
--context |
1 |
证据行两侧最小保留邻域,范围 0..=4;0 为针尖模式 |
--window |
2 |
种子区域扩展与邻域排序半径,范围 0..=8;0 规范化为 1 |
--risk-gate |
1 |
风险为 HIGH 时保护失败级错误行和事故标记行 |
--scoped |
0 |
与 --risk-gate 联动:1 时 HIGH 风险守卫只保留证据邻域内的错误/标记行,远处无关错误行照常裁剪(真实转储上压减率提升 11.7–20.1 个百分点,见 benchmarks) |
--lineno |
0 |
为筛选输出添加 N: 原文行号前缀 |
--force |
无 | 强制保留匹配行;大小写不敏感的字面子串;re: 前缀进入有限正则子集 |
--max-tokens |
无 | 输出 token 硬上限;证据行及其最小邻域优先,超限报 overflow:evidence/overflow:fill,绝不静默丢弃证据 |
--budget |
0 |
硬 kept-token 占比上限(0 < F ≤ 1,0=关);最终输出 token(保留行 + elide 省略标记)≤ F×输入;超预算行按保真优先级反向裁剪(证据/数字/结构最后裁);与 SuperCompress 官方 mean cut 64.1% 同预算对照路径 |
--structure |
0 |
1 时启用结构感知邻域:fence 代码块、import/use/#include 块、堆栈 at 链整体并入 |
--policy-file |
无 | 策略文本覆盖默认值(键白名单与下方 --policy-file 行一致:ratio/budget/context/window/elide/risk_gate/scoped/strict/lineno/max_tokens/structure/fill_floor/trim/trim_ratio/trim_op_keep/code_keep/zh_keep/num_line_keep/sym_line_keep/list_keep);优先级 CLI 显式 > 文件 > DEFAULT |
--pipeline |
无 | JSON 管线配置(config/pipeline.json 或 config/bench/profiles/*.json);plan/trim/anchor 三阶段声明式装配;未知键/越界 fail-loud;优先级 CLI 显式 > 文件 > DEFAULT |
- 只删不改:筛选结果中的保留行来自输入原文;
...仅表示被省略的区间。 - 证据不变量:证据行及其最小邻域先于预算确定,不会被
--ratio淘汰。 - 确定性:不使用随机数;排序平局也有稳定规则。
- 显式回退:无内容可保留或无查询信号时返回原文,不返回静默空正文。
mode |
含义 |
|---|---|
sieve |
已执行证据筛选 |
passthrough:small |
输入同时少于 40 行且少于约 400 token,直接返回原文 |
passthrough:longline |
输入包含超长行(单行 > 10 万字节且 > 10 万字符)无法安全切块,直接返回原文 |
passthrough:no-kept |
预算或 --context 0 下没有可保留行,返回原文 |
failopen:zero-signal |
查询没有命中,返回原文 |
overflow:evidence |
--max-tokens 下限:证据行 + 最小邻域本身已超限,保留全部证据并如实报告 |
overflow:fill |
--max-tokens 上限:预算填充后仍超限,按硬上限裁剪并报告 |
查询词与输入存在词面重叠时效果最佳。scx 不生成 embedding,也不承诺解决完全无共享词的语义检索问题。
完整入口:
scx --query "..." [OPTIONS] [file...]
| 选项 | 说明 |
|---|---|
--query <TEXT> |
当前问题或检索意图;未提供时必须至少给出一个非空 --force |
file... |
一个或多个输入文件;省略时读取 stdin;单次输入总计上限 64 MiB |
... --stat |
只输出统计行 |
... --no-stats |
只输出正文,不输出统计行 |
... --json |
向 stderr 追加 scxjson: {...} 机器可读统计;含 dropped 区间明细(--max-tokens/预算裁剪)与 max_tokens/tok_est 字段 |
--max-tokens <N> |
输出 token 硬上限;证据地板最高优先,超限报 overflow:evidence/overflow:fill |
--budget <F> |
硬 kept-token 占比上限(0 < F ≤ 1,0=关);输出 token(保留行 + elide 省略标记)≤ F×输入 token;超预算按保真优先级反向裁剪(R_FILL<R_ANCHOR<R_NUM_LINE<R_EVIDENCE),证据/数字/结构最后裁 |
--structure <0|1> |
1 时启用结构感知邻域(fence/import/stack);默认 0,关闭时输出与 v0.4.1 逐字节一致 |
--policy-file <PATH> |
策略文本覆盖默认值;键白名单 ratio/budget/context/window/elide/risk_gate/scoped/strict/lineno/max_tokens/structure/fill_floor/trim/trim_ratio/trim_op_keep/code_keep/zh_keep/num_line_keep/sym_line_keep/list_keep;非法文件报错含行号;优先级 CLI 显式 > 文件 > DEFAULT |
--pipeline <PATH> |
JSON 管线配置(plan/trim/anchor 三阶段声明式);键白名单 plan.ratio/window/context/limit、trim.enable/ratio/op_keep/code_keep/zh_keep/num_line_keep/sym_line_keep/list_keep、anchor.structure/anchors/fill_floor;未知键/越界 fail-loud 报错;优先级 CLI 显式 > 文件 > DEFAULT;评测档位模板 config/bench/profiles/{r02,r03,r04}.json |
--fill-floor <F> |
上下文/填充行最低分数门槛(默认 0 = 现状);F>0 时分数低于门槛的邻域与填充行被裁剪,压缩更深 |
--trim <0|1> |
保留行内 token 级重要性裁剪(默认 0 = 现状);1 时数字/命中词/结构锚保留,停用词与低信息量 token 按 --trim-ratio 摘除;CJK/中文逐字 token 化——命中 query 的汉字完整保留(如"内存"成词不拆散)、虚词可摘、全角数字保留,中文行不再丢字 |
--trim-ratio <F> |
--trim 1 时的低分 token 保留比例(默认 0.5;范围 0.1..=1.0) |
--force <P> |
强制保留匹配行;字面子串(大小写不敏感);re: 前缀进入有限正则子集(| 交替、[...] 字符类、* + ? 量词,Thompson NFA,非法模式报错并提示支持子集) |
--semantic <WEIGHTS> |
可选神经重打分(需 cargo build --features semantic 构建);权重文件自描述 JSON:v2 {schema:"scx-sem-2",features,weights,sha256}(命名式,特征可任意子集/顺序)或 v1 {schema:"scx-sem-1",dim,weights,sha256}(位置式,兼容);SHA256 校验失败即拒绝运行;打分 sigmoid(w·x) 经居中化(2·sigmoid−1)做有符号叠加——正提升、负降权;不启用时默认路径逐字节不变 |
--help, --version |
显示用法或版本 |
| 选项 | 说明 |
|---|---|
--mem-dir <DIR> |
记忆库目录;默认 $SCX_MEM_DIR,否则 ~/.scx-memory(Windows 为 %USERPROFILE%\.scx-memory) |
--store 1 |
将本次证据块写入记忆库;默认关闭 |
--fix <TEXT> |
随 case 保存已验证的修复结论 |
--fix-file <PATH> |
从文件读取多行修复结论,与 --fix 互斥 |
--max-bytes <N> |
记忆库总容量软配额;超限时拒绝写入 |
--recall <K> |
在正文旁路召回最多 K 条相关 case |
--recall-detail |
召回时附带摘要、原始证据行和修复结论 |
--recall-only |
只读召回,不写 query 图、会话缓存、索引或 L1 历史 |
--rate good|bad <CASE_ID> |
对一次召回结果给出反馈 |
--stats |
显示 case 数、状态、fix 覆盖率、质量均值和磁盘占用 |
--rebuild, --gc, --delete <CASE_ID> |
重建索引、清理过期条目、删除指定 case |
| 选项 | 说明 |
|---|---|
--eval <BASELINE.json> |
对冻结标注集执行 A/B 重放,比较完整管线与词面基线 |
--eval-verbose |
追加逐 case 候选诊断 |
--gate |
机械资格门:样本规模、分层、judge 元数据和基础指标 |
--gate-human |
人工弱相关/负例闭环门,要求逐候选真人 provenance |
--gate-items |
允许非人类逐候选裁决,并明确标注非人工证据 |
--annotate, --annotate-raw |
从本地库生成回归标注或盲审材料 |
--judge <BASELINE.json> |
交互式逐候选裁决 |
--l1-hist |
查看本地直答命中分布 |
运行 ./tools/scx --help 可查看当前构建支持的完整参数。
证据保留同场对照(contain5 合成语料:scx vs 头截断 vs 随机抽样基线,含证据 存活率/压减率/延迟三指标,作者侧自测、非第三方盲审)见 docs/containcmp.md,冻结口径见 docs/containment.md; 跨机性能量级见 docs/benchmarks.md。
记忆库用于保存“哪几行是证据、当时如何修复”,适合重复出现的构建、运维和故障排查问题。它默认关闭、完全本地,并使用无随机源的词面/字段统计召回,而不是 embedding。
# 1. 在问题解决后沉淀证据与修复结论
./tools/scx \
--query "db timeout connection pool" \
--store 1 \
--fix "increase pool size and restart the service" \
--mem-dir .scx-memory \
app.log
# 2. 再次遇到相似问题时只读召回
./tools/scx \
--query "database connection pool exhausted" \
--recall-only --recall 3 --recall-detail \
--mem-dir .scx-memory
# 3. 查看库状态
./tools/scx --stats --mem-dir .scx-memory默认工作流会在召回结果前加 mem: 前缀,使记忆内容与当前输入明确分离。每条 case 包含查询、证据行区间、原始证据和可选修复结论;--fix 内容是候选答案,相似症状不代表同一根因,使用前仍需验证。
--recall K 的快照缓存也按 K 校验:先用小 K 暖缓存不会让后续大 K
少返回;条数不足时自动回退完整 BM25 召回。持久化 qmap 快照仅复用 1 小时内
的结果,避免时间衰减排序长期停留在旧状态。
入库前会对已知的 password、token、Authorization、Bearer 和 URL 用户信息模式做脱敏,但这只是尽力而为的已知模式匹配,不是通用 DLP。分享日志或记忆库前请人工复核。
多进程共享同一 --mem-dir 受支持:所有跨文件操作通过 locks 按固定锁序
(cases/{id} → index → meta → qmap → fingerprints)一次取多锁,避免死锁;
持锁后的写路径使用 *_locked 变体,不自相争锁。并发压力测试覆盖
store/rate/delete/rebuild 组合。契约全文见 锁序契约。
记忆库内建一套关系型治理框架,管理记忆与记忆之间(语义冲突、版本谱系、
生命周期)以及记忆与查询之间(分层、召回)的关系,实现全部位于
src/memory/,与压缩引擎完全隔离:
| 机制 | 说明 |
|---|---|
| 写入治理与分层晋升 | 脱敏、指纹去重;新 case 默认 L0,证据完整晋升 L1(tier.rs) |
| 冲突仲裁 | 写入时 minhash 近重复检测 + 证据/质量裁决 + related 互链,审计日志 index/conflicts.log(conflict.rs) |
| 版本化取代 | supersedes 双向链:先写替换者,再标记旧事实(store.rs) |
| 逻辑退役(墓碑) | life = active/revised/retired + retire_reason,等价 tombstone 语义,召回过滤非 active(store.rs + maintenance.rs) |
| 召回融合 | 词面 BM25 × 字段/实体加权 × PRF × RRF 融合 + 记忆类型过滤(--recall-kind) |
治理有效性经官方基准冻结实证:LongMemEval 旧证据进 Top-K 89.74%→1.28%、 Memora ΔFAMA=10.68、AMA-Bench accuracy 0.512(> bm25 0.5076)。 机制详述、术语对照与生命周期见 docs/memory.md §0。
设计、存储格式、运维与实现记录统一见 本地记忆库。
压缩引擎是纯函数,不访问文件、环境变量或网络。本仓库不提供 crates.io 发布,可从源码作为 path dependency 使用:
[dependencies]
scx = { path = "../scx" }use scx::{compress, Config};
fn main() {
let log = std::fs::read_to_string("app.log").expect("read app.log");
let cfg = Config {
ratio: 0.25,
lineno: true,
..Config::default()
};
let out = compress(&log, "database timeout", &cfg);
print!("{}", out.text);
assert_eq!(out.seeds, out.evidence);
eprintln!(
"kept={} evidence={} mode={}",
out.kept, out.evidence, out.mode
);
}公开类型定义在 src/lib.rs,记忆库入口为 scx::memory。筛选引擎与记忆库、CLI I/O 相互隔离。
| 路径 | 职责 |
|---|---|
src/lib.rs |
公共 API、Config、Outcome、Mode/Risk 枚举 |
src/lib_tests.rs |
crate 根单元测试(Config/Outcome/类型探测/hash 确定性,cfg(test) 子模块) |
src/compress.rs |
sieve 内核门面:单趟压缩主链 compress/compress_bucketed、行保护策略、预算利用率、hash 子模块;拆分为 compress/ 子模块(plan/score/render) |
src/compress/plan.rs |
规划阶段:切行统计、折叠判定(fence 感知)、权重打分、种子与结构区域识别 |
src/compress/score.rs |
选择与守卫阶段:邻域/锚点/围栏/符号行标记、填充预算、风险审计与守卫(Ctx 共享上下文) |
src/compress/render.rs |
渲染阶段:保留/裁剪区间落地、行内 trim、原因注释、输出截断 |
src/analysis.rs, src/terms.rs |
归一化、结构分类(含 fence/import/stack 判定)、切词与 token 估算 |
src/policy.rs |
默认策略数据表(ScoreTable/RiskTable/RegionCfg/硬常量),不落独立硬编码文件 |
src/toml.rs |
TOML 子集解析(Entry/parse/float/size),供 --policy-file 与记忆库 meta.toml 复用 |
src/pipeline.rs |
压缩管线配置(--pipeline):JSON 声明式装配 plan/trim/anchor,三层优先级 CLI > 文件 > DEFAULT,未知键/越界 fail-loud |
src/ops.rs |
操作编排层:Op 枚举 + run + 纯渲染(统计/JSON),main.rs 仅薄壳 |
src/regex.rs |
手写有限正则子集(交替/字符类/量词,Thompson NFA,零第三方 crate) |
src/semantic.rs |
可选神经重打分(cargo feature=semantic):手写 SHA-256、权重加载校验、确定性 sigmoid |
src/json.rs |
手写 JSON parser(mcp 与 --json 渲染共用) |
src/contain.rs |
证据保留(Containment)评测协议实现 |
src/memory/ |
本地 case 存储、召回、反馈、索引与评估(locks 固定锁序) |
src/main.rs, src/args.rs, src/input.rs |
CLI 入口、声明式参数表(FLAGS)、文件 I/O |
src/args/parse.rs |
CLI 参数解析处理器(值解析分派、policy 文件应用链、终局校验),args 拆分子模块 |
src/mcp.rs |
stdio MCP server(无条件编译进主二进制,scx mcp 子命令入口;零第三方 crate) |
src/setup.rs |
scx setup 一键注册 MCP 配置(Claude/Codex/Cursor,幂等 + 写前备份 + tools/list 自检) |
tools/scx, tools/scx.cmd |
Unix / Windows 自举构建入口 |
tools/scx.py |
评测语料回放、盲审与配对统计(仅标准库;含 contain 证据保留子命令) |
examples/bench.rs |
压缩与记忆库的统一性能基准入口 |
tests/golden.rs |
stdout、stderr、退出码的逐字节差分门(37 例) |
config/ |
可重建语料、冻结标签、盲审包与语义权重(Gauge.*/contain5.*/real.*/v2.*) |
docs/ |
设计、评测协议、锁序契约与证据报告 |
src/memory/ 保持扁平、单一职责的布局:mod.rs 是唯一公开门面,存储
(store/meta/ingest/lock/json/util)、召回
(recall/ranking/index/cache/edge/classify)、学习与维护
(feedback/maintenance)和评估(eval/gate/annotate)各自成组;
不设跨层子目录,也不把内部文件格式或缓存提升为外部契约。
有意修改 CLI 语义时,需要运行冻结基线更新并逐项审查差异:
cargo test \
--test golden update_baselines -- --ignored --nocapture每次变更通过以下门禁(0.6.0 起 mcp 已并入默认轨,为「默认 + semantic」双轨;可选 feature 均需编译与测试全绿):
cargo fmt -- --checkcargo clippy --locked --all-targets -- -D warnings(另跑--features semantic轨)RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps- 单元、CLI 集成、并发、金标与评测协议测试(
golden37 例逐字节零漂移为硬红线;新行为只走新测试例) cargo test --locked(默认轨含 MCP stdio 冒烟)与--features semantic(含权重校验/确定性)cargo build --release --locked- Rust 1.82 声明 MSRV 实编译
- 50k 行压缩基准
- 10k case 倒排召回 p50 < 5 ms 性能门
- Ubuntu、macOS、Windows 三平台 CI
- Gauge 冻结语料上的质量回归门,以及“policy/AI 标签不得冒充人工闭环”的负向测试
contain5证据保留协议(自测、非第三方独立评测;见 证据保留报告)
Gauge 使用 30 起公开事故和 150 条查询,预注册主指标为 hard 层 MRR@10。在机械目标标签上,完整管线的 hard 层 MRR@10 相对朴素词面基线提升 +0.0669,paired bootstrap 95% CI [0.0238, 0.1176],permutation p=0.0020,literal 层没有退化。
当前默认配置经过后续校准,在同一语料上为 ΔMRR +0.0608,95% CI [0.0202, 0.1095],p=0.0029。这证明的是目标排序优于该词面基线,不是对 embedding、混合检索或任意 RAG 系统的普遍优势。
逐候选人工门在 hao 的 384 项标签上通过点估计,但这些标签也参与了配置校准,因此它是事后验收,不是新的独立 holdout;NDCG 差值的配对 bootstrap CI 仍跨 0,不能表述为“NDCG 显著优于基线”。
证据保留(contain5,P1 新增协议):25 个合成噪音切片(build/stack/diff/log/test 各 5,
1787 行、70 条必需证据行,含日志/堆栈/diff 混合),在 ratio=0.35 默认配置下
scx 证据保留率 70/70 = 100%(truncation 头部截断基线 0/70),平均字符压减
82.01%、token 估算压减 79.93%。这是作者侧合成语料自测,非第三方独立评测,
口径仿 SuperCompress evidence-containment;冻结语料 SHA256 见
docs/containment.md。
完整协议、结果与限制见:
以下数据来自本机 release 构建,用于量级参考,不是跨机器性能承诺。P1–P3 默认路径 逐字节不变(golden 37 例零漂移),上述快照仍有效;可选 feature(semantic 重打分、 structure 结构并入)未在此快照内。
| 工作负载 | 结果 | 条件 |
|---|---|---|
| 50k 行 / 2,338,389 字符压缩 | 中位 11.7–12.0 ms | Apple M5 Pro,三轮 × 21 次采样 |
| 10k case 稀疏查询召回 | p50 71–73 µs | 三轮 × 21 次采样 |
| 10k case 全候选宽查询 | p50 1.11–1.15 ms | 三轮 × 7 次采样 |
| 10k case 首次索引加载 | 11.6–11.8 ms | 每轮单独预热,不计入稳态 p99 |
| 10k case 冷启动线性首查 | p50 0.95–0.97 s | 三轮;受系统负载与页缓存影响 |
| 10k case 全量重建索引 | 373–388 ms | 三轮 |
基准使用合成负载:压缩输入为 50k 行混合日志,记忆库为 1 万条短日志/长堆栈 混合 case。与同一会话中的 HEAD 基线交错测量:压缩中位 12.7–12.8 ms → 11.7–12.0 ms (约 6–8%),稀疏召回 p50 163–177 µs → 71–73 µs(约 −57%),宽查询 1.17–1.39 ms → 1.11–1.15 ms(差异受负载影响),冷启动线性首查 1.01–1.03 s → 0.95–0.97 s。 稀疏提速来自“先部分选择 top-k、只排序候选窗口”,不再为 5 条结果排序全部候选; 冷启动收益来自读取 case 时不再克隆整棵 JSON;宽查询仍主要受逐候选打分约束。 它衡量实现开销与回归,不代表真实事故分布或跨机器性能。
复现:
export CARGO_TARGET_DIR="${TMPDIR:-/tmp}/scx-cargo-target"
cargo test --locked
cargo run --release --locked --example bench
cargo run --release --locked --example bench -- memory不同项目解决的任务不同,不能用单一压缩比或单条延迟做跨任务排名。这里只说明定位与可借鉴之处:
| 项目 | 主要任务 | 与 scx 的边界 |
|---|---|---|
| ripgrep | 行式正则搜索 | 不做上下文预算与证据压缩;其清晰的 CLI/core 分层与流式扫描是架构参照 |
| LLMLingua | 模型式提示压缩 | 依赖模型且可能改写/丢弃 token;scx 零模型、离线、只删整行,保留原文 |
| logreduce | 基于成功日志模型高亮异常 | 需要成功/失败基线学习 novelty,不按当前 query 选择原始证据行 |
| logparser | Drain/SLCT 等日志模板抽取 | 面向模板聚类与结构化分析,不提供查询相关的上下文预算契约 |
| loglizer | 机器学习日志异常检测 | 做异常判定/分类,不按当前查询逐行筛证据;任务与输出契约不同 |
scx 的可测目标是冻结语料上的检索 MRR、证据行保留、确定性与延迟,不是通用摘要质量或 跨语言模型压缩比。上述项目在各自任务上更成熟;本次横向审计只比较输入、模型依赖、 输出可追溯性和确定性契约,不把不同任务的压缩比或延迟做单排名。scx 只优化 “查询相关的原始行选择”。
- 词面相关优先:查询没有词面命中时会 fail-open;完全释义、无共享词的查询不在保证范围内。
- 压缩率不固定:保留全部证据的语义决定了输出存在“证据地板”;
--ratio不是硬性字符上限。 --max-tokens是上限不是下限:证据地板最高优先;下限(overflow:evidence)保留全部证据并如实报告,上限(overflow:fill)按硬上限裁剪——两者都绝不静默丢弃证据行。- 结构感知是叠加不是替代:
--structure 1的结构区间并入默认邻域;默认关闭时输出与 v0.4.1 逐字节一致。 - 正则子集有限:
re:支持交替/字符类/量词,不支持.、捕获组、锚点与简写类;非法模式报错并提示支持子集。 --semantic可选且默认关闭:需--features semantic构建;权重文件 SHA256 校验失败即拒绝运行,不启用时默认路径逐字节不变。- MCP 并入主二进制:
scx mcp子命令走 stdio,只调库内核与 JSON 渲染;scx setup一键注册到 Claude/Codex/Cursor(幂等、写前备份、写后自检)。 - 压缩产物不可二次压缩:scx 非幂等——对已压缩文本重复压缩会继续裁减(级联退化,实测额外 cut≈0.30,round-trip 已确认)。累积场景必须对原始累积文本全量重压缩,禁止对上次压缩产物再压缩。
- token 为估算值:按字符与 CJK 启发式估算,不是特定模型的 BPE 计数;
--max-tokens/预算按「启发式 × 安全系数」取保守上界(宁高估勿超预算)。 - 单机本地工具:记忆库是本地目录,不是多租户服务或分布式数据库。
- 非安全边界:
--store的脱敏不能替代 DLP、凭据扫描或人工审查。 - 输入有上限:CLI 单次输入总计 64 MiB;更大的输入需要分段。
- pre-1.0 状态:当前版本
0.11.0,CLI、case schema 和评估接口仍可能演进;生产集成应固定 commit。
欢迎聚焦的 bug 修复、测试、文档和可复现的性能改进。提交前请阅读 CONTRIBUTING.md。
export CARGO_TARGET_DIR="${TMPDIR:-/tmp}/scx-cargo-target"
cargo fmt -- --check
cargo clippy --locked --all-targets -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps
cargo test --locked
cargo build --release --lockedmain 受分支保护:常规变更需要 PR、通过的 CI 和维护者评审,直接推送会被拒绝;管理员绕过只用于仓库恢复。不要把真实凭据、客户数据或未公开事故材料放入 issue、日志或测试夹具。
安全漏洞请使用 GitHub 私密漏洞报告,不要先开公开 issue。边界说明见 SECURITY.md。
Licensed under either of Apache License, Version 2.0 or MIT license at your option. © scx contributors