乐于分享
好东西不私藏

开发AI客服建议:别从大模型开始,先从请求链路开始

开发AI客服建议:别从大模型开始,先从请求链路开始

源码拆解系列

如果你想把这篇文章和源码对着看,可以先留意文中出现的几个文件名。这个系列会继续按源码往后拆;如果这种拆解方式对你有帮助

很多人读 AI 项目源码,会一上来就找:

TEXT

大模型在哪里调用?
Prompt 在哪里?
LangChain 怎么写?

这些当然重要。

但如果你是初学者,我建议不要从这里开始。

因为 AI 客服不是一个单独的大模型调用,而是一条完整业务链路。

推荐阅读顺序

建议按这个顺序看:

TEXT

1. 前端怎么发消息
2. 后端接口从哪里接住
3. 会话怎么确定
4. Agent 怎么编排
5. 意图怎么识别
6. 业务动作怎么执行
7. 知识库怎么检索
8. 大模型怎么生成回复
9. SSE 怎么返回前端
10. 消息怎么保存

对应文件:

顺序
文件
重点
1
client/src/hooks/useChat.js
前端发请求、读 SSE
2
server/src/app.js
后端路由挂载
3
server/src/routes/chat.js
聊天接口主入口
4
server/src/services/sessionService.js
会话创建和解析
5
server/src/services/customerServiceAgent.js
LangGraph 流程
6
server/src/services/intentService.js
意图识别
7
server/src/services/actionService.js
业务动作
8
server/src/services/knowledgeService.js
知识库搜索入口
9
server/src/services/deepseekService.js
大模型调用
10
server/src/services/contextService.js
历史消息保存

第一步:先看前端怎么发消息

文件:

TEXT

client/src/hooks/useChat.js

找到:

JS

const res = await fetch('/api/chat', {
  method: 'POST',
  headers,
  body: JSON.stringify({ session_token: sessionToken, message: text }),
});

先搞清楚:

  • 请求 URL 是什么

  • 请求方法是什么

  • 请求体里有什么

  • JWT 放在哪里

  • 返回结果怎么读取

前端还会读取 SSE:

JS

const reader = res.body.getReader();

这说明后端不是普通 JSON 返回,而是流式返回。

第二步:看后端路由怎么挂载

文件:

TEXT

server/src/app.js

找到:

JS

app.use('/api/chat', chatRouter);

这表示:

TEXT

/api/chat 交给 chatRouter。

再打开:

TEXT

server/src/routes/chat.js

找到:

JS

router.post('/', optionalAuth, async (req, res) => {
  // ...
});

两者合起来就是:

TEXT

POST /api/chat

第三步:看聊天接口做了哪些事

在 routes/chat.js 里,重点看这几段:

JS

const { session_token, message } = req.body;
const userId = req.user ? req.user.id : null;

说明接口拿到了:

TEXT

用户消息
会话 token
登录用户 id

然后设置 SSE:

JS

res.setHeader('Content-Type', 'text/event-stream');

再解析会话:

JS

const sessionResult = await sessionService.resolveSession(session_token, userId);

最后调用 Agent:

JS

const agentState = await customerServiceAgent.prepareReply({ message, session });

读到这里,你就知道聊天接口的职责了。

第四步:看 Agent 流程

文件:

TEXT

server/src/services/customerServiceAgent.js

先找:

JS

const graph = new StateGraph(AgentState)

再看 4 个节点:

TEXT

recognizeIntent
runBusinessAction
retrieveKnowledge
generateReply

不要一上来纠结 LangGraph 语法。

先理解:

TEXT

这 4 个节点就是客服处理流程。

第五步:看意图识别

文件:

TEXT

server/src/services/intentService.js

重点看:

JS

async function process(message, session) {
  // ...
}

它会:

  • 读取历史

  • 读取设置

  • 读取意图上下文

  • 调 DeepSeek 识别

  • 用规则修正

  • 处理实体

  • 判断澄清

  • 更新情绪历史

这里是 AI 客服“理解用户”的核心。

第六步:看业务动作

文件:

TEXT

server/src/services/actionService.js

重点看:

JS

async function execute(intent, entities, userId, sessionId) {
  switch (intent) {
    case 'QUERY_ORDER':
      return queryOrder(entities, userId);
    case 'CANCEL_ORDER':
      return cancelOrder(entities, userId);
    case 'REFUND':
      return createRefund(entities, userId);
    case 'COMPLAINT':
      return createComplaint(entities, sessionId, userId);
    case 'PRODUCT_INQUIRY':
      return queryProduct(entities);
  }
}

这一步能让你明白:

TEXT

AI 客服不是只会说话,它会真的查数据库、改订单、建退款、建投诉。

第七步:看大模型调用

按顺序看:

TEXT

modelProvider.js
llmService.js
promptService.js
deepseekService.js

这条链是:

TEXT

创建模型对象
-> 准备流式/非流式模型
-> 定义 Prompt
-> buildIntentChain / buildReplyChain
-> recognize / chat

这时再看 LangChain,就不会抽象了。

第八步:看知识库

按顺序看:

TEXT

adminService.js
vectorService.js
knowledgeService.js

你会看到:

TEXT

知识文档怎么切片
切片怎么写入 Qdrant
聊天时怎么检索
检索结果怎么放进 Prompt

第九步:自己跑一个例子

可以用测试商品:

TEXT

南屿 AirBuds 2 主动降噪耳机

输入:

TEXT

南屿 AirBuds 2 还有货吗?

然后按源码追:

TEXT

useChat.js
-> routes/chat.js
-> sessionService.js
-> customerServiceAgent.js
-> intentService.js
-> actionService.js
-> knowledgeService.js
-> deepseekService.js
-> routes/chat.js SSE

这比直接看全部文件更有效。

最后用一句话记住

读这个项目,不要从“AI”两个字开始。

从一条请求开始:

TEXT

用户在哪里输入?
前端怎么发?
后端哪里接?
中间经过哪些服务?
最后怎么回到页面?

能把这条链路走通,再看 LangChain、LangGraph、Qdrant,都会容易很多。