githubinferredactive
llm-agent-patterns
provenance:github:doinb666/llm-agent-patterns
从零实现四种 LLM Agent 范式:ReAct / Plan-and-Solve / Reflection + 综合案例:电商客服智能体
README
# 电商客服智能体 (Customer Service Agent)
一个基于大语言模型的电商退款处理智能体,采用 **ReAct + Reflection** 组合架构,能够自动完成订单核查、政策判断、退款决策和邮件回复的全流程处理。
---
## 项目结构
```
demo2/
├── customer_service_agent.py # 客服智能体主程序(本文档对应)
├── llm_client.py # LLM 客户端封装(OpenAI 兼容接口)
├── tools.py # 通用工具执行器与工具函数
├── ReAct.py # ReAct 范式基础实现
├── ReAct_json.py # ReAct 范式 JSON 结构化输出版本
├── Plan_and_solve.py # Plan-and-Solve 范式实现
├── Reflection.py # Reflection 范式基础实现
├── Reflection_paper.py # 多维度 Reflection 学术论文写作助手
└── .env # 环境变量配置(API Key 等)
```
---
## 架构设计
### 核心范式组合
```
用户退款申请
│
▼
┌─────────────────────────────────┐
│ Phase 1:ReAct 主循环 │
│ │
│ Thought(分析) │
│ ↓ │
│ Action(调工具) │ 循环最多 8 步
│ ↓ │
│ Observation(看结果) │
│ ↓ │
│ ...直到 Finish(初步决策) │
└──────────────┬──────────────────┘
│
▼
置信度 < 0.75?
/ \
是 否
▼ ▼
┌────────────┐ 直接执行决策
│ Phase 2: │
│ Reflection │ ← LLM 扮演"资深主管"复核
│ 自我审查 │
└─────┬──────┘
│
▼
┌─────────────┐
│ Phase 3: │
│ 发送邮件 │ ← 调用 SendEmail 工具
└─────────────┘
```
### 为什么选择这种组合?
| 范式 | 作用 |
|---|---|
| **ReAct** | 处理"需要按序调用多个工具"的动态任务(查订单→查物流→查政策→决策) |
| **Reflection** | 在置信度低的边界情况下进行自我审查,提升决策审慎性 |
| **Plan-and-Solve(内化)** | 通过系统提示词固化处理步骤,不需要显式规划器 |
---
## 快速开始
### 环境要求
```bash
pip install openai python-dotenv
```
### 配置 `.env`
```env
LLM_MODEL_ID=your-model-id
LLM_API_KEY=your-api-key
LLM_BASE_URL=https://your-api-endpoint/v1
```
### 运行
```bash
cd demo2
python customer_service_agent.py
```
程序会依次运行三个测试场景,观察不同退款情况下的智能体行为。
---
## 功能模块详解
### 模块 1:业务工具函数
程序内置了模拟数据库(实际部署时替换为真实数据库/API调用)。
#### 模拟数据
| 订单号 | 用户 | 商品 | 金额 | 物流状态 | 下单日期 |
|---|---|---|---|---|---|
| ORD-2024-001 | 张三 | 无线蓝牙耳机 Pro | ¥299 | 已签收 | 2024-01-10 |
| ORD-2024-002 | 李四 | 智能手表 X1 | ¥899 | 运输中 | 2024-01-20 |
| ORD-2024-003 | 王五 | 机械键盘 RGB | ¥459 | 已签收 | 2023-12-01 |
#### 四个工具
**`QueryOrder(order_id)`**
- 输入:订单号字符串,如 `ORD-2024-001`
- 输出:订单详情 JSON(用户名、商品、金额、状态、下单日期、支付方式)
**`QueryLogistics(order_id)`**
- 输入:订单号字符串
- 输出:物流 JSON(承运商、运单号、当前状态、完整时间轴)
**`CheckRefundPolicy(json_str)`**
- 输入:`{"order_date": "YYYY-MM-DD", "status": "物流状态"}`
- 输出:政策判断结果,含推荐决策和**置信度**(关键)
退款政策规则引擎逻辑:
```
商品运输中 → approve | confidence=0.95
签收后 ≤ 7 天 → approve | confidence=0.92 (无理由退货)
签收后 8~30 天 → conditional| confidence=0.65 ⚠️ 触发 Reflection
签收后 > 30 天 → reject | confidence=0.88
其他特殊情况 → manual | confidence=0.40 ⚠️ 触发 Reflection
```
**`SendEmail(json_str)`**
- 输入:`{"to": "邮箱", "subject": "主题", "body": "正文"}`
- 输出:发送结果(当前为模拟打印,实际接入 SMTP)
---
### 模块 2:三层提示词设计
#### 第一层:`SYSTEM_PROMPT`(价值观基线)
奠定智能体的行为准则,每次 LLM 调用都会注入:
```
核心价值观:公司利益与用户体验并重
决策优先级:
1. 严格遵守退款政策(红线)
2. 政策框架内优先对用户有利的解释
3. 无法退款时给出替代方案
语气:专业、温暖,拒绝时先共情再解释
```
#### 第二层:`REACT_PROMPT`(ReAct 主循环控制)
约束 LLM 每次输出合法 JSON,分两种格式:
```json
// 调用工具时
{
"thought": "当前分析和下一步计划",
"action": "工具名称",
"action_input": "工具输入参数"
}
// 最终决策时
{
"thought": "综合判断",
"action": "Finish",
"decision": "approve | reject | conditional | escalate",
"confidence": 0.0 ~ 1.0,
"email_subject": "邮件主题",
"email_body": "邮件正文"
}
```
#### 第三层:`REFLECTION_PROMPT`(低置信度复核)
让 LLM 扮演"资深客服主管",将所有原始信息(订单、物流、政策原文)重新传入,从四个角度审查初步决策:
1. 是否遗漏了对用户有利的政策条款?
2. 申请理由是否具有合理性?
3. 边界情况下公司的最优选择(兼顾口碑成本)?
4. 是否应升级人工客服?
输出修订后的决策、新置信度和重写的邮件正文。
---
### 模块 3:`CustomerServiceAgent` 核心类
#### 主要属性
| 属性 | 说明 |
|---|---|
| `llm` | LLM 客户端实例 |
| `max_steps` | ReAct 循环最大步数,默认 8 |
| `tool_executor` | 工具执行器,管理4个业务工具 |
| `history` | 当前请求的操作历史(Action + Observation 列表) |
| `_collected_info` | 工具返回的原始数据,供 Reflection 使用 |
#### 核心方法
**`handle_refund_request(user_name, order_id, reason, user_email)`**
主入口,编排三个 Phase 的执行顺序,返回最终结果字典:
```python
{
"user": "张三",
"order_id": "ORD-2024-001",
"final_decision": "approve",
"confidence": 0.92,
"email_sent": True
}
```
**`_react_loop()`**
ReAct 主循环,每步流程:
1. 将历史记录拼接进 prompt
2. 调用 LLM 获取 JSON 响应
3. 解析 `action` 字段:
- 若为 `Finish` → 返回最终决策,退出循环
- 否则 → 调用对应工具,将结果追加进 `history` 和 `_collected_info`
**`_reflect(initial_result, reason)`**
Reflection 复核,仅在 `confidence < CONFIDENCE_THRESHOLD` 时调用:
- 把 `_collected_info` 中保存的所有原始工具数据全部注入 prompt
- 调用 LLM 一次,返回修订后的决策
**`_parse_json(text)`**
三层容错 JSON 解析,依次尝试:
1. 直接解析整段文本
2. 提取 ` ```json ... ``` ` 代码块
3. 提取第一个 `{ ... }` 块
每层都额外尝试 `strict=False` 宽松模式兜底。
**`_fallback_escalate(user_email)`**
兜底方法,当 ReAct 循环无法得出决策时,直接发送人工介入邮件,保证用户不会收不到回复。
---
## 测试场景
### 场景 1:7天内无理由退货(高置信度)
```python
agent.handle_refund_request(
user_name="张三",
order_id="ORD-2024-001",
reason="收到商品后发现不喜欢这款颜色,想退货",
user_email="zhangsan@example.com",
)
```
预期流程:`QueryOrder` → `QueryLogistics` → `CheckRefundPolicy` → `Finish(approve, confidence=0.92)` → 发邮件
Reflection 不触发,直接批准。
---
### 场景 2:超期边界情况(低置信度,触发 Reflection)
```python
agent.handle_refund_request(
user_name="王五",
order_id="ORD-2024-003",
reason="机械键盘收到后一直有按键卡顿问题,一直以为是手法问题,最近才确认是质量问题",
user_email="wangwu@example.com",
)
```
预期流程:查询信息 → `CheckRefundPolicy` 返回 `reject, confidence=0.88` → LLM 结合"质量问题"理由可能输出较低置信度 → **触发 Reflection** → 资深主管视角复核 → 给出更审慎建议(可能升级人工)
---
### 场景 3:商品在途,申请取消(高置信度)
```python
agent.handle_refund_request(
user_name="李四",
order_id="ORD-2024-002",
reason="下单后临时变更,不需要了,想取消订单退款",
user_email="lisi@example.com",
)
```
预期流程:`QueryOrder` → `QueryLogistics(运输中)` → `CheckRefundPolicy` 返回 `approve, confidence=0.95` → `Finish(approve)` → 发邮件
---
## 决策类型说明
| 决策值 | 含义 | 触发条件 |
|---|---|---|
| `approve` | 批准退款 | 符合无理由退货或在途取消政策 |
| `reject` | 拒绝退款 | 超过30天退款期限 |
| `conditional` | 有条件退款 | 需补充质量问题证明材料 |
| `escalate` | 升级人工 | 特殊情况或 LLM 决策失败兜底 |
---
## 置信度阈值说明
```python
CONFIDENCE_THRESHOLD = 0.75 # 低于此值触发 Reflection
```
置信度来源于两部分:
- **规则引擎**(`CheckRefundPolicy`):根据下单天数和物流状态按规则计算,客观可控
- **LLM 自评**:在 `Finish` 时要求 LLM 输出对自身决策的置信度
二者综合影响是否触发 Reflection 二次审查。
---
## 风险与应对
| 风险 | 应对方案 |
|---|---|
| LLM 决策失败/JSON 解析失败 | `_fallback_escalate` 兜底,用户必得到响应 |
| LLM 幻觉捏造订单信息 | 所有事实信息强制走工具查询,不依赖 LLM 凭空生成 |
| 提示词注入攻击 | 用户输入仅作为字段值注入,不作为指令执行 |
| 无限循环 | `max_steps=8` 硬性上限保护 |
| 重复发邮件 | 实际部署时需在订单维度加幂等锁(当前 demo 未实现)|
---
## 扩展指引
**替换真实数据库**:将 `_MOCK_ORDERS` 和 `_MOCK_LOGISTICS` 的查询逻辑替换为实际数据库调用或 REST API 请求。
**接入真实邮件服务**:在 `send_email()` 函数中接入 SMTP 库或邮件服务(如 SendGrid、阿里云邮件推送)。
**调整置信度阈值**:根据实际业务风险偏好调整 `CONFIDENCE_THRESHOLD`,值越高触发 Reflection 越频繁,决策越保守。
**扩展退款政策**:在 `check_refund_policy()` 中添加更多规则分支(如会员加权、品类特殊政策等)。
PUBLIC HISTORY
First discoveredMar 30, 2026
IDENTITY
inferred
Identity inferred from code signals. No PROVENANCE.yml found.
Is this yours? Claim it →METADATA
platformgithub
first seenMar 29, 2026
last updatedMar 29, 2026
last crawled4 days ago
version—
README BADGE
Add to your README:
