with one click
beaver
// 将任意文本源(书籍、文档、笔记、语料)转化为结构化 wiki 百科页面。识别并提取三种知识:fact(列表/表格型)、narrative(叙述型实体页)、skill(程序型 how-to 页)。通过 add_page.py 写入 wiki。支持永续迭代模式,自动追踪进度、捕获跨域洞察。
// 将任意文本源(书籍、文档、笔记、语料)转化为结构化 wiki 百科页面。识别并提取三种知识:fact(列表/表格型)、narrative(叙述型实体页)、skill(程序型 how-to 页)。通过 add_page.py 写入 wiki。支持永续迭代模式,自动追踪进度、捕获跨域洞察。
启动三体 Wiki 管家永续 loop。三队列系统(content/housekeeping)。每轮:W1三队列选任务→W2执行→W3自评→记账,无需用户逐轮确认。每11轮discover+housekeeping-scan,每17轮自动/wiki发布,每29轮W5反思,每37轮H17覆盖扫描/H18存根排序。工作目录:/home/baojie/work/knowledge/three-body。支持 --focus 参数指定任务范围(多实例并发时使用)。
三体 Wiki 编委审稿:检查近期 butler 工作是否违反质量规范,输出分级违规报告,给出具体纠正建议。工作目录:/home/baojie/work/knowledge/three-body。
从本 Wiki 随机抽取 1-3 个页面作为灵感种子,到网上搜索相关分析文章,发现 Wiki 真正的缺口并补齐。可接受参数指定灵感方向。标准模式写作严格限于三体原文;--ext 模式允许为原文引用的现实作者/作品建页,可补充外部背景知识。工作目录:/home/baojie/work/knowledge/three-body。
逐章反思,一次只扫一章,发现原文章节中遗漏的实体页面和改进建议。工作目录:/home/baojie/work/knowledge/three-body。
一键发布三体 Wiki:重建注册表 → 重算质量分 → 同步 docs/ → git commit → git push。此 skill 明确授权自动 commit 和 push,覆盖项目 CLAUDE.md 中的禁止自动提交/推送限制。
把项目当前所有变更按内容分组,一组一组地调用 /msg 生成提交消息并输出 git commit 命令,由用户逐组执行后再继续下一组。
| name | beaver |
| description | 将任意文本源(书籍、文档、笔记、语料)转化为结构化 wiki 百科页面。识别并提取三种知识:fact(列表/表格型)、narrative(叙述型实体页)、skill(程序型 how-to 页)。通过 add_page.py 写入 wiki。支持永续迭代模式,自动追踪进度、捕获跨域洞察。 |
将任意文本源转化为结构化 wiki 百科页面。支持单次运行和永续迭代两种模式。
在 wiki 中,所有知识都归属三种形态之一。理解这三种类型是本 skill 的基础。
| 类型 | 回答的问题 | 典型内容 | Wiki 呈现 |
|---|---|---|---|
| narrative | 这是什么?它是谁?发生了什么? | 人物传记、事件经过、地点介绍、概念解释 | 实体百科页(person/concept/event/place/…) |
| fact | 有哪些?数据是什么?清单如何? | 数据表格、属性列表、关系清单、统计数字 | 列表页(list)或任意页内的结构化数据节 |
| skill | 怎么做?流程是什么?如何判断? | 操作步骤、分析框架、决策流程、最佳实践 | 程序型页(concept 类型,结构化步骤正文) |
判断优先级:
MECE 原则:勘察表应完全覆盖来源文本中的所有实体——不仅选"有趣的",而是穷举。互不重叠,不遗漏。
| 模式 | 触发方式 | 特点 |
|---|---|---|
| 单次模式 | /beaver <文件路径或粘贴文本> | 处理完整输入,适合短文本(< 10 万字符) |
| 永续迭代模式 | /beaver --loop <文件路径> | 分批处理长文本,维护进度文件,每批后暂停或继续 |
永续模式首次启动时,创建进度追踪文件:
wiki/logs/beaver/<source-slug>/
├── progress.md # 进度:已处理批次、剩余批次
├── coverage.md # 勘察表(累积,每批追加)
└── insights.md # 跨域洞察(eureka,累积)
进度文件格式:
# beaver 进度:<source-slug>
- **来源文件**:<路径>
- **总批次**:N
- **已完成批次**:0 / N
- **已建词条**:0
## 待处理批次
- [ ] 批次1:字符 0–20000
- [ ] 批次2:字符 20000–40000
- …
## 已完成批次
(空)
接受以下任何形式的输入:
.txt、.md、.pdf、.docx)读完后,在回复中用一段话概括内容,确认理解正确再继续。
超过 10 万字符时按段落边界切分为若干批次,每批不少于 2 万字符,依次处理。
永续模式:读进度文件,跳过已完成批次,从下一个未完成批次开始。
每批必做三遍扫描,分别针对三种知识类型:
① Narrative 扫描 — 批次中出现了哪些实体?(人物/地点/事件/概念/理论/组织/器物/时代/文本)
② Fact 扫描 — 批次中是否有多项并列的清单、表格、属性对比、统计数据?
③ Skill 扫描(常被遗漏,必须独立完成)— 批次中是否描述了以下任何一种?
若 Skill 扫描有命中 → 候选 slug 以方法名或动词短语命名("X-推导框架"、"如何-设计-Y"),type = skill
产出一张知识单元勘察表:
| 序号 | 候选标题(wiki slug) | 类型 | 理由摘要(≤30字) |
|------|---------------------|------|-----------------|
| 1 | 某人物名 | narrative | 主角,有传记细节 |
| 2 | 某概念-某事件对比表 | fact | 多个事件并列属性 |
| 3 | 如何-做某事 | skill | 含步骤和判断条件 |
规则:
coverage.md对勘察表中的每个候选 slug,依次执行三层检查,任一层命中即为"已存在":
批量查重 + 质量扫描(一次运行,输出全部候选决策)
import json
d = json.load(open('wiki/public/pages.json', encoding='utf-8'))
pages, ai = d['pages'], d.get('alias_index', {})
def check_page(candidate):
"""返回 (match_type, canonical_slug, quality)"""
def _q(slug):
return pages.get(slug, {}).get('quality', '?')
if candidate in pages:
return 'exact', candidate, _q(candidate)
if candidate in ai:
return 'alias', ai[candidate], _q(ai[candidate])
hits = [(k,v) for k,v in ai.items()
if (candidate in k or k in candidate) and len(k)>=3]
if hits:
slug = max(hits, key=lambda x: len(x[0]))[1]
return 'fuzzy', slug, _q(slug)
frags = [candidate[i:i+2] for i in range(len(candidate)-1)]
scores = {}
for f in frags:
for k,v in ai.items():
if f in k and len(k)>=4:
scores[v] = scores.get(v,0)+1
if scores:
best = max(scores, key=scores.get)
if scores[best] >= 2:
return 'fragment', best, _q(best)
return 'missing', None, None
# 对所有候选批量输出
candidates = ['候选1', '候选2', ...]
for c in candidates:
match, slug, quality = check_page(c)
if match == 'missing':
print(f'[CREATE ] {c}')
elif quality in ('stub', 'basic'):
print(f'[ENRICH ] {c} → {slug} [{quality}]')
else:
print(f'[SKIP ] {c} → {slug} [{quality}]')
输出示例:
[CREATE ] 监听部
[ENRICH ] 红岸系统 → 红岸系统 [basic]
[SKIP ] 叶文洁 → 叶文洁 [featured]
[SKIP ] 乱纪元 → 乱纪元 [featured]
层3 · 内容归属检查(防止子概念重复建页,仅对 MISSING 候选执行)
若候选是某 featured 页的一个已有章节,不单独建页:
grep -rl "<关键词>" wiki/public/pages/*.md
判断结果:
[CREATE](三层未命中,层3也无归属)→ add_page.py[ENRICH](quality = stub/basic)→ Read 已有页面,按步骤4策略增补[SKIP](quality = standard/featured)→ 内容大概率已覆盖,仅在有明确新内容时精准追加,否则直接跳过按勘察表顺序,对每个知识单元:
type(见下方"页面类型映射")撰写完整 frontmatter + 正文(见下方三种模板),执行:
python3 wiki/scripts/add_page.py <SLUG> - --summary "<一句话说明>" --author beaver << 'EOF'
<frontmatter+正文>
EOF
先 Read 已有页面,判断 quality,再选策略:
| 已有 quality | 新来源信息量 | 操作 |
|---|---|---|
stub(< 5行正文) | 充足 | 替换:用新内容完整重写,质量升级 |
basic | 有新节或新引文 | 增补:在现有结构末尾插入新节,原有节不动 |
standard / featured | 有 1-2 处补充 | 精准追加:仅在最相关的节内加引文或句子 |
standard / featured | 与现有内容重复 | 跳过:写 skip 到 coverage.md,不执行写入 |
核心原则:edit_page.py 是全页替换,不是 append。增补时须先在内存中合并(Read → 插入新节 → 写回完整文件),不得用新内容覆盖来源中未涉及的已有内容。
python3 wiki/scripts/edit_page.py <SLUG> - --summary "<一句话说明>" --author beaver << 'EOF'
<合并后完整页面>
EOF
每页写入后,git add wiki/public/pages/<SLUG>.md。
每批处理完毕,审阅本批内容,判断是否有值得记录的跨域洞察:
合格的洞察必须满足以下条件之一:
不合格:内容的直接应用、重复已知事实、单领域内的观察。
大多数批次不会产生洞察——这是正常的,不更新就是正确行为。质量重于数量。
将合格洞察追加到 wiki/logs/beaver/<source-slug>/insights.md:
## <洞察标题>
<一句话核心观点。>[<来源批次>]
# 更新 progress.md:
- [ ] → [x] 标记当前批次已完成
- 更新"已建词条"计数
- 写入本批次摘要(新建N页,丰富M页,洞察K条)
若还有未完成批次 → 询问用户是否继续(或在自动模式下直接继续)。
所有批次完成后,输出汇总报告:
✓ <source-slug> 全量处理完成
- 总批次:N
- 新建词条:X
- 丰富词条:Y
- 跨域洞察:Z 条
- 进度文件:wiki/logs/beaver/<source-slug>/progress.md
每轮结束后,对本轮执行过程做一次反思,找出一个具体可改进的地方,并立即写回本 SKILL.md。
反思问题(回答其中一个):
改进写入格式:每轮在 .claude/skills/beaver/CHANGELOG.md 追加一条记录:
## R<批次号> · <YYYY-MM-DD> · <一句话改进描述>
**问题**:<本轮发生了什么具体问题,要有复现场景>
**改进**:<修改了SKILL.md的哪个步骤,加入了什么规则>
**无改进时**:写 `R<批次号> · <日期> · 无改进(原因:<一句话>)`
每轮只改一处,不求完美,只求持续进步。改进日志见 CHANGELOG.md。
| 知识类型 | 适用场景 | Wiki type 建议 |
|---|---|---|
| narrative — 人物 | 真实或虚构的个体,有传记信息 | person |
| narrative — 概念 | 抽象思想、理论、原则 | concept |
| narrative — 事件 | 有时间线的历史/情节事件 | event |
| narrative — 地点 | 真实或虚构的地理位置 | place |
| narrative — 组织 | 机构、团体、派别 | organization |
| narrative — 技术/器物 | 发明、设备、工具、方法 | technology |
| narrative — 时代/纪元 | 历史阶段、时间段 | era |
| narrative — 文本 | 书籍、典籍、文件 | book |
| fact — 独立清单页 | 多个实体的属性对比 | list |
| fact — 内嵌表格 | 嵌入 narrative/skill 页中的数据节 | (任意 type,表格在正文中) |
| skill — 操作流程 | 步骤性知识,有明确"如何做" | skill |
---
id: <slug>
type: <见类型映射>
label: <中文显示名>
aliases: [<别名1>, <别名2>]
tags: [<标签>]
description: <一句话描述,回答"这是什么",≤50字>
books: [<来源文本名>]
quality: stub
---
# <显示名>
<开篇段:1-2句定位这个实体在来源文本中的角色或意义。>
## <核心章节1>
<正文段落,包含从来源文本中提取的关键信息。>
> <引用原文(如有原文可引用时使用)>
> (<来源标注>)
## <核心章节2>
<...>
## 相关词条
- [[<关联词条1>]]
- [[<关联词条2>]]
质量标准:
stub:只有定义段,< 5 行正文basic:有 2+ 节,有 1+ 引文,≥ 15 行standard:有 3+ 节,有 3+ 引文,≥ 30 行featured:有 5+ 节,引文充实,内容权威,≥ 60 行---
id: <slug>
type: list
label: <中文显示名>
aliases: []
tags: [<标签>]
description: <一句话描述,说明这张表覆盖了什么范围>
books: [<来源文本名>]
quality: standard
---
# <显示名>
<1-2句说明本页面的内容范围和来源。>
## <分组标题1>
| 字段A | 字段B | 字段C |
|------|------|------|
| 值 | 值 | 值 |
## <分组标题2>
- **项目1**:说明
- **项目2**:说明
## 相关词条
- [[<关联词条>]]
何时使用独立 list 页面:当同类实体超过 5 个且有可比属性时,单独建页;否则将表格嵌入相关 narrative 页的某一节。
---
id: <slug>
type: skill
label: <中文显示名>
aliases: []
tags: [<标签>]
description: <一句话描述,说明"在什么情境下执行这个流程",≤50字>
books: [<来源文本名>]
quality: standard
---
# <显示名>
<开篇段:说明这个流程的目标和适用场景。>
## 前提条件
- <执行此流程需要满足的条件>
## 步骤
### 1. <步骤名>
<说明>
### 2. <步骤名>
<说明>
### 3. <步骤名>
<说明>
## 决策点
**如果 <条件A>** → <执行路径A>
**如果 <条件B>** → <执行路径B>
## 预期结果
- <完成后应达到的状态>
- <可验证的输出>
## 相关词条
- [[<关联词条>]]
所有页面中,出现其他已知实体时使用 [[词条名]] 格式内链。不要内链外部 URL。
若显示名与 slug 不同:[[slug|显示文字]]。
当知识单元 > 10 个时,按以下优先级排序依次执行:
每批最多处理 10 个页面,写完一批后暂停,展示结果并询问是否继续。
每页写入前,对照以下清单检查:
[[...]]永续迭代模式将 beaver 变成一个可以持续运行的 Butler 实例,逐章处理整本书。
INIT → READING → SURVEYING → WRITING → INSIGHT → PROGRESS → READING(下一批)
↓(全部完成)
DONE
若在 Butler 工作流中调用:
--author 使用 Butler 实例名(如 幸存者)git add wiki/public/pages/<SLUG>.mdrecord_action.py 记账(type: create-page 或 enrich-page)wiki/logs/butler/queue.md(P2 优先级,格式:- [ ] [P2] beaver <source-slug> 批次<N> create)wiki/logs/beaver/<source-slug>/下次调用 /beaver --loop <文件路径> 时,自动读取 progress.md,从上次中断处继续:
# 检查是否有未完成的 beaver 任务
ls wiki/logs/beaver/
cat wiki/logs/beaver/<source-slug>/progress.md
以下内容跳过,不建页: