# knowledge-base **Repository Path**: tbaofoot/knowledge-base ## Basic Information - **Project Name**: knowledge-base - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-14 - **Last Updated**: 2026-08-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # knowledge-base:Chroma + bge-m3 本地知识库 AI 时代的个人/团队知识库:把 Markdown / 文本文档向量化入库, 支持「向量 + BM25」混合检索与带引用溯源的问答。 核心理论参考 `../Agent学习教程/03-RAG与知识库篇`(09–11 章)。 ## 架构与链路 ```text 离线索引(ingest) 在线问答(search / ask) ┌─────────────────────────┐ ┌──────────────────────────────┐ │ docs/*.md 文档加载 │ │ 查询 │ │ ↓ │ │ ↓ 两路粗召回 │ │ Markdown 结构化分块 │ │ 向量路(bge-m3 + Chroma) │ │ (标题路径进元数据与块文本)│ │ BM25 路(jieba + rank_bm25) │ │ ↓ │ │ ↓ RRF 融合(k=61) │ │ bge-m3 向量化(L2 归一化) │ │ 可选 rerank(cross-encoder) │ │ ↓ │ │ ↓ 带编号上下文拼装 │ │ Chroma 持久化入库 │ │ LLM 生成([n] 引用 + 留退路) │ └─────────────────────────┘ └──────────────────────────────┘ ``` 与教程理论的对应关系: | 实现 | 教程出处 | | --- | --- | | Markdown 按标题切分、标题路径写进元数据并前置到块文本 | 11 章 1.3 结构化切分 | | 超长小节递归切分 + overlap(500/80 字符) | 09 章 3.2 分块 | | 入库与查询共用同一个 bge-m3 嵌入函数 | 09 章 3.3「入库查询模型必须一致」 | | 向量归一化 + cosine 距离 | 10 章 3.1 归一化后度量等价 | | 向量 + BM25 两路召回、RRF 融合 | 10 章第六节混合检索 | | 可选 bge-reranker-v2-m3 精排 | 11 章第四节 rerank | | 生成 prompt:只依据资料、[n] 引用、允许「资料中没有相关信息」 | 09 章第五节 prompt 设计 | ## 快速开始 ```bat cd /d D:\文件\knowledge-base venv-win\Scripts\activate python main.py ingest python main.py search "入职多久可以休年假" ``` 虚拟环境为 `venv-win`(Windows Python 3.12,依赖已装好); 如需重建:`python -m venv venv-win` 后按 `requirements.txt` 注释安装。 模型权重在项目内 `models/`(HF_HOME 已指向它),首次运行无需下载。 # 1. 入库 docs/ 下的示例文档(首次运行自动下载 bge-m3,约 2.2GB) python main.py ingest # 2. 只检索,看命中块与分数 python main.py search "入职多久可以休年假" python main.py search "X9-PRO 的电池容量" # 型号精确匹配,BM25 路的强项 # 3. 检索 + LLM 生成(需先 cp .env.example .env 并填 API Key) python main.py ask "出差报销的流程是什么" # 4. 查看库统计 python main.py stats ``` ## HTTP / OpenAI 兼容 API ```bat python server.py # 监听 0.0.0.0:8000,首次请求懒加载模型(约 30 秒) ``` | 接口 | 说明 | | --- | --- | | `GET /api/stats` | 库内统计 | | `POST /api/search` | 混合检索,body:`{"query": "...", "top_n": 5}` | | `POST /api/ask` | 检索 + 生成,返回 `{answer, sources}` | | `GET /v1/models` | OpenAI 兼容模型列表,模型名 `knowledge-base-rag` | | `POST /v1/chat/completions` | OpenAI 兼容,内部执行 RAG | **对接现成聊天客户端**(Open WebUI / NextChat / LobeChat / Cherry Studio): 在客户端添加自定义 OpenAI 兼容服务,API 地址填 `http://127.0.0.1:8000/v1`, API Key 任意非空(如 `sk-local`),选择模型 `knowledge-base-rag` 即可。 交互式接口文档见 `http://127.0.0.1:8000/docs`。 把自己的知识文档(`.md` / `.txt`)放进 `docs/` 再执行 `ingest` 即可; 重复入库同名文件会先删除旧块,支持文档更新后重建。 ## 关键设计决策 - **不用 LangChain,直接依赖 chromadb / sentence-transformers**:链路透明, 每个环节(分块、向量化、融合、重排、拼装)都可单独调试, 也便于对照教程逐层排查效果问题(09 章 8.4)。 - **BM25 语料直接取自 Chroma 库**:两路检索保证是同一份数据,无冗余缓存。 - **rerank 默认关闭**:重排模型约 2.2GB 且只优化排序、不能弥补召回缺失 (11 章误区 2),先确认召回质量再开启:`.env` 中设 `RERANK_ENABLED=true`, 或命令行临时加 `--rerank`。 - **LLM 可缺省**:不配 API Key 时 `ask` 降级为仅展示检索结果, 知识库检索能力本身不依赖外部服务。 ## 目录结构 ```text knowledge-base/ ├── main.py # CLI:ingest / search / ask / stats ├── kb/ │ ├── config.py # 参数与模型配置(.env 可覆盖) │ ├── chunker.py # Markdown 结构化分块 + 递归切分 │ ├── embedding.py # bge-m3 单例封装、Chroma 嵌入函数、reranker │ ├── vectorstore.py # Chroma 入库 / 删除 / 统计 │ ├── bm25.py # jieba + rank_bm25 关键词路 │ ├── retriever.py # 两路召回 + RRF 融合 + 可选重排 │ └── generator.py # 上下文拼装 + LLM 生成 ├── docs/ # 知识文档(放这里,ingest 入库) └── data/ # Chroma 持久化数据(.gitignore) ``` ## 后续优化方向(对照 11 章 checklist) - 建评估集(真实问题 + 标注命中块),用 recall@k 回归分块与检索参数; - 查询改写 / 多轮对话指代还原(11 章第二节); - parent-child 分块:小块检索、大块生成(11 章 1.4); - PDF / Word 解析入库(需引入解析库); - 多租户 / 权限场景用 Chroma 元数据 where 过滤(10 章第七节)。