从零搭建 ReAct 智能体:打造具备思考与行动能力的自动化客服机器人
一、前言
大语言模型的快速普及,让智能对话机器人走进各行各业。但在实际业务落地过程中,两类传统方案都暴露出难以规避的短板:纯文本对话机器人只能依赖模型内置知识回答问题,面对订单、库存这类实时业务数据时极易产生内容虚构,也就是常说的 “模型幻觉”;而传统自动化脚本只能匹配固定指令执行任务,缺少自主理解用户自然语言需求的能力,一旦用户改变提问句式,程序就会失效。
ReAct(Reasoning + Acting)智能体范式,完美平衡了逻辑推理与工具调用两大能力。该框架在 2022 年被正式提出,核心创新就是构建 “思考 — 执行 — 反馈” 的闭环迭代机制。智能体先通过推理规划执行步骤,再调用外部工具完成真实业务操作,最后利用工具返回的结果修正后续决策,让每一步推理都建立在客观事实之上。
本文将以电商在线客服为应用场景,使用纯 Python 代码搭建一套轻量化 ReAct 智能客服 Agent。项目包含订单查询、库存核对、邮件推送三项实用工具,完整记录每一轮推理轨迹并自动生成可视化决策链路。整个项目不依赖任何大模型接口,仅使用 Python 内置库即可运行,非常适合智能体入门学习者完成理论验证与工程实践。
二、ReAct 智能体核心机制解析
2.1 现有技术方案的缺陷
在 ReAct 框架出现之前,LLM 应用开发主要分为两条技术路线,二者都存在明显短板:
纯推理路线(思维链 CoT)思维链提示词能够引导大模型完成多步骤逻辑推演,擅长处理复杂文字推理、数学计算类任务。但该方案存在一个致命问题:模型无法访问外部数据库与业务接口,只能依靠训练阶段学习到的静态知识作答。面对动态变化的订单、商品库存数据,模型没有办法获取真实信息,只能凭空编造内容,完全无法应用于电商、运维等强时效性业务场景。
纯执行路线(固定脚本)这类程序可以直接对接数据库、邮件服务等外部工具,能够稳定执行真实业务操作。但是程序不具备语义理解能力,只能依靠关键词精准匹配来触发动作。用户一旦灵活变换话术,程序就无法识别需求,缺少任务拆解、自主纠错的智能性,灵活性极差。
2.2 ReAct 循环:思考与行动双向协同
ReAct 框架把推理和工具调用紧密结合,形成闭环迭代体系:思考用来制定行动方案,行动产生的观测结果反过来约束思考内容,实现二者相互驱动。一轮完整迭代分为三个核心环节:
- Thought(思考环节):智能体对用户的自然语言需求进行语义分析,拆解任务目标,选定下一步需要调用的工具与对应参数,对应代码中的
think推理函数。 - Action(行动环节):严格按照思考得出的结论,调用外部工具发起业务操作,本项目中对应订单查询、库存查询、发送邮件三项动作。
- Observation(观察环节):接收工具执行完毕后返回的真实业务数据,将这条信息存入对话历史,作为下一轮思考的事实依据。
智能体会持续循环执行上述三步,不断推进任务进度,直到在思考环节判定任务已经圆满完成,才终止循环并输出最终回复。这套运行机制带来了极强的协同效应:推理避免了工具盲目调用,外部真实反馈又从根源上抑制了模型幻觉问题。
2.3 数学形式化描述
从数学模型来看,智能体会保存历史所有轮次的行动与观测记录:(a1,o1),(a2,o2),…,(at−1,ot−1)。基于历史上下文,模型生成当前轮次的思考内容与执行动作: (tht,at)=π(qt,(a1,o1),…,(at−1,ot−1)) 紧接着外部环境执行动作at,返回全新的观测结果ot,把新记录追加到历史轨迹中,开启新一轮迭代。
三、项目整体架构设计
3.1 模块拆分
为了保证代码结构清晰、易于后续扩展,本项目被拆分为三大独立模块,严格对应 ReAct 的运行流程:
- 决策轨迹日志模块:负责结构化保存每一轮循环的轮次序号、思考内容、执行动作、调用参数与观测结果,同时提供格式化打印功能,直观展示完整决策链路。
- 业务工具封装模块:统一封装所有外部能力,内置模拟业务数据库,提供订单查询、库存查询、邮件发送接口,预留扩展入口,可以无缝对接真实 MySQL 数据库与邮件服务。
- 智能 Agent 主体模块:作为整个项目的运行引擎,负责驱动 “思考 — 行动 — 观察” 循环,搭建多轮对话交互窗口,在对话结束后统一输出完整推理日志。
3.2 业务功能清单
本次电商客服智能体一共实现三项基础业务能力:
- 订单查询:接收订单编号,查询对应商品名称、采购数量与物流发货状态;
- 库存查询:输入商品名称,读取当前仓库实时剩余库存;
- 邮件通知:将用户的业务咨询内容整理为文本,自动发送至指定邮箱。
3.3 运行环境说明
本项目全程仅使用 Python 标准内置库,无需通过 pip 安装第三方包,Python3.7 及以上版本即可直接运行:
- dataclasses:构建结构化数据实体,规范保存每一轮决策记录;
- typing:补充变量类型注解,提升代码规范性与可读性;
- time:添加短暂延时,模拟真实网络接口的请求耗时。
四、核心代码编写与逐段解读
4.1 轨迹日志模块:记录每一轮 ReAct 迭代
为了完整还原智能体的决策全过程,我们首先定义数据实体类DecisionRecord,把一轮循环中的全部信息进行结构化存储。配套日志管理类DecisionLogger,实现记录新增与格式化打印,输出样式和实验运行结果保持一致。
python
运行
from dataclasses import dataclass from typing import Dict, List @dataclass class DecisionRecord: round_id: int # 对话轮次 thought: str # 智能体思考内容 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): record = DecisionRecord(round_id, thought, action, params, observation) self.records.append(record) 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 业务工具模块:统一封装外部能力
我们把三项业务能力封装到工具类中,使用字典模拟业务数据库,同时设计统一的工具分发入口,后续新增功能只需要在此处扩展,上层循环逻辑无需改动。
python
运行
import time from typing import Any, Dict class CustomerServiceTools: def __init__(self): # 模拟电商业务数据库 self.order_db = { "01001": {"status": "已发货", "goods": "无线鼠标", "num": 2}, "O1002": {"status": "待发货", "goods": "机械键盘", "num": 1} } self.stock_db = { "无线鼠标": 156, "机械键盘": 23 } def query_order(self, order_no: str) -> str: 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: 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: time.sleep(0.3) return f"邮件已发送至 {receiver},内容摘要:{content[:20]}..." 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}"工具层与智能体推理层完全解耦,如果后续要对接线上业务,只需要修改这部分代码,把内存字典替换为 MySQL 查询语句,把模拟邮件替换为 SMTP 真实推送,代码复用性极高。
4.3 Agent 主体:驱动 ReAct 循环引擎
这是整个项目的核心运行引擎,包含三大核心方法:
think():对应 ReAct 的 Thought 环节,解析用户输入,输出下一步动作与参数;run_agent():完成一轮完整闭环:思考→执行工具→获取观测→写入日志;chat_loop():搭建控制台多轮对话窗口,输入 quit 结束对话并打印全部决策日志。
python
运行
class ServiceAgent: def __init__(self): self.tools = CustomerServiceTools() self.logger = DecisionLogger() self.round = 0 def think(self, user_input: str): self.round += 1 user_text = user_input.strip() # 关键词匹配推理,可无缝替换为大模型调用 if "订单" in user_text and "01001" in user_text: thought = "用户想要查询01001订单,我需要调用query_order工具,传入订单号01001" action = "query_order" params = {"order_no": "01001"} 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" params = { "receiver": "3105469252@qq.com", "content": user_text } else: thought = "无需调用工具,直接文字回复用户" action = "reply_direct" params = {} return thought, action, params def run_agent(self, user_message: str) -> str: # 一轮完整的ReAct闭环 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_id=self.round, thought=thought, action=action, params=params, observation=obs ) return obs def chat_loop(self): print("智能客服Agent已启动,输入quit结束对话") while True: user_msg = input("\n用户:") if user_msg.lower() == "quit": break result = self.run_agent(user_msg) print(f"客服回复:{result}") # 退出对话后可视化全部决策链路 self.logger.visualize() if __name__ == "__main__": agent = ServiceAgent() agent.chat_loop()当前think函数使用关键词匹配完成推理,属于简化教学版本。后续只需要把这段逻辑替换为大模型调用 + 文本解析,就能升级为具备自主语义理解能力的 LLM 智能体,完全贴合 ReAct 原生设计思想。
五、程序运行结果与效果分析
5.1 多轮对话交互效果
运行程序后,控制台开启对话交互窗口,依次执行三次业务请求,最终输入 quit 终止程序:
plaintext
智能客服Agent已启动,输入quit结束对话 用户:帮我查一下订单01001 客服回复:订单01001:商品无线鼠标,数量2,状态已发货 用户:查一下机械键盘库存 客服回复:商品【机械键盘】当前库存:23件 用户:发邮件把订单信息发给3105469252@qq.com 客服回复:邮件已发送至 3105469252@qq.com,内容摘要:发邮件把订单信息发给3105469252... 用户:quit三轮对话对应三次独立的 ReAct 循环,每一轮都严格走完 “思考 — 行动 — 观测” 完整流程。
5.2 决策链路可视化日志
对话结束后,程序自动输出三轮完整的思考行动轨迹,和实验截图保持完全一致:
plaintext
==== Agent 完整思考-行动决策链路 ==== 【第1轮】 💡思考(Thought): 用户想要查询01001订单,我需要调用query_order工具,传入订单号01001 ⚙行动(Action): query_order 📎参数(Params): {'order_no': '01001'} 📄观察(Observation): 订单01001:商品无线鼠标,数量2,状态已发货 【第2轮】 💡思考(Thought): 用户询问机械键盘库存,调用query_stock工具 ⚙行动(Action): query_stock 📎参数(Params): {'product_name': '机械键盘'} 📄观察(Observation): 商品【机械键盘】当前库存:23件 【第3轮】 💡思考(Thought): 用户要求发送邮件,调用send_email工具 ⚙行动(Action): send_email 📎参数(Params): {'receiver': '3105469252@qq.com', 'content': '发邮件把订单信息发给3105469252@qq.com'} 📄观察(Observation): 邮件已发送至 3105469252@qq.com,内容摘要:发邮件把订单信息发给3105469252... ====================================从日志可以清晰看到每一轮循环的因果关系:思考内容决定了工具调用动作,工具返回的观测结果作为本轮闭环的终点,同时存入历史上下文,为下一轮推理提供事实依据。整个执行流程严格遵循 ReAct 范式理论,实现了推理与行动双向联动。
5.3 项目实践价值总结
- 理论落地价值:将抽象的智能体循环理论拆解为可运行的代码,把 Thought、Action、Observation 三个抽象概念拆分为独立函数,打通了理论知识与工程开发之间的壁垒,非常适合实训课程作业。
- 业务落地价值:搭建了轻量化客服 Agent 框架,推理层与工具层完全解耦,既可以作为教学 Demo,也可以快速改造对接企业真实业务接口,落地电商售前咨询、工单自动处理等场景。
- 极强的扩展能力:关键词推理模块可以无缝替换为 OpenAI、通义千问、本地开源大模型,升级为具备自主规划、多轮纠错能力的 LLM 智能体。后续还可以新增退款审核、物流查询等更多工具,持续拓宽 Agent 的能力边界。
六、项目后续优化拓展方案
6.1 接入大模型实现原生 ReAct 自主推理
当前项目依靠关键词匹配完成决策,属于简化版本。下一阶段可以接入大语言模型,编写 ReAct 专用提示词,让模型自主输出 Thought 与 Action 内容,再通过正则表达式解析出工具名称和入参,彻底摆脱固定关键词的限制,打造真正自主决策的智能体。
6.2 对接真实业务数据源
将内存字典替换为 MySQL 数据库,实时读取线上订单与库存数据;改造邮件工具,对接 SMTP 协议实现真实邮件推送,让智能体具备线上生产环境交付能力。
6.3 增加上下文记忆能力
把每一轮的思考、行动、观测全部存入对话上下文,支持跨轮次任务联动。例如用户第一轮查询订单,第二轮直接要求发送本条订单信息,Agent 可以自动读取上一轮观测结果,无需用户重复填写订单号。
6.4 搭建 Web 可视化页面
基于 Flask 开发简易网页前端,将控制台的决策日志渲染成时序流程图,在线实时展示 Agent 每一步思考与工具调用过程,把纯文本日志升级为动态可视化页面,更适合课程答辩与项目演示。
七、总结
ReAct 是 LLM 智能体开发的基础框架,它有效解决了大语言模型 “只能空想,无法落地业务” 的痛点,将逻辑推理与外部工具调用紧密绑定。本文以电商智能客服为落地场景,完整实现了轻量化 ReAct 智能 Agent,从日志记录、工具封装到循环引擎层层拆解,每一段代码都对应范式中的理论环节。
对于智能体初学者而言,先完成这套无大模型依赖的规则版 ReAct 循环,能够透彻理解思考、行动、观察三者之间的迭代关系,再去对接大模型做自主推理,学习门槛会大幅降低。在企业项目开发中,这种分层解耦的代码架构拥有极高的复用性,可以快速迁移到运维机器人、办公自动化助手、数据自动查询等各类 Agent 开发项目中。
