Skip to content
asdbex1078Public

About

混沌学习

Resources

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

146 Commits

Folders and files

Repository files navigation

Knowrary

愿景:沉淀一座属于自己的、活的知识库——看得见(可视化)、长得大(可成长)、 还能把别人的脑子抄过来(跨库复制知识点)。

它能做什么:

  1. 跟着 AI 学新东西:和教练对话,把学到的东西直接沉淀成节点,相当于把 AI 蒸馏进自己的库。 代价是消耗你自己的 token。
  2. 学习者 + 审核者两个角色:学习者(learn)负责教,打开「写入审核」后,审核者(review) 会在内容写入前校验知识点对不对。审核同样要烧 token。
    • 学习者建议配强模型,审核者弱一点没关系。
    • 最佳实践:两个角色别用同一家族的模型。 同一家族的预训练语料大体相同,错会错到一块去, 互审就看不出问题。
  3. 整理、导入自己的老笔记:把已有的笔记和文章拆成节点收进库里。

    ⚠️ 注意:笔记入库时,程序会在正文前面加上元数据(frontmatter),在后面追加关系等内容, 不再是原样的纯文本。

  4. 更多功能见下文「常用命令」。

Knowrary = know + library:一个在本机跑的个人知识图谱程序。你的笔记是一堆普通的 Markdown, 它把这些 md 渲染成可拖动的结构图,再往上,增加出题与复习、把文章拆成节点、跟教练对话这些事。

程序和知识库是两个目录(2026-09-22 拆分)。这个仓库里只有程序;知识库(vault)是另一个目录, 第一次启动时你自己挑。我自己那份在 HunDun —— clone 下来 可以当参考库看,但它是只读参考:想自己写,新建一个属于你的库。

快速开始

git clone https://github.com/asdbex1078/Knowrary.git && cd Knowrary
python3 -m venv .venv && .venv/bin/pip install -r server/requirements.txt
./server/dev.sh                      # 打开 http://127.0.0.1:8765/

第一次打开先选知识库:设置 → 知识库 → 选择目录。

  • 挑一个空目录 →「选定并初始化」,程序按规范铺出骨架(nodes/ fields/ assets/ .knowrary/)。 顺手勾上「放一份示例内容」:9 个节点讲 HTTP 三代演进,覆盖全部 5 类关系,带一张摆好的图和一个学习项目 (见 examples/)。空库里什么都点不动,第一次建议勾上,不想要整片删掉即可。
  • 或者挑一个已经是库的目录(比如刚 clone 的 HunDun)直接用。
  • 之后随时切,「最近使用」里点一下就换。环境变量 KNOWRARY_VAULT 可临时覆盖,自测和脚本走的就是这条。

配置跟人,数据跟库:~/.knowrary/ 放当前选了哪个库(config.json)、模型与密钥 (llm.local.json)、复习开关(settings.json)——换一个库这些都不用重来。知识库里只有数据: 节点、领域总览、图的摆位、项目清单、复习记录、关系类型表。唯一的例外是教练侧写 (<库>/.knowrary/coach.md),它跟库走:切到别人的参考库,该读到那个库的口气。

再配模型:设置 → 模型 → 添加模型,填模型名和密钥,点 ▶ 测一下连通,保存。 不配也能用——默认全部走本机 Claude Code 的 claude -p,零配置那条路没断。

模型配置的细节

配置跟人,数据跟库。 模型与密钥写在 ~/.knowrary/llm.local.json,所有知识库共用—— 一个人会有好几个库(自己的、别人的参考库、示例库),配置绑在库上就得切一次配一次, 参考库和示例库里更不该出现密钥。库里留的只有数据:节点、摆位、项目、复习记录、关系类型表。 模板是 ~/.knowrary/llm.example.json(第一次运行时从 seed/user/ 铺过去)。 界面上配就够了,下面这些是给不开界面的场景用的:

python3 tools/knowrary/knowrary.py llm list                       # 看当前配置(--vault 不给就用当前库)
python3 tools/knowrary/knowrary.py llm test                       # 连通性测试(每个角色各问一句)
python3 tools/knowrary/knowrary.py llm probe                      # 能不能等:静默期被掐时,首字节卡在第几秒
  • provider 三种类型:claude-cli(复用本机 Claude Code 登录,零配置)、anthropic(官方 API)、openai(OpenAI 兼容协议:OpenAI / DeepSeek / 通义 / Ollama / vLLM 都是它)。
  • 两个角色:learn(对话式教练、文章拆节点、关系抽取)和 review(校验、分组判断、去重)。可以指向不同模型,用第二个模型审第一个的产出,减少单一模型的偏差。
  • 工具协议按 provider 能力自动挑,不用你管:anthropic / openai 走原生 function calling(schema 约束、可并行);claude-cli 是子进程、没有结构化工具接口,自动退回文本围栏。判据在 llm_backend.supports_tools()。
  • knowrary check 会在任何 *.local.json 被 git 跟踪时报错,防止密钥被提交。

目录

这个仓库(程序)

目录 内容
server/ 本地服务(FastAPI):只读 index、读写 layout、托管前端产物,见其 README
tools/knowrary/ CLI 与核心库(解析、索引、布局生成),见其 README
web/ 结构视图前端(Vue 3 + Vite + X6);web/dist/ 是入库的构建产物,运行期零 Node(文件名不带 content hash:Rollup 的 hash 是传递的,改一行就级联换掉几十个文件名,一次小改往 .git 里塞 6MB;缓存失效改由服务端发 Cache-Control: no-cache 负责,浏览器照旧缓存、每次拿 ETag 问一句,没变就 304)。src/canvas/ 是不碰 DOM 的算法(布局、LOD、时间线、菜单内容),src/composables/ 是按功能抽出来的成块状态(历史/回放/导览、对话),App.vue 只做编排
seed/ 出厂种子,只补不覆盖。seed/ 是建新库时铺进库里的(关系类型表、教练侧写模板、README、.gitignore);seed/user/ 是第一次运行时铺进 ~/.knowrary/ 的(LLM 配置模板 + 一页说明)
examples/day-info/ 案例:一个每天自己跑、把外部信息收进知识库、每周汇成周报的小系统。只留脚本与定时任务提示词,数据在库那边
examples/sample-vault/ 示例库:9 个节点讲 HTTP 三代演进,覆盖全部 5 个关系族,带摆好的图、学习项目、复习记录、错题本和一篇待导入的素材。初始化时勾「放一份示例内容」铺进新库,也可以直接把它当库切过去随便改(改了 git pull 会冲突,自己权衡)
doc/ 规范文档、设计文档、开发实施计划。doc/设计文档/选型对照/ 是「要不要上 X」的逐条判断(agent 框架 / 向量库 / 数据库 / 测试框架 / LLM SDK / 画布渲染),判据与总表在 选型判据.md
.claude/skills/knowrary-import/ Claude Code skill:把文章拆成节点存进知识库。可选的第三个入口——导入的完整能力在 knowrary article 和网页「导入」面板里,没有 Claude Code 一样全功能

你的知识库(另一个目录)

路径 内容
nodes/ 知识节点,一个知识点一个 md,按领域分子目录(_stubs 是待补的空壳)
fields/ 领域总览(每个顶层领域一个文件)
assets/ 节点引用的图片
relation-types.json 关系类型表:5 个族,具体类型可增长
.knowrary/coach.md、.knowrary/coaches/<项目>.md 教练侧写:我是谁、要什么口气、笔记想长成什么样。跟着这个库走——一个库一份,切到别人的参考库该读到那个库的口气,而不是把自己那份盖上去;项目级接在全局之后(覆盖全局)。每次现读不缓存,改完下一句话就生效。它只影响对话的口气与判断——工具协议和纪律在 tools/knowrary/prompts/,那是程序行为。模板是 coach.example.md,真身默认 gitignore(那写的是你自己,不是知识)
.knowrary/ 图谱的机器数据。入库的是成果:layout.json(结构视图的位置 / 分组 / 折叠状态 / 贴图 / 边拐点)、layouts/<项目>.json(项目画布)、projects.json(项目:一组 node_id 的选集 + N 份清单,清单分学习 / 面试 / 领域三种口径,带目标日期与负荷档;每周投入与每日配额在项目上。允许指向图里还没有的节点;进度与时间账不存,现算)、settings.json、imports/(每次导入的方案)。不入库的是流水与缓存:llm.local.json(密钥)、index.json(解析索引,knowrary index 随时重建)、review-log.json / quiz-log.json / question-pool.json(复习与答题)、llm-usage.json(花费)、chat/<项目>/YYYY-MM.jsonl(对话留档,没绑项目的落 _scratch/)、issues.jsonl(诊断)、backup/(写回前快照)

从别人的库里抄知识点

参考库(比如 HunDun)的正确用法是只读着看,看到有用的抄走—— 直接在别人的库里学习,下次 git pull 必冲突。两个入口,同一个对话框:

  • 画布上右键一个点(或框选几个)→「抄到别的库…」:站在参考库里往外推
  • 「导入」面板 →「从别的库抄…」:站在自己库里从别处拉

抄过来的东西:正文、frontmatter(year / layer / tags 一起)、关系连年份和说明。 落在 nodes/_抄来的/(一眼看得出哪些是抄的),但 field 保留源库的值—— 压平成一个领域的话,抄 8 个点回来会挤成一坨。复习进度从今天重新开始:别人学过不等于你学过。

关系分三种处理,这是最要紧的一处:

边的形态 怎么办 为什么
两端都抄过来了 原样带走 无歧义
指向没抄的点 自动补一个 stub 丢掉边等于悄悄削掉知识结构,而且事后不知道缺了什么。勾「把邻居也带上」则改成真抄一跳
指向目标库已有同 id 的点 进待审(pending.json),不直接连 同 id 不等于同概念,跨库尤其:你库里的「Agent」和我库里的「Agent」很可能不是一回事

同 id 已存在的节点一律跳过不覆盖,只给一条警告——抄东西不该悄悄改掉你自己写的。 源库只能是当前库或「最近使用」里的库(这条链路会读另一个目录里的 md,放行名单和目录浏览同一套)。

这一栏的规则写在 seed/.gitignore 里,建库时会铺进去。成果丢了要重做,值得进版本库; 流水进了公开历史就收不回来——我自己在这上面栽过一次(见本仓库 .gitignore 里的那段注释)。

节点约定(摘要,全文见 doc/规范文档/Markdown文档规范.md)

  • frontmatter 必填 name、field、desc;year 可选,只有填了才进入历史视图。
  • 关系写在 ## 关系 段:- 类型:: [[目标]] (年份)? — 说明?,方向从本节点指向目标,反链由解析器推导。
  • 坐标、分组、折叠状态不进 md,统一在 .knowrary/layout.json;复习与答题记录不进 md,在 .knowrary/review-log.json 与 quiz-log.json(learned 只记首次入库)。
  • year 是进历史视图的开关;start_year / end_year 用于有效期过滤(法律 / 标准场景)。

常用命令

./server/dev.sh                                                # 启动本地服务,打开 http://127.0.0.1:8765/ 看结构视图
#   画布操作:拖空白平移 / 滚轮缩放 / shift+拖空白框选 / 拖节点进别的分组框即改归属(自动保存)
#   连线:结构族默认不画(嵌套已表达,工具条可勾开);跨分组边聚合成「分组→分组 (n)」一束,点开看明细;悬停节点高亮它的边
#   缩小自动折叠成簇卡片(点卡片放大进该域,Esc 回全景)· 搜索框定位 · +便签 · +图片 · 详情面板「放引用卡」
#   点一条边挂上拐点手柄,拖圆点调走线,双击这条边清掉
#   Inbox:写好还没上画布的节点,点「放进去」或直接拖到某个分组框里(落下是金色虚线的草稿,确认位置后「定稿」)
#   欠账:草稿 / 跨分组桥 / **连边建议** / 重复候选 / stub / 方向矛盾 / **年份可疑** / **最近出的错**,点一条就定位过去
#     连边建议 = 名字摆明了有关系、图上却没连的那些对。**这一类原来叫「重复候选」**:
#     中文复合词天生共享中心语(`内存` / `堆内存` / `栈内存` 字面重合度 0.8),相似度只
#     能说"这俩像",说不出像在哪——而像在哪正是答案。含着对方 ⇒ 上下位(`包含`);
#     掐掉公共词缀两边还各剩一点 ⇒ 同级兄弟(`对比`);邻居几乎一样 ⇒ 同族(`相关`)。
#     三种都不是重复,是图上缺的边。**孤点排在最前**——它们连一条就从孤岛回到图里
#     点「连边」打开关系对话框,类型和目标已填好,但**方向和类型仍由你定**:建议是按
#     名字猜的,猜错了写进 md 就是一条骗人的边。真重复只剩一种——多出来的那截加了
#     等于没加(`MHA` / `MHA机制`),那才走「合并」
#     跨分组桥的重名分组会带上父级(`计算机系统/硬件 → AI/硬件`),否则显示成"硬件 → 硬件"
#     **孤点** = 一条关系都没有的已建节点,这张图最大的一笔欠账(整个产品都建在边上)。
#     连边建议只认得出名字有线索的那些,`eBPF`、`乐观锁` 这种得点「问 AI 连什么」——
#     **一次一个点,不批量**:47 个点跑一轮就是 47 次模型调用
#     **缺 year** 和「年份可疑」是两回事:那个是算得出来的矛盾,这个只是没填,
#     而没填的节点根本不出现在历史视图上。「让 AI 补一轮」是**一次调用**问完一批
#     (逐个问是 41 次),把握低于 0.6 的默认不勾,模型说拿不准的会如实列出来——
#     错的 year 比空的 year 难发现:它把节点摆到时间轴上一个看起来很正常的位置
#     出错流水在 .knowrary/issues.jsonl(工具失败 / 写回被拒 / LLM 挂了,只留最近 500 条)——
#     同一类反复出现,多半是工具本身有问题,不是手滑
#     年份可疑 = 演化边两端倒挂(A 演化为 B 却比 B 晚)或年份在未来——**不依赖外部知识**,
#     它不问"1997 对不对",只问"这条线自己自洽吗";口述的年份没人能核,倒挂能算出来
#   写入审核(设置 →「写入审核」,默认关):往 md 里写正文之前先让 review 角色看一眼对不对
#     **关着也照查一层**:未登记的关系类型、正文里指不到的 [[链接]]、正文太薄、新点零关系、名字撞车——
#     这些是算出来的,不花钱不用等,照常显示在卡上,只是不拦路
#     开了之后只审正文类写入(新建 / 补正文 / 重写正文),加边改年份不审;挡下时卡上给依据和改法,
#     「仍然写入」是留的后门(可在设置里关),每次强制都记进 .knowrary/issues.jsonl
#   日历:每天建了几个 / 复习几次 / 答了几道 / 烧了多少钱,热力图 + 点某天看明细、连续学习天数
#     **全是算出来的,没有第二份记录**;热力只算学习量(建 ×3、复习和答题 ×1),不算模型调用
#     学习时长故意不做:手动计时会有"忘了停表"的脏数据,被动推断会把"开着页面去吃饭"算进去
#   项目:一个项目 = 一组要掌握的点 + N 份清单。**项目是视角不是容器**——它不拥有节点,
#     同一个点在两个项目里掌握度是同一个(同一个大脑),今日清单里也只出现一次
#     清单三种口径共用一套数据——学习(按依赖顺序)/ 面试(按会怎么问)/ 领域(按覆盖度铺一张地图)
#     写个目标(如「吃透 Transformer」)+ 目标日期 + 每周投入 →「让 AI 拆一份要点」→ 划掉不要的 → 采纳 → 保存
#     拆解会避开这份计划里已经有的点(同名的默认划掉),别让同一个目标拆两次拆出一堆近义词
#     每个点带一档负荷(轻/中/重),服务端算这个期限装不装得下:装不下就给现实日期,
#     或「按现有时间压缩」出一份速学版(被砍掉的点会列出来,别当成学全了);「排截止日」把建议日填进各阶段
#     计划里的点**允许图里还没有**,那正是它的用途;「未建」的点点一下就去建
#   四个模式(快捷键 1/2/3/4),顶栏按作用域分两组:**[对话 · 项目图] 跟着当前项目走**,**[全局图 · 历史] 是整个图谱的**
#     默认落在对话——启动成本最低的入口就该是默认入口;选「🌐 全局」时「项目图」置灰(不绑项目就没有项目画布)
#     顶栏最左切项目(它决定后面三个模式看到的范围),**「🌐 全局」是一条真线**——不绑项目的对话落 _scratch,
#     随手问一句不用先建项目;右边「↗ 全局图」把当前项目的点在整张图上高亮
#   项目图是**这个项目自己的一张画布**(.knowrary/layouts/<项目>.json):只有这个项目的点,
#     还没建的画成幽灵虚线(点一下就去建)。摆好了点「同步到全局」并进主图——落草稿、**坐标不搬**,
#     疑似和图里已有的重复时先列出来让你选,不静默放上去
#   对话:跟教练聊着学——问概念、让它讲、被它考;它能搜图、读节点、看清单与计划
#     聊到图里已有的东西 → 它 read_node 拿原文再 `update_body` 补一段(**整段替换**,所以必须带原文)
#     聊到「计划里有、还没建」的点 → 它会直说在哪个项目清单里,聊完直接给你建
#     会话条上的**「梳理这段」**:回头看整段对话,该新建的新建、该补的补、关系连上,出一张卡
#     在某个项目下聊出来的新点,写入时**顺手加进这个项目的清单**(卡上写明加到哪;不加的话项目进度不认它)
#     系统提示词里带着**关系类型表**:连边只能用登记过的类型,讲发展史主要靠 `演化为` / `被激活`(方向从早指向晚)
#     一切仍然是**卡片 + 你点一下**:新建的节点立刻进复习队列,背着你生成的话掌握度从第一天就是假的
#     也能说「帮我建个 NLP 项目」:它会先看你已有的项目(名字/目标撞车的会提醒"要不要改成加一份清单")、
#     搜一遍图谱,再出项目卡;点「创建」之后还能接着让它拆点(和面板上「让 AI 拆一份」同一条链路)
#     拆出来的点会标「Transformer 里有」——**重叠是合法的**:同一个点属于两个项目,掌握度还是同一个
#     它搜图时**连"计划里还没建的点"一起搜**(一个项目常常 40 个点里 39 个还没建,只搜索引会全部漏掉)
#     卡片点「创建 / 采纳」之后会直接把你送到那个项目的面板,不用自己去左侧栏找
#     对话里判「忘了」可以直接记一次复习,判「记得」不行——要你自己点(不对称规则)
#     聊到哪、图上亮哪;点右侧图上的节点能把它带进下一轮对话
#     三档口径(会话条上切):教练(盯进度,工具全开)/ 面试(真的在考你,**不给入库工具**,边考边改图谱等于开卷)/ 聊天(只讲清楚,不催进度)
#       **不是三个 agent**:同一条链路、同一张图、同一套复习记录,换的只是提示词和工具白名单
#     多段对话:会话条上「新的一段」,切回旧的也在——会话只是留档行上的标签,列表是聚合出来的
#     每轮留档在 .knowrary/chat/<项目>/YYYY-MM.jsonl(不入库、不建索引,找旧对话用 grep)
#   每个点前面两个小方块:左「学」(灰=没建/红=只有壳/绿=有正文)、右「考」(灰=没考过/红=错过/黄=模糊或到期/绿=记得)
#     **错题本压过自评**:测验里答漏了,就算你自评点了「记得」,「考」也是红的
#   开场弹一次晨间简报:今天建什么、复习什么、大概几小时,点一条直接动手(一天只弹一次)
#   左侧栏按作用域给工具:**项目下**=清单 / 今日 / 素材;**全局下**=项目管理 / Inbox / 欠账 / 日历
#     站在全局图或历史视图时照给全局工具(那两个视图本来就是全局的)
#   今日:错题 > 到期复习 > 当前阶段未建的点 > 只有壳 > **孤点** > Inbox,每条都能直接动手(这一屏不调 LLM)
#     孤点是唯一一类「连」的任务(其余全是「写」和「考」),带着现成建议,点「连边」直接预填;
#     互为建议的一对只摆一个——连那条边两个一起脱离孤岛
#     选着某个项目时**整屏只看这个项目**(含到期与错题),但会写明"另有 N 个在别的项目"——藏起来的复习等于没有复习
#     点「开始测验」让模型按节点正文和关系出题;
#     一题一屏「写答案 → 对答案 → 自评三档」,答完整轮比对:漏掉了什么、有没有记反;
#     模型判得比你严才提示下调(只许降级);忘了 → 明天再考,记得 → 间隔往后拉;到期节点右上角有金色圆点
#   改关系/改摘要 → 先预览 diff → 确认才写回 md(自动备份到 .knowrary/backup/)
#   历史视图 tab:X 轴年份、泳道按所选时间线的子分组分(也可按抽象层 / 按流派),被激活关系是金色流动虚线,
#     滑块按年回放(不改结构布局);勾「主干道」把最长的那条演化链拉成一条水平主轴、旁支挂上下
#     (挑不出链就退回泳道);播放条上的「导览」沿这条链一站一站走,镜头推到节点上讲解
#     **双击一个点 = 只看它那条演化线**:祖先 + 后代 + 直接旁系(同父兄弟、同子汇流),
#     旁系画淡;`被激活` 不算血缘(跨代点燃会把整族拉进来)。Esc 退出
#   视图切换下拉里有「3D 总览」,或直接开 http://127.0.0.1:8765/3d/
python3 tools/knowrary/knowrary.py index --vault <你的库>             # 重建 .knowrary/index.json(结构视图/服务的数据源)
python3 tools/knowrary/knowrary.py layout init --vault <你的库> --by layer --force   # 顶层按主题、二级按抽象层重排(会重排位置,便签/贴图/拐点保留)
python3 tools/knowrary/knowrary.py layout check --vault <你的库>      # 布局引用校验:孤立记录 / Inbox 统计
python3 tools/knowrary/knowrary.py layout check --vault <你的库> --layout <项目>   # 查某个项目画布(含幽灵占位数)
python3 tools/knowrary/knowrary.py check <你的库>                     # 按规范校验全部节点(含密钥泄露检查)
python3 tools/knowrary/knowrary.py projects migrate --vault <你的库> --dry-run   # 旧 plans.json → projects.json(先看迁成什么样)
python3 tools/knowrary/knowrary.py review due --vault <你的库>        # 今天该复习什么;review done <id> 记一次复习
python3 tools/knowrary/knowrary.py digest --vault <你的库>            # 欠账清单:Inbox / 草稿 / 待复习 / 桥 / 连边建议 / 重复 / 方向矛盾
#   出题与交卷在画布的「学习」面板里(走 LLM 的 review 角色;没配模型就用 claude -p)
.venv/bin/python tools/knowrary/tests/run.py                   # core 自测(134 个用例;要 .venv,有两条跨到服务层)
node web/tests/unit.mjs                                        # 前端纯函数自测(零依赖,不用测试框架,36 个用例)
.venv/bin/python server/tests/run.py                           # 服务层自测(264 个用例)
.venv/bin/python web/tests/e2e_canvas.py                       # 画布端到端自测(真无头 Chrome 拖拽 → 落盘,临时 vault,不碰你的布局,259 个用例)
.venv/bin/python web/tests/e2e_models.py                       # 设置→模型端到端自测(真点「测试连接 / 保存」,假 OpenAI 端点,10 个用例)
.venv/bin/python web/tests/e2e_vault.py                        # 设置→知识库端到端自测(真的选目录、初始化、切库、整页重载,19 个用例)
.venv/bin/python web/tests/e2e_copy.py                         # 跨库抄知识点端到端自测(真右键、真写进另一个库,10 个用例)
cd web && npm run dev                                          # 改前端(5173,/api 代理到 8765);改完 npm run build 提交 dist
python3 tools/knowrary/knowrary.py article <文章.md> --vault <你的库> --field <领域> [--project <项目 id>] [--dry-run] [--llm <provider>]   # 无人值守:文章 → 节点
#   和网页「导入」面板同一套:同一份提示词、同一个长度闸、同一套认领 / 撞脸 / 孤立判定、同一份 JSON 容错
# 在 Claude Code 里(可选,装了才有):/knowrary-import <文章路径>  或  "把这篇文章融入我的图谱"
#
# --vault 不给也行:**CLI 和界面共用同一份「当前库」**——先看环境变量 KNOWRARY_VAULT,
# 再看设置页选中的那个(~/.knowrary/config.json)。两个都没有才会要你把路径写出来。
# 服务端同理:没选库时接口一律回 409,界面据此把人送进「设置 → 知识库」

About

混沌学习

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages