Add keyword cleanup governance workflow

This commit is contained in:
zhuyongxin
2026-03-27 16:59:52 +08:00
parent 100044e1f7
commit 32ad584348
25 changed files with 1915 additions and 18 deletions
+461
View File
@@ -0,0 +1,461 @@
# 日报级词元库与词元清洗 Skill 设计
## 1. 设计目标
当前项目已经具备:
`FreshRSS -> extraction -> LLM summary -> rule engine -> OpenClaw payload`
下一阶段希望新增“词元库”能力,目标不是做全文级检索索引,而是解决两件事:
1. 为后续规则配置提供稳定、轻量、可读的词元来源
2. 为周期性的词元清洗、合并和兴趣词补充提供数据基础
因此这套设计的核心原则是:
- 词元来源轻量化
- 数据粒度日报化
- 主链路程序化维护
- 清洗治理由独立 skill 周期性执行
- LLM 不直接修改规则或兴趣词配置
## 2. 为什么不用逐篇词元库
逐篇记录每篇文章的词元事件,虽然可追溯,但当前阶段成本过高,收益不足:
- 生成文件会很多
- 存储和调试负担更大
- 后续真正调规则时,用户更关心“最近日报里反复出现什么词”,而不是“某一篇文章具体抽到了什么词”
- 当前目标是服务日报与规则配置,不是做文章级分析平台
所以本项目不采用:
`article -> term event -> term store`
而采用:
`daily digest -> keyword aggregate -> daily term index -> global term stats`
## 3. 为什么只保留 `keywords`
当前 LLM 摘要结果里已经有两个候选字段:
- `keywords`
- `topics`
本设计只使用 `keywords` 进入词元库,不使用 `topics` 作为主来源。
原因:
- `keywords` 更具体,适合后续规则配置
- 例如 `Java`、`Go`、`Python`、`MCP`、`RAG`、`Kafka`
- `topics` 更宽泛,适合摘要展示,不适合作为精确规则命中基础
- 例如“后端工程”“AI Agent”“前沿科技”过于宽泛
- 只保留一个字段可以显著控制词元库规模
- 当前项目的真实需求是“词元可配置”,不是“主题聚类”
结论:
- `keywords` 进入词元库
- `topics` 继续保留在单篇摘要结果中,但不纳入词元统计主流程
## 4. 词元库的上游边界
词元库不直接读取所有候选文章,而只读取“最终进入日报”的内容。
也就是说,真正的词元来源是:
- `DailyDigest`
- 或等价的“已被日报选中”的 candidate 集合
不纳入词元库的内容:
- 被 `drop` 的内容
- 仅在中间候选层出现、但未进入日报的内容
- 调试产物中的临时摘要结果
这样做的好处是:
- 词元库只反映真正进入日级产物的内容
- 高频词更接近长期兴趣,而不是临时噪声
- 数据量更可控
## 5. 总体链路
目标链路调整为:
`DailyDigest -> keyword normalization -> daily term index -> global term stats -> cleaning skill review -> human confirm -> config update`
职责拆分如下:
### 5.1 程序负责
- 从日报中提取 `keywords`
- 归一化词元
- 应用别名映射
- 应用停用词过滤
- 生成每日词频
- 更新全局累计统计
### 5.2 Skill 负责
- 周期性读取词频结果
- 识别重复词、近义词、大小写变体
- 识别泛词、噪声词、低价值词
- 建议哪些词应合并、停用、加入兴趣词配置
### 5.3 人工负责
- 审核 skill 输出的建议
- 决定是否更新:
- `term_aliases`
- `term_stopwords`
- `filter_context.personal.json`
## 6. 数据文件设计
建议新增以下文件:
- `data/term_index/daily/YYYY-MM-DD.json`
- 某一天日报的词元聚合结果
- `data/term_index/term_stats.json`
- 全局累计词元统计
- `configs/term_aliases.json`
- 词元别名归一配置
- `configs/term_stopwords.json`
- 词元停用词配置
- `configs/term_cleanup_policy.json`
- 清洗阈值与治理策略配置
- `configs/term_watchlist.json`
- 当前处于观察状态的词元列表
- `configs/term_change_log.json`
- 已确认生效的词元治理变更记录
说明:
- 不新增逐篇 `term_events.jsonl`
- 不新增文章级明细文件
- 默认只保留“日报聚合结果 + 全局统计结果”
## 7. 每日词元文件结构
文件路径示例:
- `data/term_index/daily/2026-03-26.json`
建议结构:
```json
{
"date": "2026-03-26",
"source": "daily_digest",
"digest_id": "digest-2026-03-26",
"generated_at": "2026-03-26T21:30:00+08:00",
"candidate_count": 8,
"terms": [
{
"term": "AI Agent",
"normalized_term": "AI Agent",
"count": 4
},
{
"term": "MCP",
"normalized_term": "MCP",
"count": 3
},
{
"term": "RAG",
"normalized_term": "RAG",
"count": 2
}
]
}
```
字段说明:
- `date`
- 日报日期
- `source`
- 固定标记为 `daily_digest`
- `digest_id`
- 日报对象唯一标识
- `generated_at`
- 该词元文件生成时间
- `candidate_count`
- 当天日报包含的条目数
- `terms[]`
- 当天词元聚合结果
其中单条 `terms[]` 只保留:
- `term`
- `normalized_term`
- `count`
不保留:
- 逐篇文章来源列表
- 逐条命中明细
- 本地文件路径
## 8. 全局统计文件结构
文件路径:
- `data/term_index/term_stats.json`
建议结构:
```json
{
"schema_version": "v1",
"generated_at": "2026-03-26T21:30:00+08:00",
"terms": [
{
"term": "AI Agent",
"total_count": 18,
"days_seen": 6,
"first_seen": "2026-03-20",
"last_seen": "2026-03-26"
},
{
"term": "MCP",
"total_count": 12,
"days_seen": 5,
"first_seen": "2026-03-21",
"last_seen": "2026-03-26"
}
]
}
```
字段说明:
- `term`
- 最终归一后的词元
- `total_count`
- 累计出现次数
- `days_seen`
- 出现过的天数
- `first_seen`
- 首次出现日期
- `last_seen`
- 最近出现日期
当前阶段不额外记录:
- 各 category 分桶统计
- keep/review/drop 分桶统计
- 文章级来源列表
原因是:日报级词元库的第一目标是轻量稳定,不是分析平台。
## 9. 标准化与归一规则
程序在写入日报词元前,应先做标准化。
### 9.1 基础标准化
- 去除首尾空白
- 保留中英文大小写风格中的稳定写法
- 去重
- 过滤空字符串
### 9.2 别名映射
通过 `configs/term_aliases.json` 做归一。
示例:
```json
{
"Agent": "AI Agent",
"智能体": "AI Agent",
"Postgres": "PostgreSQL",
"Model Context Protocol": "MCP"
}
```
### 9.3 停用词过滤
通过 `configs/term_stopwords.json` 过滤过泛词和噪声词。
示例:
```json
[
"技术",
"系统",
"方案",
"实践",
"文章"
]
```
## 10. 为什么不让 LLM 直接维护词元库
LLM 可以帮助做清洗建议,但不适合直接维护主词元库。
原因:
- 主词元库更新应该稳定、低成本、可复现
- 词频统计属于纯程序逻辑,没必要消耗模型调用
- 如果让 LLM 直接写词元库,会引入不稳定和难审计问题
因此主流程固定为:
- LLM 只负责在摘要结果里输出 `keywords`
- 程序负责归一、聚合、统计
## 11. 词元清洗 Skill 设计
新增一个周期性清洗 skill,定位是“治理器”,不是“实时生产者”。
### 11.1 Skill 输入
建议输入:
- `data/term_index/term_stats.json`
- 最近 N 天的 `data/term_index/daily/*.json`
- `configs/term_aliases.json`
- `configs/term_stopwords.json`
- `configs/filter_context.personal.json`
### 11.2 Skill 输出
skill 不直接修改配置文件,而是生成建议文件,例如:
- `outputs/term_index/review/term-cleanup-suggestions-YYYY-MM-DD.md`
- `outputs/term_index/review/term-cleanup-suggestions-YYYY-MM-DD.json`
低复杂治理层建议补充三类输入:
- `term_cleanup_policy`
- 用来定义 watch 和 interest 的最小证据阈值
- `term_watchlist`
- 用来记录“先观察、暂不升级”的词元
- `term_change_log`
- 用来记录已经确认落地的配置变更,避免后续遗忘上下文
建议项包括:
- 建议合并的别名词
- 建议新增的停用词
- 建议加入 `interest_keywords` 的候选词
- 建议降权观察的热点词
### 11.3 Skill 允许做什么
- 发现重复词
- 发现大小写变体
- 发现中英文混用的近义词
- 发现持续高频但尚未进入兴趣配置的词
- 发现明显过泛的词
### 11.4 Skill 不允许做什么
- 直接改 `filter_rules.json`
- 直接改 `filter_context.personal.json`
- 直接覆盖 `term_stats.json`
- 在无人工确认的情况下自动生效
## 12. 建议的清洗建议文件结构
建议 JSON 文件结构如下:
```json
{
"date": "2026-03-26",
"based_on_days": 7,
"alias_suggestions": [
{
"from": "Agent",
"to": "AI Agent",
"reason": "和现有高频词语义一致,建议归并。"
}
],
"stopword_suggestions": [
{
"term": "系统",
"reason": "出现频繁但语义过泛,难以作为规则命中词。"
}
],
"interest_keyword_suggestions": [
{
"term": "MCP",
"reason": "最近多日持续高频,且符合当前 AI Agent 学习方向。"
}
]
}
```
## 13. 周期与触发方式
建议触发周期:
- 词元统计更新:每天一次,跟随日报生成
- skill 清洗:每周一次,或人工手动触发
推荐流程:
1. 当天日报生成完成
2. 程序更新 `daily/YYYY-MM-DD.json`
3. 程序更新 `term_stats.json`
4. 每周或人工触发一次词元清洗 skill
5. skill 输出建议
6. 人工确认后再更新配置文件
## 14. 与规则引擎的关系
这套词元库设计不是规则引擎的替代品,而是规则配置的辅助层。
关系如下:
- `keywords`
- 是词元库来源
- `term_stats`
- 是观察与调优依据
- `filter_context.personal.json`
- 是真正给规则引擎使用的兴趣词配置
- `filter_rules.json`
- 是最终裁决逻辑
也就是说:
`日报词元统计 -> 清洗建议 -> 人工确认 -> 更新 interest_keywords -> 规则引擎命中`
而不是:
`日报词元统计 -> 自动改规则`
## 15. 分阶段落地建议
### Phase 1
先做最小可用版本:
- 只读取日报中的 `keywords`
- 生成每日词元文件
- 生成全局累计词频文件
- 支持 `term_aliases` 和 `term_stopwords`
### Phase 2
再补治理层:
- 增加词元清洗 skill
- 输出建议文件
- 人工确认后更新配置
### Phase 3
最后再考虑增强:
- 增加趋势分析
- 增加最近 7 天热点词视图
- 增加“建议加入兴趣词”的自动排序
## 16. 一句话结论
这套设计选择“只统计日报中的 `keywords`,由程序维护轻量词元库,再由独立 skill 周期性做清洗建议”,目的是在控制数据规模的前提下,为规则配置和长期兴趣演化提供稳定、可审计、可扩展的基础设施。