怎样在网站做咨询医生挣钱创建电子商务网站的步骤
2026/1/28 18:38:48 网站建设 项目流程
怎样在网站做咨询医生挣钱,创建电子商务网站的步骤,抖音官方推广渠道,旅游信息网站开发尊敬的各位技术同仁#xff0c;下午好#xff01; 今天#xff0c;我们将深入探讨如何利用 LangGraph 这一强大的框架#xff0c;构建一个智能客服图谱驱动的闭环流程。我们的重点将放在两个核心功能上#xff1a;处理进度查询和投诉转接#xff0c;并展示如何通过精妙的…尊敬的各位技术同仁下午好今天我们将深入探讨如何利用 LangGraph 这一强大的框架构建一个智能客服图谱驱动的闭环流程。我们的重点将放在两个核心功能上处理进度查询和投诉转接并展示如何通过精妙的设计实现一个能够理解用户意图、执行复杂任务并持续保持会话上下文的智能系统。1. 智能客服图谱与LangGraph构建智能交互的基石在当今的客户服务领域用户对效率和个性化的期望越来越高。传统的客服系统往往受限于预设的规则和有限的知识库难以应对复杂多变的客户需求。智能客服图谱Intelligent Customer Service Graph, ICSG的出现旨在通过结构化地表示客户、产品、服务、流程、知识点之间的关系为智能客服系统提供深度的语义理解和推理能力。然而仅仅拥有一个强大的图谱是不够的。我们需要一个能够动态规划、执行和管理多步骤会话流程的引擎。LangGraph作为LangChain的最新演进正是为此而生。它允许我们以图形化的方式定义LLM大语言模型驱动的应用程序其中每个节点可以是LLM调用、工具执行或自定义逻辑而边则定义了状态的流转和决策逻辑。这使得构建复杂的、有状态的、闭环的智能代理成为可能。闭环流程在这里意味着系统不仅能响应用户的请求还能理解上下文记住之前的对话内容。获取信息在需要时主动询问用户补充信息。执行动作调用外部工具或API完成任务。提供反馈告知用户任务的执行结果。纠正错误在理解错误或工具执行失败时进行恢复。持续交互保持对话的连贯性直至用户满意或问题解决。我们的目标是利用LangGraph的强大能力将智能客服图谱的语义理解转化为实际的行动和连贯的对话体验。2. 核心架构与组件构建一个智能客服系统尤其是要支持“处理进度查询”和“投诉转接”这类需要与外部系统交互的功能需要以下几个核心组件用户输入与自然语言理解 (NLU) 层意图识别 (Intent Recognition)识别用户的核心意图例如“查询进度”、“发起投诉”、“通用问答”等。实体抽取 (Entity Extraction)从用户话语中提取关键信息如订单号、投诉类型、联系方式等。上下文管理维护会话历史以便LLM能够理解长对话的语境。系统状态管理一个能够清晰表示当前会话状态的数据结构包括用户的查询、识别的意图、已抽取的实体、会话历史、工具执行结果等。这是LangGraphStateGraph的核心。工具与外部服务集成进度查询工具模拟与订单管理系统或物流系统的API交互查询特定订单的当前状态。投诉转接工具模拟与CRM系统或工单系统交互创建新的投诉记录或将用户转接到人工客服。知识库查询工具处理通用问题提供预设答案。决策与流程编排 (LangGraph)根据NLU结果和当前系统状态决定下一步的动作是执行某个工具还是向用户提问或是生成通用回复。管理不同功能模块之间的流转确保任务能够按序完成。响应生成基于任务执行结果和会话上下文生成自然、准确、有帮助的回复给用户。下面我们将通过LangGraph的具体实现来详细讲解这些组件是如何协同工作的。3. LangGraph核心概念与状态定义LangGraph的核心是StateGraph。它允许我们定义一个状态对象并在图中的不同节点之间传递和修改这个状态。3.1 定义图的状态Graph State首先我们定义一个AgentState它将作为整个LangGraph工作流的共享状态。这个状态需要包含所有可能在会话中使用的信息。from typing import List, TypedDict, Annotated, Union from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, ToolMessage from langchain_core.utils.function_calling import convert_to_openai_tool from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, END, START import operator import os # 确保设置了OpenAI API Key os.environ[OPENAI_API_KEY] YOUR_OPENAI_API_KEY class AgentState(TypedDict): LangGraph的AgentState定义用于在各个节点之间传递和修改。 chat_history: Annotated[List[BaseMessage], operator.add] # 聊天历史使用operator.add合并新消息 current_intent: str # 当前识别的用户意图 entities: dict # 从用户输入中提取的实体如订单号、投诉详情等 tool_output: str # 工具执行的结果 user_query: str # 当前用户输入的原始查询 response: str # 最终发送给用户的回复 next_action: str # 下一步要采取的动作例如ask_for_order_id, transfer_complaint need_human_handoff: bool # 是否需要转接人工客服AgentState的字段解释chat_history: 存储所有BaseMessage包括用户输入、AI回复、工具调用及结果这是实现上下文管理的关键。Annotated[List[BaseMessage], operator.add]表示当在节点中修改chat_history时新的消息会被添加到现有列表的末尾。current_intent: 记录系统当前识别的用户意图例如progress_inquiry、complaint_transfer、general_query。entities: 一个字典用于存储从用户输入中提取的关键信息如{order_id: T2023001, complaint_type: 包裹破损}。tool_output: 存储由工具函数返回的字符串结果。user_query: 存储用户当前的原始输入。response: 存储最终生成的将返回给用户的回复。next_action: 用于在复杂流程中指导Agent的下一步操作例如在信息不全时提示Agent需要询问用户。need_human_handoff: 布尔值标记是否需要将请求转接给人工客服。3.2 定义工具Tools接下来我们定义系统可以调用的外部工具。这些工具可以是与数据库、CRM、物流系统等交互的函数。tool def query_order_progress(order_id: str) - str: 查询指定订单号的当前处理进度。 Args: order_id (str): 需要查询的订单编号。 Returns: str: 订单的当前状态和预计完成时间。 print(fDEBUG: Calling query_order_progress for order_id: {order_id}) # 模拟与外部订单系统交互 if order_id T2023001: return 您的订单T2023001已发货预计2天内送达。物流单号SF123456789。 elif order_id T2023002: return 您的订单T2023002正在仓库打包中预计明天出库。 elif order_id T2023003: return 您的订单T2023003已签收感谢您的购买。 else: return f未能找到订单号为 {order_id} 的信息请检查后重试。 tool def transfer_complaint(complaint_details: str, contact_info: str) - str: 将用户投诉转接到人工客服或记录到CRM系统。 Args: complaint_details (str): 用户的投诉详情。 contact_info (str): 用户的联系方式手机号、邮箱等。 Returns: str: 投诉转接结果或确认信息。 print(fDEBUG: Calling transfer_complaint with details: {complaint_details}, contact: {contact_info}) # 模拟与CRM系统或工单系统交互 if 紧急 in complaint_details or 无法解决 in complaint_details: return f已将您的紧急投诉 {complaint_details} 转接到高级客服。工单号C{hash(complaint_details contact_info) % 100000}。客服将在15分钟内与您联系请保持电话畅通。您的联系方式{contact_info}。 else: return f您的投诉 {complaint_details} 已记录。工单号C{hash(complaint_details contact_info) % 100000}。我们会在24小时内处理并回复您。您的联系方式{contact_info}。 # 将工具转换为OpenAI兼容格式供LLM调用 tools [query_order_progress, transfer_complaint] openai_tools [convert_to_openai_tool(t) for t in tools]这些工具是系统与外部世界交互的接口。tool装饰器使得这些函数可以被LangChain的LLM以函数调用的方式识别和执行。4. 构建LangGraph工作流节点与边的设计现在我们来设计LangGraph的节点和边。我们的目标是构建一个能够处理以下流程的图接收用户输入。识别用户意图和抽取实体。根据意图路由到不同的处理分支进度查询、投诉转接、通用问答。在必要时通过LLM调用工具。处理工具的输出。生成回复。如果信息不完整能够主动询问用户。在特殊情况下能够转接人工客服。4.1 初始化LLM我们将使用OpenAI的gpt-4o模型因为它在函数调用、多模态理解和通用推理方面表现出色。llm ChatOpenAI(modelgpt-4o, temperature0) # 绑定工具使得LLM能够感知并调用这些工具 llm_with_tools llm.bind_tools(openai_tools)4.2 定义节点Nodes每个节点都是一个Python函数它接收当前的AgentState并返回一个修改后的AgentState。4.2.1 意图识别与实体抽取节点 (process_user_input)这是入口节点负责接收用户的原始输入并利用LLM进行初步的意图识别和实体抽取。def process_user_input(state: AgentState) - AgentState: 接收用户输入并利用LLM进行意图识别和实体抽取。 print(---NODE: process_user_input---) user_query state[user_query] chat_history state[chat_history] # LLM的提示指导其进行意图识别和实体抽取 # 我们使用Few-shot prompting或CoT来增强其性能 prompt f 你是一个智能客服助手。请根据以下对话历史和用户最新的查询判断用户的主要意图并提取所有相关实体。 如果用户表达了查询订单进度的意图请识别并提取订单号。 如果用户表达了投诉或寻求帮助的意图请识别并提取投诉详情和可能的联系方式。 如果意图不明确或无法识别请标记为general_query。 意图类型包括progress_inquiry, complaint_transfer, general_query。 对话历史: {chat_history} 用户最新查询: {user_query} 请以JSON格式返回你的分析结果包含intent意图和entities实体字典形式。 示例 {{ intent: progress_inquiry, entities: {{order_id: T2023001}} }} 或 {{ intent: complaint_transfer, entities: {{complaint_details: 包裹破损物流太慢, contact_info: 13800138000}} }} 或 {{ intent: general_query, entities: {{}} }} # 暂时不使用LLM Function Calling而是直接解析JSON输出 # 因为意图识别和实体抽取可能需要更灵活的输出结构 response llm.invoke(prompt) try: parsed_output eval(response.content.strip()) # 简单的eval解析生产环境应使用json.loads intent parsed_output.get(intent, general_query) entities parsed_output.get(entities, {}) except Exception as e: print(fError parsing LLM output: {e}. Falling back to general_query.) intent general_query entities {} # 更新聊天历史将用户查询添加到历史中 new_chat_history chat_history [HumanMessage(contentuser_query)] return { chat_history: new_chat_history, current_intent: intent, entities: entities, user_query: user_query, # 保留原始查询 next_action: , # 清空next_action need_human_handoff: False, tool_output: , # 清空tool_output response: # 清空response }4.2.2 代理执行节点 (agent_executor)这个节点是核心它利用llm_with_tools来决定下一步是直接回答用户还是调用某个工具。它是一个通用的代理可以处理各种任务。def agent_executor(state: AgentState) - AgentState: 通用代理执行器利用LLM绑定了工具来决定下一步行动。 这可以是直接回答也可以是调用工具。 print(---NODE: agent_executor---) chat_history state[chat_history] current_intent state[current_intent] entities state[entities] user_query state[user_query] next_action state[next_action] # 根据当前意图和已有的实体构造LLM的输入 # 引导LLM进行决策 if current_intent progress_inquiry: if not entities.get(order_id): # 如果是进度查询但缺少订单号LLM应该被引导询问订单号 return {chat_history: chat_history, response: 请问您的订单号是多少, next_action: ask_for_order_id} elif current_intent complaint_transfer: if not entities.get(complaint_details): # 如果是投诉但缺少详情LLM应该被引导询问投诉详情 return {chat_history: chat_history, response: 请您详细描述一下您要投诉的问题。, next_action: ask_for_complaint_details} elif not entities.get(contact_info): # 如果有投诉详情但缺少联系方式 return {chat_history: chat_history, response: 好的请留下您的联系方式比如手机号或邮箱以便我们处理您的投诉。, next_action: ask_for_contact_info} # 构造给LLM的完整提示包括会话历史和当前的用户查询 # LLM会根据提示和绑定的工具来决定是否调用工具 messages chat_history [HumanMessage(contentuser_query)] # 使用LLM with tools进行推理 response llm_with_tools.invoke(messages) # 如果LLM决定调用工具 if response.tool_calls: tool_call response.tool_calls[0] # 假设只有一个工具调用 tool_name tool_call[name] tool_args tool_call[args] # 查找并执行对应的工具 tool_to_call next((t for t in tools if t.name tool_name), None) if tool_to_call: try: tool_result tool_to_call.invoke(tool_args) # 将工具执行结果添加到聊天历史 new_chat_history chat_history [response, ToolMessage(contenttool_result, tool_call_idtool_call[id])] return {chat_history: new_chat_history, tool_output: tool_result, response: tool_result, next_action: tool_executed} except Exception as e: error_msg f工具执行失败: {tool_name}错误信息: {e} print(error_msg) new_chat_history chat_history [response, ToolMessage(contenterror_msg, tool_call_idtool_call[id])] return {chat_history: new_chat_history, tool_output: error_msg, response: 抱歉系统暂时无法处理您的请求请稍后再试或联系人工客服。, next_action: error_occurred} else: return {chat_history: chat_history, response: 抱歉我无法识别这个工具。, next_action: error_occurred} else: # 如果LLM没有调用工具它应该生成一个直接的回复 new_chat_history chat_history [response] return {chat_history: new_chat_history, response: response.content, next_action: responded_directly}4.2.3 人工转接节点 (human_handoff_node)当系统无法处理或用户明确要求时转接到人工客服。def human_handoff_node(state: AgentState) - AgentState: 当需要人工介入时标记状态并生成转接提示。 print(---NODE: human_handoff_node---) return {need_human_handoff: True, response: 好的我已为您转接人工客服请稍候。}4.3 定义条件边Conditional Edges与路由逻辑条件边是LangGraph中实现动态流程的关键。它允许我们根据AgentState中的值来决定下一个要执行的节点。4.3.1 路由节点 (route_intent)这个节点根据current_intent来决定将控制流路由到哪个功能模块。def route_intent(state: AgentState) - str: 根据当前识别的意图路由到不同的处理节点。 print(---ROUTER: route_intent---) current_intent state[current_intent] entities state[entities] next_action state[next_action] if next_action ask_for_order_id: return ask_for_order_id_node # 需要询问订单号 elif next_action ask_for_complaint_details: return ask_for_complaint_details_node # 需要询问投诉详情 elif next_action ask_for_contact_info: return ask_for_contact_info_node # 需要询问联系方式 elif next_action tool_executed: return generate_final_response # 工具已执行生成最终回复 elif next_action responded_directly: return generate_final_response # LLM已直接回复生成最终回复 elif next_action error_occurred: return generate_final_response # 错误发生生成错误提示 if current_intent progress_inquiry: if entities.get(order_id): return agent_executor # 有订单号直接执行代理 else: return ask_for_order_id_node # 缺少订单号询问用户 elif current_intent complaint_transfer: if entities.get(complaint_details) and entities.get(contact_info): return agent_executor # 投诉详情和联系方式都有执行代理 elif entities.get(complaint_details) and not entities.get(contact_info): return ask_for_contact_info_node # 有投诉详情但缺少联系方式 else: return ask_for_complaint_details_node # 缺少投诉详情 elif current_intent general_query: return agent_executor # 通用查询直接交给代理处理 else: # 无法识别的意图也交给通用代理它可能会询问澄清 return agent_executor4.3.2 信息补全节点 (ask_for_order_id_node,ask_for_complaint_details_node,ask_for_contact_info_node)这些是辅助节点用于在特定信息缺失时生成提示语。def ask_for_order_id_node(state: AgentState) - AgentState: print(---NODE: ask_for_order_id_node---) return {response: 请问您的订单号是多少, next_action: waiting_for_order_id} def ask_for_complaint_details_node(state: AgentState) - AgentState: print(---NODE: ask_for_complaint_details_node---) return {response: 请您详细描述一下您要投诉的问题。, next_action: waiting_for_complaint_details} def ask_for_contact_info_node(state: AgentState) - AgentState: print(---NODE: ask_for_contact_info_node---) return {response: 好的请留下您的联系方式比如手机号或邮箱以便我们处理您的投诉。, next_action: waiting_for_contact_info}4.3.3 最终回复生成节点 (generate_final_response)这个节点负责汇总所有信息生成最终的回复。def generate_final_response(state: AgentState) - AgentState: print(---NODE: generate_final_response---) response_content state[response] chat_history state[chat_history] # 如果response为空说明LLM在agent_executor中直接返回了结果或者工具直接返回了结果 if not response_content and state[tool_output]: response_content state[tool_output] elif not response_content and state[next_action] responded_directly and len(chat_history) 0: # 如果是LLM直接回复且response字段为空说明回复内容在chat_history的最后一个AIMessage中 last_message chat_history[-1] if isinstance(last_message, AIMessage): response_content last_message.content # 更新聊天历史添加AI的最终回复 new_chat_history chat_history [AIMessage(contentresponse_content)] # 清空当前的user_query和next_action准备迎接下一个用户输入 return { chat_history: new_chat_history, response: response_content, user_query: , # 清空等待下一个用户输入 next_action: , # 清空 current_intent: , # 清空等待重新识别意图 entities: {} # 清空等待重新抽取实体 }5. 组装LangGraph现在我们将所有节点和路由器组装成一个完整的StateGraph。# 构建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(process_user_input, process_user_input) workflow.add_node(agent_executor, agent_executor) workflow.add_node(human_handoff_node, human_handoff_node) workflow.add_node(ask_for_order_id_node, ask_for_order_id_node) workflow.add_node(ask_for_complaint_details_node, ask_for_complaint_details_node) workflow.add_node(ask_for_contact_info_node, ask_for_contact_info_node) workflow.add_node(generate_final_response, generate_final_response) # 设置入口点 workflow.set_entry_point(process_user_input) # 添加边 # 从用户输入处理节点到意图路由 workflow.add_edge(process_user_input, route_intent) # 从信息补全节点询问订单号到路由以便再次处理用户输入 workflow.add_edge(ask_for_order_id_node, route_intent) workflow.add_edge(ask_for_complaint_details_node, route_intent) workflow.add_edge(ask_for_contact_info_node, route_intent) # 从agent_executor到路由因为agent_executor执行完可能需要根据next_action进一步判断 workflow.add_edge(agent_executor, route_intent) # 从路由节点根据逻辑跳转到不同的处理分支 workflow.add_conditional_edges( route_intent, route_intent, { agent_executor: agent_executor, # 意图明确且信息完整交给agent_executor ask_for_order_id_node: ask_for_order_id_node, # 缺少订单号 ask_for_complaint_details_node: ask_for_complaint_details_node, # 缺少投诉详情 ask_for_contact_info_node: ask_for_contact_info_node, # 缺少联系方式 generate_final_response: generate_final_response, # 工具执行完毕或直接回复生成最终回复 } ) # 最终回复生成后视为一个交互回合结束回到起始点等待新的用户输入 # 实际上我们可以让它回到 process_user_input但为了演示闭环的结束我们先指向END # 在实际应用中generate_final_response 应该回到一个等待用户输入的循环点 workflow.add_edge(generate_final_response, END) # 暂时没有直接的human_handoff_node的入口可以根据业务逻辑添加 # workflow.add_edge(human_handoff_node, END) # 简化处理转接后结束当前流程重要说明在一个真正的闭环对话系统中generate_final_response节点不应该直接连接到END。它应该回溯到process_user_input节点或者一个等待用户输入的节点以实现持续的对话。但是为了清晰地演示一个“请求-响应”的完整闭环我们暂时将其指向END。在实际应用中您会通过一个外部循环来调用graph.stream()或graph.invoke()每次调用代表一个用户请求。# 编译图 app workflow.compile()6. 运行闭环流程处理进度查询与投诉转接示例现在让我们通过几个具体的场景来演示这个LangGraph驱动的智能客服系统。6.1 场景一处理进度查询 (Progress Inquiry)子场景 1.1: 提供完整订单号用户输入我的订单T2023001怎么样了print(n--- 用户查询: 我的订单T2023001怎么样了 ---) initial_state AgentState(chat_history[], user_query我的订单T2023001怎么样了, current_intent, entities{}, tool_output, response, next_action, need_human_handoffFalse) for s in app.stream(initial_state): print(s) if __end__ in s: final_state s[__end__] print(f最终回复: {final_state[response]}) print(f最终聊天历史: {final_state[chat_history]})预期输出流解释process_user_input节点识别意图为progress_inquiry提取order_id: T2023001。route_intent节点根据current_intent和entities路由到agent_executor。agent_executor节点通过llm_with_tools调用query_order_progress工具。工具执行返回订单进度。agent_executor更新tool_output和response设置next_action为tool_executed。route_intent再次被调用根据next_action路由到generate_final_response。generate_final_response节点生成最终回复并更新chat_history然后流程结束END。子场景 1.2: 缺少订单号需要系统追问用户输入我的订单怎么样了print(n--- 用户查询: 我的订单怎么样了 ---) initial_state AgentState(chat_history[], user_query我的订单怎么样了, current_intent, entities{}, tool_output, response, next_action, need_human_handoffFalse) for s in app.stream(initial_state): print(s) if __end__ in s: final_state s[__end__] print(f最终回复: {final_state[response]}) print(f最终聊天历史: {final_state[chat_history]})预期输出流解释process_user_input识别意图为progress_inquiry但entities中缺少order_id。route_intent节点检测到progress_inquiry但无order_id路由到ask_for_order_id_node。ask_for_order_id_node返回response: 请问您的订单号是多少next_action: waiting_for_order_id。route_intent再次被调用根据next_action路由到generate_final_response。generate_final_response节点将询问信息作为最终回复流程结束。这展示了闭环流程中“获取信息”的能力。在真实的对话系统中用户会接着输入订单号而系统需要能够将这个订单号与之前的“订单查询”意图关联起来。这需要更精细的会话上下文管理和状态更新逻辑。为了演示多轮对话我们需要稍微修改运行方式手动模拟多轮print(n--- 多轮对话场景订单查询先问号再提供 ---) current_chat_history [] # 第一轮用户询问订单但未提供订单号 user_input_1 我的订单怎么样了 print(f用户: {user_input_1}) initial_state_1 AgentState(chat_historycurrent_chat_history, user_queryuser_input_1, current_intent, entities{}, tool_output, response, next_action, need_human_handoffFalse) for s in app.stream(initial_state_1): if __end__ in s: final_state_1 s[__end__] current_chat_history final_state_1[chat_history] ai_response_1 final_state_1[response] print(fAI: {ai_response_1}) break # 结束当前轮 # 第二轮用户提供订单号 user_input_2 订单号是T2023002 print(f用户: {user_input_2}) # 这里需要将上一轮的 chat_history 传递下去并更新 user_query initial_state_2 AgentState( chat_historycurrent_chat_history, user_queryuser_input_2, current_intentprogress_inquiry, # 假设系统能够记住之前的意图 entities{order_id: T2023002}, # 假设系统能够从新输入中提取订单号 tool_output, response, next_action, need_human_handoffFalse ) for s in app.stream(initial_state_2): if __end__ in s: final_state_2 s[__end__] current_chat_history final_state_2[chat_history] ai_response_2 final_state_2[response] print(fAI: {ai_response_2}) break # 结束当前轮注意在initial_state_2中我手动设置了current_intent和entities。在更完善的系统中process_user_input节点会更智能地利用chat_history来判断是否是同一意图的延续并从最新的user_query中补充实体。这通常通过LLM的Few-shot提示或更复杂的NLU模型来实现。6.2 场景二投诉转接 (Complaint Transfer)子场景 2.1: 提供完整投诉信息用户输入我要投诉我的包裹破损了我的手机号是13800138000。print(n--- 用户查询: 我要投诉我的包裹破损了我的手机号是13800138000。 ---) initial_state AgentState(chat_history[], user_query我要投诉我的包裹破损了我的手机号是13800138000。, current_intent, entities{}, tool_output, response, next_action, need_human_handoffFalse) for s in app.stream(initial_state): print(s) if __end__ in s: final_state s[__end__] print(f最终回复: {final_state[response]}) print(f最终聊天历史: {final_state[chat_history]})预期输出流解释process_user_input节点识别意图为complaint_transfer提取complaint_details: 包裹破损和contact_info: 13800138000。route_intent节点路由到agent_executor。agent_executor节点通过llm_with_tools调用transfer_complaint工具。工具执行返回投诉转接结果。agent_executor更新tool_output和response设置next_action为tool_executed。route_intent再次被调用路由到generate_final_response。generate_final_response节点生成最终回复流程结束。子场景 2.2: 缺少联系方式系统追问用户输入我要投诉我的包裹破损了。print(n--- 多轮对话场景投诉转接先投诉再问联系方式 ---) current_chat_history_complaint [] # 第一轮用户投诉但未提供联系方式 user_input_c1 我要投诉我的包裹破损了。 print(f用户: {user_input_c1}) initial_state_c1 AgentState(chat_historycurrent_chat_history_complaint, user_queryuser_input_c1, current_intent, entities{}, tool_output, response, next_action, need_human_handoffFalse) for s in app.stream(initial_state_c1): if __end__ in s: final_state_c1 s[__end__] current_chat_history_complaint final_state_c1[chat_history] ai_response_c1 final_state_c1[response] print(fAI: {ai_response_c1}) break # 第二轮用户提供联系方式 user_input_c2 我的手机号是13800138000。 print(f用户: {user_input_c2}) initial_state_c2 AgentState( chat_historycurrent_chat_history_complaint, user_queryuser_input_c2, current_intentcomplaint_transfer, # 假设系统能够记住之前的意图 entities{complaint_details: 包裹破损, contact_info: 13800138000}, # 假设能够从多轮对话中整合实体 tool_output, response, next_action, need_human_handoffFalse ) for s in app.stream(initial_state_c2): if __end__ in s: final_state_c2 s[__end__] current_chat_history_complaint final_state_c2[chat_history] ai_response_c2 final_state_c2[response] print(fAI: {ai_response_c2}) break7. 增强闭环流程的健壮性与智能性当前实现的闭环流程已经能够处理基本的多轮对话和工具调用但一个生产级的智能客服系统还需要考虑更多。7.1 完善意图识别与实体抽取更复杂的NLU模型使用专门训练的意图识别和实体抽取模型或者为LLM提供更丰富的Few-shot示例和更细致的Prompt工程使其能够更好地从多轮对话中提取和补充信息。正则表达式与槽位填充对于像订单号、手机号这类有固定格式的实体可以结合正则表达式进行强约束提取确保准确性。上下文实体融合当用户在后续轮次提供信息时系统需要能够智能地将新信息与当前意图的缺失槽位进行匹配和填充。这要求process_user_input节点更加智能或者在route_intent之后添加一个entity_resolver节点。7.2 错误处理与恢复机制工具调用失败当agent_executor中的工具调用失败时我们目前只是返回一个通用错误。更健壮的做法是重试机制尝试重新调用工具。备用方案如果工具持续失败引导用户尝试其他解决途径或直接转接人工。错误日志详细记录错误信息便于后期分析和改进。LLM生成无效输出如果LLM生成了无法解析的JSON或不符合预期的回复系统应该能够检测到并进行恢复例如提示LLM重新生成或者使用一个默认的回复。7.3 上下文切换与意图重定向用户可能会在查询订单进度时突然提出一个无关的问题例如“你们的营业时间是几点”。当前的系统可能会将它视为general_query处理。更高级的系统需要动态意图切换允许用户在不完成当前任务的情况下切换到新任务并在完成后可以选择返回原任务或结束。意图优先级定义不同意图的优先级例如紧急投诉可能高于一般查询。确认机制在意图切换时可以向用户确认“您是想问营业时间吗那订单查询的问题我们稍后再处理可以吗”7.4 人工干预与监控人工转接的更精细化控制不仅仅是human_handoff_node系统可以在多轮失败后、用户明确要求后、或检测到情绪负面时主动建议转接人工。实时监控与运营监控客服系统的对话数据、工具调用成功率、用户满意度等指标及时发现问题并进行优化。人机协作在某些复杂场景下可以设计系统先提供初步信息然后将上下文和初步信息一同转交给人工客服提升人工客服的效率。7.5 持久化与状态恢复当前的AgentState仅存在于单次app.stream()调用中。在实际应用中需要将会话状态持久化到数据库中例如Redis、PostgreSQL以便用户在中断对话后可以从上次离开的地方继续。LangChain提供了RunnableWithMessageHistory可以方便地集成消息历史的持久化。8. 展望未来多Agent协作与深度集成随着LangGraph和LLM技术的发展智能客服系统将进一步演进多Agent协作针对不同的客服任务如订单管理、技术支持、销售咨询可以设计多个专业的LangGraph代理。当一个代理无法处理时可以将其转交给另一个更专业的代理形成一个Agent网络。情感识别与情绪管理结合情感分析技术识别用户的情绪状态从而调整回复的语气和策略例如在用户情绪激动时优先转接人工。主动式服务基于用户行为和历史数据系统可以主动向用户推送相关信息如订单状态更新、促销活动等。与企业内部系统深度集成不仅仅是简单的API调用而是通过LangGraph构建的代理能够更深入地理解企业内部流程和数据模型实现更复杂的自动化任务如自动修改订单、处理退换货申请等。结语今天我们深入探讨了如何利用LangGraph构建一个支持“处理进度查询”和“投诉转接”的闭环智能客服系统。从图谱状态的定义、工具的集成到核心节点的实现和流程的编排我们展示了LangGraph在构建复杂、有状态、意图驱动的LLM应用方面的强大能力。通过模块化的设计和清晰的路由逻辑我们不仅能够响应用户请求还能主动获取信息、执行外部动作并维持连贯的对话体验。这仅仅是开始未来智能客服的潜力无限期待各位能够将这些技术应用到更广阔的实践中。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询