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

发布时间:2026/7/19 4:11:12
用 Solon AI ReActAgent 落地智能客服工单处理 电商平台售后工单日均 5,000人工处理有三个老大难痛点 表现 后果响应慢 首响经常要等很久 客户满意度下降处理不一致 同样“丢件”不同客服结果不同 投诉升级重复劳动 大量工单是同一类问题 人力被低价值查询占满核心矛盾工单量增速明显快于客服团队扩编速度。一、业务方案1.1 目标常见问题由 Agent 自动处理首响从分钟级降到秒级同类问题走同一套 SOP复杂 / 敏感工单自动转人工1.2 流程对比改造前客户提交工单 → 排队 → 客服人工查看 → 查订单 → 查物流 → 判断 → 回复改造后客户提交工单 → Agent 秒级响应 → 自动查订单、查物流 → 自动判断 → 自动处理无法处理时 → 转人工 附完整上下文二、技术落地ReActAgent 实现2.1 模块结构com.example.csagent/├── tools/│ ├── OrderTools.java # 查询订单│ ├── LogisticTools.java # 查询物流│ └── MarketingTools.java # 申请退款/发券├── hitl/│ └── HitlWebController.java # 审批续传接口└── CSAgentApp.java # 启动入口2.2 工具定义真实 API在 Solon AI 中业务工具应继承 AbsToolProvider方法上标注 ToolMappingimport 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 组装 ReActAgentimport 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 会自主完成get_order → 拿到物流单号 track_123 和金额 158get_logistic_status → 识别 lostapply_compensation(strategyrefund, amount158) → 触发退款2.4 业务 SOP 怎么写不要再写虚构的 AiInterceptor 路由表。正确做法是把 SOP 写进 system prompt把动作封装成工具让 Agent 自己按规则调用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 暂停执行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/1286HITLTask 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();