从零搭建可可视化思考链路的智能客服 Agent:拆解工具调用、决策日志与邮件归档完整实现
从零搭建可可视化思考链路的智能客服 Agent拆解工具调用、决策日志与邮件归档完整实现一、前言从传统客服到 Agent 智能体的技术跃迁在大模型普及之前传统在线客服系统大多基于关键词匹配、固定问答库搭建只能应对标准化、单一化咨询。一旦用户提出跨场景复合需求 —— 比如先查订单、再问库存、最后要求导出全部对话记录发送邮件传统客服代码就会陷入逻辑臃肿、分支爆炸的困境。随着 Agent 智能体技术落地“思考 (Thought)- 行动 (Action)- 观察 (Observation)” 的闭环范式成为解决复杂任务调度的标准方案。不同于简单的 if-else 判断Agent 拥有独立的意图思考模块、可扩展工具集、完整决策记录链路三大核心能力它能自主判断用户需求、选择对应工具执行、保存每一轮推理过程甚至支持对话数据自动归档推送。本文将基于一份完整可运行的 Python 工程带大家从零拆解一款轻量化工业级智能客服 Agent。项目实现三大核心工具订单查询、商品库存查询、对话记录邮件自动推送同时内置可视化决策日志模块每一轮用户交互都会完整打印 Agent 的内心思考、调用工具、入参、返回结果完美复现大模型 Agent 的推理过程无需依赖任何第三方大模型 API纯规则即可落地新手也能看懂、运行、二次改造。完整工程包含四大分层模块决策日志实体层、工具集封装层、Agent 核心推理层、交互式对话入口。全文将逐模块解析代码设计思想、业务落地场景、可扩展优化方案同时结合运行演示截图展示实际交互效果适合想入门 Agent 开发、搭建私有客服机器人、学习工具调用逻辑的开发者阅读。二、项目整体架构设计分层解耦易于扩展整个智能客服 Agent 采用分层模块化设计四层结构职责完全隔离符合高内聚低耦合编程思想后续新增业务工具、替换 LLM 推理、扩展日志存储都无需改动核心逻辑决策日志层DecisionLogger负责存储每一轮对话 Agent 的完整推理链路封装实体类记录轮次、思考内容、调用工具、参数、返回结果提供可视化打印方法直观展示 Agent “大脑” 的思考过程对应截图中完整的【Agent 完整思考 - 行动决策链路】输出。工具集层CustomerServiceTools统一封装所有业务能力工具当前内置订单查询、库存查询、QQ 邮件发送三大工具提供统一run_tool分发路由新增业务仅需新增工具函数 路由判断不用改动 Agent 推理逻辑。内置模拟订单、库存数据库同时集成 yagmail 实现真实 SMTP 邮件发送支持对话记录一键归档。Agent 核心推理层ServiceAgent整个项目的调度中枢实现经典 T-A-O思考 - 行动 - 观察闭环。think()方法完成用户意图识别规则匹配可无缝替换为 GPT / 文心一言等大模型run_agent()串联思考、工具执行、日志存储、对话历史保存全流程chat_loop()提供交互式命令行多轮对话。程序入口层极简启动入口实例化 Agent 并启动对话循环输入quit即可退出程序退出后自动打印全部轮次的决策日志。运行流程总览用户输入对话 → Agent 思考模块识别需求 → 匹配对应业务工具 → 工具执行返回结果 → 保存本轮对话历史与推理日志 → 输出客服回复 → 用户持续交互直至输入 quit 退出 → 批量可视化所有轮次完整思考链路。三、核心模块深度源码解析3.1 决策日志实体层实现 Agent 思考过程可追溯、可视化很多新手开发 Agent 时会忽略推理过程记录只关注最终返回给用户的结果但在生产环境中可追溯的决策日志是排查问题、优化意图识别的核心依据。例如用户输入指令没有触发预期工具、工具参数传递错误通过日志就能直接定位 Agent 哪一轮思考出现偏差。项目使用dataclass定义DecisionRecord数据实体标准化每一轮推理的存储字段对话轮次、思考文本、调用工具名、工具入参字典、工具返回观察结果。配套DecisionLogger日志管理器提供新增记录、批量可视化打印两个核心方法。环境部署与前置配置3.1 第三方库安装项目仅依赖yagmail邮件库打开终端 / Notebook 单元格执行安装命令python# 适配云Notebook精准安装避免环境错位 import sys !{sys.executable} -m pip install yagmail --user -i https://pypi.tuna.tsinghua.edu.cn/simpleKaggle 环境注意带--user参数安装的库存储在临时用户目录重启内核会丢失每次启动会话需重新执行安装代码全局安装可移除--user参数。3.2 QQ 邮箱授权码获取邮件发送必备代码无法直接使用 QQ 登录密码登录 SMTP 服务器必须开启 POP3/IMAP 服务并生成 16 位授权码操作步骤浏览器打开mail.qq.com登录发件 QQ 账号页面右上角「设置」→ 顶部切换「账户」标签下滑找到POP3/IMAP/SMTP服务点击开启完成短信 / 扫码安全验证验证通过后点击「生成授权码」复制页面展示的 16 位字母 数字组合妥善保存仅显示一次丢失需重新生成。3.3 邮箱配置参数替换在CustomerServiceTools类初始化方法中修改三处邮箱配置pythonself.sender_mail 你的QQ账号qq.com # 发件QQ邮箱 self.auth_code 你的QQ邮箱授权码 # 16位授权码 self.receiver_mail 你的QQ账号qq.com # 接收对话记录的目标邮箱pythondataclass class DecisionRecord: round_id: int # 对话轮次 thought: str # Agent思考内容 action: str # 执行动作工具名 action_params: Dict # 工具入参 observation: str # 工具返回结果 class DecisionLogger: def __init__(self): self.records: List[DecisionRecord] [] def add_record(self, round_id: int, thought: str, action: str, params: Dict, observation: str): rec DecisionRecord(round_id, thought, action, params, observation) self.records.append(rec) def visualize(self): 可视化打印完整思考行动链 print(\n Agent 完整思考-行动决策链路 ) for item in self.records: print(f\n【第{item.round_id}轮】) print(f 思考(Thought): {item.thought}) print(f⚙️ 行动(Action): {item.action}) print(f 参数(Params): {item.action_params}) print(f 观察(Observation): {item.observation}) print()结合运行截图可以看到每一轮交互都会按固定格式输出结构化日志第 1 轮用户查询 O1001 订单Agent 思考内容、调用query_order工具、传入订单号参数、工具返回订单详情全部完整展示第 4 轮执行邮件发送时日志清晰记录邮件收件人、拼接完整对话记录作为邮件正文全程透明可追溯。日志模块的业务价值开发调试快速定位意图识别逻辑 bug比如用户输入模糊指令时 Agent 错误匹配工具业务复盘运营可导出完整推理链路分析用户高频咨询需求优化客服话术LLM 迁移兼容如果后续将规则匹配替换为大模型日志格式完全对齐主流 LLM Agent 框架LangChain、LlamaIndex无需重构日志存储逻辑。3.2 工具集封装层统一管理业务能力低门槛扩展工具是 Agent 和真实业务系统交互的桥梁本项目将所有工具收敛在CustomerServiceTools类中内置模拟数据库、邮箱配置、工具分发路由三大工具各司其职相互解耦。3.2.1 模拟业务数据库内置订单库order_db、库存库stock_db模拟后端业务服务生产环境可直接替换为 MySQL、Redis 接口调用无需改动上层 Agent 逻辑python运行self.order_db { O1001: {status: 已发货, goods: 无线鼠标, num: 2}, O1002: {status: 待发货, goods: 机械键盘, num: 1} } self.stock_db { 无线鼠标: 156, 机械键盘: 23 }观测层DecisionLogger 可观测决策日志模块4.1.1 DecisionRecord 日志实体使用dataclass定义标准化日志存储结构固定 5 类核心字段统一存储每一轮 Agent 完整决策信息解决日志格式混乱、字段缺失问题python运行dataclass class DecisionRecord: round_id: int # 对话轮次区分多轮会话 thought: str # AI完整思考推理文本解决黑盒问题 action: str # 执行动作标识工具名/reply_direct action_params: Dict # 工具调用入参字典用于调试参数错误 observation: str # 工具执行返回结果客服回复文本每一次用户交互都会生成一条DecisionRecord对象存入日志列表永久缓存至会话结束。4.1.2 DecisionLogger 日志管理类提供两大核心方法add_record()接收本轮全部决策数据实例化日志实体并存入列表visualize()格式化遍历全部日志分层打印轮次、思考、动作、参数、返回结果清晰展示 AI 完整推理链路便于开发调试与业务复盘。python运行class DecisionLogger: def __init__(self): self.records: List[DecisionRecord] [] # 写入单轮决策记录 def add_record(self, round_id: int, thought: str, action: str, params: Dict, observation: str): rec DecisionRecord(round_id, thought, action, params, observation) self.records.append(rec) # 可视化打印全链路日志 def visualize(self): print(\n Agent 完整思考-行动决策链路 ) for item in self.records: print(f\n【第{item.round_id}轮】) print(f 思考(Thought): {item.thought}) print(f⚙️ 行动(Action): {item.action}) print(f 参数(Params): {item.action_params}) print(f 观察(Observation): {item.observation}) print()4.2 能力层CustomerServiceTools 业务工具集————————————————版权声明本文为CSDN博主「Q19175349932」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。原文链接https://blog.csdn.net/Q19175349932/article/details/1625130723.2.2 订单 库存查询工具query_order、query_stock为基础查询工具加入time.sleep(0.2)模拟真实接口网络延迟返回标准化可读文本直接对外输出给用户容错处理覆盖订单号 / 商品不存在场景。3.2.3 真实 QQ 邮箱发送工具核心特色功能区别于仅模拟邮件输出的 Demo本项目基于yagmail封装真实 SMTP 邮件发送能力支持将全部多轮对话历史拼接为邮件正文一键归档对话记录适配企业客服会话留存需求。python运行def send_email(self, receiver: str, content: str) - str: try: mail_client yagmail.SMTP( userself.sender_mail, passwordself.auth_code, hostsmtp.qq.com ) mail_client.send( toreceiver, subject【智能客服Agent完整对话记录】, contentscontent ) return f✅ 对话记录邮件发送成功收件人{receiver} except Exception as err: return f❌ 邮件发送失败错误详情{str(err)}代码增加全局异常捕获避免邮箱配置错误、网络波动导致整个客服程序崩溃QQ 邮箱配置区单独抽离注释标注使用者仅需替换发件邮箱、授权码、收件邮箱即可使用。3.2.4 统一工具分发器run_tool通过工具名字符串路由分发Agent 仅需传递工具名和参数字典不用感知每个工具的入参细节。后续新增物流查询、退款申请等工具只需要新增函数 增加一行elif判断完美满足业务迭代需求符合开闭设计原则。3.3 Agent 核心层T-A-O 闭环智能体调度中枢ServiceAgent是整个项目的核心串联思考、工具执行、日志存储、对话记录四大能力实现标准 Agent 闭环流程。3.3.1 意图思考模块think()当前采用轻量化关键词规则匹配实现意图识别零成本即可运行同时预留完美的大模型替换接口。方法返回三元组思考文本、工具名称、工具参数字典。python运行def think(self, user_input: str) - tuple[str, str, Dict]: self.round 1 user_text user_input.strip() if 订单 in user_text and O1001 in user_text: thought 用户想要查询O1001订单调用query_order工具传入订单号O1001 action query_order params {order_no: O1001} elif 库存 in user_text and 机械键盘 in user_text: thought 用户询问机械键盘库存调用query_stock工具 action query_stock params {product_name: 机械键盘} elif 发邮件 in user_text: thought 用户请求发送全部对话记录邮件调用send_email工具把历史对话作为邮件正文 action send_email mail_content 本次智能客服完整对话记录 \n for idx, item in enumerate(self.dialog_history, 1): mail_content f\n【第{idx}轮】\n用户{item[user]}\n客服{item[reply]}\n params { receiver: self.tools.receiver_mail, content: mail_content } else: thought 无法识别用户需求无需调用工具返回兜底提示 action reply_direct params {} return thought, action, params逻辑覆盖三类核心用户需求订单查询、库存查询、对话邮件归档无法匹配时走兜底直接回复引导用户输入规范指令。同时内置dialog_history列表永久保存每一轮用户提问与客服回复执行发邮件工具时自动遍历拼接完整对话文本。3.3.2 单次闭环执行run_agent()完成一轮完整交互全流程调用 think 获取推理结果 → 判断是否需要调用工具 → 执行工具获取返回内容 → 写入决策日志 → 保存对话历史最终返回客服回复文本给终端打印。3.3.3 交互式对话循环chat_loop()提供命令行交互式入口打印使用指引持续接收用户输入输入quit终止循环程序退出时自动调用日志可视化方法批量输出所有轮次完整推理链路和截图运行效果完全对应。3.4 程序入口层极简启动代码隔离业务逻辑与启动代码结构清晰python运行if __name__ __main__: agent ServiceAgent() agent.chat_loop()四、项目运行演示还原多轮对话完整流程结合两张运行截图完整复现用户多轮交互场景直观感受 Agent 完整工作链路4.1 对话交互流程第一轮用户输入「帮我查找一下订单 O1001」 Agent 思考识别用户查询订单调用query_order工具传入订单号 O1001工具返回订单详情客服输出订单信息保存本轮对话与推理日志。第二轮用户输入「帮我查看机械键盘的库存还有多少」 关键词匹配触发库存查询工具返回机械键盘库存 23 件完成第二轮记录。第三轮用户输入「帮我发送邮件到邮箱」 关键词仅包含 “邮件”无 “发邮件” 完整关键词匹配兜底分支返回引导提示文本日志标记reply_direct无工具调用。第四轮用户输入「发邮件」 精准匹配邮件发送意图自动读取前 3 轮全部对话历史拼接为邮件正文调用send_email工具发送至配置 QQ 邮箱返回发送成功提示。终止交互用户输入quit退出对话循环程序批量打印 4 轮完整思考 - 行动决策链路每一轮 Agent 的内心推理、工具参数、返回结果全部结构化输出。4.2 运行效果核心亮点推理全透明普通客服程序只会输出回复文本本项目完整还原 Agent “思考过程”复现大模型 Agent 的思维链CoT效果是学习思维链技术绝佳入门案例真实业务落地能力不只是模拟 Demo邮件模块可真实收发对话记录订单、库存模块可无缝对接企业后端接口高容错鲁棒性工具调用异常捕获、未知指令兜底回复、邮箱发送失败捕获不会出现程序崩溃轻量化无依赖仅依赖 yagmail 第三方库其余均为 Python 标准库安装一行pip install yagmail即可运行无需 GPU、大模型 API 密钥。五、工程扩展与生产级优化方案本项目是轻量化 Agent Demo在此基础上可从四大维度升级为企业级智能客服系统下面给出可落地优化思路5.1 意图识别升级规则匹配替换为大模型 LLM当前think()方法基于关键词规则适合标准化指令面对模糊、口语化用户提问如 “我之前买的鼠标订单查一下”“键盘还有货吗把聊天记录发我邮箱”识别能力不足。可将think()重构为调用大模型 APIOpenAI、通义千问、本地 Llama3通过 Prompt 约束大模型输出固定 JSON 格式的思考、动作、参数日志、工具层完全不用改动兼容现有架构。5.2 持久化存储优化当前决策日志、对话历史仅保存在内存程序退出即销毁生产环境需要持久化对话记录、决策日志写入 SQLite/MySQL增加对话 ID、用户 ID、时间戳字段日志支持导出 Excel、PDF 文件搭配邮件工具实现自动日报推送接入 Elasticsearch支持对话内容全文检索方便运营复盘。5.3 工具集能力拓展基于统一run_tool路由快速新增企业客服高频工具物流查询工具对接快递 100 开放 API输入订单号获取物流轨迹售后退款工具调用售后系统接口提交退款申请、查询退款进度商品推荐工具根据用户查询的商品返回关联配件库存与活动优惠知识库检索工具接入向量数据库实现产品 FAQ 智能问答。5.4 交互界面升级当前仅支持命令行交互可快速封装上层交互界面Web 端基于 Gradio/Streamlit 搭建可视化网页客服界面实时展示 Agent 思考日志对接企业渠道封装 API 接口对接小程序、企业微信、抖音小店客服窗口可视化面板实时展示每一轮 T-A-O 推理链路用于产品演示、教学培训。5.5 安全与风控优化参数校验对订单号、邮箱、商品名校验输入格式防止注入攻击邮件权限管控限制仅管理员邮箱接收对话记录避免会话数据泄露访问限流单用户每分钟工具调用次数限制防止恶意高频查询压垮业务数据库敏感词过滤对话内容过滤手机号、身份证等隐私信息邮件发送前脱敏处理。六、总结Agent 开发入门核心收获本文完整实现了一套分层架构、可追溯推理、具备真实业务能力的轻量化智能客服 Agent从代码分层设计、T-A-O 智能体闭环、工具调用路由、决策日志可视化、多轮对话邮件归档多个维度完成拆解。对于 Agent 技术入门学习者通过本项目可以掌握三大核心知识点Agent 标准 T-A-O 闭环范式理解智能体 “思考判断 - 工具执行 - 结果观察” 的基础运行逻辑这是所有大模型 AgentAutoGPT、LangChain Agent的底层核心原理模块化工程设计思想业务工具、推理逻辑、日志存储分层解耦掌握可扩展、易维护的 Python 工程开发规范业务落地 Demo 改造能力基于现有代码快速拓展客服场景功能无缝对接后端数据库、邮件、第三方 API低成本搭建私有智能客服机器人。不同于网上大量仅做模拟输出、无真实业务能力的玩具 Demo本项目的邮件归档、可视化推理日志两大特色功能可直接用于课程作业、技术演示、小型企业内部客服工具。读者运行代码后可基于文中给出的扩展方案尝试接入大模型、Web 界面、数据库持久化一步步从 Demo 升级为完整可用的生产级智能客服系统。可完整运行代码import time import yagmail from typing import Dict, List, Any from dataclasses import dataclass # ---------------------- 1. 决策日志实体 ---------------------- dataclass class DecisionRecord: round_id: int # 对话轮次 thought: str # Agent思考内容 action: str # 执行动作工具名 action_params: Dict # 工具入参 observation: str # 工具返回结果 class DecisionLogger: 决策日志管理器用于可视化思考过程 def __init__(self): self.records: List[DecisionRecord] [] def add_record(self, round_id: int, thought: str, action: str, params: Dict, observation: str): rec DecisionRecord(round_id, thought, action, params, observation) self.records.append(rec) def visualize(self): 可视化打印完整思考行动链 print(\n Agent 完整思考-行动决策链路 ) for item in self.records: print(f\n【第{item.round_id}轮】) print(f 思考(Thought): {item.thought}) print(f⚙️ 行动(Action): {item.action}) print(f 参数(Params): {item.action_params}) print(f 观察(Observation): {item.observation}) print() # ---------------------- 2. 工具集订单、库存、真实邮件发送 ---------------------- class CustomerServiceTools: 客服可用工具库 def __init__(self): # 【核心配置区必须修改为你自己的信息】 self.sender_mail 你的QQ账号qq.com # 发件人QQ邮箱 self.auth_code 你的QQ邮箱授权码 # 网页mail.qq.com生成的授权码 self.receiver_mail 你的QQ账号qq.com # 接收对话记录的邮箱 # # 模拟业务数据库 self.order_db { O1001: {status: 已发货, goods: 无线鼠标, num: 2}, O1002: {status: 待发货, goods: 机械键盘, num: 1} } self.stock_db { 无线鼠标: 156, 机械键盘: 23 } def query_order(self, order_no: str) - str: 工具1查询订单 time.sleep(0.2) if order_no in self.order_db: info self.order_db[order_no] return f订单{order_no}商品{info[goods]}数量{info[num]}状态{info[status]} else: return f未查询到订单号 {order_no} def query_stock(self, product_name: str) - str: 工具2查询库存 time.sleep(0.2) stock self.stock_db.get(product_name, 0) return f商品【{product_name}】当前库存{stock}件 def send_email(self, receiver: str, content: str) - str: 工具3真实QQ邮箱发送捕获异常防崩溃 try: # 连接QQ邮箱SMTP服务器 mail_client yagmail.SMTP( userself.sender_mail, passwordself.auth_code, hostsmtp.qq.com ) # 发送邮件 mail_client.send( toreceiver, subject【智能客服Agent完整对话记录】, contentscontent ) return f✅ 对话记录邮件发送成功收件人{receiver} except Exception as err: return f❌ 邮件发送失败错误详情{str(err)} # 工具路由分发器 def run_tool(self, tool_name: str, params: Dict[str, Any]) - str: if tool_name query_order: return self.query_order(params[order_no]) elif tool_name query_stock: return self.query_stock(params[product_name]) elif tool_name send_email: return self.send_email(params[receiver], params[content]) else: return f不存在工具{tool_name} # ---------------------- 3. Agent核心思考-行动-观察闭环 ---------------------- class ServiceAgent: def __init__(self): self.tools CustomerServiceTools() self.logger DecisionLogger() self.round 0 # 新增存储全部对话历史 self.dialog_history [] def think(self, user_input: str) - tuple[str, str, Dict]: 意图识别模块规则匹配可替换大模型LLM self.round 1 user_text user_input.strip() if 订单 in user_text and O1001 in user_text: thought 用户想要查询O1001订单调用query_order工具传入订单号O1001 action query_order params {order_no: O1001} elif 库存 in user_text and 机械键盘 in user_text: thought 用户询问机械键盘库存调用query_stock工具 action query_stock params {product_name: 机械键盘} elif 发邮件 in user_text: thought 用户请求发送全部对话记录邮件调用send_email工具把历史对话作为邮件正文 action send_email # 拼接完整对话记录作为邮件内容 mail_content 本次智能客服完整对话记录 \n for idx, item in enumerate(self.dialog_history, 1): mail_content f\n【第{idx}轮】\n用户{item[user]}\n客服{item[reply]}\n params { receiver: self.tools.receiver_mail, content: mail_content } else: thought 无法识别用户需求无需调用工具返回兜底提示 action reply_direct params {} return thought, action, params def run_agent(self, user_message: str) - str: 单次完整思考-执行-记录闭环 thought, action, params self.think(user_message) if action reply_direct: obs 暂时无法识别您的请求请提供订单号/商品名称或输入发邮件发送全部对话记录 else: obs self.tools.run_tool(action, params) # 写入决策日志 self.logger.add_record( round_idself.round, thoughtthought, actionaction, paramsparams, observationobs ) # 保存本轮用户提问客服回复到对话历史 self.dialog_history.append({ user: user_message, reply: obs }) return obs def chat_loop(self): 交互式多轮对话入口 print( 智能客服Agent已启动) print(使用指令示例) print(1. 查询O1001订单) print(2. 机械键盘库存还有多少) print(3. 发邮件自动把所有对话记录发送到邮箱) print(输入 quit 退出对话\n) while True: user_msg input(用户) if user_msg.lower() quit: break reply self.run_agent(user_msg) print(f客服回复{reply}\n) # 退出后打印完整决策链路 self.logger.visualize() # ---------------------- 4. 程序入口 ---------------------- if __name__ __main__: agent ServiceAgent() agent.chat_loop()