LangGraph与MCP实战:构建可扩展电商客服智能体系统

发布时间:2026/7/13 13:08:59

LangGraph与MCP实战:构建可扩展电商客服智能体系统 如果你正在学习AI大模型开发特别是智能体Agent相关的技术可能会遇到一个普遍的问题为什么看了很多教程代码也能跑起来但一到实际项目就不知道如何设计架构这背后往往是因为缺少对现代智能体开发框架的深入理解。LangChain、LangGraph和MCP模型上下文协议这三个技术栈正在重新定义智能体开发的工程实践。它们不是简单的API封装而是提供了一套完整的架构思维模式。从简单的对话机器人到复杂的多智能体协作系统这些框架解决了传统开发中的核心痛点状态管理、工具集成和流程编排。本文将基于一个完整的电商客服智能体项目带你从零构建一个具备实际业务价值的智能体系统。不同于简单的Hello World示例我们将重点讲解如何设计可扩展的架构、如何处理真实业务逻辑以及如何避免常见的工程陷阱。1. 智能体开发的核心挑战与框架选择1.1 为什么传统的开发模式在智能体场景下失效在传统的软件开发中我们习惯于线性的、确定性的逻辑流程。但智能体开发面临的是完全不同的挑战状态复杂性多轮对话中需要维护复杂的上下文状态动态路由根据用户意图动态选择处理逻辑工具集成安全、规范地调用外部API和数据源错误处理优雅地处理LLM生成内容的不确定性1.2 LangChain、LangGraph、MCP的定位差异很多开发者容易混淆这三个框架的适用场景其实它们各有明确的职责边界LangChain提供基础构建块适合相对线性的任务链优势快速原型开发简单的问答和检索场景局限复杂的状态管理和循环逻辑处理困难LangGraph专门解决复杂工作流编排核心基于状态机的图结构支持循环、分支、并行适用多轮对话、多智能体协作、复杂决策流程MCP标准化工具集成协议价值统一的工具发现、调用和安全管控场景需要集成多个外部系统和数据源的复杂应用1.3 电商客服场景的技术选型分析以快时尚电商客服为例业务特点决定了技术选择多轮对话用户可能先问订单状态再要求修改地址最后投诉物流问题系统集成需要连接订单系统、物流系统、库存系统等个性化处理VIP用户、高投诉用户需要特殊流程这种场景下纯LangChain难以胜任而LangGraphMCP的组合提供了完美解决方案。2. 环境准备与项目架构设计2.1 开发环境配置# 系统要求 # - Python 3.10 # - Node.js 18 (用于MCP相关工具) # - AWS CLI (如果使用Bedrock) # 清理和配置Node.js环境如需要 sudo apt-get remove nodejs npm node sudo apt-get purge nodejs curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.0/install.sh | bash source ~/.bashrc nvm install 18 nvm use 18 nvm alias default 18 # 创建项目目录 mkdir customer-service-agent cd customer-service-agent2.2 项目依赖配置# requirements.txt langchain0.1.0 langchain_community0.0.1 langchain_mcp_adapters0.1.0 boto31.34.0 python-dotenv1.0.0 regex2023.0.0 mcp-server0.1.0 aioconsole0.7.0 fastapi0.104.0 uvicorn0.24.02.3 系统架构设计项目的核心架构分为三个层次接口层MCP服务器提供标准化工具接口智能体层多个专用Agent处理不同业务场景服务层封装业务逻辑和数据访问客户请求 → MCP客户端 → 意图识别Agent → 业务Agent → 业务服务 → 外部系统3. 核心组件实现详解3.1 MCP服务器设计与实现MCP服务器的核心价值在于提供统一的工具接口让智能体能够安全、规范地访问外部系统。# server.py from mcp.server.fastmcp import FastMCP import json import uuid from typing import Optional, Dict, Any from main import CustomerServiceSystem # 初始化FastMCP服务器 mcp FastMCP(CustomerService) system CustomerServiceSystem() mcp.tool() async def process_question(question: str, conversation_id: Optional[str] None) - str: 处理客户服务问题并返回响应 try: response, new_conversation_id system.process_question(question, conversation_id) result { response: response, conversation_id: new_conversation_id } return json.dumps(result, ensure_asciiFalse) except Exception as e: return json.dumps({ error: f处理问题时发生错误: {str(e)}, question: question }) mcp.tool() async def get_order_info(order_id: str) - str: 获取特定订单的信息 try: order_info system.order_service.get_order_info(order_id) if order_info: return json.dumps({order: order_info}, ensure_asciiFalse) return json.dumps({error: f订单 {order_id} 未找到}) except Exception as e: return json.dumps({error: f获取订单信息时发生错误: {str(e)}}) mcp.tool() async def update_order_address(order_id: str, new_address: str) - str: 更新订单配送地址 try: success system.order_service.update_address(order_id, new_address) if success: updated_order system.order_service.get_order_info(order_id) return json.dumps({ message: 地址更新成功, order: updated_order }, ensure_asciiFalse) return json.dumps({error: f更新订单 {order_id} 地址失败}) except Exception as e: return json.dumps({error: f更新地址时发生错误: {str(e)}}) if __name__ __main__: mcp.run(transportsse)MCP服务器的关键设计要点错误处理每个工具都包含完整的异常捕获和友好错误信息数据序列化使用JSON确保跨语言兼容性异步支持所有工具都支持异步操作提高并发性能3.2 智能体基类设计基础Agent类提供了所有智能体的共享功能包括对话历史管理和LLM调用。# agents/base_agent.py from abc import ABC, abstractmethod from typing import Dict, Optional, List from langchain_community.chat_models import BedrockChat from langchain.prompts import ChatPromptTemplate from langchain.schema import BaseMessage class BaseAgent(ABC): 所有客户服务智能体的基类 def __init__(self, model_id: str anthropic.claude-3-sonnet-20240229-v1:0, region: str us-west-2): 使用Bedrock模型初始化智能体 self.llm BedrockChat( model_idmodel_id, model_kwargs{temperature: 0.7, max_tokens: 2048}, region_nameregion ) self.conversation_history: Dict[str, List[BaseMessage]] {} def _get_history(self, conversation_id: str) - List[BaseMessage]: 获取特定对话的历史记录 return self.conversation_history.get(conversation_id, []) def _update_history(self, conversation_id: str, user_message: str, assistant_message: str): 更新对话历史记录 if conversation_id not in self.conversation_history: self.conversation_history[conversation_id] [] self.conversation_history[conversation_id].extend([ {role: user, content: user_message}, {role: assistant, content: assistant_message} ]) abstractmethod def process(self, user_input: str, conversation_id: Optional[str] None, **kwargs) - tuple[str, str]: 处理用户输入并返回响应 pass基类设计的关键考虑抽象接口强制子类实现核心处理逻辑历史管理统一管理对话上下文支持多轮对话模型配置集中管理LLM配置便于切换不同模型3.3 意图识别智能体意图识别是智能路由的第一道关卡直接影响后续处理的质量。# agents/intent_recognition_agent.py from typing import Optional, List, Dict import uuid from langchain.prompts import ChatPromptTemplate from agents.base_agent import BaseAgent class IntentRecognitionAgent(BaseAgent): 从客户问题中识别意图的智能体 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.prompt ChatPromptTemplate.from_messages([ (system, 你是时尚电商客户服务的意图识别系统。 你的任务是分析客户问题并确定是否涉及 1. ORDER ISSUES (订单状态、修改、问题或支付) 2. LOGISTICS ISSUES (配送地址、运输方式、配送问题) 请参考提供的对话历史来理解当前问题的上下文。 仅用意图关键词响应: ORDER 或 LOGISTICS 不要用完整句子响应。), (human, 对话历史:\n{history}\n\n当前问题: {question}) ]) def process(self, user_input: str, conversation_id: Optional[str] None, history: List[Dict[str, str]] None, **kwargs) - tuple[str, str]: 处理用户输入以确定其意图 if not conversation_id: conversation_id str(uuid.uuid4()) # 格式化对话历史 formatted_history \n.join([ f{msg[role].capitalize()}: {msg[content]} for msg in (history or []) ]) # 获取链式响应 chain self.prompt | self.llm response chain.invoke({ history: formatted_history, question: user_input }) intent response.content.strip().upper() # 验证和规范化意图 if ORDER in intent: intent ORDER elif LOGISTICS in intent: intent LOGISTICS else: intent UNKNOWN return intent, conversation_id意图识别的技术要点提示工程明确的指令约束LLM输出格式历史利用考虑对话上下文提高识别准确率结果规范化将LLM输出转换为标准枚举值3.4 订单问题处理智能体订单智能体需要结合业务规则SOP和实时数据来提供准确响应。# agents/order_issue_agent.py from typing import Optional, List, Dict import uuid from langchain.prompts import ChatPromptTemplate from agents.base_agent import BaseAgent from services.order_service import OrderService from services.sop_service import SOPService class OrderIssueAgent(BaseAgent): 处理订单相关客户问题的智能体 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.order_service OrderService() self.sop_service SOPService() self.prompt ChatPromptTemplate.from_messages([ (system, 你是处理订单问题的客户服务代理。 请按照以下决策树处理客户询问 {decision_tree} 先前对话 {history} 指南 - 请遵循决策树不要随意响应 - 如果不确定询问的对象请要求更多细节 - 这是即时消息保持回复简短简洁 - 不要使用此致敬礼等正式结束语 - 不要以客户的身份响应), (human, 订单信息 {order_info} 客户问题{question}) ]) def _format_order_info(self, order_info: Optional[dict]) - str: 为提示格式化订单信息 if not order_info: return 未提供具体的订单信息。 return ( f订单详情\n f- 订单ID: {order_info[order_id]}\n f- 客户: {order_info[customer_name]}\n f- 商品: {, .join(order_info[items])}\n f- 状态: {order_info[status]}\n f- 配送地址: {order_info[address]} ) def process(self, user_input: str, conversation_id: Optional[str] None, order_id: Optional[str] None, history: List[Dict[str, str]] None, **kwargs) - tuple[str, str]: 处理订单相关客户询问 if not conversation_id: conversation_id str(uuid.uuid4()) # 如果提供了订单ID获取订单信息 order_info None if order_id: order_info self.order_service.get_order_info(order_id) # 准备链式调用 chain self.prompt | self.llm # 获取响应 response chain.invoke({ decision_tree: self.sop_service.order_decision_tree, history: self._format_history(history or []), order_info: self._format_order_info(order_info), question: user_input }) return response.content, conversation_id订单智能体的关键设计业务规则集成将SOP决策树作为系统提示的一部分数据驱动实时获取订单信息确保响应准确性上下文感知利用对话历史提供连贯的服务体验4. 业务服务层实现4.1 订单服务实现订单服务负责所有订单相关的数据操作提供稳定的数据访问接口。# services/order_service.py import json import os from typing import List, Dict, Optional class OrderService: 订单数据管理服务 def __init__(self, data_file: str order_data.txt): self.data_file data_file self._initialize_data() def _initialize_data(self): 如果不存在则初始化订单数据文件 if not os.path.exists(self.data_file): initial_data [ { order_id: 123, customer_name: Alice Chen, items: [T-shirt, Jeans], address: Xicheng District, Beijing, status: Processing }, { order_id: 456, customer_name: Bob Wang, items: [Dress, Shoes], address: Haidian District, Beijing, status: Shipped }, { order_id: 789, customer_name: Charlie Liu, items: [Jacket, Hat], address: Dongcheng District, Beijing, status: Delivered } ] self.save_order_data(initial_data) def get_order_data(self) - List[Dict]: 从文件读取订单数据 try: with open(self.data_file, r, encodingutf-8) as file: return json.load(file) except Exception as e: print(f读取订单数据错误: {str(e)}) return [] def save_order_data(self, order_data: List[Dict]) - bool: 保存订单数据到文件 try: with open(self.data_file, w, encodingutf-8) as file: json.dump(order_data, file, indent2, ensure_asciiFalse) return True except Exception as e: print(f保存订单数据错误: {str(e)}) return False def get_order_info(self, order_id: str) - Optional[Dict]: 获取特定订单的信息 order_data self.get_order_data() return next((order for order in order_data if order[order_id] order_id), None) def update_address(self, order_id: str, new_address: str) - bool: 更新特定订单的地址 order_data self.get_order_data() for order in order_data: if order[order_id] order_id: order[address] new_address return self.save_order_data(order_data) return False订单服务的设计原则数据持久化使用文件存储便于演示和测试错误处理完善的异常处理和数据验证接口简洁提供清晰的CRUD操作接口4.2 SOP服务实现标准操作程序SOP服务封装了业务规则确保智能体响应符合公司政策。# services/sop_service.py class SOPService: 管理标准操作程序决策树的服务 property def order_decision_tree(self) - str: return # 订单问题决策树 1. 订单状态 1.1. 我的订单在哪里 - 使用订单ID检查订单状态 2. 订单修改 2.1. 我可以修改/删除订单吗 - 检查订单是否仍在处理中 2.3. 我想向订单添加商品 - 检查订单是否仍在处理中 property def logistics_decision_tree(self) - str: return # 物流问题决策树 1. 包裹位置查询 1.2. 包裹超过预计送达时间 1.2.1. 在承运商网站检查包裹跟踪 1.2.1.1. 超过ETA 7天 - 建议再等待2-3天 1.2.1.2. 超过ETA 7天且有跟踪更新 - 建议等待2-3天并联系承运商 1.2.1.2.1. 客户不愿等待 - 提供100积分补偿 1.2.1.2.2. 客户非常不满 - 提供100%店铺信用最终方案100%现金退款 1.2.1.3. 超过ETA 7天且无跟踪更新 - 提供100%店铺信用或重新发货选项 1.3. 跟踪显示4天以上无更新 1.3.1. 仍在ETA内 - 升级至物流团队调查 1.3.2. 超过ETA - 遵循包裹超过预计送达时间流程 1.4. 配送尝试失败 1.4.1. 中东地区 - 确认配送信息请求GPS链接注册重新配送 1.4.2. 其他地区 - 确认配送信息建议保持电话畅通提供承运商联系方式 1.5. 包裹退回发件人 1.5.1. 配送地址与系统匹配 - 优先重新发货或提供100%店铺信用 1.5.2. 配送地址不正确 - 提供50-100%店铺信用或重新发货选项 2. 配送地址 2.1. 更改配送地址 - 如果订单未发货则更新地址 2.3. 地址验证 - 确认地址详情 3. 包裹标记为已送达但未收到 3.1. 检查是整个包裹未收到还是缺少物品 3.1.1. 与客户分享并验证地址 3.3.1. 首次客户 3.3.1.1. 地址正确 - 提供重新发货或100%现金退款 3.3.1.2. 地址不正确 - 提供50%店铺信用最终重新发货或100%现金退款 3.3.2. 回头客 3.3.2.1. 地址正确且订单$200 - 提供100%店铺信用 3.3.2.2. 地址不正确且订单$200 - 提供50%店铺信用 3.3.2.3. 订单$200 - 升级至团队负责人 5. 包裹等待取件 5.1. 验证客户是否收到取件通知 5.2. 提供承运商联系信息以获取取件详情 6. 合并包裹缺少物品 6.1. 提供选项 6.1.1. 安排重新发货 6.1.2. 提供100%店铺信用6个月有效期 6.1.3. 如果客户拒绝两者 - 提供100%现金退款 注意特殊考虑 - 如果客户已支付关税不要提供重新发货 - 对于BNPL支付方式Klarna/Afterpay强调店铺信用不是真实货币 - 对于$200订单且有特殊情况升级至团队负责人 SOP服务的设计价值业务规则集中化所有业务逻辑统一管理易于维护决策树结构清晰便于业务人员理解版本控制支持不同版本的SOP规则5. 系统集成与主控流程5.1 主系统协调器主系统负责协调各个智能体和工作流程是整个应用的大脑。# main.py import uuid import json import asyncio import aioconsole import re from typing import Optional, Dict, Any from langchain_community.chat_models import BedrockChat from langchain_mcp_adapters.client import MultiServerMCPClient from agents.intent_recognition_agent import IntentRecognitionAgent from agents.order_issue_agent import OrderIssueAgent from agents.logistics_issue_agent import LogisticsIssueAgent from services.order_service import OrderService from services.sop_service import SOPService class CustomerServiceSystem: 协调智能体和服务的主客户服务系统 def __init__(self, model_id: str anthropic.claude-3-sonnet-20240229-v1:0, region: str us-west-2): 使用其智能体和服务初始化客户服务系统 # 初始化智能体 self.intent_agent IntentRecognitionAgent(model_idmodel_id, regionregion) self.order_agent OrderIssueAgent(model_idmodel_id, regionregion) self.logistics_agent LogisticsIssueAgent(model_idmodel_id, regionregion) # 初始化服务 self.order_service OrderService() self.sop_service SOPService() # 存储活跃对话 self.conversations: Dict[str, Dict[str, Any]] {} def process_question(self, user_question: str, conversation_id: Optional[str] None) - tuple[str, str]: 通过多智能体系统处理客户问题 # 如果未提供对话ID则生成 if not conversation_id: conversation_id str(uuid.uuid4()) self.conversations[conversation_id] {order_id: None, history: []} # 添加用户问题到对话历史 self.conversations[conversation_id][history].append({ role: user, content: user_question }) # 第一层意图识别 intent, _ self.intent_agent.process( user_question, conversation_id, historyself.conversations[conversation_id][history] ) print(f识别到的意图: {intent}) # 从问题中提取订单ID如果存在 order_id_match re.search( rorder\s(?:id\s)?(?:number\s)?(?:#\s*)?(\d), user_question, re.IGNORECASE ) if order_id_match: self.conversations[conversation_id][order_id] order_id_match.group(1) # 第二层基于意图处理 if intent ORDER: response, _ self.order_agent.process( user_question, conversation_id, order_idself.conversations[conversation_id].get(order_id), historyself.conversations[conversation_id][history] ) elif intent LOGISTICS: response, _ self.logistics_agent.process( user_question, conversation_id, order_idself.conversations[conversation_id].get(order_id), historyself.conversations[conversation_id][history] ) else: response 我不确定您的问题是关于订单还是物流问题。请提供更多细节。 # 添加智能体响应到对话历史 self.conversations[conversation_id][history].append({ role: assistant, content: response }) return response, conversation_id async def interactive_session(): 运行与客户服务系统的交互式会话 system CustomerServiceSystem() conversation_id None print(欢迎使用时尚电商客户服务) print(您可以询问关于订单或物流的问题。) print(输入 exit 结束对话。) print(\n可用测试订单: 123, 456, 789) print(- * 50) # 初始化MCP客户端 client MultiServerMCPClient({ customer_service: { url: http://localhost:8000/sse, transport: sse, } }) tools await client.get_tools() process_question_tool next( tool for tool in tools if tool.name process_question ) while True: user_input await aioconsole.ainput(\n客户: ) if user_input.lower() exit: print(感谢使用我们的客户服务。再见) break try: result await process_question_tool.arun({ question: user_input, conversation_id: conversation_id }) response_data json.loads(result) print(f\n客服: {response_data[response]}) conversation_id response_data[conversation_id] except Exception as e: print(f\n错误: {str(e)}) if __name__ __main__: asyncio.run(interactive_session())主系统的关键设计工作流协调智能路由用户请求到合适的处理单元状态管理维护对话上下文和业务状态错误隔离单个智能体故障不影响整体系统6. 部署与运行6.1 启动脚本配置#!/bin/bash # start_server.sh # 如果虚拟环境不存在则创建 if [ ! -d venv ]; then echo 创建虚拟环境... python3 -m venv venv fi # 激活虚拟环境 source venv/bin/activate # 如果尚未安装则安装依赖 if [ ! -f venv/installed ]; then echo 安装依赖... pip install -r requirements.txt touch venv/installed fi # 启动MCP服务器 echo 启动MCP服务器... python server.py#!/bin/bash # start_client.sh source venv/bin/activate python3 main.py deactivate6.2 运行流程启动服务器chmod x start_server.sh ./start_server.sh启动客户端新终端chmod x start_client.sh ./start_client.sh6.3 测试示例系统启动后可以进行完整的业务流测试客户: 订单123的状态是什么 客服: 让我检查订单#123的状态... 对于Alice Chen下的订单#123当前状态是处理中。订单包含T恤和牛仔裤计划配送到北京市西城区。 客户: 我可以把订单123的地址改为北京市朝阳区X路123号吗 客服: 由于您的订单#123尚未发货我可以将配送地址更新为 北京市朝阳区X路123号 请确认这个新地址是否正确。一旦确认我将在系统中进行更改。 客户: 我确认 客服: 好的我已将订单#123的配送地址更新为 北京市朝阳区X路123号 新地址已保存在我们的系统中。7. 常见问题与解决方案7.1 环境配置问题问题现象可能原因解决方案ModuleNotFoundError依赖未正确安装重新安装requirements.txtAWS权限错误Bedrock访问权限不足检查AWS CLI配置和IAM权限端口占用8000端口被占用更改server.py中的端口配置7.2 业务逻辑问题意图识别不准确原因提示词不够明确或训练数据偏差解决优化提示词添加更多示例订单信息获取失败原因数据文件格式错误或权限问题解决检查order_data.txt格式和文件权限7.3 性能优化建议缓存策略对频繁访问的订单数据添加缓存异步处理对耗时操作使用异步模式连接池数据库和外部API连接使用连接池8. 扩展到LangGraph架构8.1 为什么需要LangGraph当业务复杂度增加时纯LangChain架构会遇到限制多轮对话状态管理困难复杂业务流程编排繁琐错误处理和回退机制不完善8.2 LangGraph改造示例from typing import TypedDict, Optional from langgraph.graph import StateGraph, END class CustomerServiceState(TypedDict): intent: str order_details: Optional[dict] compensation_level: int escalation_needed: bool final_resolution: Optional[str] def intent_node(state: CustomerServiceState): # 动态决定下一个节点 if state[intent] ORDER and state[order_details] is None: return fetch_order_details elif state[compensation_level] 2: return escalate_to_manager else: return standard_processing # 构建图结构 graph StateGraph(CustomerServiceState) graph.add_node(intent_recognition, intent_node) # 添加更多节点和边...LangGraph的优势可视化流程图形化展示业务逻辑流状态管理显式管理复杂对话状态灵活路由支持条件分支和循环9. 生产环境最佳实践9.1 安全考虑输入验证对所有用户输入进行严格验证权限控制基于角色的数据访问控制审计日志记录所有敏感操作9.2 监控与运维健康检查实现应用级健康检查端点指标收集收集响应时间、错误率等关键指标日志聚合使用集中式日志管理系统9.3 性能优化模型选择根据业务需求选择合适的LLM模型缓存策略对LLM响应实施智能缓存批量处理对类似请求进行批量处理这个完整的智能体开发实战项目展示了如何将LangChain、MCP和LangGraph技术栈应用于真实的业务场景。通过模块化设计和清晰的架构分层系统具备了良好的可扩展性和维护性。开发者可以基于这个基础框架根据具体业务需求进行定制和扩展。

相关新闻