
Headroom 文本压缩工具指南搜索结果、构建日志与长文本的显式压缩实践【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom在 Headroom 中JSON 工具输出由 SmartCrusher 自动处理而搜索结果、构建日志和长文档这类有损、依赖上下文的文本压缩则通过一组显式调用opt-in的独立工具提供给应用层SearchCompressor、LogCompressor、文本压缩器以及内容类型检测detect_content_type。本文基于 wiki/text-compression.md 的完整骨架展开并结合当前仓库中 headroom/transforms 的 Python 接口、crates/headroom-core 的 Rust 内核实现与配套测试讲清每个压缩器的调用方式、保留策略、配置参数、内容类型路由与选型建议。读完你可以把这些压缩器直接嵌入自己的 Agent 或工具调用链路在可控前提下显著减少送入 LLM 的 token 量。设计哲学为什么文本压缩是 opt-in原文档给出了明确的设计取舍SmartCrusher 之所以可以自动压缩 JSON是因为它保结构、安全而文本压缩是有损且依赖上下文的丢弃不相关行/句子是否压缩、何时压缩应该由应用自行决定。SmartCrusher - JSON结构保持自动应用 文本压缩工具 - 有损/上下文相关应用显式调用完全可控从源码结构看这一定位贯穿了实现三个压缩器的compress()方法只在被显式调用时才工作而仓库中统一的内容路由入口 ContentRouter 也是先做类型检测、再分派到对应压缩器ContentRouter._get_search_compressor等调用点在 headroom/transforms/search_compressor.py 的模块文档中被明确提及。可用工具一览原文档的工具总览表输入类型与适用场景工具输入类型使用场景SearchCompressorgrep/ripgrep 输出file:line:content格式的搜索结果LogCompressor构建/测试日志pytest、npm、cargo、make 输出TextCompressor通用文本任意带锚点保留的纯文本detect_content_type任意内容内容类型检测用于路由决策对应源码位置headroom/transforms/search_compressor.pyheadroom/transforms/log_compressor.pyheadroom/transforms/text_crusher.py文本压缩的当前实现详见下文headroom/transforms/content_detector.py这些符号均从 headroom/transforms/init.py 以懒加载方式导出_LAZY_EXPORTS 模块级__getattr__即from headroom.transforms import SearchCompressor这类导入会按需加载具体子模块避免导入 SDK 时的重依赖成本。SearchCompressor压缩 grep/ripgrep 搜索结果SearchCompressor压缩搜索输出grep、ripgrep、ag同时保留真正相关的匹配行。原文档的标准用法from headroom.transforms import SearchCompressor # 你的 grep/ripgrep 输出可能上千行 search_results src/utils.py:42:def process_data(items): src/utils.py:43: \\\Process items.\\\ src/models.py:15:class DataProcessor: src/models.py:89: def process(self, items): ... 还有数百行匹配 ... # 在你判断合适的时机显式压缩 compressor SearchCompressor() result compressor.compress(search_results, contextfind process) print(fCompressed {result.original_match_count} matches to {result.compressed_match_count}) print(result.compressed)保留策略What Gets Preserved原文档列出四类必保内容精确查询命中包含搜索词的行高相关命中按与context的相似度打分BM25文件多样性保证不同文件都有结果被保留首/末命中保留结果集开头与结尾的上下文源码级实现Rust 内核与解析边界当前 SearchCompressor 是薄 Python 封装shimcompress()完全委托给 crates/headroom-core/src/transforms/search_compressor.rs 的 Rust 实现Phase 3e.2 移植Python 侧保留SearchMatch、FileMatches、SearchCompressorConfig、SearchCompressionResult等公共 dataclass 面。模块文档headroom/transforms/search_compressor.py列出了 Rust 移植带来的关键 bug 修复这些正是文件多样性、首末命中等保留策略在真实场景中的边界处理Windows 路径旧正则把盘符冒号C:\Users\…误当作行号分隔符导致 Windows 格式行被静默丢弃Rust 解析器识别盘符前缀后从其后开始扫描行号。文件名含-旧_RG_CONTEXT_PATTERN用[^:-]排除了路径中的连字符pre-commit-config.yaml-42-line这类名字会被解析错Rust 解析器改为锚定行号标记行内最早的sep\dsep。CJK 查询无空格中文查询无法按词切分Python 侧通过_cjk_bigrams()生成字符二元组参与打分headroom/transforms/search_compressor.py与 Rustcjk_bigrams保持码位区间一致相关行为由 tests/test_search_compressor_cjk.py 固定。打分逻辑在 Python 侧的_score_matches中可直接读到与 Rust 常量逐字对齐headroom/transforms/search_compressor.py上下文词长度 2 的去重词 CJK bigram每命中一个0.3错误信号PRIORITY_PATTERNS_SEARCH优先级模式首个命中0.5之后每降一级-0.1每行最多一次错误加成配置项context_keywords中每个词命中0.4分数上限 1.0。选择阶段则先用 headroom/transforms/adaptive_sizer.py 的compute_optimal_k()在[5, max_total_matches]内自适应地确定总保留条数bias参数可偏移该值再按文件总分排序 → 每文件保留首/末命中 高分命中 → 按行号排序输出的流程选取最后为每个被截断的文件追加[... and N more matches in file]摘要行。配置参数原文档给出的配置示例表达各参数的意图from headroom.transforms import SearchCompressor, SearchCompressorConfig config SearchCompressorConfig( max_results50, # 最多保留 50 条匹配 preserve_file_diversityTrue, # 确保不同文件都有代表 relevance_threshold0.3, # 保留所需的最低相关分 ) compressor SearchCompressor(config)需要说明的是当前仓库中SearchCompressorConfig的实际字段见 headroom/transforms/search_compressor.py写作可运行代码时应以这些字段为准字段默认值含义max_matches_per_file5每个文件最多保留的匹配条数always_keep_firstTrue每文件保留首个命中always_keep_lastTrue每文件保留末个命中max_total_matches30全局匹配总数上限自适应 k 的上界max_files15参与输出的文件数上限context_keywords[]额外加权的关键词每个 0.4 分boost_errorsTrue对含错误信号的行加成enable_ccrTrue是否启用 CCR 可回取标记min_matches_for_ccr10触发 CCR 存储的最小匹配数group_by_fileFalserg --heading风格分组输出路径只输出一次proxy token 模式启用结果对象与 CCR 可回取SearchCompressionResultheadroom/transforms/search_compressor.py除compressed、original、匹配计数、files_affected、compression_ratio外还提供tokens_saved_estimate按 4 字符 ≈ 1 token 粗略估算的节省 token 数matches_omitted被省略的匹配数cache_key与summariesCCRCompressed Context Retrieval机制的产物。CCR 的工作方式值得单独说明当匹配数达到min_matches_for_ccr且压缩比达标min_compression_ratio_for_ccr固定 0.8时Rust 内核计算MD5(original)[:24]作为cache_key并嵌入压缩输出中的标记Python shim 再把原始内容写入生产CompressionStore_persist_to_python_ccrheadroom/transforms/search_compressor.py使被丢弃的行在后续轮次仍可通过标记回取而不是永久丢失。存储失败会以 warning 日志显式暴露不再静默吞掉。LogCompressor压缩构建与测试输出LogCompressor压缩构建/测试日志同时保留错误、警告与汇总行。原文档用法from headroom.transforms import LogCompressor # 上千行的 pytest 输出 build_output test session starts collected 500 items tests/test_foo.py::test_1 PASSED ... 数百个通过的测试 ... tests/test_bar.py::test_fail FAILED AssertionError: expected 5, got 3 1 failed, 499 passed # 压缩日志保留错误与堆栈 compressor LogCompressor() result compressor.compress(build_output) # 错误、堆栈与汇总行被保留 print(result.compressed) print(fCompression ratio: {result.compression_ratio:.1%})保留策略What Gets Preserved错误与失败含 ERROR、FAILED、Exception 等的行警告可能重要的 Warning 消息堆栈跟踪完整的 traceback 便于调试汇总行测试/构建 summary章节头之类的结构标记源码级实现多语言堆栈识别与帧折叠LogCompressor 同样是 Rust 薄封装compress()委托给 crates/headroom-core/src/transforms/log_compressor.rsPhase 3e.5 移植检测的日志格式覆盖pytest、npm、cargo、make、jest与genericLogFormat枚举headroom/transforms/log_compressor.py。移植文档headroom/transforms/log_compressor.py记录了几个影响保留质量的关键修复堆栈跟踪状态机旧实现遇到任何空行就终止堆栈捕获会丢掉链式异常Caused by续接中间的帧Rust 版本按语言风味Python / Rust panic / Go goroutine dump / .NET / Java分派空行可留在 Python traceback 内部。保守去重旧版本全局归一化数字/路径/十六进制会把尾部变量形状相同但消息不同的错误类别折叠到一起Rust 版只在第一个:/之后归一化尾部区域消息标识符保持区分Python 镜像实现见_dedupe_similarheadroom/transforms/log_compressor.py。行分类与打分规则Python 镜像与 Rust 分类规则一致headroom/transforms/log_compressor.py级别识别ERROR/FAIL基础分 1.0WARN0.5INFO0.1DEBUG0.05TRACE0.02堆栈行0.3汇总行0.4上限 1.0堆栈模式覆盖 PythonTraceback、JS/Javaat …(file:line:col)、Rust-- file:line:col与 panic backtrace、Gopanic:/goroutine、.NETUnhandled exception、JavaCaused by:与... N more等完整模式清单见_parse_lines汇总模式识别/---分隔线、N passed/failed/skipped、Tests: N、TOTAL/Summary、Build … succeeded/failed等。选择算法_select_lines的流程按级别分桶 → 错误/失败各取首末 高分行_select_with_first_last→ 警告去重后取前max_warnings条 → 最多max_stack_traces段堆栈、每段最多stack_trace_max_lines行 → 汇总行 → 为选中行补充error_context_lines上下文 → 若超限按分数裁剪并恢复行号顺序。LogCompressorConfig的完整默认值headroom/transforms/log_compressor.py字段默认值含义max_errors10保留的错误/失败行数上限error_context_lines3每个选中行的前后上下文行数keep_first_error/keep_last_errorTrue保留首个/末个错误max_stack_traces3保留的堆栈段数上限stack_trace_max_lines20单段堆栈的最大行数max_warnings5保留的警告行数上限dedupe_warningsTrue对警告做保守去重keep_summary_linesTrue保留汇总行max_total_lines100总行数上限自适应 k 上界enable_ccr/min_lines_for_ccrTrue/50CCR 开关与触发最小行数collapse_runtime_framesTrue超长长堆栈时折叠运行时/标准库帧trace_head_frames/trace_app_frames3/5帧折叠时保留的头部帧与应用帧数结果对象LogCompressionResult提供original_line_count、compressed_line_count、format_detected识别出的日志格式、compression_ratio、tokens_saved_estimate、lines_omitted与stats各级别计数输出尾部会以[N lines omitted: x ERROR, y FAIL, z WARN, w INFO]形式告知省略构成。堆栈同样支持 CCR 回取min_compression_ratio_for_ccr固定 0.5触发条件比搜索压缩更宽松。相关回归测试见 tests/test_log_compressor.py。TextCompressor带锚点保留的通用文本压缩原文档的通用文本用法from headroom.transforms import TextCompressor long_text ... 数千行文档 ... compressor TextCompressor() result compressor.compress(long_text, contextauthentication) print(result.compressed)其保留策略为按与context的相似度打分保留相关段落、保留锚点标题、章节标记、关键关键词、维持文档组织结构。当前实现Rust 抽取式 TextCrusher在今天的仓库中这一锚点保留的通用文本压缩角色由 headroom/transforms/text_crusher.py 的TextCrusher承担它是 headroom/_core即crates/headroom-core原生TextCrusher的 Python 封装抽取式extractive——保留的句子是原文逐字片段仅裁剪空白后以换行重新连接只选择、不改写。模块文档明确其定位对大型纯文本它是 kompressModernBERT 语义压缩在请求路径上的毫秒级替代方案且复用与 SmartCrusher 相同的 BM25 相关度评分器而不是各自实现一套。TextCrusherConfigheadroom/transforms/text_crusher.py字段默认值含义target_ratio0.5目标压缩比保留比例w_recency1.0句子评分中位置/新鲜度权重w_relevance2.0与 context 的相关度权重最高w_salience1.5显著度权重min_segment_chars12参与选择的最小片段长度near_dup_threshold0.85词 shingle 近似去重阈值min_segments_for_crush6片段数不足时不压缩小文本原样通过compress(content, context, target_ratioNone)返回 Rust 结果对象含compressed、original_tokens、compressed_tokens、compression_ratio、kept_segments、total_segments。共享的 BM25 评分器实现在 crates/headroom-core/src/relevance/bm25.rs零 ML 依赖的纯 Rust 分词UUID 优先、4 位以上数字 ID、字母数字默认k11.5、b0.75原始分按max_score默认 10.0归一到 [0,1]含 8 长度 token 的命中额外 0.3UUID、长 ID 是高信号匹配。锚点保留这一设计在 JSON 路径上由 headroom/transforms/anchor_selector.py 的AnchorSelector以策略权重FRONT_HEAVY/BACK_HEAVY/BALANCED/DISTRIBUTED显式建模文本路径的段落选择则通过w_relevance主导的相关度打分达成同等目标。路由层 ContentRouter 在文本超过体积门限时会走 TextCrusher 快速通道懒加载见其_get_text_crusher附近实现。回归测试见 tests/test_text_compressors.py。内容类型检测detect_content_type原文档示例——先检测、再路由from headroom.transforms import detect_content_type, ContentType content src/main.py:42:def process(): detection detect_content_type(content) if detection.content_type ContentType.SEARCH_RESULTS: # 路由到 SearchCompressor pass elif detection.content_type ContentType.BUILD_OUTPUT: # 路由到 LogCompressor pass elif detection.content_type ContentType.PLAIN_TEXT: # 路由到 TextCompressor pass原文档的简化类型表类型检测模式SEARCH_RESULTSfile:line:content格式BUILD_OUTPUTpytest、npm、cargo 标记JSON有效 JSON 结构PLAIN_TEXT默认回退当前实现的完整类型集与优先级ContentType 枚举 实际包含 9 类JSON_ARRAY、SOURCE_CODE、SEARCH_RESULTS、BUILD_OUTPUT、GIT_DIFF、HTML、TABULAR、STRUCTURED_CONFIG、PLAIN_TEXT。detect_content_type() 按以下优先级与置信度阈值依次检测返回DetectionResult(content_type, confidence, metadata)JSON最高优先靠解析而非表面模式识别支持包裹 JSON 的负载解码出的 JSON 须占内容 ≥60%与 web_search 常见的空格分隔连续 JSON 对象normalize_concatenated_json可将其改写为真正的数组供 SmartCrusher 处理裸标量不算结构化数据。Git diff置信度 ≥0.7识别diff --git、diff --combined/--cc、--- a/、与 combined-diff头扫描窗口 500 行以容纳长 commit 消息。HTML≥0.7!doctype/html/head/body与结构标签计数——HTML 需要的是内容抽取而非 token 压缩。搜索结果≥0.6前 100 行中 ≥30% 非空行匹配path:line:形状且至少 2 行命中冒号前段不得含、、防止把 ISO 时间戳、XML 包装器误判为 grep 输出——因为 SearchCompressor 只保留匹配行误判即数据丢失。构建/日志≥0.524 条日志模式级别关键词、时间戳、PASSED/FAILED/SKIPPED、npm ERR!/cargo error、各语言堆栈头前 200 行占比 ≥10%。表格≥0.6Markdown 表头分隔行置信度 0.95优先其次按,/\t/;/|的列数一致性判 CSV/TSV并带散文防护。结构化配置≥0.6TOML/INI 用标准库解析器确认tomllib/configparser消歧[section]形态YAML 走启发式键行 ≥3、占比 ≥0.6、带缩进/文档标记/列表等结构信号并有散文与 front-matter 防护。源码≥0.5按 Python/JS/TS/Go/Rust/Java/C#/PHP 的模式计分最佳语言需 ≥3 次命中metadata.language给出识别语言。回退PLAIN_TEXT置信度 0.5。metadata字段携带类型特定的决策信息如搜索的matching_lines/total_lines、JSON 的item_count/is_dict_array、diff 的header_matches/change_lines可直接用于你自己的路由策略。集成模式应用层显式路由原文档给出的完整集成模板detect → 分派 → JSON 交给 SmartCrusherfrom headroom.transforms import ( detect_content_type, ContentType, SearchCompressor, LogCompressor, TextCompressor, ) def compress_tool_output(content: str, context: str ) - str: 应用层显式控制的压缩。 detection detect_content_type(content) if detection.content_type ContentType.SEARCH_RESULTS: result SearchCompressor().compress(content, context) return result.compressed elif detection.content_type ContentType.BUILD_OUTPUT: result LogCompressor().compress(content) return result.compressed elif detection.content_type ContentType.PLAIN_TEXT: result TextCompressor().compress(content, context) return result.compressed else: # JSON 或其他 —— 交给 SmartCrusher 自动处理 return content两点补充说明帮助你把该模板落到当前代码库模板中未知内容原样返回、交给 SmartCrusher的分支与检测器的第一优先级一致——JSON_ARRAY永远不会掉进PLAIN_TEXT回退。当前仓库中等价路由的生产实现就是 ContentRouter它按detection.content_type分派到 Search/Log/Text/Diff/Tabular/Config 等策略模板可视为其最小手工版。LogCompressor.compress()的签名保留了context参数以兼容旧调用面但当前实现并不使用该参数headroom/transforms/log_compressor.py 中有del context并注明原因日志压缩的上下文完全来自行内级别与结构识别。性能特征原文档给出的典型性能数据以当前仓库为参考基线压缩器典型输入输出速度SearchCompressor1000 条匹配30–50 条匹配~2msLogCompressor5000 行100–200 行~3msTextCompressor10000 字符2000 字符~2ms这些毫秒级数字的前提是主压缩路径全部在 Rust 内核crates/headroom-core中执行Python 侧只做参数映射与结果包装文本路径的 TextCrusher 也明确以毫秒级而非分钟级作为与语义压缩kompress的分工边界。保留总量由自适应 sizingcompute_optimal_kbias可调在配置上下界之间动态确定而不是死板取上限——输入越稀重复度高、方差低保留条数越保守。选型建议When to Use原文档的选型表完整保留场景建议JSON 工具输出交给 SmartCrusher 自动处理grep/ripgrep 结果用 SearchCompressorpytest/npm/cargo 输出用 LogCompressor文档/README用 TextCompressor未知内容用 detect_content_type 路由延伸阅读源码与测试索引Python 接口层headroom/transforms/search_compressor.py、headroom/transforms/log_compressor.py、headroom/transforms/content_detector.py、headroom/transforms/text_crusher.py、headroom/transforms/anchor_selector.py、headroom/transforms/adaptive_sizer.py、headroom/transforms/content_router.pyRust 内核crates/headroom-core/src/transforms/search_compressor.rs、crates/headroom-core/src/transforms/log_compressor.rs、crates/headroom-core/src/relevance/bm25.rs回归测试tests/test_search_compressor.py、tests/test_search_compressor_cjk.py、tests/test_log_compressor.py、tests/test_text_compressors.py适用前提提醒SearchCompressor/LogCompressor/TextCrusher均为硬导入 Rust 扩展无静默降级——wheel 缺失时直接报错需用scripts/build_rust_extension.sh构建或安装预编译 wheelCCR 回取能力依赖进程内CompressionStore可用。以上即 Headroom 文本压缩工具的完整能力面显式调用、可配置阈值、多语言堆栈感知、内容类型路由与毫秒级 Rust 性能覆盖编码 Agent 中最常见的三类大文本工具输出。【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考