rag-from-scratch
从零实现 RAG 流水线,用 Node.js 亲手拆解 Embedding、向量检索与上下文增强的每
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
从零实现 RAG 流水线,用 Node.js 亲手拆解 Embedding、向量检索与上下文增强的每
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象你向一个 AI 助手提问:"公司去年 Q3 的收入是多少?"它回答得头头是道,但你追问数据来源,它却支支吾吾——因为它根本没有访问你公司数据库的权限。这就是 RAG(检索增强生成)要解决的核心问题:让大语言模型在回答问题前,先去"图书馆"查一查真实资料。
然而,大多数 RAG 教程上来就甩给你 LangChain 的 API 调用、Chroma 向量数据库的连接方式,底层原理一概不提。你调用的是 chain.invoke(),但 Embedding 怎么把文字变成数字?向量检索为什么能找到"语义相似"的内容?Context 怎么拼进 Prompt?——全是黑箱。
pguso/rag-from-scratch 正是为打破这个黑箱而生。这个 GitHub 项目用纯 Node.js 从零实现 RAG 的每一个环节:不依赖 LangChain、不调用云端 API、不使用第三方向量库,所有代码都是教学导向,每一行都有详细注释。
本项目作者 pguso 是一位活跃的 GitHub 开发者,他的核心理念可以概括为一句话:"让 AI 工具的可理解性和可访问性回到开发者手中"。
pguso 的成名作是 ai-agents-from-scratch,该项目同样从零实现了 AI Agent 的核心组件(ReAct、Tool Use、Memory 等),获得了数千 star。在此基础上,他选择继续深耕 RAG 领域,推出了本项目。
RAG 之所以值得单独成项目,是因为它虽然概念简单,但实现细节极其繁杂:
每一个问题都有无数种解法,但没有哪个教程会告诉你"为什么这样选"。本项目就是要填上这个坑。
项目采用典型的模块化架构,将 RAG 流水线拆分为六个核心模块,每个模块都可以独立使用或替换:
负责将各种格式的原始数据加载为统一格式。目前支持:
pdf-parse):从 PDF 文件中提取文本将长文档切分为适合 Embedding 的小块(Chunk)。切分策略直接影响检索质量:
将文本转换为高维向量。项目同时支持两种方案:
本地方案(node-llama-cpp):
云端方案(OpenAI):
text-embedding-3-small API关键代码位于 src/embeddings/EmbeddingModel.js,实现了统一的 Embedding 接口,支持缓存(EmbeddingCache.js)避免重复计算。
存储 Embedding 向量并提供相似度检索。项目实现了多个后端:
| 后端 | 说明 | 适用场景 |
|---|---|---|
| InMemoryVectorStore | 纯内存实现,无需额外服务 | 开发测试、快速原型 |
| LanceDBVectorStore | 嵌入式向量数据库,持久化存储 | 本地生产环境 |
| QdrantVectorStore | 对接 Qdrant 向量数据库 | 需要高性能和云端部署 |
所有 Vector Store 都继承自 BaseVectorStore,保证接口一致性。
根据用户 Query 从向量数据库中检索相关文档。项目实现了多种检索策略:
将上述模块串联成完整的 RAG 流水线:
项目的 README 定义了一条清晰的学习曲线,从最简单的演示到完整的生产级 RAG:
00_how_rag_works/)用 70 行纯 JavaScript 展示 RAG 的本质:检索 + 生成。没有任何外部依赖,使用最朴素的关键词匹配来演示"给定问题 → 找相关文档 → 用文档内容回答"的全流程。这个例子故意"简单粗暴",目的是让读者先理解 RAG 在做什么,再去关心"怎么做得好"。
01_intro_to_llms/)介绍如何用 node-llama-cpp 本地加载 GGUF 格式的 LLM,以及如何用 OpenAI API 调用云端模型。为后续生成阶段做铺垫。
02_data_loading/)从 PDF 文件中提取文本,处理编码问题,去除噪声内容。这是 RAG 流水线的数据入口。
03_text_splitting_and_chunking/)深入讨论 Chunk 大小、Overlap、切分边界等问题。不同的切分策略对检索召回率有显著影响。
04_intro_to_embeddings/)从词袋模型到 Transformer,深入浅出讲解 Embedding 如何将文字映射为向量。特别适合没有 NLP 背景的后端开发者。
05_building_vector_store/)手把手实现一个简化版向量数据库,包含:
06_retrieval_strategies/)高级检索技术的实战讲解:混合检索如何融合关键词和语义?MMR(最大边际相关性)如何避免检索结果同质化?Query 改写如何提升召回率?
作为教学项目,pguso/rag-from-scratch 对硬件要求相对宽松:
最低配置(纯 CPU 运行):
推荐配置(本地 Embedding):
离线运行能力: 项目设计上优先支持本地 LLM(通过 node-llama-cpp),不需要 OpenAI API Key 也能完整运行 Embedding 和生成阶段。只需在 .env 中配置本地模型路径即可。
一个有趣的问题是:RAG 通常是 Python 的天下(LangChain、LlamaIndex、Chroma 全是 Python),为什么这个项目选择 Node.js?
作者 pguso 的解释是:"JavaScript/TypeScript 开发者数量远超 Python 开发者,但在 AI 领域被严重忽视了"。许多前端或全栈工程师想了解 AI 原理,却被 Python 门槛挡在门外。本项目降低了这一门槛,让 JavaScript 开发者也能从零理解 RAG 的每个细节。
技术栈亮点:
type: "module",全面拥抱现代 JavaScriptpdf-parse、openai、node-llama-cpp 等成熟 npm 包没有项目是完美的,pguso/rag-from-scratch 也有其局限性:
生产环境不友好:作为教学项目,代码追求可读性而非性能。InMemoryVectorStore 每次重启数据丢失,不适合生产使用。
缺乏测试覆盖:项目几乎没有单元测试和集成测试,代码质量依赖作者手动维护。
Embedding 模型限制:本地 Embedding 使用的是 LLM(Qwen 系列)而非专门的 Embedding 模型(如 bge 系列),向量质量可能不如专业 Embedding 模型。
不处理多语言:RAG 在跨语言场景(如中文文档 + 英文问题)下的处理未在项目中涉及。
更新维护状态:作者最后一次 commit 距今已有数月,LangChain/LlamaIndex 等快速迭代的情况下,教学代码可能存在 API 滞后。
pguso/rag-from-scratch 的价值不仅在于代码本身,更在于它代表了一种**"逆向工程"**的学习方法论。
在 AI 工具越来越傻瓜化的今天,很多人会用 LangChain 搭 RAG,却不知道 Embedding 的原理、不理解向量检索的数学基础。一旦遇到问题(比如检索结果质量差、Context 溢出),就束手无策。
本项目用 7 个渐进式的示例,将 RAG 的每个环节拆解到"能用代码解释清楚"的程度。这对于:
星标数 1457、fork 数 173 的数据表明,这种"从零理解"的学习方式确实击中了大量开发者的痛点。
本报告基于 pguso/rag-from-scratch v1.0.0(main 分支,2026 年 6 月)源码分析生成。