id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week
| id |
title |
type |
domain |
stack |
tags |
level |
prerequisites |
est_hours |
related |
week |
| scenario.ticket-system |
工单系统:AI 自动分类与路由、状态机、SLA 超时升级和坐席协作 |
scenario |
cross |
| postgresql |
| mq |
| redis |
| langchain |
| gin |
| fastapi |
| react |
|
| 工单 |
| 状态机 |
| 自动分类 |
| 路由 |
| SLA |
| 延迟队列 |
| 审计 |
| 乐观锁 |
|
intermediate |
| backend.postgresql.index |
| ai.langchain.index |
|
3 |
| ai.langchain.scenario.ticket-triage |
| backend.postgresql.scenario.order-state-audit |
| backend.mq.scenario.delayed-order-cancel |
| frontend.react.scenario.long-task-ui |
|
|
工单系统:AI 自动分类与路由、状态机、SLA 超时升级和坐席协作
业务背景与问题
客服中心的工单靠人工分派:
- 分类不准、分派慢,首次响应时间长;
- 工单状态混乱(已关闭的又被改回处理中),没有操作记录;
- 超过 SLA 没人知道;
- 两个坐席同时处理同一工单,互相覆盖。
约束
- 分类错误会耽误处理,但人工可以纠正。
- 需要审计:谁在什么时候做了什么。
- AI 不可用时系统照常运行(降级为人工分派)。
方案设计
- 状态机与审计(PostgreSQL):
new → triaged → assigned → in_progress → waiting_customer → resolved → closed,只允许合法转换;每次转换在同一事务中写事件表;version 字段做乐观锁。见订单状态与审计。
- AI 分类(LangChain 结构化输出):类别、优先级、建议处理组、置信度、理由;置信度低于阈值进入“待人工分类”;坐席的纠正记录为评测数据。见工单智能分诊。
- 异步流程:创建工单后发消息,分类服务消费(重试、死信);回写结果时校验状态和版本,不覆盖人工修改。
- SLA:按优先级计算截止时间,投递延迟消息;到期时再检查当前状态,仍未处理才升级。见延迟消息。
- 坐席界面(React):列表实时更新,显示 AI 分类理由,一键采纳或纠正;处理中用 Redis 软锁(带过期)提示其他人。见长任务界面。
- 降级:分类服务超时或不可用时,工单直接进入人工分派队列。
关键代码
状态转换 + 乐观锁 + 审计(一个事务中):
分类结果结构(示意):
取舍
| 决策 |
选择 |
原因 |
| 分类方式 |
大模型结构化输出 + 置信度阈值 |
冷启动快;纠正数据积累后可训练小模型降成本 |
| 并发控制 |
乐观锁 + 软锁提示 |
冲突少,悲观锁会让坐席等待 |
| SLA |
延迟消息 + 到期检查,定时扫描兜底 |
及时且可靠 |
| 语言 |
工单核心用 Go(Gin),AI 分类用 Python |
发挥两者优势;全部 Python 也可以 |
易错点
- AI 分类结果覆盖了人工已修改的字段。
- 状态转换只靠前端隐藏按钮,数据库层没有约束。
- 延迟消息到期时不检查当前状态,已处理的工单也被升级。
- 审计日志和业务更新不在同一事务中。
面试怎么讲
“工单系统用状态机约束转换,每次转换在同一事务中写审计事件,乐观锁防止坐席互相覆盖。AI 分类用结构化输出给出类别、优先级、建议组和置信度,低于阈值进入人工队列,纠正记录作为评测数据。SLA 用延迟消息,到期再检查状态决定是否升级。分类服务挂了就直接人工分派,不影响主流程。”