当前位置: 首页 > news >正文

从零构建智能客服Agent:工具、决策循环与实战优化 | 附完整代码

大家好,我是阿龙。今天我们不聊虚的,直接动手做一个能自主决策、调用外部工具的智能客服Agent。它会像人类客服一样:先查订单、再查知识库,最后给出精准回复,甚至能根据规则拒绝不合规的退款请求。

我会用DeepSeek模型作为大脑,配合三个核心工具(订单查询、知识库搜索、退款处理),实现一个完整的ReAct决策循环。全文包含可直接运行的代码,以及两个真实业务场景的推演。

本文所有代码已开源,文末有完整代码,建议收藏后阅读。


一、为什么客服Agent需要“工具”?

纯大模型(如ChatGPT)只能根据训练数据回答,无法获取实时订单状态、无法执行退款操作。而工具(Tool)赋予它“动手能力”:

  • 查询工具:对接数据库,获取订单详情
  • 知识工具:对接RAG(检索增强生成),查询最新政策
  • 操作工具:执行退款申请等敏感操作

我们的客服Agent会这样工作:
用户提问 → 模型思考 → 调用工具 → 获取结果 → 继续思考 → 最终回答
这个过程叫ReAct(Reason + Act),是当前最主流的Agent实现模式。


二、准备三个核心工具函数

我们先实现三个模拟工具,实际项目中可以把它们换成真实API或数据库查询。

python

import json # 1. 订单查询(模拟数据库) def get_order_details(order_id: str): """查询订单状态和发货信息""" mock_db = { "ORD-123": {"status": "已发货", "delivery_date": "2023-12-01", "items": ["iPhone 15"]}, "ORD-456": {"status": "待付款", "items": ["MacBook Pro"]} } result = mock_db.get(order_id) if result: return json.dumps(result, ensure_ascii=False) return json.dumps({"error": "订单不存在"}) # 2. 退款处理(模拟提交) def process_refund(order_id: str, reason: str): """提交退款申请(需人工审核)""" print(f"【系统】正在处理订单 {order_id} 的退款,原因: {reason}") return json.dumps({"status": "success", "message": "退款申请已提交人工审核"}) # 3. 知识库搜索(假设第三讲已实现RAG) from lecture3_rag import CustomerServiceBot # 伪代码,你需要替换为自己的RAG类 rag_bot = CustomerServiceBot() rag_bot.initialize_data() def search_knowledge_base(query: str): """查询退货政策、会员权益等""" return rag_bot.answer(query)

注意:实际使用时,请将 lecture3_rag 替换为你自己的RAG实现,或者直接用一个简单的关键词匹配函数代替。


三、让DeepSeek理解这些工具

我们需要把工具的描述信息注册成模型可以理解的JSON Schema格式。这样DeepSeek在生成回复时,会知道什么时候该调用哪个工具,以及需要传递什么参数。

python

agent_tools = [ { "type": "function", "function": { "name": "get_order_details", "description": "根据订单号查询订单状态、发货信息", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单号,例如 ORD-123"} }, "required": ["order_id"] } } }, { "type": "function", "function": { "name": "search_knowledge_base", "description": "当问题涉及退货政策、会员权益、运费规则等通用知识时使用", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "搜索关键词或问题"} }, "required": ["query"] } } }, { "type": "function", "function": { "name": "process_refund", "description": "为指定订单提交退款申请,需用户确认后才可调用", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单号"}, "reason": {"type": "string", "description": "退款原因"} }, "required": ["order_id", "reason"] } } } ]

四、Agent核心:ReAct决策循环

现在到了最关键的环节——循环。我们将不断调用DeepSeek,检查它是否要求调用工具,如果有就执行工具并把结果返回给它,直到它给出最终答案。

python

import json from openai import OpenAI # DeepSeek 兼容OpenAI接口 client = OpenAI( api_key="your-api-key", base_url="https://api.deepseek.com" ) # 工具函数映射表 available_functions = { "get_order_details": get_order_details, "search_knowledge_base": search_knowledge_base, "process_refund": process_refund } def run_agent(user_input): # 初始化对话历史(包含系统指令) messages = [ {"role": "system", "content": "你是一个智能客服Agent。即使你知道答案,也优先使用知识库工具确认。处理订单问题时必须先查询订单状态。退款操作必须用户明确同意才能调用process_refund。"}, {"role": "user", "content": user_input} ] while True: # 1. 调用DeepSeek模型 response = client.chat.completions.create( model="deepseek-chat", messages=messages, tools=agent_tools, tool_choice="auto" ) response_msg = response.choices[0].message # 2. 检查模型是否要求调用工具 tool_calls = response_msg.tool_calls if tool_calls: # 将模型的工具调用意图加入历史(防止它“失忆”) messages.append(response_msg) # 3. 执行所有工具调用(可能一次多个,如并发查询) for tool_call in tool_calls: func_name = tool_call.function.name func_args = json.loads(tool_call.function.arguments) func_to_call = available_functions.get(func_name) print(f"【Agent动作】调用 {func_name} 参数: {func_args}") # 执行函数并获取结果 func_response = func_to_call(**func_args) # 4. 将工具结果作为新消息加入历史 messages.append({ "tool_call_id": tool_call.id, "role": "tool", "name": func_name, "content": str(func_response), }) # 继续循环,模型会看到工具结果并决定下一步 else: # 没有工具调用,说明模型已经准备好最终回答 print(f"【Agent回答】: {response_msg.content}") return response_msg.content

几点说明

tool_choice="auto" 让模型自行决定是否需要调用工具。

工具结果通过 role="tool" 返回给模型,模型会把这些结果当作“观察”来推理下一步。

循环直到模型返回普通文本(即最终答案)才结束。


五、实战场景推演

让我们用两个真实业务问题测试这个Agent。

场景1:复合问题(订单查询 + 政策咨询)

用户输入

“我的订单ORD-123还没收到,是不是丢件了?还有你们的退款政策是啥?”

执行过程(模拟输出):

text

【Agent动作】调用 get_order_details 参数: {'order_id': 'ORD-123'} 【Agent动作】调用 search_knowledge_base 参数: {'query': '退款政策'} 【Agent回答】: 关于您的订单ORD-123,系统显示已于12月1日发货,状态正常,请耐心等待。另外,我们的退款政策是支持7天无理由退换货...

可以看到,Agent先查了订单状态,又查了知识库,最后将两者整合回答。这正是多工具协作的魅力。

场景2:工具链式调用(按规则决策)

用户输入

“帮我把订单ORD-123退了。”

执行过程(模拟输出):

text

【Agent动作】调用 get_order_details 参数: {'order_id': 'ORD-123'} 【Agent思考】订单状态是“已发货”,不能直接取消,需要告知用户收货后申请退货。 【Agent回答】: 您的订单ORD-123已经发货了,无法直接取消。您可以在收货后申请7天无理由退货。

这里Agent没有盲目调用 process_refund,而是根据业务规则(已发货订单不能直接退款)做出了合理决策。这就是系统提示词和工具调用的结合——模型“理解”了业务约束。


六、优化技巧:减少幻觉 & 提升性能

6.1 强化系统提示词

为了防止模型编造订单数据或擅自退款,我们可以在系统提示中加入硬性约束

python

SYSTEM_PROMPT = """ 你是一个严谨的电商业务助手。 1. 禁止伪造订单数据,必须使用 `get_order_details` 查询。 2. 只有在用户明确确认后,才能调用 `process_refund` 涉及资金的接口。 3. 如果工具返回 `Error`,请直接告诉用户错误原因,不要尝试自己编造成功的结果。 """

6.2 并行工具调用

DeepSeek支持一次返回多个工具调用(例如同时查天气和查汇率)。我们可以利用Python的concurrent.futures并发执行,降低延迟:

python

from concurrent.futures import ThreadPoolExecutor with ThreadPoolExecutor() as executor: futures = [] for tool_call in tool_calls: func = available_functions[tool_call.function.name] args = json.loads(tool_call.function.arguments) futures.append(executor.submit(func, **args)) results = [f.result() for f in futures]

然后将结果依次加入消息列表即可。


七、未来探索:多Agent协作与Workflow

单个Agent能力有限,你可以进一步设计多Agent系统

  • 接待Agent:分类用户意图
  • 售后Agent:专门处理退款(持有限定工具)
  • 技术Agent:专门查阅文档(RAG)

对于标准化流程(如退款必须经过“查询订单→确认用户→提交申请”),也可以将部分流程硬编码为Workflow,只在异常时让Agent介入。这样既有确定性,又有灵活性。


八、总结

今天我们实现了一个能自主思考、调用工具、遵循业务规则的智能客服Agent。核心点包括:

  1. 工具定义:用函数封装外部能力
  2. 工具描述:通过JSON Schema让模型理解工具
  3. ReAct循环:反复调用模型,执行工具,直到获得答案
  4. 实战场景:复合问题、链式决策
  5. 优化:系统提示约束、并行调用

你可以在此基础上扩展更多工具(如查物流、查积分、修改地址),甚至可以接入真实数据库和RAG系统。Agent的能力边界,只取决于你提供的工具丰富程度

欢迎在评论区留下你的想法,或者分享你用Agent解决的实际问题。如果觉得文章有用,请点个赞,让更多人看到!


完整代码已整合(下载即可运行,记得替换API key和RAG实现):

完整项目代码下载地址:https://pan.baidu.com/s/1Wm7eAajXU2OqfTIQO0IE2g?pwd=3qte

(本文代码基于DeepSeek API,兼容OpenAI SDK,其他模型需调整接口)

http://www.jsqmd.com/news/455294/

相关文章:

  • MogFace-large与计算机网络:构建高可用分布式人脸检测微服务
  • 5个窗口管理难题的终极解决方案:WindowResizer让多屏协作效率提升30%
  • 窗口尺寸掌控者:WindowResizer重新定义桌面空间管理
  • 突破窗口限制:5大核心功能让WindowResizer成为多任务效率神器
  • Qwen-Image在电商海报中的应用:一键生成带促销文案的商品图
  • 突破ControlNet模型加载障碍:3种解决方案全解析
  • 告别繁琐操作:AltDrag窗口管理工具如何提升Windows效率?
  • Windows窗口管理新范式:AltDrag让窗口操作效率提升200%的秘密
  • OpenGL彩色线段绘制技巧:如何用glColor4ub实现渐变效果(避坑指南)
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4与Node.js集成:构建轻量级AI聊天服务
  • Unity新手必看:Sprite Renderer点击事件实现全攻略(附BoxCollider 2D避坑指南)
  • YOLOv10官版镜像适合谁?一文看懂五大应用场景与避坑指南
  • 深入解析clock latency对block和top flatten的timing相关性影响及优化策略
  • 4个关键步骤:ComfyUI ControlNet Aux开源工具模型配置完全指南
  • 从3.2s到380ms:我们如何在金融级SLA下实现Java函数冷启动“零感知”(含字节码裁剪与init-time profiling实战)
  • 窗口管理效率革命:用AltDrag解放你的双手
  • Hunyuan-MT-7B新手教程:从镜像拉取到翻译测试,完整步骤详解
  • 设备重生:AppleRa1n如何让闲置iOS设备重获新生
  • 第三节:RAG基础(概念、工作流程、文档分块、向量和Embedding等等)
  • 5个技巧让Windows窗口管理效率提升100%:AltDrag效率工具实战指南
  • 多智能体并行协作开发模式 Claude Code Agent Teams 完整上手攻略
  • OFA图像描述模型结合Transformer架构优化:提升描述准确性与流畅度
  • 3个步骤搞定运行库管理难题:VisualCppRedist AIO的一站式解决方案
  • coreDNS部署
  • Flutter 三方库 flutter_native_splash 的鸿蒙化适配指南 - 掌握原生启动页自动化配置技术、助力鸿蒙应用构建极致第一印象与零闪烁开启的视觉美学体系
  • 震惊!这些竟是超好用的AI获客渠道服务商!
  • Granite TimeSeries FlowState R1生成多元时间序列预测效果:关联指标协同分析
  • ChatGPT私有化部署实战指南:从零搭建到生产环境避坑
  • 保姆级教学:圣女司幼幽-造相Z-Turbo模型提示词编写技巧
  • LiuJuan20260223Zimage模型企业级部署架构设计:高可用与弹性伸缩