用 Solon AI ReActAgent 落地智能客服工单处理

某电商平台售后工单日均 5,000+,人工处理有三个老大难:

痛点 表现 后果
响应慢 首响经常要等很久 客户满意度下降
处理不一致 同样"丢件",不同客服结果不同 投诉升级
重复劳动 大量工单是同一类问题 人力被低价值查询占满

核心矛盾:工单量增速明显快于客服团队扩编速度。

一、业务方案

1.1 目标

  • 常见问题由 Agent 自动处理
  • 首响从分钟级降到秒级
  • 同类问题走同一套 SOP
  • 复杂 / 敏感工单自动转人工

1.2 流程对比

text 复制代码
改造前:
客户提交工单 → 排队 → 客服人工查看 → 查订单 → 查物流 → 判断 → 回复

改造后:
客户提交工单 → Agent 秒级响应 → 自动查订单、查物流 → 自动判断 → 自动处理
(无法处理时 → 转人工 + 附完整上下文)

二、技术落地(ReActAgent 实现)

2.1 模块结构

text 复制代码
com.example.csagent/
├── tools/
│   ├── OrderTools.java            # 查询订单
│   ├── LogisticTools.java         # 查询物流
│   └── MarketingTools.java        # 申请退款/发券
├── hitl/
│   └── HitlWebController.java     # 审批续传接口
└── CSAgentApp.java                # 启动入口

2.2 工具定义(真实 API)

在 Solon AI 中,业务工具应继承 AbsToolProvider,方法上标注 @ToolMapping

java 复制代码
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.chat.tool.AbsToolProvider;
import org.noear.solon.annotation.Param;

/** 订单领域工具 */
public class OrderTools extends AbsToolProvider {
    @ToolMapping(description = "根据订单号查询订单详情,获取商品名、金额、物流单号")
    public String get_order(@Param(description = "订单号") String orderId) {
        // 生产环境改为调用内部订单服务
        if ("ORD_20251229".equals(orderId)) {
            return "{\"orderId\":\"ORD_20251229\", \"amount\": 158.0, "
                    + "\"trackNo\": \"track_123\", \"sku\": \"智能耳机\"}";
        }
        return "{\"error\": \"订单不存在\"}";
    }
}

/** 物流领域工具 */
public class LogisticTools extends AbsToolProvider {
    @ToolMapping(description = "根据物流单号查询当前运输状态")
    public String get_logistic_status(@Param(description = "物流单号") String trackNo) {
        if ("track_123".equals(trackNo)) {
            return "{\"status\": \"lost\", \"info\": \"包裹在上海分拨中心丢失\"}";
        }
        return "{\"error\": \"查无此单\"}";
    }
}

/** 营销/补偿领域工具 */
public class MarketingTools extends AbsToolProvider {
    @ToolMapping(description = "根据赔付策略发放补偿。"
            + "规则:小额订单(<=100)发优惠券(coupon);大额订单(>100)申请全额退款(refund)")
    public String apply_compensation(
            @Param(description = "赔付策略:coupon 或 refund") String strategy,
            @Param(description = "订单金额") double amount) {
        if ("refund".equals(strategy) && amount > 100) {
            return "【系统指令】已成功提交退款申请,金额 " + amount
                    + " 元预计 24 小时内原路退回。";
        } else if ("coupon".equals(strategy)) {
            return "【系统指令】已发放 20 元补偿优惠券至用户账户。";
        }
        return "【人工逻辑】赔付策略与金额不匹配,已转交人工客服审核。";
    }
}

2.3 组装 ReActAgent

java 复制代码
import org.noear.solon.ai.agent.AgentSession;
import org.noear.solon.ai.agent.react.ReActAgent;
import org.noear.solon.ai.agent.session.InMemoryAgentSession;
import org.noear.solon.ai.chat.ChatModel;

ChatModel chatModel = LlmUtil.getChatModel();

ReActAgent agent = ReActAgent.of(chatModel)
        .defaultToolAdd(new OrderTools())
        .defaultToolAdd(new LogisticTools())
        .defaultToolAdd(new MarketingTools())
        .modelOptions(o -> o.temperature(0.0)) // 决策场景建议低温
        .maxTurns(10)
        .autoRethink(true)
        .build();

AgentSession session = InMemoryAgentSession.of("demo_customer_job_001");

String userPrompt = "我的订单号是 ORD_20251229,到现在还没收到货,帮我查查怎么回事并给出处理方案。";

String result = agent.prompt(userPrompt)
        .session(session)
        .call()
        .getContent();

System.out.println(result);

Agent 会自主完成:

  1. get_order → 拿到物流单号 track_123 和金额 158
  2. get_logistic_status → 识别 lost
  3. apply_compensation(strategy=refund, amount=158) → 触发退款

2.4 业务 SOP 怎么写?

不要再写虚构的 AiInterceptor 路由表。正确做法是:

  1. 把 SOP 写进 system prompt
  2. 把动作封装成工具,让 Agent 自己按规则调用
java 复制代码
ReActAgent agent = ReActAgent.of(chatModel)
        .systemPrompt(t -> """
            你是电商售后决策助手。处理规则:
            1. 先查订单,再查物流
            2. 若物流状态为 lost:
               - 金额 <= 100:发优惠券
               - 金额 > 100:申请全额退款
            3. 若已签收:引导客户联系邻居/快递员,不要直接退款
            4. 无法判断时说明原因并建议转人工
            """)
        .defaultToolAdd(new OrderTools())
        .defaultToolAdd(new LogisticTools())
        .defaultToolAdd(new MarketingTools())
        .build();

2.5 人工升级兜底(HITL)

金额超过阈值时,用官方 HITLInterceptor 暂停执行:

java 复制代码
import org.noear.solon.ai.agent.react.intercept.HITLInterceptor;
import org.noear.solon.ai.agent.react.intercept.HITL;
import org.noear.solon.ai.agent.react.intercept.HITLDecision;
import org.noear.solon.ai.agent.react.intercept.HITLTask;

HITLInterceptor hitl = new HITLInterceptor()
        .onTool("apply_compensation", (trace, args) -> {
            double amount = Double.parseDouble(args.get("amount").toString());
            return amount > 100 ? "大额赔付需人工审核" : null; // null = 放行
        });

ReActAgent agent = ReActAgent.of(chatModel)
        .defaultToolAdd(new OrderTools())
        .defaultToolAdd(new LogisticTools())
        .defaultToolAdd(new MarketingTools())
        .defaultInterceptorAdd(hitl)
        .build();

审批提交与续传(对齐 article/1286):

java 复制代码
HITLTask task = HITL.getPendingTask(session);

if ("approve".equals(action)) {
    HITL.submit(session, task.getToolName(),
            HITLDecision.approve().comment("管理员已核实"));
} else {
    HITL.submit(session, task.getToolName(),
            HITLDecision.reject("风险操作,已被管理员驳回"));
}

// 提交后静默续传
ReActResponse resp = agent.prompt().session(session).call();

三、业务效果(定性)

上线后常见变化:

  • 自动链路:查单 → 定位问题 → 标准赔付,秒级完成
  • 人工链路:大额/异常单由 AI 备好上下文,人只做确认
  • 一致性:同一类问题按统一规则处理,减少"看人下菜"

不在此编造具体百分比。真实数据请以你们线上埋点为准。

真实处理示例

客户:"我的订单号是 ORD_20251229,到现在还没收到货"

Agent 处理链路

  1. get_order("ORD_20251229") → 金额 158,物流单号 track_123
  2. get_logistic_status("track_123") → lost
  3. 金额 > 100 → 触发 apply_compensation(refund, 158)
  4. 若已配 HITL,则先挂起审批,管理员点"批准"后继续

四、同类场景扩展

业务场景 不同工具 不同规则 兜底条件
保险理赔 保单查询、定损 不同险种流程 金额超阈值
物流投诉 运单追踪、赔偿计算 延误/破损/丢件 赔偿超阈值
物业报修 工单系统、维修派单 紧急/普通/预约 漏水/断电
酒店客服 预订查询、退款 取消/投诉/加订 升级值班经理
银行信用卡 账单查询、挂失 盗刷/降额/提额 账户安全相关

五、落地建议

  1. 从高频低价值工单开始:查物流、查订单先跑通
  2. HITL 阈值从宽到严:初期退款全审批,再逐步放宽
  3. SOP 写进 prompt + 工具描述:不要虚构拦截器路由
  4. 保留"转人工"底线:客户明确要求时立即升级

参考

相关推荐
我是坏垠2 小时前
Crypto、Cipher与Password:Java加密开发的三个核心概念
java·开发语言·python
white_ant2 小时前
JDK LTS 版本升级迁移注意事项大全
java·开发语言
广州灵眸科技有限公司4 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
库克克4 小时前
【C++ 】内联函数
java·开发语言·c++
zh_xuan4 小时前
java 虚拟线程
java·开发语言·虚拟线程
努力搬砖的咸鱼4 小时前
如何开始使用agent
ai·agent·ai编程
jason成都4 小时前
RTKLIB Java 移植踩坑复盘:卡尔曼滤波核心逻辑修复与滑坡场景实测验证
java·开发语言
垚森4 小时前
AI原生编程-马里奥成长记(已更新到第三关卡,等你来冲关)
ai·马里奥
老毛肚5 小时前
juc线程通信
java·开发语言·jvm