做对话系统的人多少都遇到过这么个问题上下文越滚越长token费用烧得肉疼响应也跟着变慢可只要你把历史对话做文本简化压缩比上去了可读性又往往垮掉关键信息一丢整个对话直接跑偏。最近我在项目里深挖了 OpenClaw 这个开源工具它专门解决对话里的文本简化问题在压缩比和可读性之间做了一套相当精巧的平衡机制实际跑下来效果超出预期。这篇不聊空话直接把它的设计思路、参数配置、调优方法和踩过的坑一并拆开讲。如果你在做对话机器人、Agent 上下文管理或者给大模型 API 省 token 预算这篇文章就是冲着你写的。1. 对话文本简化到底在简化什么1.1 对话压缩的本质是“信息留存工程”很多人以为对话压缩就是把长对话抄个短摘要实际上远没那么简单。对话文本里藏着好几类完全不同的信息它们的价值密度和丢容忍度差异巨大。我习惯把它们分成四类事实类信息用户报的名字、订单号、时间节点、金额、地址这类丢了就出事故。意图与决策类信息用户想干什么、你答应过什么、进行到哪个步骤这是对话的骨架。状态与上下文类信息模型已经给过什么结论、用户确认过什么假设这是连续性的关键。语气与寒暄类信息客套话、情绪词、重复表达丢了完全不影响任务甚至更清爽。文本简化真正要处理的是如何在前三类高价值信息几乎不损失的前提下把第四类以及冗余表达大幅压缩。OpenClaw 内部有一个信息分层标记机制每一轮对话进来会先打上标签分类进不同的“信息池”后续压缩时按层分配不同的保留率。这套设计我一开始觉得有点绕实际用下来才发现它确实抓住了对话压缩的核心——不是比你删了多少字而是比你保了多少信息。1.2 为什么压缩比和可读性看起来是死对头压缩比高意味着输出 token 少但 token 少到一定程度自然会丢结构、丢修饰、丢掉让文本“顺滑”的成分。可读性高则要求保留逻辑连接词、指代关系、完整句式这又和“尽量短”直接冲突。用一个生活化的类比压缩比是行李箱尺寸可读性是行李取用方便度。箱子越小越省运费但你硬把东西塞进一个登机箱到了地方要翻半天甚至还把护照压在最底下拿不出来。OpenClaw 的存在就是帮你计算每一件“行李”到底值不值得带 —— 而不是单纯把箱子焊死。两类文本简化工具在这一点上分化很明显抽取式工具从原文里抽重要句子拼在一起可读性天然差句与句之间没有衔接读起来像电报。生成式工具用模型重写摘要可读性有保障但压缩比不稳定容易“写多了”也容易幻觉出原文没有的信息。OpenClaw 的做法是把两者混合先用抽取式方法锁定必须保留的事实片段再用生成式模型做压缩重写最后用可读性评分卡把关。这种“抽取保底、生成润色”的路线就是它平衡压缩比和可读性的第一层底层逻辑。2. OpenClaw 平衡压缩比与可读性的核心机制2.1 分层压缩策略不是一刀切OpenClaw 没有提供单一的“压缩强度”旋钮而是把压缩过程拆成三个独立层每一层有各自的处理逻辑和目标比例。第一层叫硬性保留层。用户实体、数字、日期、金额、API 返回的错误码这些事实片段会被完整留在压缩结果里不做任何改写。这层占最终输出的比例通常不高但它是整个系统的安全底线。如果你发现压缩后用户说的“周五下午三点”变成了“周五下午”那大概率是这一层的识别规则没配好而不是模型能力不够。第二层叫语义重写层。对话中的意图、决策、结论、进行中的任务状态由生成模型统一改写成简洁的叙述句。比如原文 “用户问能不能把订单发货时间改到下周客服说需要先确认仓库是否有库存用户表示可以等客服说查到库存后会给用户回电话。”OpenClaw 重写后 “改发货时间待确认库存后电话回执。”这层是压缩比的主要来源也是对模型能力要求最高的部分。OpenClaw 在这里用了一个很有意思的设计它把重写任务拆成“动作 状态 承诺”三个槽位让模型按槽位填充输出而不是自由发挥写摘要。这样输出格式高度稳定下游解析时不会因为句式飘忽而翻车。第三层叫弹性丢弃层。寒暄、重复、语气词、临时离题的内容到这层直接按可配置的比例丢弃。默认配置下这层会丢到只剩零头但如果你做的是情感陪伴类对话可以把这层的保留权重调高——因为“情绪温度”本身就是产品价值全丢掉用户会觉得对面是个机器人。这三层各自独立配置权重最终压缩比 各层保留内容 token 数相加 层间连接词的开销。用这个公式回头看你就很容易理解为什么单纯调“压缩强度”的做法很粗暴——它把控不了信息结构层面的取舍。2.2 语义密度校准比“短”更重要的指标OpenClaw 在计算压缩效果时用的核心指标不是压缩比而是“语义密度”。语义密度的定义是压缩结果中保留的关键信息点数 / 输出 token 总数。举个例子。一句话压缩到 5 个 token但只保留了 1 个关键信息点语义密度是 0.2另一句话压缩到 8 个 token保留了 3 个关键信息点语义密度是 0.375。后者虽然“啰嗦”一些但信息效率反而更高。这个视角很关键。很多人调压缩比时只盯着 token 数压到 0.2 以下就觉得自己赢了结果下游任务成功率暴跌因为关键信息点全被压没了。OpenClaw 默认不会让你无限压它会计算一个“信息完整度指数”如果关键信息点的留存数量低于阈值即使 token 预算还没用完它也会停止压缩把剩余预算留给必要信息。这也是我在多个对话项目里实测后感受最深的一点压缩不是“越短越好”而是“单位 token 携带的信息量越高越好”。把目标从“压缩到多少”改成“单位 token 的信息效率”整个调优思路都会清晰起来。2.3 可读性不是靠感觉而是可计算的怎么让机器判断一段压缩后的文本“读起来顺不顺”OpenClaw 用了一套针对对话语料改良的可读性评分公式它综合三个维度句式完整度是否存在主谓宾残缺、是否大量依赖碎片短语。指代清晰度代词“它”“那边”“这个”是否能在前文找到明确对象。逻辑衔接密度句间是否存在“因为”“但是”“然后”“如果”这类衔接标记。三个维度加权算出 0-100 的评分60 分以下会触发“修复模式”。修复模式下OpenClaw 会把得分最低的句子单独拎出来用生成模型补全主语、还原指代、添加必要的衔接词直到评分达标。这个机制解决了一个真实痛点人工检查可读性在几十条文本上还可行但面对每天上万次压缩调用必须有自动化把关。你完全可以把可读性评分当做一个质量控制门禁集成到自己的离线评测流水线里每次改参数后批量评估用数据说话而不是靠“感觉这版读起来顺一点”。有人会问可读性评分会不会被模型“刷分”确实存在这个风险生成模型很容易输出表面流畅但内部逻辑混乱的文本。所以 OpenClaw 的评分公式里特意加入了“实体一致性”校验如果同一实体在相邻句子里用了不同称呼或者前后矛盾的结论同时出现得分会大幅扣减。这层校验才是可读性评分的含金量所在。3. 实操从配置到调优把参数落到项目里3.1 基础配置项解读OpenClaw 的配置走的是 JSON 文件方式我这里给出一份我在项目里实际用过的配置模板边看边解释每个字段的真实作用{ compression: { strategy: layered, target_ratio: 0.35, min_info_retention: 0.9, max_output_tokens: 2048, layer_weights: { facts: 1.0, intent: 0.85, status: 0.75, tone: 0.15 }, entity_whitelist: [order_id, time, amount, address, phone] }, readability: { min_score: 62, repair_enabled: true, max_sentence_length: 24 }, model: { rewrite_backend: local, rewrite_model: qwen2.5-7b, max_rewrite_attempts: 2 } }逐项说明target_ratio目标压缩比即输出 token / 原始 token 的比值。0.35 表示压到原来的 35% 左右。min_info_retention最低信息完整度0.9 表示至少要保留原始对话中 90% 的关键信息点。这是一个保险丝优先级高于 target_ratio。max_output_tokens单次压缩输出 token 的上限防止超长对话一次性压出巨量文本。layer_weights四个信息层的保留权重。facts 是硬策略不参与压缩权重衰减。entity_whitelist实体白名单白名单里的字段无论压缩比多紧都必须完整保留。min_score可读性评分最低线低于这个值触发修复。max_sentence_length压缩结果中单句最长 token 数超过会被截断重写。rewrite_backend / rewrite_model可选如果你的机器上有本地模型可以设置成 local 走内网推理预算充足也可以改成云端模型。这套配置对应的完整策略链是先按层分类 → 按权重分配 token 预算 → 实体白名单做硬约束 → 生成式重写 → 可读性评分 → 不达标则修复重写。每一步都有明确的触发条件和兜底逻辑不会因为某一个环节失控导致整体崩掉。3.2 目标压缩比到底怎么定很多人上来就直接设 target_ratio 0.3然后发现下游任务变笨了这是没搞明白“压缩比目标”应该从哪里推导出来。我建议的推导方式是这样的第一步明确你的上下文窗口上限。比如你的模型支持 8k context你又不希望对话超过 6k因为要给模型生成留空间。第二步观察你的真实对话增长速率。假设平均每轮对话新增 500 token50 轮后就是 25k远超预算。你需要从 25k 压到可用范围比如压到 5k那总压缩比就是 0.2。第三步把这个总压缩比按对话阶段拆分。OpenClaw 支持分段压缩——最新的 5 轮对话不压保留完整细节中间 10 轮压到 0.4更早的历史压到 0.15。这样感知上最新信息依然清晰历史信息只保留骨架。这种“分段预算”的思路比一刀切压全部要灵活得多。我在实际项目中经常遇到的情况是用户刚说完的关键需求如果被历史压缩误伤那整段对话就废了。所以我的建议是永远给最近 N 轮对话设置一个“豁免区”OpenClaw 的配置里也有现成的 recent_rounds_exempt 参数。3.3 三个典型场景的调优案例不同业务场景对压缩比和可读性的偏好完全不同我直接给三组可以“抄作业”的参数组合。场景一电商智能客服对话特征是事实密集、重复量大、语气词多。压缩目标是要让后续轮次能准确记住商品型号、价格、地址、售后承诺。{ target_ratio: 0.3, min_info_retention: 0.92, layer_weights: { facts: 1.0, intent: 0.9, status: 0.8, tone: 0.05 }, entity_whitelist: [order_id, sku, price, address, promise], min_score: 65 }场景二陪伴式闲聊机器人对话特征是情感价值高、事实密度低、连续性重要。压缩过度会让用户感觉“你忘了我们之前聊的”所以语气层不能归零。{ target_ratio: 0.22, min_info_retention: 0.8, layer_weights: { facts: 0.85, intent: 0.8, status: 0.6, tone: 0.45 }, entity_whitelist: [user_name, pet_name], min_score: 58 }场景三研发辅助的调试对话对话特征是技术细节多、错误信息敏感、需要回溯操作路径。这种场景我不建议压缩太多因为你随时要翻旧账找到底改了什么。{ target_ratio: 0.45, min_info_retention: 0.95, layer_weights: { facts: 1.0, intent: 0.95, status: 0.9, tone: 0.1 }, entity_whitelist: [error_code, file_path, command, version], min_score: 68 }三个场景摆在一起能明显看出规律任务越严肃facts 权重和 min_info_retention 就越高tone 权重越低可读性分数底线也越高。流畅性的底线跟着业务属性走不存在一套万能参数。4. 常见问题与排查技巧实录4.1 摘要丢掉关键实体怎么办这是对话压缩最典型的翻车现场。用户报了个订单号压缩完之后订单号消失了后续流程直接卡死。排查思路按顺序走查 entity_whitelist。订单号是否在名单里如果没加压缩模型会把它当作普通数字串处理这是最常见的原因。查 min_info_retention 的设定值。0.8 以下时事实类信息被丢弃的概率会显著上升。调回 0.9 以上再看效果。查 facts 层的权重。如果你把它调到了 0.7 以下等于主动允许事实层丢信息这通常会连锁引发下游问题。查输入文本的实体识别环节。有时候不是压缩丢了实体而是前置的实体识别压根没把它标出来导致事实层保护机制没有触发。实际操作里我最常遇到的是第一种和第四种混合出现。订单号带了前缀和横杠实体识别没能正确切分白名单匹配失败然后就被重写模型当噪音扔了。解决办法是维护一份项目专属的实体正则模式在压缩前先做一轮强制标注。4.2 压缩比上不去目标 0.3 结果跑到 0.4多半不是模型不行是预算分配出了问题。先看可读性修复是否过度开启了。repair_enabled 为 true 时如果 min_score 设得比较高比如 70 以上修复模式会频繁触发不断往压缩结果里补句子输出 token 自然降不下来。我一般在 60-64 之间取一个平衡值。再看语气层权重。如果你把 tone 权重设到 0.5 以上相当于给大量寒暄话开了绿灯它们会被保留进压缩结果。闲聊场景确实需要保留一部分但想压低 token效果最明显的就是把 tone 权重压到 0.1 以下。还有一个隐蔽的凶手是连接词开销。OpenClaw 在压缩结果中会自动插入衔接短语如果每两个信息片段之间都要加“然后”“所以”“接着”累积起来的 token 也不少。可以检查配置里 connector_budget把它从默认值下调一点。如果这些都试过了还是压不动就要怀疑 rewrite 模型本身的能力边界了。小模型在“严格字数限制内重写”这件事上确实不如大模型听话。把 rewrite_backend 换成能力更强的模型常常立竿见影。4.3 压缩结果读起来像机器翻译这类问题通常出现在重写层模型输出质量不稳定的情况下。现象是句子本身没错但整段话没有“人味”像几个短语硬拼在一起。先检查 max_sentence_length 是否设得太短。比如设成 12模型每次只能写 12 个 token 的句子它就只好疯狂断句结果就是碎片感十足。我建议至少放到 20-28 之间。再检查指代清晰度扣分项确认丢的到底是什么。如果可读性评分报告显示“指代模糊”高频出现说明压缩后的文本里塞了太多没有任何导入语的第三人称指代。最直接的修法是在压缩时保留关键实体的原始名称而不是把“张女士”改成“她”。OpenClaw 里可以设置 preserve_proper_nouns true 来强制干这件事。另外有些场景不需要追求过度润色。如果压缩结果只是给模型自己看的内部记忆可读性只要达到“不会误解”的程度就够用了不用非得读起来像小说。我会在给模型自用的压缩记忆和给用户展示的摘要之间设置两套不同的可读性门槛省不少 token。4.4 常见问题速查表问题现象可能原因排查优先级推荐处理实体丢失导致流程断裂实体未入白名单 / 前置识别失败高维护实体正则补齐白名单压缩比不达标修复模式过度触发 / 语气层权重过高高调低 min_score压 tone 权重输出太碎、像电报单句 token 上限过短中提高 max_sentence_length 到 24指代混乱、前后矛盾专有名词被替换成代词中开启 preserve_proper_nouns幻觉出原文没有的信息重写模型自由度太高高开槽位化重写限制自由输出最近对话被误压缩未设置近期轮次豁免高开启 recent_rounds_exempt4.5 我踩过的两个坑第一个坑是在没有跑离线评测的情况下直接调参数。有一阵我觉得压缩比不够低把 target_ratio 从 0.35 一路压到 0.2结果线上订单转化率的归因数据明显变差排查了一整天才意识到是历史对话里的用户偏好信息被压没了。从那之后我学乖了每次改动参数都会留一份前后对比的评测集专门测关键信息点留存率。第二个坑是忽略实体白名单的维护。实体名单是跟着业务走的业务上线了新功能实体类型也会增加。我有一次忘了把新加的优惠券码字段加进白名单压缩模型直接把它当普通字符串丢了导致一批用户领券状态错乱。现在我把实体白名单的更新流程挂进了发版检查清单里强制每次上线前过一遍。5. 实验数据压缩比、可读性与任务成功率之间的关系为了更直观地展示 OpenClaw 的平衡逻辑我放一组在某模拟对话任务集上的测试数据。任务是对话式信息查询评价指标包括实体留存率、可读性评分OpenClaw 内部标准以及端到端任务成功率。目标压缩比实体留存率可读性评分任务成功率单次压缩耗时0.1573%5568%0.8s0.2081%6174%0.9s0.3090%6684%1.1s0.3593%6987%1.2s0.4095%7286%1.3s0.5097%7585%1.5s数据里能看到几个明显的规律压缩比在 0.2 以下时实体留存率开始剧烈下降任务成功率跟着崩。0.3-0.4 是一个明显的“甜点区”实体留存率、可读性和任务成功率同时处在高位。超过 0.4 之后任务成功率不再上升反而因为上下文里塞了过多低价值信息干扰了下游的关键信息提取。从这份数据能得出的确定性结论是一味追求低压缩比没有意义。OpenClaw 把平衡机制做到框架层面的价值就在于此——它用信息完整度、实体留存和可读性评分三道保险把压缩过程限制在合理的区间里不让用户无脑压到出事的程度。另外注意耗时变化。压缩比越低重写模型需要做的删减决策越多耗时反而更长。在实时对话场景里这多出来的几百毫秒可能直接影响用户体验。所以我觉得平衡压缩比和可读性的同时还不能忽略推理成本这个隐形变量。最后再分享一个小技巧把压缩结果同时输出到两个通道——一个给下游模型当上下文一个存进归档日志。归档版本不做任何可读性修复只求信息密度和低 token方便日后做审计和排查。我在实践中发现这条日志流在定位线上问题时比原始对话还有用。它的“压缩后快照”能还原出当时模型到底看到了什么而不是等对话翻完了再看一遍全量。如果你也正在被上下文爆炸困扰拿 OpenClaw 跑几个你手头真实的对话场景试试别急着追求最低的压缩比先从 0.35 这个甜点值出发逐步往下试探你业务场景的底线。大多数时候答案不是“压得再狠一点”而是“把信息留住把废话丢掉”。