数据截至 (上游 commit 9ad3e4e49aa3)
Kotaemon — 这是什么 · 全景 · 阅读地图
30 秒导读: Kotaemon 是一个开源的 RAG(Retrieval-Augmented Generation,检索增强生成:先从你的文档里查资料,再让大模型据此作答)项目。它有两层——底层
kotaemon是一套可复用的 RAG 组件库,上层ktem是一个开箱即用的 Gradio 问答网页应用。终端用户拿它上传文档、聊天问答、看带引用的答案;开发者拿它当积木,拼自己的 RAG 流水线。本章只做总览和路由,不深入任何子系统——细节都在后面各章。
1. 这是什么(零基础也能懂)
一句话定义
Kotaemon = 一个干净、可定制的"和你的文档聊天"的 RAG 工具,同时面向两类人:想直接用的终端用户,和想搭自己 RAG 管线的开发者(见 README.md 的 Introduction 段)。
解决什么问题
假设你有一堆 PDF、Word、网页,想 问它们问题——比如"这份合同的违约金条款是怎么写的?"。直接把整堆文档塞给大模型行不通:太长、贵、还会让模型胡编。
RAG 的套路是:先检索(retrieve)出最相关的几段文字当"证据",再让模型只根据这些证据作答,并标出引用。Kotaemon 把这套流程做成了产品——你上传文档,它切分入库;你提问,它检索+作答,还在浏览器里高亮出答案来自原文的哪一段。
给谁用
| 角色 | 怎么用 | README 里的说法 |
|---|---|---|
| 终端用户 | 打开网页,上传文档,聊天问答,看带引用的答案 | "End users: Those who use apps built with kotaemon" |
| 开发者 | import kotaemon,用它的组件拼自己的 RAG 管线 | "Developers: Those who built with kotaemon" |
| 贡献者 | 给这个 repo 提 PR | "Contributors: Those who make kotaemon better" |
它能做什么(README 的 Key Features 提炼)
- 自托管的文档问答 Web-UI:多用户登录、私有/公开文档集合、分享对话。
- 管理 LLM 与 Embedding 模型:本地模型(Ollama、llama-cpp)和 API(OpenAI、Azure、Cohere、Groq)都支持。
- 混合 RAG 管线:默认就带全文检索 + 向量检索的混合检索,再加重排,保证检索质量(细节见 03-hybrid-retrieval.md)。
- 带引用 + 文档预览:答案给出详细引用,可在内置 PDF 查看器里高亮原文(细节见 04-qa-citation.md)。
- 复杂推理:问题分解、ReAct、ReWOO 等 agent 式推理(细节见 05-agentic-reasoning.md)。
用起来什么样
装好之后,启动只有一行(README.md:181):
python app.py
浏览器会自动打开,默认用户名/密码都是 admin。上传文档 → 在 Chat 页提问 → 得到带引用高亮的答案。开发者视角则是把 kotaemon 当库调用,后面各章会拆开每个组件。
一句话直觉
把 Kotaemon 想成"给文档装了个搜索引擎 + 会引用的助教":kotaemon 库是助教的各种技能(读文档、切 分、检索、作答),ktem 应用是把这些技能摆到一个网页课堂里、让你点几下就能用的外壳。
2. 全景图(它大概怎么转)
双包结构:库 vs 应用
Kotaemon 这个仓库其实是两个 Python 包,分层清晰:
| 包 | 是什么 | pyproject 里的描述 | 依赖谁 |
|---|---|---|---|
kotaemon | 可复用的 RAG 组件库,建在 theflow 之上 | "Kotaemon core library for AI development."(libs/kotaemon/pyproject.toml:22) | theflow、llama-index、langchain 等 |
ktem | 一个 Gradio 应用,用可插拔的 index/reasoning 组合出问答界面 | "RAG-based Question and Answering Application"(libs/ktem/pyproject.toml:20) | gradio、sqlmodel,以及 kotaemon |
关键分工用一句话说清:
kotaemon(在libs/kotaemon/kotaemon/)提供积木——base/(组件基类)、indices/、llms/、embeddings/、rerankings/、storages/、agents/等。所有积木都继承同一个基类BaseComponent(libs/kotaemon/kotaemon/base/component.py:9),因此能像乐高一样互相组合。这一层的原理见 01-component-model.md。ktem(在libs/ktem/ktem/)是外壳——它定义两个可插拔的扩展点:- index(索引):怎么把文档装进库、怎么检索。默认是
FileIndex。 - reasoning(推理):怎么从"问题"走到"答案"。默认是
FullQAPipeline,还有 ReAct、ReWOO 等。
- index(索引):怎么把文档装进库、怎么检索。默认是
这两个扩展点都在 flowsettings.py 里用点号字符串列出来,应用启动时按字符串动态导入。例如推理管线(flowsettings.py:319-324):
KH_REASONINGS = [
"ktem.reasoning.simple.FullQAPipeline",
"ktem.reasoning.simple.FullDecomposeQAPipeline",
"ktem.reasoning.react.ReactAgentPipeline",
"ktem.reasoning.rewoo.RewooAgentPipeline",
]
应用启动时 App.register_reasonings() 逐个 import_dotted_string 把它们注册进一个全局字典 reasonings(libs/ktem/ktem/app.py:95-103)。索引同理用 KH_INDICES / KH_INDEX_TYPES(flowsettings.py:370-404)。这就是"可插拔"的实现——加一个自己的类、往列表里填一行字符串,UI 上就多一个选项。
分层结构图
下面这张图从上到下就是"用户点开的网页 → 应用外壳 → 组件库 → 外部存储/模型"。左侧是 ktem 应用层,右侧是 kotaemon 库层。
用户浏览器 (Gradio Web-UI)
│
┌───────────────┴────────────────┐
│ ktem 应用 │
│ app.py → ktem.main.App.make() │
│ │
│ ┌──────────┐ ┌───────────┐ │
│ │ index │ │ reasoning │ │ ← 两个可插拔扩展点
│ │ FileIndex│ │FullQA/ReAct│ │ (由 flowsettings 里的
│ └────┬─────┘ └─────┬─────┘ │ 点号字符串动态注册)
└────────┼───────────────┼────────┘
│ 调用 │ 调用
┌────────┼───────────────┼────────┐
│ ▼ kotaemon 库 ▼ │
│ indexing retriever reasoning │
│ loaders embeddings llms │
│ splitters rerankings agents │
│ └─ 全都是 BaseComponent ─┘ │
└────────┬───────────────┬────────┘
▼ ▼
向量库/文档库 LLM / Embedding
(Chroma/LanceDB/ (OpenAI/Ollama/
Elasticsearch…) Azure…)
一次问答的端到端主线(高层,不进代码)
这是理解整个 项目的主脊梁——一句提问从进到出走了哪几站:
用户提问
│
▼
① retriever 检索 ─→ 从索引里并行拉候选(向量 + 全文),再重排精选
│ (默认管线的 retrievers,见 04/03 章)
▼
② evidence 组装 ─→ 把检索到的文档拼成"证据"文本(+ 多模态图像)
│ PrepareEvidencePipeline
▼
③ answering 生成 ─→ 把 [问题 + 证据] 喂给 LLM,流式产出答案
│ AnswerWithContextPipeline
▼
带引用的输出 ─→ 答案 + 引用高亮 + 相关度分数,推回浏览器
在默认推理管线 FullQAPipeline 里,这条主线就是它 stream() 方法的骨架(libs/ktem/ktem/reasoning/simple.py:281):先 retrieve() 取文档(:108),再过 evidence_pipeline 得到证据(:295),最后 answering_pipeline.stream() 出答案并 prepare_citations 组织引用(:225)。每一站的具体机制都留给后面的章节,本章只到"看懂大盘"为止。
3. 阅读地图(建议顺序 + 每章一句话)
各章由浅入深排列,建议顺序即列表顺序:
| 顺序 | 章节 | 一句话讲什么 |
|---|---|---|
| 0 | index.md(本章) | 这是什么、双层全景、一次问答的主线、代码地图总表 |
| 1 | 01-component-model.md | 组件模型:所有积木都继承 BaseComponent,因此"一切皆可组合"——这是全项目的地基 |
| 2 | 02-indexing.md | 把文档装进库:文件怎么被加载、切分、向量化、写入索引 |
| 3 | 03-hybrid-retrieval.md | 混合检索与重排:并行跑向量检索 + 全文检索,再用 reranker 精 排 |
| 4 | 04-qa-citation.md | 生成答案与引用:证据怎么组装、带引证问答怎么做、附加物(高亮/分数)怎么来 |
| 5 | 05-agentic-reasoning.md | 可插拔推理:ReAct、ReWOO 与插件式架构,怎么加自己的推理管线 |
怎么读: 先读第 1 章打地基(理解 BaseComponent 后,后面全部机制都是同一套组合模型);想搞索引/检索就顺着 2→3;只关心问答与引用直接跳第 4 章;想扩展推理逻辑看第 5 章。
4. 代码地图(总表)
只列入口与总控——各子系统的详细代码地图在对应章节末尾。所有路径相对克隆根 libs/…;符号名可直接 grep 定位,比行号抗漂移。
| 主题 | 文件路径 | 符号名 |
|---|---|---|
| 应用启动入口(一行起服务) | app.py | App、app.make()、demo.queue().launch() |
| 库的顶层包(遥测关闭的 monkey-patch) | libs/kotaemon/kotaemon/__init__.py | (模块级) |
| 组件基类(全库地基) | libs/kotaemon/kotaemon/base/component.py | BaseComponent |
| 库对外导出的核心符号 | libs/kotaemon/kotaemon/base/__init__.py | BaseComponent、Document、Param、Node |
| 应用主类( 渲染 UI、注册扩展点) | libs/ktem/ktem/main.py | App、App.ui |
| 应用基类(启动时装配 index/reasoning) | libs/ktem/ktem/app.py | BaseApp、register_reasonings、index_manager |
| 推理管线全局注册表 | libs/ktem/ktem/components.py | reasonings |
| 默认推理管线(端到端主线) | libs/ktem/ktem/reasoning/simple.py | FullQAPipeline、retrieve、stream |
| 推理扩展点基类 | libs/ktem/ktem/reasoning/base.py | BaseReasoning、get_pipeline、get_info |
| 索引扩展点基类 | libs/ktem/ktem/index/base.py | BaseIndex |
| 索引管理器 | libs/ktem/ktem/index/manager.py | IndexManager |
| 全局配置(存储、索引、推理管线列表) | flowsettings.py | KH_REASONINGS、KH_INDICES、KH_INDEX_TYPES、KH_DOCSTORE、KH_VECTORSTORE |
下一步: 从 01-component-model.md 开始——先理解
BaseComponent这块地基,后面每一章讲的机制(索引、检索、问答、推理)本质上都是这套组合模型的不同拼法。