基于 RAG(Retrieval-Augmented Generation)的个人知识库问答 Agent。扫描指定目录下的 Markdown 学习笔记和 PDF 文档,进行清洗、切块、向量化后存入向量数据库,用户可以用自然语言提问,Agent 从知识库中检索相关内容并生成准确回答。
后端基于 NestJS + LangChain 构建,支持 Agent 驱动的工具调用、混合检索、SM-2 间隔复习、记忆系统和用户认证。
扫描目录 → 文本提取 → 清洗 → 分块 → 向量化 → 存入 PostgreSQL + pgvector
↓
提问 → Agent 循环(ReAct) → 调用工具检索 → LLM 生成带来源标注的回答
| 组件 | 技术 | 说明 |
|---|---|---|
| 后端框架 | NestJS | 模块化架构,依赖注入 |
| 大模型框架 | LangChain | LLM 调用、工具管理、RAG 管道 |
| 对话模型 | OpenAI / Ollama / 千文 / DeepSeek | 通过 .env 切换供应商 |
| Embedding | OpenAI / Ollama / 千文 / DeepSeek | 通过 .env 切换供应商 |
| 向量存储 | PostgreSQL + pgvector | 余弦距离检索,生产级可靠 |
| 记忆存储 | PostgreSQL | 用户画像、学习记录、复习计划 |
| 用户认证 | JWT + Passport + bcrypt | 登录/注册/资料管理/密码修改 |
| 前端 | React + Vite + Tailwind CSS | 聊天式 UI + 用户认证 + 深色模式 |
| 包管理 | pnpm workspace | Monorepo 统一管理 |
| 部署 | Docker + docker-compose | 一键部署 PostgreSQL + 前后端 |
- Node.js 18+
- pnpm 包管理器
- PostgreSQL 14+ 并启用 pgvector 扩展
- LLM API Key(以下任选其一):
pnpm installcd backend
cp .env.example .env编辑 .env,填入真实的 API Key 和数据库连接字符串。
确保 PostgreSQL 已安装 pgvector 扩展:
CREATE DATABASE rag_knowledge;
CREATE EXTENSION IF NOT EXISTS vector;pnpm dev:backend后端运行在 http://localhost:3000/api
pnpm dev:frontend前端运行在 http://localhost:5173
# 配置环境变量
echo "LLM_API_KEY=your-api-key" > .env.production
echo "EMBEDDING_API_KEY=your-api-key" >> .env.production
# 启动所有服务
docker-compose up -d访问 http://localhost 即可使用。
服务组件:
- PostgreSQL (pgvector/pgvector:pg16) — 端口 5432
- 后端 (NestJS) — 端口 3000
- 前端 (Nginx) — 端口 80
- 注册/登录 — 首次使用需注册账号,已登录后直接进入主页
- 上传文档 — 在侧边栏点击上传区域,支持 PDF、Markdown 和纯文本文件
- 扫描目录 — 在侧边栏点击"扫描本地目录"按钮,扫描指定目录下的 .md/.pdf/.txt 文件
- 自动处理 — 文本自动清洗、分块、向量化、存入 PostgreSQL
- 提问 — 在聊天框输入问题,Agent 会从知识库中检索并回答
- 复习 — Agent 推送复习提醒,生成学习总结
- 个人中心 — 管理账号信息、修改密码
通过 .env 文件中的 LLM_PROVIDER 和 EMBEDDING_PROVIDER 切换模型供应商。
LLM_PROVIDER=qianwen
LLM_API_KEY=sk-your-dashscope-key
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL=qwen2-7b-chat
EMBEDDING_PROVIDER=qianwen
EMBEDDING_API_KEY=sk-your-dashscope-key
EMBEDDING_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
EMBEDDING_MODEL=text-embedding-v3LLM_PROVIDER=openai
LLM_API_KEY=sk-your-openai-key
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o-miniLLM_PROVIDER=deepseek
LLM_API_KEY=sk-your-deepseek-key
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_MODEL=deepseek-chatLLM_PROVIDER=ollama
LLM_BASE_URL=http://localhost:11434
LLM_MODEL=llama3| 端点 | 方法 | 说明 |
|---|---|---|
/chat |
POST | 聊天(默认 Agent 模式,可传 mode: "rag") |
/chat/rag |
POST | RAG 模式问答 |
/chat/agent |
POST | Agent 模式问答 |
| 端点 | 方法 | 说明 |
|---|---|---|
/ingestion/text |
POST | 导入文本 |
/ingestion/file |
POST | 导入文件 |
/ingestion/directory |
POST | 导入目录 |
/ingestion/upload |
POST | 上传文件(multipart/form-data) |
/ingestion/scan |
POST | 手动触发目录扫描 |
| 端点 | 方法 | 说明 |
|---|---|---|
/auth/login |
POST | 登录 |
/auth/register |
POST | 注册 |
/auth/profile |
GET | 获取当前用户信息(需认证) |
/auth/profile |
PUT | 更新用户资料(需认证) |
/auth/change-password |
POST | 修改密码(需认证) |
| 端点 | 方法 | 说明 |
|---|---|---|
/memory/reviews |
GET/POST | 获取待复习主题 / 标记已复习 |
/memory/profile |
GET/POST/PUT | 获取/更新用户画像 |
/memory/topics |
GET | 主题频率统计 |
/memory/sessions |
GET | 最近学习记录 |
/memory/stats |
GET | 记忆系统综合统计 |
| 端点 | 方法 | 说明 |
|---|---|---|
/tools |
GET | 列出可用工具 |
/health |
GET | 健康检查 |
Agent 可调用 6 个核心工具(只读,无写入能力):
| 工具 | 类型 | 说明 |
|---|---|---|
scan_directory |
扫描 | 扫描指定目录下的笔记文件 |
read_file |
读取 | 读取指定文件的完整内容 |
search_notes |
检索 | 语义 + BM25 混合搜索笔记 |
list_tags |
检索 | 列出所有标签及使用频率 |
suggest_reviews |
记忆 | 获取待复习主题列表 |
summarize_recent |
记忆 | 生成近期学习总结 |
RAG/
├── backend/ # NestJS 后端
│ ├── src/
│ │ ├── main.ts # 应用入口
│ │ ├── app.module.ts # 根模块
│ │ ├── config/ # 配置模块
│ │ ├── core/ # 核心服务
│ │ │ ├── database.module.ts # PostgreSQL 连接池
│ │ │ ├── llm.service.ts # LLM 服务
│ │ │ ├── embedding.service.ts # Embedding 服务
│ │ │ ├── vector-store.service.ts # pgvector 向量存储
│ │ │ └── tools/
│ │ │ └── tool-registry.service.ts
│ │ ├── memory/ # 记忆系统
│ │ │ ├── memory-database.service.ts # PostgreSQL 记忆存储
│ │ │ ├── learning-tracker.service.ts
│ │ │ ├── memory-context.service.ts
│ │ │ └── sm2-algorithm.ts
│ │ ├── pipeline/ # RAG 管道
│ │ │ ├── ingestion.service.ts
│ │ │ ├── retrieval.service.ts
│ │ │ └── bm25-retriever.ts
│ │ ├── agent/ # Agent 循环
│ │ │ └── agent.service.ts
│ │ ├── tools/ # 工具实现
│ │ │ ├── scan-directory.tool.ts
│ │ │ ├── read-file.tool.ts
│ │ │ ├── note-tools.service.ts
│ │ │ └── tools.module.ts
│ │ ├── auth/ # 用户认证(JWT + Passport)
│ │ ├── user/ # 用户管理
│ │ └── controllers/ # API 控制器
│ ├── notes/ # 示例笔记目录
│ ├── .env.example
│ ├── Dockerfile
│ └── package.json
├── frontend/ # React 前端
│ ├── src/
│ │ ├── api/ # API 客户端
│ │ ├── components/ # UI 组件
│ │ ├── contexts/ # 认证上下文
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── pages/ # 页面(Chat/Login/Register/Profile)
│ │ ├── routes/ # 路由配置
│ │ └── App.tsx
│ ├── Dockerfile
│ ├── nginx.conf
│ └── package.json
├── docker-compose.yml # Docker 编排
├── pnpm-workspace.yaml # Workspace 配置
├── package.json # 根 package.json
└── .npmrc # pnpm 配置
向量语义检索(pgvector <=> 余弦距离) + BM25 关键词检索 → RRF(Reciprocal Rank Fusion, k=60)融合 → Top-K 上下文构建 → LLM 生成带来源标注的回答
SM-2 算法管理复习计划,根据反馈质量动态调整复习间隔。
基于内容 SHA256 哈希,导入前自动跳过重复内容。
JWT + Passport 实现无状态认证,bcrypt 哈希存储密码,前端 axios 拦截器自动附加 token。
pnpm install # 安装依赖
pnpm dev:backend # 后端开发模式
pnpm dev:frontend # 前端开发模式
pnpm build # 构建前后端
pnpm lint:backend # 后端 lint
pnpm lint:frontend # 前端 lint
pnpm test:backend # 后端测试
docker-compose up -d # Docker 一键部署UNLICENSED