先编译再检索:一个不用 embedding 的开源知识库

tybot2025 2026-08-28 15:28 1

市面上大多数「知识库问答」工具的套路都差不多:把文档切块、算 embedding 、塞进向量库,提问时按相似度召回若干碎片喂给 LLM 。KaaS 做了两个和主流不太一样的选择:



  1. 先编译再检索:不直接对原始碎片做 RAG 。先用 LLM 把散乱内容编译成一篇篇结构化的 Markdown Wiki 文章,再在这上面做检索。

  2. 不用 embedding:检索阶段没有向量库、没有相似度计算。文章目录直接喂给 LLM ,让它像人翻目录一样选页、读全文。


这篇讲整套系统的骨架和几个关键取舍,单个机制的细节留给后续文章。




解决什么问题


KaaS 最初是我们内部的一个工具。知识散落在文档、会议、邮件里,每当有人转岗或离开,他积累的上下文就跟着走了,接手的人要花几周重新拼凑。


我们要的是让散乱输入沉淀成可读、可编辑、能长期演进的知识资产:人能直接打开读的 Markdown ,而不是黑盒向量库。这也定了架构的走向:编译质量第一,检索只是编译产物之上的一层薄导航。


把散乱笔记蒸馏成结构化、可读的 Wiki ,再检索




带来了什么价值


对使用者来说,KaaS 的价值集中在几点:


先编译成结构化 Wiki 再检索,而不是切块加向量召回



  • 散乱的笔记、文档、会议记录被编译成分类清晰、带溯源的 Markdown Wiki ,能长期积累复用。

  • 用自然语言提问,拿到带引用的回答,同一个问题不用反复被问第二遍。

  • 产出是纯 Markdown:可读、可 git 版本管理、可手改。AI 生成、人工校准,质量随用随涨。

  • 部署轻,docker compose up 或 CLI 一键启动,默认 SQLite ,无向量库重依赖。

  • 通过 MCP 的 ask 工具,Claude Code 、Codex 、openclaw 都能把这套 Wiki 当知识源直接查询。

  • 对接任意 OpenAI-compatible 端点,可以全本地跑,数据不出境。




怎么做到的


整体架构


KaaS 系统架构


三层分工:


























技术 职责
Web UI React + Vite + shadcn/ui Chat / Submit / Wiki / Status 四个页面
Go Backend 标准库 net/http REST/SSE API 、Worker Pool 、任务队列、MCP 端点
Python AI 引擎 kb-ai ( uv ) 编译流水线、LLM 迭代检索、Chat

存储默认 SQLite (零依赖,go run 即可跑),存任务队列和编译状态;检索走纯 LLM 迭代,不依赖任何嵌入模型。


检索不用 embedding ,让 LLM 直接翻目录


这是 KaaS 和 naive RAG 的关键差别。编译阶段会维护一份 master-index.md 作为全量文章目录(标题加摘要)。检索时不做向量召回,而是把这份目录连同问题一起喂给 LLM ,让它选出最相关的文章路径,再把选中的文章整篇读进来做回答上下文。


核心就三步:


store = KBStore(kb_dir, read_only=True)
catalog = store.existing_articles() # 1. 读 master-index 目录
if not catalog:
return []
meta_by_path = {a.path: a for a in catalog}
selected = _select_relevant(catalog, query, model, max_select=max_articles) # 2. LLM 选页
return _read_selected(store, meta_by_path, selected) # 3. 读全文

LLM 选页就是一段结构化 prompt ,让模型从目录里挑路径并返回 {"paths": [...]};选中的页整篇读入,仅按 MAX_ARTICLE_CHARS = 12_000 截断以控制 prompt 预算。全流程没有一处 import 向量库或 embedding 模型。


这套方案能成立,是因为编译已经把噪声去掉了:进入检索的是结构化、去重后的文章,目录里的标题和摘要足以让 LLM 导航。好处是部署轻,不需要 chromadb / sentence-transformers / pytorch 这些重依赖,镜像小、无需预下载模型。代价是:只靠目录摘要导航,一篇文章如果只在正文深处才和问题相关、标题摘要里没体现,就可能选不到。这个「 body-depth 召回」缺口是否值得引入向量检索,留待后续按价值评估。


编译流水线:Extract → Classify → Write → Index


检索能这么轻,前提是编译够重。KaaS 的编译是一条 4 阶段流水线:



  • Extract:从原始文本提取概念、实体、决策、行动项

  • Classify:把提取结果映射到已有文章,或标记为新建

  • Write:创建/合并 Markdown 文章

  • Index:更新 Markdown 索引( master-index / topic-index )


服务端把 Classify→Write→Index 编排成一条带并发和 SSE 进度的流水线。工程难点在去噪(单个 LLM 调用卡死不能拖垮整批)和去重(并行分组不能各自「发明」同名文章),这两点在系列首篇《 4 阶段编译流水线:先编译再检索,如何去噪去重》里已经展开,这里不再重复。


接进任意 AI agent:一个 ask tool 的 MCP 设计


编译好的 Wiki 不只给自家 Web UI 用,还能被任意支持 Model Context Protocol 的 agent ( Claude Code / Codex / openclaw )当成可问答的知识源。KaaS 的 MCP server 只暴露一个 ask 工具:


@mcp.tool()
def ask(query: str, paths: list[str] | None = None, model: str | None = None) -> dict:

它不重写检索逻辑,而是直接复用 chat core (run_server_chat_http):跑一遍 LLM 迭代检索,再让 LLM 生成带内联 [Title](path) 引用的答案。MCP 的 tools/call 是请求/响应式的,chat core 是流式的,所以 ask 用一个 collector 把流事件收集成完整答案再返回。


两种传输:stdio (默认,agent 本地 spawn kb-ai mcp,自包含)和 streamable-http 。远程场景由 Go 后端在 /mcp 原生服务,保持 :8080 单一对外 origin 。




小结


KaaS 的核心做法是把成本压在编译阶段:编译时做足去噪、去重、结构化,检索就能很轻,不用 embedding ,只让 LLM 翻目录读全文。也因为产出是 Markdown ,它能用 git 管理、手动编辑、被任意 agent 当知识源接入。


几个实现选择也遵循同一个思路:能简单就不复杂。检索用 LLM 迭代翻目录,没有额外堆一个向量库。


后续每篇会钻进一个机制:编译流水线的去噪去重(已发布)、为什么敢不用 embedding 、Worker 并发与故障恢复、ask tool 的 MCP 设计。代码都是公开的,感兴趣可以直接翻 GitHub 仓库。




致谢


KaaS 的核心思路受 Andrej Karpathy 的 「 LLM Wiki 」 gist 启发:把知识编译成一个持续演进、相互链接的 Wiki ,随时间沉淀复用,省掉每次提问都对原始数据重跑 RAG 的老路。感谢他把这个模式讲清楚了。




项目地址


https://github.com/bybit-exchange/kaas


欢迎使用 KaaS 并 star 支持我们!

最新回复 (5)
  • robinxplorer 08-28 16:13
    1
    不会巨慢吗?
  • zthxxx 08-28 17:05
    2
    @tybot2025 顺便问下架构图用什么 skill 画的?挺干净的
  • langsfang 08-28 17:54
    3
    有没有 benchmark, 能够证明这种方法的优势呢?
  • zuokanyunqishi 08-29 22:29
    4
    我用 python vb 了个简单知识库..
  • MAzrael 08-29 22:33
    5
    想问一下,这个架构有在超大规模知识库上测试过没,对比传统的 rag 和基于 KG 的增强,有进行过对比没
    1 、百万级文档的 Markdown 索引有多大,上下文会爆吗?
    2 、这个和 KG 有本质区别吗?按文中的 4 阶段流水线,感觉 KG 也可以做这个事,也能绕过 embedding 。
    3 、rag 情况下,不太理解这个绕过 embedding 的目的是啥,还是说你们这个思路在召回上能够有巨大提升?
    4 、感觉这个 4 个阶段跑下来,每个阶段之间都有“精度损失”,并且按照 LLM WIKI 的思路,索引——聚合知识——原信息,LLM 在回答时需要跑好几轮,token 成本应该高不少
* 帖子来源V2EX
返回