Java 8老系统AI工单助手实战:先做推荐,不要一上来自动派单
为什么要写这个系列
做Java后端十年,我接触过不少企业的核心系统。
金融、电商、政务——行业不同,但底层的现状惊人地相似:生产系统还在Java 8,框架停在Spring Boot 2.x甚至更早,代码跑了很多年,没人敢轻易动。
去年开始,几乎每个项目都在谈接AI。
但真正动手的时候,团队就卡住了。
不是因为不懂大模型,而是老系统本身接不住。JDK版本不够,Spring AI引不进来;依赖树牵一发动全身,升级一个包怕带崩一片;生产流量压着,不敢拿主流程赌一个AI试点。
更危险的是硬塞。我见过团队在老系统的Service层直接new一个HttpClient调模型API,Prompt拼在业务代码里,超时没配、降级没有。模型响应慢的时候,老系统的订单查询线程池被占满,主流程跟着卡住。还有团队把用户手机号、身份证原样送进Prompt,过了两个月才被安全审计发现。
这种事见多了,我就开始想一个问题:老系统不具备直接接入AI的条件,这是不是大多数企业的常态?
答案是肯定的。而且这不应该成为接不了AI的理由。
核心思路其实就三条:
老系统少改 —— 不升级 JDK,不引入 Spring AI 依赖 AI 能力旁路 —— 独立部署,老系统通过 HTTP 或 MQ 调用 企业边界先行 —— 脱敏、审计、降级、幂等比模型调用更重要这个系列就是把这三条线展开成10讲。
从AI Gateway到MCP工具中心,从SQL Agent到RAG知识库,从工单Agent到多Agent研发团队——每一讲都围绕同一个前提:
你的老系统还在跑Java 8,你不能为了AI去赌它的稳定性。
每讲配套一个可运行的Maven Lab,不讲空架构,不写Hello World。你跑得通Demo,看得到边界,拿得到代码。
这就是我做这个系列的原因。
Java 8老系统AI工单助手实战:先做推荐,不要一上来自动派单
企业上AI工单,第一反应往往是:
能不能让AI自动处理? 能不能让AI自动派单? 能不能让AI直接闭环?
听起来很爽,做起来很惨。
自动闭环意味着AI对结果负责。在客服场景里,这意味着AI直接决定派谁、修不修、退不退钱——每一步都是客户体验的雷区。一旦出错,客户投诉升级,企业没有回退路径。
更稳的第一步,是让AI做工单助手,不是工单执行者。
具体来说:
AI 摘要问题 → 判断分类 → 识别优先级 → 发现 SLA 风险 → 推荐处理人 → 等待人工确认 → 派单执行AI在这个链路里是提效工具,不是决策主体。这是企业AI落地的第一道安全门。
工单助手在架构里的位置:MCP Tool Center的第一个真实出口
第2讲搭了MCP Tool Center——把老系统的能力标准化成MCP工具,让AI Agent调用。工单助手就是这个架构的第一个真实出口,不是Demo,是生产级旁路。
老系统工单事件(CRM / 呼叫中心 / 售后系统) ↓ MCP Tool Center 推送 TicketEvent ↓ TicketAgentService 分析 ↓ 分类 / 优先级 / SLA风险 / 推荐处理人 ↓ AssignmentConfirmationService 等待人工确认 ↓ 派单执行(回写到工单系统)注意这里没有直接连老系统的数据库,所有交互通过MCP Tool Center的标准事件通道走。这是第2讲就定好的旁路原则:老系统不动,AI能力嫁接进来。
代码结构
src/main/java/com/ynzz/lab/chapter07/agent/ ├── TicketAgentService ← 主流程:事件 → 分析 → 推荐 ├── TicketClassifier ← 分类:PAYMENT / ORDER_DELIVERY / GENERAL ├── TicketPriorityPolicy ← 优先级:HIGH / MEDIUM / LOW + SLA风险判断 ├── TicketMaskingService ← 脱敏:手机号、地址等敏感字段 ├── AssignmentPolicy ← 处理人推荐 + 推荐理由 ├── AssignmentConfirmationService ← 人工确认后才实际派单 └── TicketAuditService ← 审计日志 src/main/java/com/ynzz/lab/chapter07/common/ ├── TicketEvent ← 输入事件 └── TicketAnalysisResult ← 输出结果(含状态枚举) src/main/java/com/ynzz/lab/chapter07/policy/ └── AssigneeRecommendation ← 推荐结构体:assignee + reason主入口是TicketAgentService.analyze(event),它编排全流程,但不执行派单——派单是AssignmentConfirmationService.confirm()的职责,必须带confirmedBy参数。
核心逻辑一:TicketClassifier关键词规则分类
classify(title: String, content: String): TicketCategory完整规则表:
| 关键词(title或content) | 命中条件 | 分类结果 | Demo命中情况 |
|---|---|---|---|
| “支付”或”未支付” | 包含任一关键词 | PAYMENT | 工单1标题含”支付”和”未支付” ✅ |
| “发货”或”物流”或”延迟” | 包含任一关键词 | ORDER_DELIVERY | 工单2标题含”延迟”,内容含”发货” ✅ |
| 其他 | 无上述关键词 | GENERAL | 咨询类、投诉类、降级工单等 |
为什么要用关键词而不是模型?
企业内部工单场景,关键词规则有三个不可替代的优势:
- 可审计:分拣逻辑写在代码里,业务负责人能review。模型分类你没法解释”为什么这个工单进了支付类”。
- 可配置:运营人员看懂”包含支付进支付组”,比看懂prompt engineering容易一百倍。
- 稳定:不受模型版本漂移影响,同一个工单三个月前后分类结果一致。
关键词规则做底座,模型做增强——这是企业落地的标准路径。
核心逻辑二:TicketPriorityPolicy优先级与SLA风险
priorityOf(category: TicketCategory, content: String): TicketPriority hasSlaRisk(priority: TicketPriority, content: String): Boolean优先级规则表:
| 条件 | 优先级 | 说明 |
|---|---|---|
| category = PAYMENT | HIGH | 资金状态风险,涉及订单状态机,客诉升级概率高 |
| content 包含”三天”或”延迟” | MEDIUM | 可能触发履约SLA,不处理会升级 |
| 其他 | LOW | 普通咨询,先进通用服务台消化 |
SLA风险判断表:
| 条件 | slaRisk | 说明 |
|---|---|---|
| priority = HIGH | true | 高优先级工单本身SLA时限紧张 |
| content 包含”三天” | true | “三天”是SLA触发阈值——用户明确感知了履约超时 |
设计细节:”三天”是硬编码在规则里的数字阈值。不是说AI自己理解”三天很紧急”,而是把业务规则翻译成了一条if条件。这比让模型自由发挥稳定一百倍。
优先级不是情绪化等级,是业务触发条件。
核心逻辑三:AssignmentPolicy处理人推荐与理由
recommend(category: TicketCategory, priority: TicketPriority): AssigneeRecommendation推荐规则表:
| 分类 | 推荐处理人 | 推荐理由 |
|---|---|---|
| PAYMENT | pay-team-lisi | 支付团队值班人员,具备支付回调和订单状态对账经验 |
| ORDER_DELIVERY | order-team-zhangsan | 订单履约团队值班人员,熟悉仓库出库和物流状态排查 |
| GENERAL | service-desk | 通用服务台先接收,判断是否升类 |
真实项目的演进路径:
硬编码 → 值班表配置(值班人轮流换) → 技能标签匹配(谁处理过同类工单谁优先) → 历史数据加权(谁处理得快、评价高谁冒出来)每一步都可以独立演进,不是一上来就做大模型匹配。
核心逻辑四:TicketAgentService主流程顺序
analyze(event: TicketEvent)的调用链:
TicketEvent ↓ ① TicketMaskingService.mask() ← 脱敏原文 ↓ ② TicketClassifier.classify() ← 分类 ↓ ③ TicketPriorityPolicy.priorityOf() ← 优先级 ↓ ④ TicketPriorityPolicy.hasSlaRisk() ← SLA风险 ↓ ⑤ AssignmentPolicy.recommend() ← 推荐处理人 ↓ ⑥ TicketAuditService.record() ← 审计记录 ↓ TicketAnalysisResult status = WAITING_FOR_HUMAN_CONFIRMATION为什么是这个顺序?
① 脱敏必须排第一。工单内容里有手机号、地址、订单号。这些字段进模型之前要先脱敏,否则就是合规风险。脱敏后生成maskedFields列表,告诉后续环节”哪些字段被动过”。
② 分类在优先级之前。优先级规则依赖分类结果——PAYMENT类直接HIGH,不依赖内容。分类错了,优先级必然错,整个链路都歪。
③ 优先级在SLA之前。SLA风险判断依赖优先级字段:HIGH优先级天然带SLA风险。如果把这两步反过来,就没法利用优先级这个中间结果。
④ 推荐在最后。推荐处理人需要同时看分类和优先级——同是HIGH优先级,支付类进支付组,履约类进履约组,不能只看优先级。
⑤ 审计在最后。审计记录要一次性写入,包含分类结果、优先级、SLA风险、推荐处理人全量信息。不是每步单独写,那样审计记录是碎片化的。
这个顺序是因果依赖倒推出来的。把顺序写清楚,规则链就是可解释、可调试、可让业务负责人review的。
两个Demo工单完整推导
工单一:用户支付成功但订单仍显示未支付
输入:
ticketId = T202606050001 title = 用户支付成功但订单仍显示未支付 content = 用户反馈 10:32 已支付,订单号 O202606050001,后台仍显示 CREATED,手机号 13800000000。 source = customer-service逐步命中规则:
| 步骤 | 执行逻辑 | 命中的规则 | 输出 |
|---|---|---|---|
| ① 脱敏 | 检测手机号正则 1[3-9][0-9]{9} | TicketMaskingService | maskedFields=["mobile"],13800000000 → 1********** |
| ② 分类 | title + content 扫描关键词 | 命中”支付”+“未支付” | category=PAYMENT |
| ③ 优先级 | priorityOf(PAYMENT, content) | category=PAYMENT → HIGH | priority=HIGH |
| ④ SLA风险 | hasSlaRisk(HIGH, content) | priority=HIGH → slaRisk=true | slaRisk=true |
| ⑤ 推荐 | recommend(PAYMENT, HIGH) | PAYMENT → pay-team-lisi | recommendedAssignee=pay-team-lisi |
| ⑥ 审计 | 记录全量字段 | TicketAuditService.record() | auditId=xxx |
| 结果 | 不派单 | 规则 | status=WAITING_FOR_HUMAN_CONFIRMATION |
最终输出:
{ "ticketId": "T202606050001", "category": "PAYMENT", "priority": "HIGH", "slaRisk": true, "recommendedAssignee": "pay-team-lisi", "recommendationReason": "支付团队值班人员,具备支付回调和订单状态对账经验", "assignmentStatus": "WAITING_FOR_HUMAN_CONFIRMATION", "maskedFields": ["mobile"] }工单二:用户咨询订单延迟发货
输入:
ticketId = T202606050002 title = 用户咨询订单延迟发货 content = 用户说订单已经三天没有发货,希望确认仓库进度。 source = customer-service逐步命中规则:
| 步骤 | 执行逻辑 | 命中的规则 | 输出 |
|---|---|---|---|
| ① 脱敏 | content扫描敏感字段 | 无手机号/地址 | maskedFields=[] |
| ② 分类 | title + content扫描关键词 | 命中”延迟”+“发货” | category=ORDER_DELIVERY |
| ③ 优先级 | priorityOf(ORDER_DELIVERY, content) | 命中”三天”+“延迟” | priority=MEDIUM |
| ④ SLA风险 | hasSlaRisk(MEDIUM, content) | 命中”三天” | slaRisk=true |
| ⑤ 推荐 | recommend(ORDER_DELIVERY, MEDIUM) | ORDER_DELIVERY → order-team-zhangsan | recommendedAssignee=order-team-zhangsan |
| ⑥ 审计 | 记录全量字段 | TicketAuditService.record() | auditId=xxx |
| 结果 | 不派单 | 规则 | status=WAITING_FOR_HUMAN_CONFIRMATION |
两个工单对比:
| 字段 | 工单1(支付异常) | 工单2(履约延迟) |
|---|---|---|
| category | PAYMENT | ORDER_DELIVERY |
| priority | HIGH | MEDIUM |
| slaRisk | true | true |
| recommendedAssignee | pay-team-lisi | order-team-zhangsan |
| maskedFields | ["mobile"] | [] |
| assignmentStatus | WAITING_FOR_HUMAN_CONFIRMATION | WAITING_FOR_HUMAN_CONFIRMATION |
两个工单都是WAITING_FOR_HUMAN_CONFIRMATION——这才是Demo的核心信息。AI算完了,但不自己动手。
为什么人工确认后才能派单
这是架构里最容易被挑战的地方:AI分析了半天,为什么不能直接派单?
① 责任边界必须清晰。AI推荐处理人,人工确认处理人,最后派单的是系统。出问题回溯链路清楚:AI给了推荐,人工做了决策,系统执行了指令。如果AI直接派单,”是AI派的”——这个责任模型在企业里没有买单方。
② 推荐准确率有上限,场景有边界。Demo规则引擎覆盖了三个分类。但真实工单里有大量模糊场景:用户描述混乱、同时涉及多个问题、用户情绪化表达等。AI分类准确率80%已经很高,但那20%落在高优先级工单上就是投诉和资损。
③ 人工确认是信任建立机制,不是效率瓶颈。客服主管看了一眼分类和推荐,点一下确认,3秒钟。但这个动作让他知道系统干了什么,建立了信任。第一阶段人工确认,第二阶段低风险自动派单试点,第三阶段扩大范围——这是企业接受AI的标准路径。
AssignmentConfirmationService.confirm()的签名设计:
public TicketAnalysisResult confirm(String ticketId, String confirmedBy)必须传confirmedBy——谁确认的,什么时候确认的。这条记录进了审计日志,是合规追溯的依据。
企业避坑
坑一:让AI自动关闭工单。关闭工单意味着客户问题被宣告”已解决”,但如果客户还在投诉,自动关闭会直接触发客诉升级。关闭动作必须保留人工审核节点,或者接入知识库标准答案 + 客户确认短信双验证。
坑二:高优先级工单不经人工确认直接派单。HIGH优先级工单往往是SLA违约窗口期最短的那类。派错人比派慢了的损失更大。高优先级必须走人工确认,这是铁律。
坑三:工单原文裸给模型。手机号、地址、订单号、身份证号在工单里是高频出现字段。这些字段进模型之前必须脱敏,否则有数据合规风险。脱敏要覆盖工单的title和content两个字段,不能只处理content。
坑四:推荐不输出理由。recommend()方法必须返回AssigneeRecommendation(含assignee + reason),不能只返回一个处理人ID。没有理由,工单分发记录就是黑盒,团队无法review和优化。
坑五:跳过审计日志。每个工单的分析结果、分类决策、人工确认记录必须完整落库。这不只是合规要求,也是后续迭代规则引擎的数据基础——你得知道AI分类错了多少次、哪个分类规则命中率最低。
从Demo到落地:四条工程路径
① SLA规则引擎
当前Demo的SLA风险判断是硬编码Stub,真实项目需要接入SLA配置表:
SLA配置表(优先级 × 客户等级 × 工单类型) → 不同组合对应不同的响应时限和升级规则 → 超时自动触发升级通知 + 提升优先级 → 业务人员可维护的配置,不是代码里的 if-else② 历史相似工单RAG(第6讲知识库延伸)
新工单进来时,基于embedding检索相似历史工单的处理方案:
新工单 → embedding → 向量检索 ↓ Top-3 相似历史工单 ↓ 处理方案摘要 + 历史处理人 + 客户评价 ↓ 一并推给当前处理人这条链路的ROI很高:处理同类问题的重复时间大幅减少,新人上手速度提升,历史高评价方案被复用而不是每次重新探索。
③ 自动派单门槛设计
不是所有工单都要人工确认,要设计一个门槛规则:
自动派单试点的准入条件: ✓ 分类 = GENERAL ✓ 优先级 = LOW ✓ 知识库命中标准答案置信度 > 0.9 ✓ 非首次咨询(避免用户换人引发不满) ✓ 推荐处理人的历史确认率 > 95%(团队信任度门槛)这五条都命中,才开启自动派单试点。开了试点也要有监控仪表盘:自动派单准确率、人工干预率、客户满意度,三个数字每周review。
④ 工单系统集成
支持的主流工单系统: 飞书工单(Feishu / Lark) 钉钉工单 企业微信工单 JIRA Service Management 自研工单系统(通过 Webhook / API)集成的核心是MCP Tool Center的双向通道:接收工单事件、分析、回写处理结果到工单系统。飞书/钉钉场景下,回写结果可以直接推送消息给处理人,体验闭环。
小结
工单AI落地不是一上来就”全自动处理”,而是:
工单事件(MCP 推送) ↓ 脱敏(手机号 / 地址 / 身份证) ↓ 摘要 + 分类 + 优先级 + SLA 风险 ↓ 推荐处理人 + 推荐理由 ↓ 审计记录 ↓ 人工确认(或低风险自动派单) ↓ 派单执行这个链路里,AI是提效工具,不是决策主体。分类靠规则,优先级靠业务定义,推荐靠值班表——每一步都是显式的、可审计的、可让业务负责人负责的。
真正的工程难度不在于让AI跑起来,而在于把业务规则翻译成稳定可维护的代码,并设计好人工确认的边界。这是企业AI落地和Demo的分水岭。
AI 工单助手的目标不是替代客服主管,而是让他从读原始文字、猜分类、查值班表里解放出来,把精力放在真正需要判断的工单上。
