ClaWiser noise-reduction
git clone https://github.com/MattWenJun/ClaWiser
T=$(mktemp -d) && git clone --depth=1 https://github.com/MattWenJun/ClaWiser "$T" && mkdir -p ~/.claude/skills && cp -r "$T/assets/noise-reduction" ~/.claude/skills/mattwenjun-clawiser-noise-reduction && rm -rf "$T"
assets/noise-reduction/SKILL.mdNoise Reduction — 数据降噪
信号 = 用户与 agent 的对话(双方发言)。其他一切 = 管道噪声。 管道噪声包括工具调用、系统提示、metadata 注入、heartbeat 协议、JSON 输出、内部独白。
两层降噪架构
降噪在两个层面发生,顺序很重要——先用结构化信号在入口处拦截,再用文本模式匹配清理余量。
Layer 1:Merge 入口层(结构化过滤,内置)
merge 脚本在读取 session 文件时,利用
sessions.json 的结构化元数据做第一轮过滤:
- Session 类型过滤:cron 和 subagent 类型的 session 整个跳过。这些是自动化输出,不是人机对话。判断依据是
中每个 session 的sessions.json
/kind
字段。type - 消息元数据过滤:
消息(delivery-mirror
或model === 'delivery-mirror'
)被跳过。这些是内部投递确认,是 LLM 响应的副本。provider === 'openclaw' - 归档文件支持:
和.jsonl.deleted.*
文件也会被读取——这些是 compaction 和 /new 操作归档的对话数据,包含真实内容。.jsonl.reset.*
为什么在入口层做? 因为这些信号是结构化的(JSON 字段、文件名 pattern),100% 确定,零误杀风险。在数据进入文本分析之前就拦截,既减少了后续处理量,也避免了用文本 pattern 去猜测 session 类型的脆弱性。
Layer 2:文本模式匹配层(按环境配置)
经过 Layer 1 之后的数据仍然包含噪声——heartbeat、系统消息、工具输出、内部独白等。这些噪声的特征是文本层面的,需要 pattern matching 来识别。这就是本 skill 的核心工作:诊断你的环境有哪些噪声 pattern,编写对应的过滤规则。
判断标准: Layer 1 处理的是"这整个 session / 消息不该出现"(结构性排除),Layer 2 处理的是"这条消息的内容是噪声"(内容性过滤)。如果你发现某类噪声可以用结构化元数据 100% 确定,优先在 merge 脚本的入口层处理,而不是写文本 pattern。
前置条件
- 已执行
,有 merge 脚本和 transcripts 目录memory-deposit - 至少有 1 天的原始 session JSONL 数据
执行模式
默认分步执行。 每步独立运行,步间通过文件传递状态。
- Run 1: Step 1-2(读 references + 跑诊断脚本)→ 输出
(~2 分钟)memory/noise-profile-<date>.md - Run 2: Step 3(读噪声画像 + 写规则)→ 修改 merge 脚本(~4 分钟)
- Run 3: Step 4(跑验证脚本 + 判断)→ 输出验证结果(~2 分钟)
分步时不需要前序 session 的上下文——每步的输入和输出都是文件。
断点恢复
每步完成后写
memory/noise-reduction-state.json:
{ "version": "0.5.0", "startedAt": "2026-03-16T10:00:00Z", "targetDate": "2026-03-15", "completedSteps": [1, 2], "noiseProfilePath": "memory/noise-profile-2026-03-15.md", "mergeScriptBackup": true }
开始执行前先检查这个文件。 如果存在,从
completedSteps 的下一步继续,不要重头开始。
全部完成(Step 4 通过)后删除 state 文件。Step 4 不通过时,把
completedSteps 回退到 [1, 2],下次从 Step 3 重做。
超时自动处理
OpenClaw 默认每个 agent turn 限时 600 秒。如果单步执行超时被中断,state 文件保留了进度,下次触发时自动恢复。
如果某一步确实需要更长时间(如 Step 3 的 merge 脚本较复杂),可以用 gateway 工具临时调大超时:
gateway(action=config.patch, path="agents.defaults.timeoutSeconds", raw="900")
跑完后调回来:
gateway(action=config.patch, path="agents.defaults.timeoutSeconds", raw="600")
第 1 步:理解噪声分类
session 原始数据里的内容分两类:
| 保留 | 清掉 |
|---|---|
| 用户发言 | 系统消息(、Compaction、Queued announce) |
| agent 发言 | 协议噪声(heartbeat、cron prompt、) |
元数据注入(、、) | |
工具输出(JSON、文件路径、纯数字、) | |
内部独白(、) |
详细的噪声类型和识别特征见
references/noise-categories.md。
完成后更新 state 文件:
completedSteps: [1]。
第 2 步:诊断噪声环境
运行诊断脚本
node scripts/diagnose-noise.js <YYYY-MM-DD> --out memory/noise-profile-<date>.md
脚本自动完成:读取 session JSONL、采样全量 user+assistant 消息、按已知 pattern 分类、检测环境特征。输出一份结构化噪声画像。
⚠️ 脚本的分类是初步的(固定 pattern matching)。 读完输出后,根据你对环境的了解补充脚本可能遗漏的噪声类型。特别注意:
- 脚本标注了"⚠️ 需要注意"的项目——这些是需要特殊处理的环境特征
- 脚本无法识别上下文相关的噪声(如 cron prompt 后面的 assistant 回复),会在报告中提示
- 检查"消息样本"段落,确认分类是否合理
完成后更新 state 文件:
completedSteps: [1, 2],noiseProfilePath: "memory/noise-profile-<date>.md"。
第 3 步:编写降噪规则
在 merge 脚本里编写过滤逻辑。
规则设计原则
- 按 role 分流:user 和 assistant 的噪声模式不同,分开处理。⚠️ 分类器中的用户/agent 标识要匹配实际名字(从 USER.md 和 IDENTITY.md 读取),不要硬编码通用称谓
- 先处理量大的:从噪声画像占比最高的类别开始
- 保守过滤:不确定的消息默认保留。误保留的代价远小于误杀
- 标注 reason:每条规则标注过滤原因(如
)skip('heartbeat')
⚠️ 元数据包裹的特殊处理
渠道注入的元数据(如
RULE INJECTION、Conversation info)可能包裹着真实用户文本。不能整条丢弃——先剥离元数据,检查剩余内容是否为空,有内容则保留。
统计输出
在 merge 脚本末尾加统计,每次执行自动打印:
[noise-reduction] 原始: 847 条 | 保留: 412 条 | 压缩率: 48.6% [noise-reduction] skip 分布: heartbeat=89, cron_prompt=67, tool_json=134, ...
修改 merge 脚本前,先备份当前版本:
cp merge-daily-transcript.js merge-daily-transcript.js.bak。如果中途被中断,下次可以从备份恢复。
参考实现见
references/example-classifier.md。
完成后更新 state 文件:
completedSteps: [1, 2, 3],mergeScriptBackup: true。
第 4 步:验证降噪效果
运行验证脚本
node scripts/validate-noise-reduction.js <YYYY-MM-DD>
脚本自动完成:采集原始 user+assistant 消息、对比 transcript 产出、抽样、标注可疑项。输出一份结构化报告。
⚠️ 脚本只产出报告,不产出 pass/fail 判定。你来判断。
指标与目标
| 指标 | 定义 | 目标 |
|---|---|---|
| 压缩率 | user+assistant 消息中,被过滤条数 ÷ user+assistant 总条数 | 30%-60%(典型),60%-80%(高噪声环境可能正常) |
| 误杀率 | 被过滤消息中实际是对话的占比 | < 2% |
| 遗漏率 | 保留消息中实际是噪声的占比 | < 5% |
注意:压缩率只算 user 和 assistant 角色的消息。tool/system 等非对话角色由 merge 脚本的 role 过滤处理,不计入 noise-reduction 的压缩率。
读报告、做判断
- 看报告的压缩率:在 30%-60% 区间内吗?
- 看被过滤消息抽样:逐条检查,有没有真实对话被误杀?数误杀条数 ÷ 抽样总数 = 误杀率
- 看保留消息抽样:逐条检查,有没有噪声被遗漏?数遗漏条数 ÷ 抽样总数 = 遗漏率
- 重点关注报告中标 ⚠️ 的可疑项
不过时怎么办
误杀率 > 2%:
- 列出所有被误杀的消息
- 找到每条的 skip reason(merge 脚本的哪条规则触发的?)
- 缩窄该规则的匹配范围,或加排除条件
- 查
的"误杀率 > 2%"段落,对照排查references/common-failures.md
遗漏率 > 5%:
- 列出保留消息中的噪声
- 按
分类——是哪类噪声?references/noise-categories.md - 为每类遗漏写对应的过滤规则
- 查
的"遗漏率 > 5%"段落,对照排查references/common-failures.md
遗漏率超标不能用"保守原则"跳过——保守是指不确定的消息默认保留,不是指明确的噪声可以放过。
压缩率判定:
- 30%-60%:典型健康范围,直接看误杀率和遗漏率
- 60%-80%:高噪声环境可能出现(cron 任务多、heartbeat 频繁)。检查误杀率——如果 < 2%,说明噪声确实多,压缩率合理,通过。 不要试图把压缩率降到 60% 以下
- > 80%:几乎肯定有误杀,查
的"压缩率 > 80%"段落common-failures.md - < 20%:规则覆盖不足,查
的"压缩率 < 20%"段落common-failures.md
调整后仍未达标:记录当前结果和未解决的问题,不必追求完美——后续 merge 的统计输出会持续可见。Step 4 不通过需要重做 Step 3 时,更新 state 文件
completedSteps: [1, 2]。
首次验证结果记录到噪声画像。
验证通过后删除 state 文件(
memory/noise-reduction-state.json),任务完成。
验证通过后,在 AGENTS.md 中写入:
## 降噪状态 - 覆盖渠道:[Telegram / Discord / ...] - 新增渠道时重跑 noise-reduction - 用户反馈记忆力差 / 搜不到东西时,先检查降噪规则是否覆盖当前渠道,必要时重跑 noise-reduction
agent 每次启动读 AGENTS.md,自动感知渠道变化和记忆质量问题的排查路径。
依赖关系
- 前置:
(提供 merge 脚本和 transcripts 目录)memory-deposit - 产出:降噪规则 + 统计输出,写入 merge 脚本