返回笔记首页

AI 全栈开发实战 — 项目总览与快速启动

主题配置

课程技术栈:LangChain.js + Vue3 + Node.js + DeepSeek API


一、课程做的是什么项目

四章内容围绕同一个业务场景:极速购电商平台的 AI 客服系统

每一章在上一章的基础上递进,最终在第四章把所有能力整合到一起。

第一章:基础对话模块

实现了一个最基础的流式对话客服界面。用户输入问题,AI 扮演"小购"客服角色逐字输出回答。

核心技术:LangChain.js 的 Model / Prompt / Chain 三大基础抽象,SSE 流式输出,Vue3 Composable 封装对话逻辑。

访问地址:http://localhost:5173(对话页)


第二章:订单查询 Agent

在对话基础上,让 AI 具备调用工具的能力。用户询问订单状态、物流信息,AI 会自动调用相应工具查询数据,再把结果组织成自然语言回答。前端实时展示工具调用过程。

核心技术:Function Calling,LangChain.js Tool 定义,ReAct Agent,AgentExecutor,中间步骤可视化。

内置测试数据:订单 ORD-001(已发货)、ORD-002(待付款)、ORD-003(已完成)

访问地址:http://localhost:5173/agent


第三章:商品知识库问答

给 AI 接入私有知识库。用户询问商品规格、售后政策时,系统先从向量数据库检索相关内容,再由 AI 基于检索结果回答,不依赖模型的参数记忆。前端展示回答的参考来源。

核心技术:RAG(检索增强生成),文本向量化,pgvector 向量存储,RecursiveCharacterTextSplitter 文档切分,LangChain.js LCEL 管道。

知识库内容:蓝牙耳机 X1 Pro、机械键盘 K200、iPhone 手机壳的商品介绍,以及退货/换货/退款/保修政策。

访问地址:http://localhost:5173/rag


第四章:多 Agent 智能中枢

把前三章的能力整合到一个统一入口。用户发来任意问题,系统自动识别意图,路由到对应的处理模块(订单查询 / 知识库检索 / 通用对话),最后汇合生成回答。前端展示完整的工作流执行轨迹。

核心技术:LangGraph StateGraph,意图识别节点,条件边路由,多节点状态传递,流式工作流执行。

访问地址:http://localhost:5173/graph


二、项目目录结构

markdown
langchain-course/
├── server/                          # Node.js + Express 后端(所有章节共用)
│   ├── src/
│   │   ├── models/
│   │   │   ├── deepseek.js          # DeepSeek 模型封装(第一章起)
│   │   │   └── embedding.js         # Embedding 模型封装(第三章起)
│   │   ├── prompts/
│   │   │   └── customer-service.js  # 客服 Prompt 模板(第一章)
│   │   ├── chains/
│   │   │   ├── basic-chat.js        # 基础对话 Chain(第一章)
│   │   │   └── rag-chain.js         # RAG Chain(第三章)
│   │   ├── tools/
│   │   │   └── order-tools.js       # 订单查询工具(第二章)
│   │   ├── agents/
│   │   │   └── customer-agent.js    # 订单 Agent(第二章)
│   │   ├── graphs/                  # LangGraph 工作流(第四章)
│   │   │   ├── state.js
│   │   │   ├── customer-graph.js
│   │   │   └── nodes/
│   │   │       ├── intent-router.js
│   │   │       ├── order-agent.js
│   │   │       ├── rag-node.js
│   │   │       ├── general-chat.js
│   │   │       └── answer-synthesizer.js
│   │   ├── data/
│   │   │   ├── mock.js              # 模拟订单数据(第二章)
│   │   │   └── knowledge/           # 知识库文档(第三章)
│   │   │       ├── products.md
│   │   │       └── policies.md
│   │   ├── db/
│   │   │   └── postgres.js          # pg 连接池(第三章)
│   │   ├── scripts/
│   │   │   └── ingest.js            # 文档入库脚本(第三章,一次性执行)
│   │   ├── routes/
│   │   │   ├── chat.js              # 第一章接口
│   │   │   ├── agent.js             # 第二章接口
│   │   │   ├── rag.js               # 第三章接口
│   │   │   └── graph.js             # 第四章接口
│   │   └── index.js                 # Express 入口
│   ├── .env                         # 环境变量(不提交 Git)
│   ├── .env.example                 # 环境变量模板
│   └── package.json
│
└── client/                          # Vue3 前端(所有章节共用)
    └── src/
        ├── composables/
        │   ├── useChat.js           # 第一章
        │   ├── useAgent.js          # 第二章
        │   ├── useRag.js            # 第三章
        │   └── useGraph.js          # 第四章
        ├── views/
        │   ├── ChatView.vue         # 第一章
        │   ├── AgentView.vue        # 第二章
        │   ├── RagView.vue          # 第三章
        │   └── GraphView.vue        # 第四章
        └── router/
            └── index.js             # 路由配置

三、API Key 配置

3.1 获取 DeepSeek API Key

  1. 访问 https://platform.deepseek.com
  2. 注册账号并登录
  3. 进入"API Keys"页面,点击"创建 API Key"
  4. 复制生成的 Key,格式为 sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

新用户有免费额度,足够跑完整个课程。

3.2 创建 .env 文件

server/ 目录下执行:

bash
cp .env.example .env

用编辑器打开 server/.env,填入内容:

bash
# DeepSeek API Key,替换成你自己的
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# DeepSeek API 地址,不需要修改
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1

# 模型名称,不需要修改
MODEL_NAME=deepseek-chat

# Embedding 模型(第三章用到)
# 方式一智谱 AI:EMBEDDING_MODEL=embedding-3
# 方式二阿里云百炼:EMBEDDING_MODEL=text-embedding-v3
EMBEDDING_MODEL=embedding-3

# 服务端口
PORT=3000

# PostgreSQL 配置(第三章用到)
PG_HOST=localhost
PG_PORT=5432
PG_USER=postgres
PG_PASSWORD=postgres
PG_DATABASE=langchain_course

3.3 关于 Embedding 模型

第三章的 RAG 功能需要 Embedding API 把文本转成向量。课程推荐使用国内模型,两个选择如下。

方式一(推荐):智谱 AI

注册地址:https://open.bigmodel.cn,注册即可获取 API Key,新用户有免费额度,足够跑完整个课程。

第一步,在 .env 里加上:

bash
ZHIPU_API_KEY=你的智谱APIKey

第二步,修改 server/src/models/embedding.js

javascript
// server/src/models/embedding.js
import { OpenAIEmbeddings } from '@langchain/openai';
import 'dotenv/config';

export const embeddings = new OpenAIEmbeddings({
  modelName:    'embedding-3',
  openAIApiKey: process.env.ZHIPU_API_KEY,
  configuration: {
    baseURL: 'https://open.bigmodel.cn/api/paas/v4',
  },
});
方式二:阿里云百炼(通义)

注册地址:https://bailian.console.aliyun.com,用阿里云账号登录后开通百炼服务即可获取 API Key。适合已经在用阿里云的项目,账单统一管理更方便。

第一步,在 .env 里加上:

bash
DASHSCOPE_API_KEY=你的百炼APIKey

第二步,修改 server/src/models/embedding.js

javascript
// server/src/models/embedding.js
import { OpenAIEmbeddings } from '@langchain/openai';
import 'dotenv/config';

export const embeddings = new OpenAIEmbeddings({
  modelName:    'text-embedding-v3',
  openAIApiKey: process.env.DASHSCOPE_API_KEY,
  configuration: {
    baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
  },
});

两种方式都兼容 OpenAI 协议,除了 modelNameopenAIApiKeybaseURL 三个字段不同,其余代码完全一样。

注意:入库(ingest.js)和检索(rag-chain.js)必须使用同一个 Embedding 模型。中途换模型需要清空数据库重新入库:

bash
docker exec -it pgvector-dev psql -U postgres -d langchain_course -c "TRUNCATE knowledge_embeddings;"
node src/scripts/ingest.js

四、完整运行步骤

4.1 第一章(基础对话)

第一章不依赖数据库,最简单,配好 API Key 即可运行。

bash
# 安装后端依赖
cd server
pnpm install

# 启动后端
pnpm dev
# 看到 "server running on http://localhost:3000" 表示启动成功

# 新开一个终端,安装前端依赖
cd client
pnpm install

# 启动前端
pnpm dev
# 看到 "Local: http://localhost:5173" 表示启动成功

打开浏览器访问 http://localhost:5173,输入任意问题测试对话。


4.2 第二章(订单 Agent)

第二章在第一章基础上新增了 Agent 路由,不需要额外配置,直接运行即可。

bash
# 后端和前端保持第一章的启动方式不变
# 访问 http://localhost:5173/agent

# 测试用例:
# "查一下订单 ORD-001 的状态"
# "订单 ORD-001 的快递到哪了?"
# "我有哪些订单?"(userId 默认为 U-100)

4.3 第三章(RAG 知识库)

第三章需要先启动 PostgreSQL + pgvector,再执行一次文档入库脚本。

第一步:启动 pgvector

bash
docker run -d \
  --name pgvector-dev \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=langchain_course \
  -p 5432:5432 \
  pgvector/pgvector:pg16

如果已经创建过容器,只需启动:

bash
docker start pgvector-dev
第二步:开启 vector 扩展
bash
docker exec -it pgvector-dev psql -U postgres -d langchain_course -c "CREATE EXTENSION IF NOT EXISTS vector;"
第三步:执行文档入库(只需一次)
bash
cd server
node src/scripts/ingest.js
# 看到 "入库完成" 表示成功
第四步:启动服务
bash
# 后端
pnpm dev

# 前端
pnpm dev

# 访问 http://localhost:5173/rag

测试用例:

plain
"蓝牙耳机 X1 Pro 续航多少小时"   → 知识库有,给出准确回答
"退款需要多少天"                  → 知识库有,给出退款流程
"最新的 iPhone 16 有货吗"         → 知识库没有,告知无相关信息

4.4 第四章(多 Agent 中枢)

第四章依赖第三章的 pgvector,确保数据库已启动且知识库已入库后直接运行。

bash
# 确认 pgvector 已启动
docker start pgvector-dev

# 后端(已包含所有章节的路由)
cd server
pnpm dev

# 前端
cd client
pnpm dev

# 访问 http://localhost:5173/graph

测试用例:

plain
"订单 ORD-001 发货了吗"   → 路由到 orderAgent,查询订单
"退款需要多少天"           → 路由到 ragNode,检索知识库
"你好"                    → 路由到 generalChat,通用对话

前端会展示完整的工作流执行轨迹,比如:意图识别 → 订单查询 → 整理回答。


五、接口汇总

章节 方法 路径 说明
第一章 POST /api/chat/stream 流式对话,SSE
第二章 POST /api/agent/stream Agent 对话,SSE,含中间步骤
第三章 POST /api/rag/query RAG 问答,SSE,含来源信息
第四章 POST /api/graph/stream 多 Agent 工作流,SSE,含节点事件

所有流式接口的请求体格式:

json
{
  "message": "用户输入的问题",
  "history": [
    { "role": "user",      "content": "上一条用户消息" },
    { "role": "assistant", "content": "上一条 AI 回复" }
  ]
}

六、常见启动问题

后端启动后访问报 404

检查 src/index.js 里各章节路由是否都已注册:

javascript
app.use('/api/chat',  chatRouter);
app.use('/api/agent', agentRouter);
app.use('/api/rag',   ragRouter);
app.use('/api/graph', graphRouter);

前端访问 /agent、/rag、/graph 报 404

检查 client/src/router/index.js 里四个页面的路由是否都已注册:

javascript
const routes = [
  { path: '/',       component: ChatView  },
  { path: '/agent',  component: AgentView },
  { path: '/rag',    component: RagView   },
  { path: '/graph',  component: GraphView },
];
ingest.js 执行失败报 "relation does not exist"

pgvector 扩展没开启,执行:

bash
docker exec -it pgvector-dev psql -U postgres -d langchain_course -c "CREATE EXTENSION IF NOT EXISTS vector;"
API 调用报 401

.env 里的 DEEPSEEK_API_KEY 填写有误,或者 Key 已过期。重新检查 Key 是否正确复制,注意前后不能有空格。

第三章检索结果不准

Embedding 入库和检索必须使用同一个模型。如果入库时用的是智谱 AI 的 embedding-3,检索时也必须用同一个模型,不能混用。中途换模型必须清空数据库重新入库。