# rag-mini-demo **Repository Path**: webthree/rag-mini-demo ## Basic Information - **Project Name**: rag-mini-demo - **Description**: 轻量级RAG入门示例,展示检索增强生成核心流程,适合开发者快速理解与上手构建基础AI问答应用。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-11-11 - **Last Updated**: 2026-11-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RAG 最小知识库 Demo 这是一个只处理 Markdown 的最小 RAG 项目,用一条 SQLite 数据链路演示: ```text Markdown -> 按标题、段落解析 -> 按模型 token 数切块 -> bge-small-zh-v1.5 分词与向量化 -> Float32 BLOB 写入 SQLite -> 查询向量化 -> 余弦相似度召回 Top-K ``` ## 运行 需要 Node.js 22 或更高版本。 ```powershell cd rag-mini-demo npm install npm run demo ``` 模型已经放在 `models/`,首次运行不需要下载。运行后会在脚本所在目录创建或更新 `rag-demo.sqlite3`。 ## 导入和检索 ```powershell node rag-demo.js ingest README.md node rag-demo.js search "知识库如何把文档变成向量?" ``` 也可以使用 npm 参数: ```powershell npm run ingest -- README.md npm run search -- "知识库如何把文档变成向量?" ``` 导入同一路径的 Markdown 会替换旧版本;删除旧文档时,关联知识块会通过外键级联删除。 ## 建议阅读顺序 源码使用三类注释帮助阅读: - 函数上方的注释说明输入、输出、副作用和它在数据流中的位置。 - 关键变量与 SQL 约束旁解释“为什么这样设计”,而不只是复述代码。 - 容易混淆的检索、归一化和二进制转换处说明常见误区与生产环境差异。 第一次阅读时可以按下面的调用顺序走。先理解入库,再理解检索: 1. `run()`:识别 `demo`、`ingest`、`search` 命令并分发参数。 2. `configureModel()`:优先使用 `models/` 中的本地模型,找不到时才联网下载。 3. `openDatabase()`:创建 `documents`、`chunks`、`meta` 三张表,并启用外键级联。 4. `parseMarkdown()`:读取 Markdown,去掉 frontmatter,并按标题切小节。 5. `splitBlocks()` 与 `chunkMarkdown()`:先保留自然段落,再用模型 tokenizer 精确控制块大小。 6. `embedTexts()`:调用 BGE 模型,把文本转换成 512 维归一化向量。 7. `indexMarkdown()`:在事务中替换文档元数据和所有知识块。 8. `search()`:把问题映射到同一向量空间,扫描知识块并计算点积、排序、召回。 ## 动手理解数据流 运行 `npm run demo` 会依次打印解析、分词、向量化和召回结果。最值得观察的是: - 字符数不等于 token 数。切块是否合适以模型 tokenizer 计算出的 token 数为准。 - 每个知识块都带着所属标题,因此片段离开原文后仍保留一部分上下文。 - SQLite 中的向量是连续 Float32 字节,不是 JSON 数组,也不是 SQLite 原生向量类型。 - L2 归一化后的点积等于余弦相似度;分数只表示相关程度,不是答案正确的概率。 可以尝试修改 `rag-demo.js` 顶部的 `CHUNK_TARGET_TOKENS` 和 `CHUNK_MAX_TOKENS`,重新运行 `npm run demo`,比较知识块数量、长度和召回结果。也可以导入 README 后,用含义相近但字面 不同的两个问题检索,观察语义相似度是否比单纯关键词匹配更灵活。 ## 从本示例走向生产 RAG 本项目的职责到“召回最相关的知识块”为止。生产 RAG 通常还会继续: 1. 按相关度、去重、文档多样性等规则筛选召回结果。 2. 将用户问题和知识块组织进提示词,调用大语言模型生成回答。 3. 要求回答引用知识块来源,并处理“知识库没有答案”的情况。 4. 增加文档增量更新、权限隔离、向量索引、关键词与向量混合检索等能力。 因此,`search()` 的 Top-K 结果是“可供下一步使用的资料”,不是最终答案。 ## 数据库 - `documents`:文档来源、标题和导入时间。 - `chunks`:知识块正文、所属标题、token 数和 2048 字节向量 BLOB。 - `meta`:记录当前向量模型名称和维度。当前示例只记录元数据,不会在更换模型后自动迁移旧向量。 当前检索为了便于理解,会扫描全部向量。正式项目在知识块很多时,应改用向量索引 或“向量检索 + 关键词检索”的混合召回。