如果你想把这篇文章和源码对着看可以先留意文中出现的几个文件名。这个系列会继续按源码往后拆这一篇只看一个文件TEXTserver/src/services/customerServiceAgent.js它是本项目的客服 Agent 编排中心。如果说/api/chat是聊天接口入口那么customerServiceAgent.js就是TEXT用户消息进入后真正按步骤处理客服任务的流程图。这个 Agent 做了什么用户发来一句话以后系统不是直接调用 DeepSeek。它会按顺序做 4 件事TEXT1. recognizeIntent识别意图2. runBusinessAction执行业务动作3. retrieveKnowledge检索知识库4. generateReply生成回复源码里的图是这样搭的JSconst graph new StateGraph(AgentState) .addNode(recognizeIntent, recognizeIntent) .addNode(runBusinessAction, runBusinessAction) .addNode(retrieveKnowledge, retrieveKnowledge) .addNode(generateReply, generateReply) .addEdge(START, recognizeIntent) .addEdge(recognizeIntent, runBusinessAction) .addEdge(runBusinessAction, retrieveKnowledge) .addEdge(retrieveKnowledge, generateReply) .addEdge(generateReply, END) .compile();画成图Mermaid 流程图静态示意START↓recognizeIntent / 识别意图A↓runBusinessAction / 执行业务动作B↓retrieveKnowledge / 检索知识库C↓generateReply / 生成回复流D↓END4.1 引入的 LangGraph 方法文件开头引入了JSconst { Annotation, END, START, StateGraph } require(langchain/langgraph);这几个东西分别可以这样理解名称作用StateGraph创建一张可执行的流程图Annotation定义图里的状态字段START图的起点END图的终点本项目的 LangGraph 用法比较清晰TEXT先定义状态 AgentState再定义节点函数再 addNode再 addEdge最后 compile这就是搭一个 Agent 图的基本步骤。4.2 定义 AgentState项目里的AgentState是JSconst AgentState Annotation.Root({ message: Annotation(), session: Annotation(), intentResult: Annotation(), loginRequired: Annotation(), actionResult: Annotation(), retrievedKnowledge: Annotation(), history: Annotation(), messages: Annotation(), stream: Annotation(),});可以把它理解成TEXT贯穿整个 Agent 流程的共享状态包。每个节点都从里面拿东西也往里面放东西。字段含义字段含义message用户当前消息session当前聊天会话intentResult意图识别结果loginRequired是否需要登录actionResult业务动作结果retrievedKnowledge知识库检索结果history历史对话messages给大模型的消息列表stream大模型回复流比如第一个节点返回JSreturn { intentResult };后面的节点就能通过JSstate.intentResult拿到它。4.3 节点 1recognizeIntent第一个节点JSasync function recognizeIntent(state) { const intentResult await intentService.process(state.message, state.session); return { intentResult };}它做的事是TEXT根据用户消息和当前会话识别用户想干什么。例如用户说TEXT南屿 AirBuds 2 还有货吗识别结果可能是JSON{ intent: PRODUCT_INQUIRY, entities: { product_name: 南屿 AirBuds 2 主动降噪耳机 }, emotion: neutral, retrievalQuery: 南屿 AirBuds 2 还有货吗}这个节点本身不直接调 DeepSeek而是交给TEXTintentService.process()因为意图识别还有规则修正、多轮上下文、情绪记录等逻辑。4.3 节点 2runBusinessAction第二个节点JSasync function runBusinessAction(state) { const { intentResult, session } state; if (!intentResult || intentResult.type clarification) { return { actionResult: null, loginRequired: false }; } if (isLoginRequired(intentResult.intent, session)) { return { actionResult: null, loginRequired: true }; } const actionResult await actionService.execute( intentResult.intent, intentResult.entities, session.user_id, session.id ); return { actionResult, loginRequired: false };}这个节点的关键词是TEXT业务动作。它会根据意图调用actionService.execute()。例如意图业务动作QUERY_ORDER查询订单CANCEL_ORDER取消订单REFUND创建退款申请COMPLAINT创建投诉PRODUCT_INQUIRY查询商品它还会判断是否需要登录JSconst loginRequiredIntents [QUERY_ORDER, CANCEL_ORDER, REFUND];所以游客问商品可以继续游客要退款会被拦截。4.3 节点 3retrieveKnowledge第三个节点JSasync function retrieveKnowledge(state) { if (!state.intentResult || state.intentResult.type clarification || state.loginRequired) { return { retrievedKnowledge: [] }; } const retrievedKnowledge await knowledgeService.search( state.intentResult.retrievalQuery || state.message, { intent: state.intentResult.intent, } ); return { retrievedKnowledge };}它做的是TEXT按用户问题和意图检索知识库。不是所有场景都检索。比如需要澄清时不检索需要登录但未登录时不检索商品咨询、通用问答、投诉更适合检索这样可以避免不必要的知识库调用。4.3 节点 4generateReply第四个节点JSasync function generateReply(state) { if (!state.intentResult || state.intentResult.type clarification || state.loginRequired) { return { stream: null }; } const history await contextService.getContext(state.session.id); const messages [...history, new HumanMessage(state.message)]; const stream await deepseekService.chat(messages, { businessData: state.actionResult state.actionResult.data, actionMessage: state.actionResult state.actionResult.message, retrievedKnowledge: state.retrievedKnowledge, intent: state.intentResult.intent, entities: state.intentResult.entities, emotion: state.intentResult.emotion, sootheMode: state.intentResult.sootheMode, settings: state.intentResult.settings, }); return { history, messages, stream };}这个节点把所有材料汇总起来历史对话当前消息业务数据知识库内容意图和实体情绪信息店铺设置然后调用TEXTdeepseekService.chat()得到一个流式回复stream。4.4 把节点连接成图前面 4 个节点定义完以后项目用addEdge串起来JS.addEdge(START, recognizeIntent).addEdge(recognizeIntent, runBusinessAction).addEdge(runBusinessAction, retrieveKnowledge).addEdge(retrieveKnowledge, generateReply).addEdge(generateReply, END)这就是流程顺序。最后JS.compile();表示把这张图编译成可执行对象。调用入口是JSasync function prepareReply({ message, session }) { return graph.invoke({ message, session, retrievedKnowledge: [], loginRequired: false, });}聊天接口只需要调用JScustomerServiceAgent.prepareReply({ message, session })就能拿到整张图执行后的状态。用一个例子串起来用户问TEXT南屿 AirBuds 2 主动降噪耳机还有货吗流程可能是TEXTrecognizeIntent- 识别 PRODUCT_INQUIRY提取 product_namerunBusinessAction- actionService.queryProduct() 查 MySQL拿到库存 86、价格 399retrieveKnowledge- Qdrant 检索商品说明找到主动降噪、续航等知识generateReply- DeepSeek 结合业务数据和知识库生成回复流最终回复可能是TEXT有货的。南屿 AirBuds 2 当前库存是 86 件价格是 399 元。这款支持最高 42dB 混合主动降噪单次续航约 7 小时适合通勤和办公室使用。这句话里库存、价格来自 MySQL降噪、续航来自知识库/商品说明表达方式来自大模型流程顺序由 LangGraph 保证最后用一句话记住这个项目里的 LangGraph Agent 不是神秘东西。它就是一张按顺序执行的客服流程图TEXT识别意图- 执行业务动作- 检索知识库- 生成回复AgentState负责在节点之间传数据addNode定义每一步addEdge定义顺序graph.invoke()真正执行。看懂customerServiceAgent.js就看懂了这个 AI 客服的主干编排。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
LangGraph 客服 Agent 是怎么搭起来的:从 AgentState 到四个节点
发布时间:2026/6/9 1:25:38
如果你想把这篇文章和源码对着看可以先留意文中出现的几个文件名。这个系列会继续按源码往后拆这一篇只看一个文件TEXTserver/src/services/customerServiceAgent.js它是本项目的客服 Agent 编排中心。如果说/api/chat是聊天接口入口那么customerServiceAgent.js就是TEXT用户消息进入后真正按步骤处理客服任务的流程图。这个 Agent 做了什么用户发来一句话以后系统不是直接调用 DeepSeek。它会按顺序做 4 件事TEXT1. recognizeIntent识别意图2. runBusinessAction执行业务动作3. retrieveKnowledge检索知识库4. generateReply生成回复源码里的图是这样搭的JSconst graph new StateGraph(AgentState) .addNode(recognizeIntent, recognizeIntent) .addNode(runBusinessAction, runBusinessAction) .addNode(retrieveKnowledge, retrieveKnowledge) .addNode(generateReply, generateReply) .addEdge(START, recognizeIntent) .addEdge(recognizeIntent, runBusinessAction) .addEdge(runBusinessAction, retrieveKnowledge) .addEdge(retrieveKnowledge, generateReply) .addEdge(generateReply, END) .compile();画成图Mermaid 流程图静态示意START↓recognizeIntent / 识别意图A↓runBusinessAction / 执行业务动作B↓retrieveKnowledge / 检索知识库C↓generateReply / 生成回复流D↓END4.1 引入的 LangGraph 方法文件开头引入了JSconst { Annotation, END, START, StateGraph } require(langchain/langgraph);这几个东西分别可以这样理解名称作用StateGraph创建一张可执行的流程图Annotation定义图里的状态字段START图的起点END图的终点本项目的 LangGraph 用法比较清晰TEXT先定义状态 AgentState再定义节点函数再 addNode再 addEdge最后 compile这就是搭一个 Agent 图的基本步骤。4.2 定义 AgentState项目里的AgentState是JSconst AgentState Annotation.Root({ message: Annotation(), session: Annotation(), intentResult: Annotation(), loginRequired: Annotation(), actionResult: Annotation(), retrievedKnowledge: Annotation(), history: Annotation(), messages: Annotation(), stream: Annotation(),});可以把它理解成TEXT贯穿整个 Agent 流程的共享状态包。每个节点都从里面拿东西也往里面放东西。字段含义字段含义message用户当前消息session当前聊天会话intentResult意图识别结果loginRequired是否需要登录actionResult业务动作结果retrievedKnowledge知识库检索结果history历史对话messages给大模型的消息列表stream大模型回复流比如第一个节点返回JSreturn { intentResult };后面的节点就能通过JSstate.intentResult拿到它。4.3 节点 1recognizeIntent第一个节点JSasync function recognizeIntent(state) { const intentResult await intentService.process(state.message, state.session); return { intentResult };}它做的事是TEXT根据用户消息和当前会话识别用户想干什么。例如用户说TEXT南屿 AirBuds 2 还有货吗识别结果可能是JSON{ intent: PRODUCT_INQUIRY, entities: { product_name: 南屿 AirBuds 2 主动降噪耳机 }, emotion: neutral, retrievalQuery: 南屿 AirBuds 2 还有货吗}这个节点本身不直接调 DeepSeek而是交给TEXTintentService.process()因为意图识别还有规则修正、多轮上下文、情绪记录等逻辑。4.3 节点 2runBusinessAction第二个节点JSasync function runBusinessAction(state) { const { intentResult, session } state; if (!intentResult || intentResult.type clarification) { return { actionResult: null, loginRequired: false }; } if (isLoginRequired(intentResult.intent, session)) { return { actionResult: null, loginRequired: true }; } const actionResult await actionService.execute( intentResult.intent, intentResult.entities, session.user_id, session.id ); return { actionResult, loginRequired: false };}这个节点的关键词是TEXT业务动作。它会根据意图调用actionService.execute()。例如意图业务动作QUERY_ORDER查询订单CANCEL_ORDER取消订单REFUND创建退款申请COMPLAINT创建投诉PRODUCT_INQUIRY查询商品它还会判断是否需要登录JSconst loginRequiredIntents [QUERY_ORDER, CANCEL_ORDER, REFUND];所以游客问商品可以继续游客要退款会被拦截。4.3 节点 3retrieveKnowledge第三个节点JSasync function retrieveKnowledge(state) { if (!state.intentResult || state.intentResult.type clarification || state.loginRequired) { return { retrievedKnowledge: [] }; } const retrievedKnowledge await knowledgeService.search( state.intentResult.retrievalQuery || state.message, { intent: state.intentResult.intent, } ); return { retrievedKnowledge };}它做的是TEXT按用户问题和意图检索知识库。不是所有场景都检索。比如需要澄清时不检索需要登录但未登录时不检索商品咨询、通用问答、投诉更适合检索这样可以避免不必要的知识库调用。4.3 节点 4generateReply第四个节点JSasync function generateReply(state) { if (!state.intentResult || state.intentResult.type clarification || state.loginRequired) { return { stream: null }; } const history await contextService.getContext(state.session.id); const messages [...history, new HumanMessage(state.message)]; const stream await deepseekService.chat(messages, { businessData: state.actionResult state.actionResult.data, actionMessage: state.actionResult state.actionResult.message, retrievedKnowledge: state.retrievedKnowledge, intent: state.intentResult.intent, entities: state.intentResult.entities, emotion: state.intentResult.emotion, sootheMode: state.intentResult.sootheMode, settings: state.intentResult.settings, }); return { history, messages, stream };}这个节点把所有材料汇总起来历史对话当前消息业务数据知识库内容意图和实体情绪信息店铺设置然后调用TEXTdeepseekService.chat()得到一个流式回复stream。4.4 把节点连接成图前面 4 个节点定义完以后项目用addEdge串起来JS.addEdge(START, recognizeIntent).addEdge(recognizeIntent, runBusinessAction).addEdge(runBusinessAction, retrieveKnowledge).addEdge(retrieveKnowledge, generateReply).addEdge(generateReply, END)这就是流程顺序。最后JS.compile();表示把这张图编译成可执行对象。调用入口是JSasync function prepareReply({ message, session }) { return graph.invoke({ message, session, retrievedKnowledge: [], loginRequired: false, });}聊天接口只需要调用JScustomerServiceAgent.prepareReply({ message, session })就能拿到整张图执行后的状态。用一个例子串起来用户问TEXT南屿 AirBuds 2 主动降噪耳机还有货吗流程可能是TEXTrecognizeIntent- 识别 PRODUCT_INQUIRY提取 product_namerunBusinessAction- actionService.queryProduct() 查 MySQL拿到库存 86、价格 399retrieveKnowledge- Qdrant 检索商品说明找到主动降噪、续航等知识generateReply- DeepSeek 结合业务数据和知识库生成回复流最终回复可能是TEXT有货的。南屿 AirBuds 2 当前库存是 86 件价格是 399 元。这款支持最高 42dB 混合主动降噪单次续航约 7 小时适合通勤和办公室使用。这句话里库存、价格来自 MySQL降噪、续航来自知识库/商品说明表达方式来自大模型流程顺序由 LangGraph 保证最后用一句话记住这个项目里的 LangGraph Agent 不是神秘东西。它就是一张按顺序执行的客服流程图TEXT识别意图- 执行业务动作- 检索知识库- 生成回复AgentState负责在节点之间传数据addNode定义每一步addEdge定义顺序graph.invoke()真正执行。看懂customerServiceAgent.js就看懂了这个 AI 客服的主干编排。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】