# 日报级词元库与词元清洗 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.json` - `outputs/term_index/review/term-cleanup-suggestions-YYYY-MM-DD.md` 其中建议语义为: - JSON 是 review / apply 之间的唯一正式建议产物 - Markdown 是人工临时审阅展示稿,不是长期真相来源 低复杂治理层建议补充三类输入: - `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 生成 suggestions JSON(正式建议产物) 6. 如需要人工阅读,再临时生成 Markdown 展示稿 7. 人工确认后再更新配置文件 ## 14. 与规则引擎的关系 这套词元库设计不是规则引擎的替代品,而是规则配置的辅助层。 关系如下: - `keywords` - 是词元库来源 - `term_stats` - 是观察与调优依据 - `filter_context.personal.json` - 是真正给规则引擎使用的兴趣词配置 - `filter_rules.json` - 是最终裁决逻辑 也就是说: `日报词元统计 -> 清洗建议 -> 人工确认 -> 更新 interest_keywords -> 规则引擎命中` 而不是: `日报词元统计 -> 自动改规则` ## 15. 分阶段落地建议 ### Phase 1 先做最小可用版本: - 只读取日报中的 `keywords` - 生成每日词元文件 - 生成全局累计词频文件 - 支持 `term_aliases` 和 `term_stopwords` ### Phase 2 再补治理层: - 增加词元清洗 skill - 输出建议文件(以 JSON 为正式产物) - Markdown 仅作为按需生成的人工展示层 - 人工确认后更新配置 ### Phase 3 最后再考虑增强: - 增加趋势分析 - 增加最近 7 天热点词视图 - 增加“建议加入兴趣词”的自动排序 ## 16. 一句话结论 这套设计选择“只统计日报中的 `keywords`,由程序维护轻量词元库,再由独立 skill 周期性做清洗建议”,目的是在控制数据规模的前提下,为规则配置和长期兴趣演化提供稳定、可审计、可扩展的基础设施。 补充的产物策略是: - facts/state 长期保留 - suggestions JSON 作为正式建议产物短期保留 - review bundle 与 Markdown 展示稿降级为临时工作文件 / 展示层