这些年积累了不少笔记资料,大致分三类:
-
看到好的资料内容,随手就保存下来。
-
在公司研发时记录下来的各种笔记资料。
-
自己的知识学习心得,慢慢整理成了现在的博客。
保存下来的资料内容和公司资料,很多早就积了灰;反倒是博客里的内容,还会经常翻看、经常维护。
不过这些大多是零散的「机械知识」,彼此之间很难建立有机的链路。最近就想着,是不是该找个知识库好好管起来。下载了黑曜石(Obsidian)体验了一下,感觉不太好上手——与其迁就别人的设计,不如自己撸一个:挑出自己最常用的功能实现,还能在这个基础上随心所欲地做个性化。
于是借助神器 Claude Code,前后花了两个星期左右,初见成效——现在已经能日常使用了,体验下来还挺不错。
1. 需求
这是最初画的需求思维导图,如今大部分都已落地:资料文档管理、知识图谱、知识库 AI 助手。

2. 特性
目前实现的功能特性:
- 富文本知识库:打开文档即所见即所得编辑(基于 Vditor),输入防抖自动保存;10 套主题环(默认浅/深 + Catppuccin Mocha/Latte、Nord、Rosé Pine/Dawn、暖色 Primary、樱花、棉花糖)一键轮换,界面字体(跟随主题/系统默认/霞鹜文楷/站酷快乐体)可独立切换。
- 混合搜索:关键词路(中文分词 go-ego/gse + SQLite FTS5,中文正文自动退化为加权 LIKE 兜底)与语义路(嵌入向量余弦召回,可选)双路并行召回 → RRF 融合 → 可选重排,每一段都能独立降级,搜索绝不整体失败。另有独立的逐行文字搜索(/api/textsearch)。
- AI 聊天(agentic RAG + 联网 + 长期记忆):SSE 流式对话,模型在最多 8 轮工具循环里自行 list_docs / search_docs / read_doc / create_doc / delete_doc / save_memory 决定检索深度与是否记住偏好,实际读过的文档作为「来源」回传,触到轮次上限时优雅收尾成文而非报错;配置了可联网的模型组时还常驻 web_search 工具,由模型按规则判定是否联网;用户偏好经 save_memory 写入固定记忆文件,跨会话持续生效。兼容任意 OpenAI 风格端点。
- 省钱路由 + 深度思考:双组配置(主文本组 + 可选图文组),带图走图文组、纯文本走文本组、联网子请求优先图文组,确定性路由;「深度思考」开关按问题专业性在 flash / pro 档之间自动升降。
- AI 改文档:对话中让模型改写当前文档,三级流水线(携带补丁 → agentic 编辑循环 → 全文重写兜底),改动始终经 diff 预览、用户确认后才落盘。
- 知识图谱:纯本地 TextRank(零模型调用)从文档标签与 AI 会话中提取知识点,力导引渲染文档与知识点的关联网络,可按时间窗浏览。
3. 技术栈
整个项目刻意做得很「轻」:一个单二进制、零外部服务依赖,数据全落在本地磁盘(一堆 Markdown 文件 + 一个 SQLite 文件)。
| 层 | 选型 |
|---|---|
| 语言 | Go 1.21 |
| Web | Gin(+ gzip 压缩静态资源与页面)+ Cobra(CLI) |
| 存储 | 文件系统(Markdown 真相源)+ SQLite(GORM + glebarez 纯 Go 驱动,FTS5 全文索引) |
| 分词 / 关键词 | go-ego/gse(中文分词 + TextRank 提取器,均内嵌词典) |
| 语义检索 | 嵌入向量以 BLOB 存 SQLite + Go 暴力余弦(刻意不引向量库,个人库体量下毫秒级) |
| AI | sashabaranov/go-openai(OpenAI 兼容端点) |
| 前端 | 原生 JS + 手写 CSS(设计令牌,无框架);Vditor 富文本、marked 渲染、force-graph 知识图谱,全部自托管 |
4. 主要功能成果
4.1. 首页
界面整体参考了 VS Code 的布局:左侧活动栏 + 资源管理器手风琴,主区域是编辑器。
首页会汇总最近打开的文档、收藏,以及一张知识图谱的简略预览,一进来就能看到自己最近在忙些什么。

4.2. 资料内容
知识库以 Markdown 为载体,打开文档就直接进入所见即所得编辑,输入防抖自动保存——没有「编辑 / 预览 / 保存」这些多余的按钮,像用普通笔记软件一样顺手。
背后其实是一套「双存储」设计:文件系统里的 Markdown 是唯一真相源,SQLite 只存元数据 + 全文索引,两者由同一个写入口保证一致。这样既能享受数据库的搜索能力,又不会被数据库绑架——所有内容随时能用任何编辑器直接打开,甚至丢进 git 管理。

4.3. 知识图谱
知识图谱有些人觉得鸡肋,我个人倒是挺喜欢的:把零散的知识点关联起来,那种可视化的冲击力,看着还挺惊艳。除了展示资料库里的知识点,图谱还支持知识点搜索,鼠标 hover 到某个节点时,会高亮出与它相关的整条知识链路。
整张图谱零大模型调用:知识点提取用的是本地 TextRank(gse 分词器自带的提取器),数据全部来自 SQLite,纯本地计算,再用力导引布局渲染。这样即便离线、即便不配任何 AI,图谱照样能用。原本一篇篇孤立的「机械知识」,就这样被标签和对话串成了一张网。

4.4. AI 助手(问答检索)
检索是 agentic 的:不是常见的「一次性召回一堆片段塞给模型」,而是让模型在最多 8 轮工具循环里自己决定调用哪些工具,读到信息足够为止,最后把真正读过的文档作为「来源」列出来:
- list_docs —— 先拉一份全库清单(标题 + 标签),专治「帮我总结整个知识库」这类广度问题;
- search_docs —— 混合搜索,按问题找最相关的文档;
- read_doc —— 读原文。
让模型自己决定检索深度,对个人知识库这种「小而杂」的语料,反而比一次性召回更准。
search_docs 背后是一套混合搜索,分三段流水线,每一段都能独立降级:
- 关键词路 —— 中文分词 + SQLite FTS5,中文正文查不到时自动退化成加权 LIKE 兜底;
- 语义路 —— 把问题转成向量,和文档向量算余弦相似度召回;
- 融合 + 精排 —— 两路并行召回后用 RRF 融合,配了 rerank 模型再精排一遍。
就算语义层没配、或某一路挂了,搜索也绝不会整体失败,最差退回关键词结果。语义这块我特意没有引入向量库:向量直接以 BLOB 存进 SQLite、用 Go 暴力算余弦——个人知识库这点体量,毫秒级就扫完了,没必要为它多背一个组件。
另外两个我很在意的能力:
- web_search 联网 —— 知识库查不到、或问题有时效性时,模型会自己去搜;
- save_memory 长期记忆 —— 像「以后回答都用编号列表」这类偏好,会被它写进一个固定的记忆文件,跨会话一直生效,不用每次重新交代。

5. 后记
这段时间 Claude Code 神器也给干冒烟~~~
靠着神器,项目能这么快成型,说实话有点超出预期。
功能虽然基本齐了,但还有不少细节要打磨——搜索的精度、图谱的布局、AI 的提示词,都还有优化空间。就当是块长期养着的自留地,后面有空慢慢加强吧。
