在理论课程中,我们深入探讨了 RAG(检索增强生成)的核心原理、架构,以及从"流水线"到"智能体"的演进路径。
本项目是理论课程的配套实战环节。我们将跳出"纸上谈兵",使用 TypeScript 结合业界前沿的 LangChain 生态和 LangGraph 编排框架,配合 Chroma 向量数据库,从零搭建一个具备自我反思、自我修正能力的 Agentic RAG(智能体 RAG) 系统。
通过本项目,你将深入理解 RAG 系统内部的数据流转与决策逻辑,而不仅仅是调用现成接口。
一个完整的 TypeScript 项目仓库,包含两个循序渐进的实践模块:
对应代码目录: src/1-simple-rag
核心内容:
核心功能:
data/*)转化为向量索引对应代码目录: src/2-agentic-rag
核心内容:
核心功能:
语言:TypeScript / Node.js
编排框架:
向量数据库:Chroma(本地 Docker 部署)
模型服务:OpenAI (gpt-3.5/gpt-4) 或兼容 OpenAI 格式的模型(如 Ollama 或 CNB 提供的大模型接口)
本仓库为教学实践仓库,作业提交采用 Fork 仓库 → 修改代码并提交 → 向当前仓库提交 PR 的形式。
GraphState 增加 history 字段,使 Agent 能够记住之前的对话上下文(可选)src/file-loaders/index.ts 和 src/file-splitter/index.ts,注册更多 loader 支持 PDF、Word、Excel 等格式文档的加载和分割(可选)rag-bootcamp/ ├── data/ # 示例文档数据 ├── src/ │ ├── models/ # 模型调用类 │ ├── db/ # 向量数据库调用类 │ ├── file-loaders/ # 文件加载类 │ ├── file-splitter/ # 文件分割类 │ ├── 1-simple-rag/ # 实践1:基础 RAG 代码 │ └── 2-agentic-rag/ # 实践2:Agentic RAG 代码 (LangGraph) ├── docker-compose.yaml # Chroma 数据库启动配置 ├── .env.example # 环境变量模版 └── package.json # 依赖配置
rag:ingest 数据入库)1-simple-rag 代码,理解 Splitter 和 Embedding 的作用2-agentic-rag,重点理解 graph.ts 中的 addConditionalEdges 逻辑,观察 Agent 如何进行"反思";尝试修改 Prompt 或更换测试文档,观察系统表现Q:运行 rag:ingest 时报错 ChromaConnectionError: Failed to connect to chromadb?
A:请检查以下两项:
docker ps),若没有,重新执行 docker compose up -d.env 中的 CHROMA_DB_URL 是否正确(通常是 http://localhost:8000)Q:执行本地向量化模型时报错 [E:onnxruntime:onnxruntime-node, env.cc:234 ThreadMain]?
这个错误的原因在于开源的onnx在分配cpu时只能从0开始,因此如果一个docker的cpuset.cpus不是从0开始的就可能报这个错误。
可以忽略此报错正常运行。
Q:必须使用 OpenAI 吗?
A:代码默认配置为 OpenAI。如果需要使用 Azure 或 Ollama,请修改 src/models/llm.ts 文件。
Q:必须使用 本地 embeddings 模型吗?
A:代码默认使用由 Chroma 提供的本地运行的 embeddings 模型( all-MiniLM-L6-v2 )。如果需要其他模型,请修改 src/models/embedding.ts 文件。
Q:LangGraph 是什么?为什么要用它?
A:LangGraph 允许我们定义"循环"结构。传统的 Chain 是直线流程(A→B→C),而 LangGraph 支持条件判断(如"如果 B 效果不好,跳回 A 重做"),这是构建智能 Agent 的关键特性。
完成本项目后,你将掌握:
✅ 全栈思维:使用 TypeScript 进行 AI 工程开发
✅ 向量工程:Chroma 数据库的实际操作与数据治理
✅ 图编排能力:理解 StateGraph,掌握条件边(Conditional Edge)和节点(Node)的交互
✅ Agent 原理:亲手实现"反思"与"工具调用"模式
本项目使用 Chroma 作为本地向量库,请确保已安装 Docker。
# 在项目根目录下运行
docker compose up -d
等待片刻,确保 Chroma 服务在 localhost:8000 启动。
# 安装依赖
npm install # 建议使用 bun install ,速度更快
# 配置环境变量
# CNB 远程开发环境下直接执行,自动替换 CNB 环境变量
envsubst < .env.example > .env
# 或手动复制并编辑 .env 文件,填入你的 OPENAI_API_KEY
# cp .env.example .env
知识入库
npm run rag:ingest
基础查询测试
npm run rag:query
运行智能体
npm run agent:run
命令行交互式对话(新增)
npm run agent:cli
新增 src/2-agentic-rag/cli.ts,支持实时多轮对话:
使用方法:
npm run agent:cli
交互命令:
clear / cls → 清空屏幕help / h / ? → 显示帮助exit / quit / q → 退出程序特性:
新增 webSearchNode,当本地知识库没有答案时自动联网搜索:
配置:
# 在 .env 文件中启用
ENABLE_WEB_SEARCH=true
TAVILY_API_KEY=your_tavily_api_key_here
工作流程:
注意:需要先在 Tavily 注册获取 API Key。
已在 GraphState 中新增 history 字段,支持多轮对话:
配置:
# 在 .env 文件中启用(默认已启用)
ENABLE_HISTORY=true
使用场景:
MAX_HISTORY_ROUNDS)结合向量检索和关键词检索,提高召回率:
配置:
# 在 .env 文件中启用
ENABLE_HYBRID_RETRIEVE=true
工作原理:
优势:
使用 LLM 对检索结果按相关性重新排序:
配置:
# 在 .env 文件中启用
ENABLE_RE_RANK=true
工作原理:
优势:
扩展了文件加载器,支持更多文档格式:
支持的格式:
.txt - 纯文本文件.md - Markdown 文件.csv - CSV 表格文件.json - JSON 文件.pdf - PDF 文档可扩展格式(需安装额外依赖):
.docx / .doc - Word 文档.xlsx / .xls - Excel 表格.pptx - PowerPoint 演示文稿.html - HTML 网页如何添加更多格式支持:
npm install @langchain/community
src/file-loaders/index.ts 中注册新的 loader:import { UnstructuredLoader } from "@langchain/community/document_loaders/fs/unstructured";
// 在 LOADER_REGISTRY 中添加
".docx": UnstructuredLoader,
".xlsx": UnstructuredLoader,
所有功能开关都可以通过 .env 文件配置:
# 功能开关
ENABLE_HYBRID_RETRIEVE=false # 混合检索
ENABLE_RE_RANK=false # 文档重排序
ENABLE_WEB_SEARCH=false # Web 搜索
ENABLE_HISTORY=true # 对话历史
nodes.ts 中调整 prompt 模板extractKeywordsNode 提取关键词hybridRetrieveNode 结合向量+关键词检索reRankNode 使用 LLM 重新排序cli.ts 交互式命令行界面webSearchNode 集成 Tavily APIGraphState 中添加 history 字段updateHistoryNode 更新历史src/file-loaders/index.ts 支持更多格式祝你编码愉快!如有问题,请回顾理论课程 PPT 或查阅 LangChain 和 Chroma 官方文档。🎉