本文是「从零搭建私人 RAG 实战」专栏的第二篇,专注于 CorpRAG 项目的技术栈介绍和本地开发环境配置。
前言:为什么需要专门的环境准备章节?
在「从零搭建私人 RAG 实战」的第一篇中,我们主要聚焦于如何用 Markdown 沉淀技术决策与业务决策。但是,要真正开始构建 RAG 系统,我们需要先了解项目使用的技术栈,并把本地开发环境准备就绪。
这一章将:
- 详细介绍 CorpRAG 使用的技术栈及其各自作用;
- 梳理整个项目的目录结构与分层职责;
- 一步一步指导你完成本地开发环境的配置;
- 确保所有依赖都正确安装,为后续的索引和检索开发做好准备。
一、CorpRAG 使用的技术栈
根据当前项目的 package.json,主要技术如下:
| 技术 | 在项目中的作用 |
|---|---|
| TypeScript | 编写文档索引、检索和服务代码 |
| Node.js 20+ | 项目运行环境 |
| LangChain.js | 提供 Document、文本分块、Embedding 和 VectorStore 等抽象 |
| Ollama | 在本地运行 Embedding 模型 |
nomic-embed-text | 将文档和用户问题转换为向量 |
| LanceDB | 在本地保存向量、正文和元数据,并执行相似度搜索 |
| MCP SDK | 将知识库检索能力提供给 Claude Code 等 AI 客户端 |
gray-matter | 解析 Markdown 顶部的 YAML Frontmatter |
| Zod | 校验配置和 MCP 工具输入 |
tsx | 在开发阶段直接运行 TypeScript |
tsup | 将 TypeScript 构建为可执行的 ESM 产物 |
这里需要区分几个容易混淆的角色:
- Ollama 是本地模型运行服务;
nomic-embed-text是实际生成向量的 Embedding 模型;- LangChain.js 负责连接文档、分块器、模型和向量库;
- LanceDB 负责保存和检索向量;
- MCP 负责把检索能力暴露给 AI 客户端。
MCP 本身不负责生成向量,也不负责相似度搜索。它是 RAG 系统的接口层。
整个最小链路可以表示为:
Markdown 决策文档
↓ 加载与分块
Ollama + nomic-embed-text 生成向量
↓
LanceDB 保存向量、正文和元数据
↓
根据任务执行语义检索
↓
MCP 返回相关决策片段和来源
↓
Claude Code 使用项目知识完成任务
二、项目目录结构
了解技术栈后,再来看这些技术在项目中分别落在哪些目录和文件里。为了突出核心代码,下面省略了 node_modules/、.git/ 等无须手动维护的目录:
CorpRAG/
├── data/ # 业务文档与本地向量数据
│ ├── EXT-BADR.md # EXT 系统的业务架构决策
│ ├── EXT-FADR.md # EXT 系统的前端架构决策
│ ├── FR-BADR.md # FR 系统的业务架构决策
│ ├── FR-FADR.md # FR 系统的前端架构决策
│ ├── GA-BADR.md # GA 系统的业务架构决策
│ ├── GA-FADR.md # GA 系统的前端架构决策
│ └── vector-db/ # 索引时生成的 LanceDB 数据目录
├── src/ # TypeScript 源码
│ ├── cli/
│ │ └── index-cli.ts # 知识库索引命令行入口
│ ├── infrastructure/ # 外部能力与基础设施封装
│ │ ├── document-loader.ts # 加载 Markdown 并解析 Frontmatter
│ │ ├── embeddings.ts # 封装 Ollama Embedding 模型
│ │ ├── text-splitter.ts # 文档分块
│ │ └── vector-store.ts # LanceDB 连接、写入与查询
│ ├── mcp/
│ │ └── server.ts # MCP Server 和工具定义
│ ├── rag/ # RAG 核心流程
│ │ ├── indexer.ts # 文档加载、分块、向量化与入库
│ │ └── retriever.ts # 问题向量化与相似度检索
│ ├── config.ts # 系统、模型、分块和路径配置
│ └── stdio.ts # MCP stdio 传输入口
├── .gitignore # Git 忽略规则
├── package.json # 依赖、Node.js 版本与 npm 脚本
├── package-lock.json # npm 依赖版本锁定文件
└── tsconfig.json # TypeScript 编译配置
其中,data/vector-db/ 并不是需要提前创建和维护的源码目录。首次执行索引后,LanceDB 会在这里生成本地数据库文件;执行 npm run build 后,项目根目录还会生成 dist/ 构建产物目录。
1. src/infrastructure:封装外部能力
这一层负责处理“如何调用外部组件”:
document-loader.ts读取 Markdown 文件,并通过gray-matter解析 YAML Frontmatter;text-splitter.ts使用 LangChain.js 将长文档切分为适合向量化的片段;embeddings.ts连接 Ollama,并调用nomic-embed-text生成向量;vector-store.ts负责连接 LanceDB,完成向量写入和相似度查询。
把这些实现集中在基础设施层,可以避免 RAG 主流程直接依赖大量第三方 API 细节。
2. src/rag:组织索引与检索流程
这一层负责“按什么顺序完成 RAG 任务”:
indexer.ts组织文档加载、文本分块、向量生成和向量入库;retriever.ts接收查询条件,执行语义检索并整理结果。
因此,infrastructure 提供单项能力,rag 则把这些能力组合成完整业务流程。
3. src/cli 与 src/mcp:两个使用入口
项目提供两类入口,但它们复用同一套 RAG 能力:
npm run index
↓
src/cli/index-cli.ts
↓
src/rag/indexer.ts
↓
加载文档 → 分块 → 生成向量 → 写入 LanceDB
npm run stdio
↓
src/stdio.ts
↓
src/mcp/server.ts
↓
src/rag/retriever.ts
↓
生成问题向量 → 查询 LanceDB → 返回相关文档片段
config.ts 是两条链路共享的配置中心。它定义了系统列表、Ollama 地址、Embedding 模型、分块大小、检索数量、文档目录和向量数据库目录,并允许通过环境变量覆盖默认值。
这样的目录划分形成了清晰的依赖方向:入口层调用 RAG 核心层,RAG 核心层再调用基础设施层。后续实现具体功能时,我们会沿着这个结构逐步展开。
三、准备本地开发环境
1. 安装 Node.js 20+
先确认 Node.js 版本:
node -v
项目要求:
v20.x.x 或更高版本
然后安装依赖:
npm install
2. 安装并启动 Ollama
安装 Ollama 后,确认命令可以正常执行:
ollama --version
下载项目使用的 Embedding 模型:
ollama pull nomic-embed-text
查看本地模型列表:
ollama list
需要注意,nomic-embed-text 是 Embedding 模型,只负责把文本转换为向量,不负责生成自然语言回答。
3. 准备 Markdown 决策文档
至少准备一份 BADR 和一份 FADR:
data/PROJECT-BADR.md
data/PROJECT-FADR.md
建议先各写一条真实决策,不要为了测试一次性制造大量空洞内容。
4. 检查项目脚本
当前项目提供了以下命令:
# 运行索引相关 CLI
npm run index
# 以 stdio 方式启动 MCP Server
npm run stdio
# 构建项目
npm run build
# 运行构建后的 MCP Server
npm run start
本篇只要求完成文档和环境准备。LanceDB 不需要单独部署服务,后续运行索引程序时会在本地创建向量数据目录。
本章完成了什么?
这一篇完成了 CorpRAG 项目的技术栈介绍和本地开发环境准备:
- 梳理了 CorpRAG 使用的完整技术栈;
- 解释了各个技术组件在 RAG 链路中的作用;
- 认识了项目目录结构、代码分层和两条核心入口链路;
- 完成了 Node.js 20+ 环境的配置;
- 安装了 Ollama 和 nomic-embed-text Embedding 模型;
- 介绍了项目的基本脚本命令。
现在你的本地开发环境已经准备就绪!
总结
技术栈的选择是构建 RAG 系统的基础,而稳定的本地开发环境则是后续开发的保障。
- Ollama 让我们可以在本地运行 Embedding 模型;
- LangChain.js 提供了统一的抽象层,连接文档、模型和向量库;
- LanceDB 作为本地向量数据库,无需额外部署服务;
- MCP 则把检索能力暴露给 Claude Code 等 AI 客户端。
环境准备就绪后,下一篇我们将回到决策文档的处理,从 Markdown 文档加载和文本分块开始,逐步实现 CorpRAG 的索引链路。