小型设备厂售后报修怎么用语音机器人识别故障类型并自动生成工单?
摘要
设备客户来电报修,会描述设备故障现象。语音机器人识别故障类型,收集客户信息,自动创建售后工单,分配给售后工程师处理。本文结合一家小型设备厂售后报修系统的落地过程,讲清楚语音机器人怎么接住报修电话、怎么从客户口语描述里识别故障类型、怎么通过多轮对话把设备型号和联系人等槽位收齐、怎么自动建单并分派给合适的售后工程师。内容包括整体架构、故障分类的规则与模型配合、槽位收集的对话设计、工单字段映射、分派策略、异常兜底,以及上线后的效果数据和踩坑复盘。代码和表格都是工程里实际用过的简化版,适合正在做售后报修自动化、语音机器人、工单系统的开发和运营同学参考。
关键词
小型设备厂;语音机器人;售后报修;故障类型识别;工单自动创建;ASR语音转写;多轮对话;售后工单系统;意图识别
一、先说结论:这套系统解决什么问题
一句话概括:客户打报修电话进来,语音机器人在几轮对话内问清故障现象、设备型号、城市和联系人,系统判断故障类型,自动建好售后工单并分派给对应区域的工程师,识别不了的、客户着急的转人工内勤。
它解决的是四个具体痛点:
| 痛点 | 过去做法 | 自动化后 |
|---|---|---|
| 登记耗时长 | 内勤边听边手写,单通3到5分钟 | 机器人对话采集,内勤只处理转人工部分 |
| 故障类型靠经验 | 新内勤容易分错,工程师白跑 | 规则+模型双保险,低置信度转人工判断 |
| 分派不准 | 翻通讯录找区域工程师,来回转 | 按技能、区域、负载自动选人 |
| 夜间周末无人接 | 客户留言,次日处理 | 机器人接单,次日优先派 |
下面从业务场景开始,把技术实现一步步拆开。
二、业务场景:小型设备厂售后报修的真实情况
先交代背景。我们这家厂做的是小型包装机械和食品加工设备,全国几千家客户,售后团队十来个人。设备单价几万到几十万不等,客户以中小食品厂、包装厂为主。设备故障大致分几类:
-
电气类:不启动、跳闸、报警代码、温控异常、电机不转。
-
机械类:异响、卡料、传送带跑偏、轴承发热、漏油。
-
工艺类:封口不牢、计量不准、温度上不去、压力不稳。
-
操作类:客户不会调参数、不会换模具、误操作导致停机。
客户来电报修时,描述方式非常口语化。有人上来就说“你们那台机器又不转了”,有人会说“封口机封不牢,袋子一撕就开”,还有人直接报报警代码“显示E03”。售后内勤需要边听边判断:这是哪类故障、客户买的是哪款设备、在哪个城市、急不急、之前有没有修过。判断完再决定派哪个工程师、带什么配件。
过去的流程是:客户打电话 → 内勤接听 → 手写记录 → 挂机后录入Excel或简易工单系统 → 微信或电话通知工程师。问题很明显:高峰期电话占线,内勤忙起来记录不全,故障类型靠个人经验判断,新来的内勤容易分错。更麻烦的是晚上和周末,内勤下班后客户报修只能留言,第二天才能处理。
技术目标很明确:客户来电后,语音机器人先接住,通过几轮对话把故障现象、设备型号、联系人、地址问清楚,系统自动判断故障类型并创建工单,按规则分派给对应售后工程师。识别不了的、客户着急的,转人工内勤。整个链路要快,客户等不了机器人啰嗦半天。
三、整体架构:电话进来之后发生了什么
架构不复杂,小型设备厂不需要堆太多组件,关键是链路短、稳定、好维护。
text
客户来电
│
▼
400电话线路 ──呼叫事件──▶ 接入服务(Webhook)
│ │
▼ ▼
语音机器人(IVR+ASR+对话管理) 会话状态服务
│ │
▼ ▼
故障分类服务 ──────────▶ 工单创建服务
│ │
▼ ▼
槽位收集(多轮对话) 分派引擎
│ │
▼ ▼
工单系统(API) ──▶ 售后工程师企微/短信通知
电话线路这块,我们用的是优音通信的400号码线路,提供呼叫事件推送和语音流对接能力,接入方式比较直接。呼叫事件里带主叫号码、通话开始时间、被叫号码等字段,这些是后续关联客户历史记录的基础。
语音机器人负责三件事:一是IVR导航,让客户按键选择“报修”“咨询”“投诉”等大类;二是ASR实时转写,把客户说的话变成文本;三是对话管理,按槽位逐项收集信息。故障分类服务在对话过程中持续跑,文本每增量一次就做一次轻量判断,等关键信息收齐后再做最终分类。工单创建服务拿到分类结果和槽位信息后调工单系统API建单,分派引擎按规则选工程师。
这里有个设计取舍:语音机器人是全语音交互,还是“语音+按键”混合?我们最终选了混合。纯语音对老年客户不友好,纯按键又收集不了故障描述。实际做法是:设备型号让客户按键选择或口述数字,故障现象让客户自由说,联系人电话直接用来电号码兜底,地址让客户说或者按键选省份。这样对话轮次控制在四到六轮,大部分客户能接受。
四、核心技术一:故障类型识别,规则打底、模型补语义
4.1 为什么小型设备厂适合规则先行
大型设备企业的故障类型可能有几百种,小型设备厂的故障类型相对集中。我们统计了历史工单,高频故障大概二十来种,覆盖了八成以上的报修。这种分布下,规则匹配的性价比很高:可解释、可快速调整、不需要标注大量数据。我们第一版完全用规则,上线两周就把高频故障的识别率做到了七成多。
故障分类的规则不是简单的关键词命中,而是“关键词+否定词+上下文”的组合。比如客户说“不是电机的问题,是封口不牢”,要能识别出否定结构,不能简单匹配“电机”就判成电气故障。我们用了简单的正则和关键词窗口,先把高频故障的典型表达覆盖住。
python
import re
FAULT_RULES = {
"electrical_start": [r"不启动", r"启动不了", r"开不了机", r"没反应", r"跳闸"],
"electrical_alarm": [r"报警", r"报错", r"显示[A-Z]\d+", r"代码[Ee]\d+"],
"mechanical_noise": [r"异响", r"响声", r"噪音", r"咔咔", r"嗡嗡"],
"mechanical_jam": [r"卡料", r"卡住", r"堵了", r"不下料"],
"seal_issue": [r"封口不牢", r"封不严", r"一撕就开", r"封口(很|太)?差"],
"temp_issue": [r"温度上不去", r"不加热", r"温控不准", r"温度不稳"],
"weigh_issue": [r"计量不准", r"重量不对", r"称不准", r"下料不准"],
}
NEGATION_WORDS = ["不是", "没有", "并非", "排除"]
def rule_classify_fault(text: str) -> list[tuple[str, float]]:
results = []
for fault_type, patterns in FAULT_RULES.items():
hits = 0
for p in patterns:
for m in re.finditer(p, text):
start = max(0, m.start() - 6)
window = text[start:m.start()]
if any(neg in window for neg in NEGATION_WORDS):
continue
hits += 1
if hits > 0:
conf = min(0.55 + 0.12 * hits, 0.85)
results.append((fault_type, conf))
results.sort(key=lambda x: x[1], reverse=True)
return results
规则层还有一个实际作用:强信号快速建单。客户如果直接报出报警代码,比如“显示E03”,规则命中后可以直接触发预建单,同时继续对话收集其他信息。这样即使后续对话中断,工单也已经落下来了,内勤能看到一条待补全的记录。
4.2 模型补的是“说法不一样”的场景
规则覆盖不了的是表达变体。比如同样是不下料,客户可能说“料斗里面下不去”“螺杆不转”“送料电机没劲”,这些词规则没覆盖,但语义上属于同一类故障。我们用一个轻量的中文文本分类模型做补充,输入是ASR转写的前若干轮对话文本,输出故障类型概率。
训练数据来自历史工单的“故障描述”字段和对应的故障分类标签。样本量不大,几千条,做了类别平衡。模型没有追求高参数量,用的是一个小尺寸预训练模型微调,推理延迟控制在百毫秒级,不影响对话体验。阈值定在0.7,低于阈值的交给规则结果或者转人工。
4.3 融合决策
规则和模型的融合策略很简单:规则强命中(置信度≥0.85)直接用规则;规则和模型一致时取较高置信度;模型置信度≥0.75且规则没命中时用模型;其余情况标记“待确认”,工单照建但故障类型留空,由内勤补。
python
def classify_fault(text: str) -> dict:
rule_results = rule_classify_fault(text)
model_label, model_conf = model_predict_fault(text)
if rule_results and rule_results[0][1] >= 0.85:
return {"fault_type": rule_results[0][0], "confidence": rule_results[0][1], "source": "rule"}
if rule_results and model_label == rule_results[0][0]:
return {"fault_type": model_label, "confidence": max(rule_results[0][1], model_conf), "source": "fusion"}
if model_conf >= 0.75:
return {"fault_type": model_label, "confidence": model_conf, "source": "model"}
if rule_results:
return {"fault_type": rule_results[0][0], "confidence": rule_results[0][1], "source": "rule_low"}
return {"fault_type": "unknown", "confidence": 0.0, "source": "fallback"}
五、核心技术二:客户信息采集,多轮对话怎么设计才不招人烦
故障类型是工单的核心字段,但光有故障类型不够,还得知道是哪台设备、谁在用、在哪儿、怎么联系。这些信息我们按槽位来收。
5.1 槽位定义
| 槽位 | 是否必填 | 收集方式 | 兜底策略 |
|---|---|---|---|
| 设备型号 | 是 | 按键选择或口述数字 | 来电号码关联历史工单 |
| 故障现象 | 是 | 自由说,ASR转写 | 转人工补录 |
| 联系人 | 是 | 来电号码默认,可修改 | 来电号码 |
| 联系电话 | 是 | 来电号码默认 | 来电号码 |
| 所在城市 | 是 | 口述或按键选省份 | 历史工单地址 |
| 紧急程度 | 否 | 按键选择(急/不急) | 默认一般 |
设备型号是最容易卡住的槽位。小型设备厂客户往往记不住型号,只说“就是那台封口机”。我们的做法是双通道:一是让客户按键选择大类(封口机、包装机、杀菌锅等),二是来电号码关联历史工单,如果这个号码之前报修过,直接带出设备型号让客户确认。两个通道都没有的,转人工。
故障现象槽位不设固定话术,让客户自由说,ASR实时转写。对话管理会判断客户说了几轮、有没有提到关键故障词,如果客户说了两轮还没说到点上,机器人会追问一句“是设备不启动、还是有异响、还是封口不牢?”给客户几个选项,降低表达门槛。
5.2 对话流程示例
text
机器人:您好,这里是XX设备售后报修,请问设备出了什么问题? 客户:那个封口机封不牢,袋子一撕就开。 机器人:好的,封口不牢。请问您是哪款设备?可以按1封口机,按2包装机,按3其他。 客户:1。 机器人:封口机。请问您在哪个城市? 客户:山东临沂。 机器人:好的。您的来电号码是138xxxx1234,联系人怎么称呼? 客户:我姓王。 机器人:王先生您好,故障已记录:封口机封口不牢,山东临沂,联系电话138xxxx1234。马上为您安排售后工程师,请稍候。
整个对话控制在五轮以内,大部分客户四十秒左右能完成。客户如果中途说“我着急,直接找人工”,对话管理直接切人工,不纠缠。
5.3 槽位提取的代码思路
槽位提取用的是规则+词典。城市用行政区划词典匹配,联系人用“我姓X”“我是X”这类模式,设备型号按键直接取值。故障现象不提取结构化字段,整段转写文本作为工单描述。
python
def extract_slots(dialog_history: list[dict]) -> dict:
slots = {}
full_text = " ".join([t["text"] for t in dialog_history if t["role"] == "customer"])
# 城市匹配
for city in CITY_DICT:
if city in full_text:
slots["city"] = city
break
# 联系人
m = re.search(r"(我姓|我是|免贵姓)([\u4e00-\u9fa5])", full_text)
if m:
slots["contact_name"] = m.group(2) + "先生/女士"
# 设备型号从按键结果取
for t in dialog_history:
if t.get("slot") == "device_model":
slots["device_model"] = t["value"]
return slots
六、核心技术三:工单自动创建与分派
6.1 工单字段映射
故障类型和槽位收齐后,工单创建服务按模板建单。不同故障类型的工单字段略有差异,比如电气类需要带报警代码,机械类需要带设备运行时长,工艺类需要带物料类型。我们做了一张映射表,放在配置里,售后主管可以自己改。
| 故障类型 | 工单模板 | 必填字段 | 默认优先级 | 建议技能标签 |
|---|---|---|---|---|
| electrical_start | 电气维修单 | 设备型号、城市、联系人、故障描述 | 高 | 电气 |
| electrical_alarm | 电气维修单 | 设备型号、报警代码、城市、联系人 | 高 | 电气 |
| mechanical_noise | 机械维修单 | 设备型号、城市、联系人、故障描述 | 中 | 机械 |
| mechanical_jam | 机械维修单 | 设备型号、城市、联系人、故障描述 | 高 | 机械 |
| seal_issue | 工艺维修单 | 设备型号、物料类型、城市、联系人 | 中 | 工艺 |
| temp_issue | 工艺维修单 | 设备型号、温度设定、城市、联系人 | 中 | 工艺 |
| unknown | 通用报修单 | 设备型号、城市、联系人、故障描述 | 中 | 待定 |
工单创建接口带上 source=voice_robot、call_id、fault_type、confidence、auto_created=true 等字段,方便后续统计自助报修完成率和分类准确率。
python
import requests
def create_service_ticket(call_info: dict, slots: dict, fault: dict) -> dict:
payload = {
"title": f"{slots.get('device_model', '设备')}-{fault['fault_type']}-{slots.get('city', '')}",
"type": FAULT_TO_TICKET_TYPE.get(fault["fault_type"], "通用报修单"),
"priority": FAULT_TO_PRIORITY.get(fault["fault_type"], "中"),
"description": call_info["transcript_summary"],
"device_model": slots.get("device_model"),
"city": slots.get("city"),
"contact_name": slots.get("contact_name"),
"contact_phone": call_info["caller"],
"call_id": call_info["call_id"],
"fault_type": fault["fault_type"],
"intent_confidence": fault["confidence"],
"auto_created": True,
"source": "voice_robot",
}
resp = requests.post(TICKET_API, json=payload, timeout=3)
resp.raise_for_status()
return resp.json()
超时设短一点,3秒足够。工单创建失败不能阻塞通话,失败就记一条待补偿任务,走异步重试。工单接口一定要做幂等,同一个 call_id 重复推送不能建出两张单,这个在呼叫事件重推的时候很容易出问题。
6.2 分派引擎:按技能、区域、负载三要素选人
建单之后是分派。小型设备厂售后工程师人数不多,十来个人,但每个人擅长的领域不一样:有人偏电气,有人偏机械,有人偏工艺调试。分派规则按优先级依次判断:
-
技能匹配:故障类型对应的技能标签,优先派给有该标签的工程师。
-
区域匹配:工程师负责的区域覆盖客户所在城市,跨区域派单成本高。
-
负载均衡:同等条件下选当前未关闭工单数少的工程师。
-
兜底:以上都不满足,派给售后主管人工分派。
这套规则用配置表维护,售后主管可以调整工程师的技能标签和负责区域,不需要改代码。
python
def assign_engineer(ticket: dict, engineers: list[dict]) -> str | None:
candidates = [e for e in engineers if ticket["fault_type"] in e["skills"]]
if not candidates:
return None # 兜底给主管
regional = [e for e in candidates if ticket["city"] in e["regions"]]
pool = regional if regional else candidates
pool.sort(key=lambda e: e["open_ticket_count"])
return pool[0]["engineer_id"]
分派完成后,工单系统给工程师发企业微信或短信通知,带工单链接和客户电话。工程师接单后状态回写,客户那边如果留了手机号,系统会发一条确认短信,告诉客户工单号和预计联系时间。
七、异常兜底:语音机器人不能硬扛所有情况
语音机器人最怕的是“客户说半天,机器人没听懂还不让转人工”。我们定了五个兜底原则:
原则一:两轮没听清就转人工。 同一个槽位连续追问两次还没拿到有效信息,直接切人工内勤,不耗客户时间。
原则二:客户说“转人工”立即转。 识别到“人工”“找个人”“客服”等词,不解释不挽留,直接切。
原则三:投诉类不进机器人。 IVR第一层按键如果客户选“投诉”,直接转人工,不走报修流程。投诉和报修混在一起处理容易激化情绪。
原则四:挂机后补全。 客户中途挂断的,已经收集到的槽位和转写文本照常建单,标记“待补全”,内勤看到后回拨补信息。不能因为客户挂了就丢掉这条报修。
原则五:故障类型低置信度不硬派。 置信度低于0.6的工单,故障类型留空,分派给售后主管人工判断,避免派错工程师白跑一趟。
八、上线效果与踩坑复盘
上线三个多月,数据如下:
| 指标 | 上线前 | 上线三个月后 |
|---|---|---|
| 语音机器人自助完成报修比例 | — | 约68% |
| 工单自动创建覆盖率 | 0 | 约85% |
| 故障类型分类准确率(人工抽检300通) | — | 82% |
| 售后内勤单通登记时间 | 平均3到5分钟 | 约1分钟(仅处理转人工部分) |
| 夜间和周末报修响应 | 次日处理 | 机器人接单,次日优先派 |
低置信度转人工判断的比例从上线初期的四成左右降到一成五左右,说明模型在持续纠错回流中逐步收敛。
踩过的坑挑几个说:
坑一:客户口述设备型号根本不可靠。 一开始我们让客户直接说型号,结果十个人里有八个说不清,有人说“就是那个小封口机”,有人说“去年买的那个”。后来改成按键选大类+来电号码关联历史工单,槽位收集完成率从五成多提到八成五。
坑二:ASR把报警代码识别错。 客户说“E零三”,ASR转成“一零三”,规则匹配不上。后来在热词表里加了报警代码的读法变体,同时让客户按键输入数字,准确率才上来。热词表里还要放设备型号、常见故障词、配件名称,每周更新一次。
坑三:一个电话说多个故障。 客户说“封口不牢,而且有时候还跳闸”。单标签分类只能取一个,我们改成主故障+附注故障,主故障走分派,附注故障写进工单描述让工程师现场判断。
坑四:方言和背景噪音。 小型设备厂的客户很多在车间里打电话,机器噪音大,加上各地方言,ASR转写质量下滑。我们的做法是对话设计上尽量用短问句和选项式提问,减少长段自由说的依赖;同时IVR里保留按键通道,客户说不清可以按。
坑五:工程师不习惯看工单。 系统上线后工程师还是习惯等内勤打电话,工单挂在系统里没人接。后来我们把企业微信通知做成卡片式,点开就是工单详情和一键接单,同时在周会上盯了两周接单时效,习惯才慢慢扭过来。技术系统再好,流程不跟上也白搭。
九、常见问题FAQ
Q1:小型设备厂一定要上语音机器人吗?先人工接行不行?
行,但要看量。如果日均报修电话在二三十通以内,人工内勤加简易工单系统能撑住。超过这个量,高峰期占线和登记遗漏的问题会明显。建议先把工单系统和分派规则跑通,语音机器人可以后上,避免一上来摊子铺太大。
Q2:故障类型识别,规则和模型哪个先上?
先上规则。小型设备厂高频故障集中,规则两周能覆盖七成以上场景,可解释、好调整。模型用来补表达变体,等规则跑稳、积累了一批纠错数据再训练,效果更实在。
Q3:客户说不清设备型号怎么办?
双通道兜底:一是按键选设备大类,二是来电号码关联历史工单带出型号让客户确认。两个都没有的转人工。别指望客户能准确口述型号,这是实际踩过的坑。
Q4:ASR转写不准怎么优化?
先做热词表,把设备型号、报警代码读法、故障词、配件名挂进去;再考虑电话场景专用模型;车间噪音大的场景,对话设计上多用短问句和按键选项,减少对长段自由说的依赖。
Q5:工单分派错了怎么办?
分派规则里保留“售后主管人工改派”入口,工程师端提供“转派”按钮并记录原因。改派数据定期复盘,该调技能标签调标签,该调区域调区域。
Q6:怎么衡量这套系统有没有效果?
看四个指标:语音机器人自助完成报修比例、工单自动创建覆盖率、人工抽检故障分类准确率、内勤单通登记耗时。再补一个工程师首次响应时长,基本能说明问题。
十、小结
整套方案的核心就四件事:把语音变成文本,把文本变成故障标签,把标签和槽位变成工单,把工单分给对的人。技术上没有特别高深的东西,难在细节打磨——热词表、设备型号兜底、否定词处理、置信度阈值、转人工时机,每一项都需要结合业务反复调。
如果团队刚开始做,建议先上规则层和工单创建链路,把强信号场景跑通,快速拿到收益,再逐步引入模型和多轮对话优化。别一上来就追求端到端的智能对话,工单系统对接、字段映射、分派规则、异常兜底这些“脏活”才是决定项目能不能落地的关键。
代码示例里的函数都是简化版,实际工程里还要考虑并发、幂等、日志埋点、灰度开关这些。工单创建接口一定要做幂等,这个在呼叫事件重推的时候很容易出问题。
最后提一句数据回流。故障分类不是一锤子买卖,内勤的每一次改类型、工程师的每一次转派、客户的每一次挂断,都是模型和规则迭代的燃料。把这条链路打通,系统才会越用越准。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)