🚀 前端开发者的 AI 入门指南:5 分钟搭建你的第一个 RAG 智能问答系统

作为一名前端开发者,你是否也有这样的困扰:

  • 😫 想学 AI 开发,但看到 Python、PyTorch、CUDA 就头大?
  • 😫 好不容易配好环境,下载模型又要几十 GB,等了半天还失败?
  • 😫 网上的教程都是 Python 的,作为前端开发者完全看不懂?
  • 😫 想做个 AI 项目练手,但不知道从何下手?

别担心!这篇文章就是为你准备的。

我开源了一个完全基于 JavaScript/TypeScript 的 RAG(检索增强生成)智能问答系统,让你用熟悉的技术栈,5 分钟就能搭建一个属于自己的 AI 助手!快年底了,还不整点活儿!

🎯 项目效果

先看看最终效果:

核心功能:

  • 📚 上传你的文档(PDF、Word、Markdown、TXT)
  • 🤖 用自然语言提问
  • 💬 获得基于文档内容的精准回答
  • 🔍 自动标注答案来源

就像拥有一个读过所有文档的智能助手!

💡 为什么这个项目适合前端开发者?

1. 100% 熟悉的技术栈

scss 复制代码
传统 AI 项目                    本项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Python + PyTorch         →     Node.js + TypeScript
Conda 环境配置           →     npm install
本地模型下载 (50GB+)     →     API 调用 (0 安装)
GPU 服务器               →     普通电脑即可
复杂的依赖管理           →     package.json 搞定

前端技术栈:

  • ✅ React 18 + TypeScript + Vite
  • ✅ TailwindCSS(现代化样式)
  • ✅ React Markdown(Markdown 渲染)

后端技术栈:

  • ✅ Node.js + Express + TypeScript
  • ✅ LangChain.js(AI 应用框架的 JS 版本)
  • ✅ LanceDB(向量数据库,无需额外安装)

2. 真正的开箱即用

bash 复制代码
# 只需三步
git clone https://github.com/jinghaonode/rag-knowledge-assistant.git
cd rag-knowledge-assistant
./start.sh  # 或 start.bat (Windows)

# 就这么简单!

前置要求:

  • Node.js 18+(前端开发者必备)
  • 智谱 API Key(免费注册,新用户有免费额度)

3. 完整的学习资源

这不仅是一个工具,更是一个学习 AI 开发的完整案例:

  • 📚 文档处理:学习如何解析 PDF、Word 等格式
  • 🔍 向量检索:理解语义搜索的原理
  • 🤖 AI 集成:掌握 LangChain.js 的使用
  • 💬 流式输出:实现实时对话体验
  • 🎨 UI 设计:现代化的聊天界面

🏗️ 技术架构详解

RAG 是什么?

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合了信息检索和文本生成的 AI 技术。

简单来说:

  1. 📤 用户上传文档 → 系统将文档切分并向量化存储
  2. 💬 用户提问 → 系统检索相关文档片段
  3. 🤖 AI 基于检索到的内容生成回答

为什么需要 RAG?

  • 大语言模型的知识是有限的(训练数据截止日期)
  • 无法回答你私有文档中的内容
  • RAG 让 AI 能够基于你的文档回答问题

系统架构

graph LR A[用户上传文档] --> B[文档解析] B --> C[文本分块] C --> D[向量化] D --> E[LanceDB 存储] F[用户提问] --> G[查询优化] G --> H[混合检索] H --> I[向量检索] H --> J[关键词检索] I --> K[相关文档] J --> K K --> L[GLM-4 生成回答] L --> M[流式输出]

核心技术点

1. 文档处理(Document Processing)

typescript 复制代码
// 支持多种文档格式
const loaders = {
  ".pdf": PDFLoader,
  ".docx": DocxLoader,
  ".md": TextLoader,
  ".txt": TextLoader,
};

// 智能分块
const textSplitter = new RecursiveCharacterTextSplitter({
  chunkSize: 500, // 每块 500 字符
  chunkOverlap: 100, // 重叠 100 字符(保持上下文连贯)
});

为什么要分块?

  • AI 模型有 Token 限制
  • 分块可以提高检索精度
  • 重叠部分保证上下文连贯性

2. 向量化存储(Vector Store)

typescript 复制代码
// 使用智谱 Embedding 模型
const embeddings = new OpenAIEmbeddings({
  modelName: "embedding-3",
  openAIApiKey: process.env.GLM_API_KEY,
  configuration: {
    baseURL: "https://open.bigmodel.cn/api/paas/v4",
  },
});

// 存储到 LanceDB
const vectorStore = await LanceDB.fromDocuments(documents, embeddings, {
  uri: "./lancedb",
});

什么是向量化?

  • 将文本转换为数字向量(一串数字)
  • 语义相似的文本,向量也相似
  • 可以通过向量相似度进行语义搜索

3. 混合检索(Hybrid Search)

typescript 复制代码
// 向量检索(语义搜索)
const vectorDocs = await vectorStore.similaritySearch(query, 6);

// 关键词检索(精确匹配)
const keywordDocs = await keywordSearch(query);

// 智能合并去重
const finalDocs = mergeAndDeduplicate(vectorDocs, keywordDocs);

为什么要混合检索?

  • 向量检索:理解语义,找到相关内容
  • 关键词检索:精确匹配专业术语
  • 两者结合,提高准确率

4. 流式输出(Streaming)

typescript 复制代码
// 后端:使用 SSE(Server-Sent Events)
const stream = await chain.stream({ question: query });

for await (const chunk of stream) {
  res.write(`data: ${JSON.stringify(chunk)}\n\n`);
}

// 前端:实时接收并显示
const response = await fetch("/api/chat", {
  method: "POST",
  body: JSON.stringify({ message }),
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  setMessages((prev) => [...prev, { text }]);
}

流式输出的好处:

  • 实时显示 AI 生成过程
  • 提升用户体验
  • 类似 ChatGPT 的打字效果

🚀 快速开始

1. 获取 API Key

访问 智谱 AI 开放平台

  1. 注册并登录
  2. 进入控制台 → API 管理
  3. 创建 API Key
  4. 复制 Key

💡 新用户有免费额度,足够测试使用!

2. 克隆并启动项目

bash 复制代码
# 克隆项目
git clone https://github.com/jinghaonode/rag-knowledge-assistant.git
cd rag-knowledge-assistant

# 配置 API Key
cp backend/.env.example backend/.env
# 编辑 backend/.env,填入你的 API Key

# 一键启动
./start.sh          # macOS/Linux
start.bat           # Windows

3. 访问应用

📁 项目结构

bash 复制代码
rag-knowledge-assistant/
├── backend/                    # 后端服务
│   ├── src/
│   │   ├── server.ts          # Express 服务器
│   │   ├── routes/            # API 路由
│   │   │   ├── chat.ts        # 聊天接口
│   │   │   ├── upload.ts      # 上传接口
│   │   │   └── knowledge.ts   # 知识库管理
│   │   └── services/          # 核心服务
│   │       ├── vectorstore.ts # 向量存储
│   │       └── ragChain.ts    # RAG 检索链
│   └── .env.example           # 环境变量模板
├── frontend/                   # 前端应用
│   └── src/
│       ├── App.tsx            # 主应用
│       └── components/        # React 组件
│           ├── ChatMessage.tsx
│           ├── ChatInput.tsx
│           └── KnowledgeModal.tsx
└── README.md

🎓 核心代码解析

1. 文档上传处理

typescript 复制代码
// backend/src/routes/upload.ts
import multer from "multer";
import { vectorStore } from "../services/vectorstore.js";

const upload = multer({ dest: "uploads/" });

router.post("/", upload.single("file"), async (req, res) => {
  try {
    const file = req.file;

    // 1. 加载文档
    const loader = getLoader(file.path, file.mimetype);
    const docs = await loader.load();

    // 2. 文本分块
    const splitter = new RecursiveCharacterTextSplitter({
      chunkSize: 500,
      chunkOverlap: 100,
    });
    const splitDocs = await splitter.splitDocuments(docs);

    // 3. 向量化并存储
    await vectorStore.addDocuments(splitDocs);

    res.json({ success: true, chunks: splitDocs.length });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

2. 智能问答实现

typescript 复制代码
// backend/src/routes/chat.ts
import { ragChain } from "../services/ragChain.js";

router.post("/", async (req, res) => {
  const { message } = req.body;

  // 设置 SSE 响应头
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  try {
    // 流式生成回答
    const stream = await ragChain.stream({
      question: message,
    });

    for await (const chunk of stream) {
      res.write(`data: ${JSON.stringify(chunk)}\n\n`);
    }

    res.write("data: [DONE]\n\n");
    res.end();
  } catch (error) {
    res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
    res.end();
  }
});

3. RAG 检索链

typescript 复制代码
// backend/src/services/ragChain.ts
import { ChatOpenAI } from "@langchain/openai";
import { createRetrievalChain } from "langchain/chains/retrieval";

// 初始化 GLM-4 模型
const llm = new ChatOpenAI({
  modelName: "glm-4-flash",
  openAIApiKey: process.env.GLM_API_KEY,
  configuration: {
    baseURL: "https://open.bigmodel.cn/api/paas/v4",
  },
  streaming: true,
});

// 创建检索器
const retriever = vectorStore.asRetriever({
  k: 6, // 检索 6 个最相关的文档块
});

// 创建 RAG 链
export const ragChain = createRetrievalChain({
  llm,
  retriever,
  prompt: `你是一个智能助手。基于以下文档内容回答问题:

{context}

问题:{question}

请给出准确、详细的回答。如果文档中没有相关信息,请明确说明。`,
});

4. 前端聊天组件

typescript 复制代码
// frontend/src/components/ChatInput.tsx
const ChatInput = ({ onSend }) => {
  const [message, setMessage] = useState("");

  const handleSend = async () => {
    if (!message.trim()) return;

    // 发送消息
    onSend(message);
    setMessage("");

    // 调用 API
    const response = await fetch("http://localhost:3001/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message }),
    });

    // 处理流式响应
    const reader = response.body.getReader();
    const decoder = new TextDecoder();

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      const chunk = decoder.decode(value);
      const lines = chunk.split("\n");

      for (const line of lines) {
        if (line.startsWith("data: ")) {
          const data = line.slice(6);
          if (data === "[DONE]") break;

          const parsed = JSON.parse(data);
          onReceive(parsed);
        }
      }
    }
  };

  return (
    <div className="flex gap-2">
      <input
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        onKeyPress={(e) => e.key === "Enter" && handleSend()}
        placeholder="输入你的问题..."
        className="flex-1 px-4 py-2 border rounded-lg"
      />
      <button
        onClick={handleSend}
        className="px-6 py-2 bg-blue-500 text-white rounded-lg"
      >
        发送
      </button>
    </div>
  );
};

🎨 进阶优化

1. 查询优化

typescript 复制代码
// 提取关键词
const extractKeywords = async (query: string) => {
  const prompt = `从以下问题中提取 3-5 个关键词:${query}`;
  const response = await llm.call(prompt);
  return response.split(",").map((k) => k.trim());
};

// 查询改写
const rewriteQuery = async (query: string) => {
  const prompt = `将以下问题改写为更适合检索的形式:${query}`;
  return await llm.call(prompt);
};

2. 相似度过滤

typescript 复制代码
// 只保留相似度高于阈值的文档
const filteredDocs = docs.filter((doc) => {
  return doc.metadata.score > 0.45; // 相似度阈值
});

3. 答案质量提升

typescript 复制代码
const prompt = `你是一个专业的智能助手。请基于以下文档内容回答问题。

要求:
1. 回答要准确、详细
2. 如果文档中没有相关信息,明确说明
3. 引用具体的文档来源
4. 使用 Markdown 格式,让回答更易读

文档内容:
{context}

问题:{question}

回答:`;

🚀 部署上线

1. 本地构建

bash 复制代码
# 后端构建
cd backend
npm run build

# 前端构建
cd frontend
npm run build

2. 部署到服务器

bash 复制代码
# 使用 PM2 管理进程
npm install -g pm2

# 启动后端
cd backend
pm2 start dist/server.js --name rag-backend

# 启动前端(使用 nginx 或其他静态服务器)

3. Docker 部署

dockerfile 复制代码
# Dockerfile
FROM node:18-alpine

WORKDIR /app

# 安装依赖
COPY package*.json ./
RUN npm install

# 复制代码
COPY . .

# 构建
RUN npm run build

# 启动
CMD ["npm", "start"]

💡 扩展思路

基于这个项目,你可以:

1. 接入其他 AI 模型

typescript 复制代码
// OpenAI
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  openAIApiKey: process.env.OPENAI_API_KEY,
});

// DeepSeek
const llm = new ChatOpenAI({
  modelName: "deepseek-chat",
  openAIApiKey: process.env.DEEPSEEK_API_KEY,
  configuration: {
    baseURL: "https://api.deepseek.com",
  },
});

2. 添加更多文档格式

typescript 复制代码
// Excel
import { ExcelLoader } from "langchain/document_loaders";

// CSV
import { CSVLoader } from "langchain/document_loaders";

// 网页
import { CheerioWebBaseLoader } from "langchain/document_loaders";

3. 实现多轮对话

typescript 复制代码
// 添加对话历史
const chatHistory = [];

const response = await ragChain.call({
  question: message,
  chat_history: chatHistory,
});

chatHistory.push({ question: message, answer: response });

4. 添加用户认证

typescript 复制代码
import jwt from "jsonwebtoken";

// JWT 认证中间件
const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) return res.status(401).json({ error: "Unauthorized" });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(401).json({ error: "Invalid token" });
  }
};

📊 性能优化建议

1. 缓存策略

typescript 复制代码
import NodeCache from "node-cache";

const cache = new NodeCache({ stdTTL: 600 }); // 10 分钟缓存

// 缓存检索结果
const getCachedResults = async (query: string) => {
  const cached = cache.get(query);
  if (cached) return cached;

  const results = await vectorStore.similaritySearch(query);
  cache.set(query, results);
  return results;
};

2. 批量处理

typescript 复制代码
// 批量上传文档
const uploadBatch = async (files: File[]) => {
  const promises = files.map((file) => processDocument(file));
  await Promise.all(promises);
};

3. 数据库优化

typescript 复制代码
// 定期清理过期数据
const cleanupOldDocuments = async () => {
  const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
  await vectorStore.delete({
    filter: `timestamp < ${thirtyDaysAgo}`,
  });
};

🎯 学习路径建议

如果你是 AI 开发新手,建议按以下顺序学习:

第一阶段:运行起来(1 天)

  1. ✅ 克隆项目并成功运行
  2. ✅ 上传文档并测试问答
  3. ✅ 理解整体流程

第二阶段:理解原理(3-5 天)

  1. 📚 学习 RAG 的基本概念
  2. 🔍 理解向量化和语义搜索
  3. 🤖 了解 LangChain.js 的使用
  4. 💬 学习流式输出的实现

第三阶段:动手改造(1-2 周)

  1. 🎨 修改 UI 样式
  2. ⚙️ 调整检索参数
  3. 🔧 添加新功能
  4. 🚀 部署到服务器

第四阶段:深入优化(持续)

  1. 📊 性能优化
  2. 🔐 安全加固
  3. 📈 监控和日志
  4. 🎯 用户体验提升

🤝 参与贡献

欢迎提交 Issue 和 Pull Request!

项目地址: github.com/jinghaonode...

如果这个项目对你有帮助,请给个 Star ⭐️

📚 参考资源

💬 最后的话

作为前端开发者,我们不应该被 Python 和复杂的环境配置挡在 AI 开发的门外。

这个项目证明了:用 JavaScript/TypeScript 也能做出强大的 AI 应用!

希望这个项目能帮助更多前端开发者:

  • 🎯 快速入门 AI 开发
  • 📚 理解 RAG 技术原理
  • 🚀 搭建自己的 AI 应用
  • 💡 激发更多创意想法

AI 时代已经到来,让我们一起用熟悉的技术栈,创造更多可能!


如果你觉得这篇文章有帮助,欢迎:

  • 👍 点赞支持
  • 💬 评论交流
  • 🔗 分享给更多前端小伙伴
  • ⭐️ 给项目一个 Star

有任何问题,欢迎在评论区讨论!


作者: \hnode
项目地址: github.com/jinghaonode...
联系方式: 1137772623@qq.com

相关推荐
大模型真好玩5 小时前
LangChain1.0实战之多模态RAG系统(二)——多模态RAG系统图片分析与语音转写功能实现
人工智能·langchain·mcp
大模型教程6 小时前
谷歌AI Agent技术指南深度解读,从概念到生产
langchain·llm·agent
爱装代码的小瓶子6 小时前
【初识AI】大模型和LangChain?
人工智能·langchain
AI大模型7 小时前
LangChain、LangGraph、LangSmith这些AI开发框架有什么区别?一篇文章解释清楚
langchain·llm·agent
爬点儿啥7 小时前
[Ai Agent] 09 LangGraph 进阶:构建可控、可协作的多智能体系统
人工智能·ai·langchain·大模型·agent·langgraph
吴佳浩10 小时前
LangChain / LLM 开发中:invoke() 与 predict() 的区别
python·langchain·llm
大模型教程20 小时前
LangChain×Qwen3:高性能RAG系统实战项目
程序员·langchain·llm
AI大模型21 小时前
打造生产级复杂 RAG 系统:LangChain, LangGraph 与 RAGAS 实战指南
langchain·llm·agent
AI大模型21 小时前
写给小白看的使用LangChain构建基于知识图谱的RAG系统实战教程
langchain·llm·agent