博世家电维修AI智能体:RAG架构实现工单自动生成与案例检索

发布时间:2026/10/27 6:17:20
博世家电维修AI智能体:RAG架构实现工单自动生成与案例检索

1. 项目缘起:从一张手写工单说起

我在家电售后这行干了快十二年,前六年跑现场修机器,后六年蹲在后台做技术支持。你要问我最头疼的事是什么,不是那些疑难杂症,而是故障工单的编写。一张工单写得好不好,直接决定了后续维修效率、配件调拨准确率,甚至客户满意度。但现实是,大部分维修师傅在客户家里蹲着,手上全是油污,掏出手机对着工单系统戳半天,最后写出来的东西是这样的:“冰箱不制冷,换了压缩机,好了。”——就这十几个字,信息量几乎为零。

博世这个品牌大家都熟,德系精工的代表,产品线从冰箱、洗衣机到洗碗机、烤箱,型号多如牛毛。同一个“不制冷”的故障现象,背后可能是压缩机启动器坏了、可能是温控板故障、可能是制冷剂泄漏、也可能是门封条老化导致冷气外泄。如果工单上只写“不制冷”,后台的配件计划员就得靠猜,猜错了配件发过去装不上,师傅白跑一趟,客户多等三天,三方全输。

所以当我第一次接触到“博世维修AI智能体”这个概念时,我的反应是:这事要是真能落地,功德无量。这个智能体要干两件事:第一,帮师傅把故障工单写规范、写完整;第二,从海量旧案例里快速检索出相似故障,给出维修建议。说白了,就是给每个师傅配一个“老师傅外挂”——你描述个大概,它帮你补全细节、匹配历史经验。

这篇文章,我就把这个智能体的设计思路、技术选型、实操细节和踩过的坑,从头到尾捋一遍。不管你是做售后管理的、搞智能体开发的,还是单纯对AI落地感兴趣,都能从中拿到可以直接抄作业的东西。

2. 整体设计思路:为什么是“检索+生成”双引擎

2.1 核心需求拆解:师傅到底需要什么

在动手设计之前,我先干了件笨但管用的事:跟着三个不同工龄的师傅跑了整整一周的现场。工龄分别是两年、五年、十年。我记录了他们写工单的全过程,发现几个关键痛点。

两年经验的师傅,最大的问题是不知道该写什么。他看到一个故障码,知道要换某个件,但说不清楚故障现象和判断依据。五年经验的师傅,能写清楚现象和操作,但懒得写全,觉得“反正后台懂”。十年经验的师傅,写得又快又准,但他脑子里那套经验,根本传不出来——你让他教新人,他只会说“你多修几年就知道了”。

这三个痛点对应了三个需求:补全、规范、传承。补全是帮新手把信息补完整,规范是让老手别偷懒,传承是把老师傅的隐性知识显性化。一个智能体要同时满足这三个需求,单靠一个大模型生成是不够的,必须结合检索。

这里插一句我的判断:纯生成式AI在维修场景下有个致命问题——它会“编”。你问它“博世某型号冰箱E01故障码什么意思”,它可能给你编一个听起来很合理的解释,但实际上是错的。维修这行,错一个判断,可能就是几百块的配件和几个小时的人工。所以检索必须作为生成的锚点,让AI基于真实历史案例来说话,而不是凭空发挥。

2.2 双引擎架构:检索增强生成的实际落地

最终确定的架构是检索增强生成,业内叫RAG。这个架构不新鲜,但用在维修工单场景,有几个关键设计点。

整个流程是这样的:师傅在手机端输入一段自然语言描述,比如“客户说冰箱冷冻室结冰很厚,冷藏室不冷,压缩机一直响”。系统先把这段描述做意图识别和实体抽取,提取出品牌、品类、故障现象、关键部件等结构化信息。然后拿这些信息去案例库做混合检索——既做关键词匹配,也做语义向量匹配。检索出Top 5相似案例后,把这些案例作为上下文,连同师傅的原始描述一起喂给大模型,让大模型生成一份规范的工单草稿,并附上“参考案例”和“建议排查方向”。

这里有个细节值得展开:为什么用混合检索而不是纯向量检索。我实测过,纯向量检索在维修场景下有个坑——它太“语义”了。比如“不制冷”和“制冷效果差”,向量距离很近,但实际维修中,前者可能是完全不制冷,后者可能是制冷慢,排查方向完全不同。而关键词检索能精确匹配“不制冷”这个短语。所以混合检索是必须的,关键词保精度,向量保召回。

2.3 技术选型:为什么没选纯平台方案

现在市面上智能体平台很多,扣子、Dify这些我都试过。平台方案的好处是快,拖拖拽拽就能搭一个Demo。但真要用在博世维修这种场景,平台方案有几个绕不过去的问题。

第一是数据安全。维修案例库里有客户地址、电话、机器序列号,这些数据不可能传到第三方平台。第二是检索可控性。平台自带的检索功能,你没法精细调整关键词权重、没法自定义分词词典。维修这行有大量专业术语和型号编码,通用分词器根本切不对。第三是成本。平台按调用次数收费,我们日均工单量几千条,长期算下来比自己部署贵得多。

所以最终选了自建方案:Python + FastAPI做后端,向量库用Milvus,关键词检索用Elasticsearch,大模型用本地部署的开源模型加一个云端API做兜底。这个组合听起来复杂,但每个组件都有明确的理由。Milvus处理千万级向量检索性能稳定,Elasticsearch的IK分词器可以自定义词典,本地模型保证核心数据不出内网。

3. 核心细节解析:从工单文本到结构化知识的转化

3.1 故障描述的结构化抽取:让机器看懂“人话”

师傅写的原始描述,是典型的非结构化文本。要让机器能检索、能匹配,第一步就是结构化抽取。我们定义了一个维修领域的实体框架,包含以下几个维度。

实体类型说明示例
产品品类冰箱、洗衣机、洗碗机等冰箱
产品型号博世具体型号编码KGN56AL40C
故障现象客户感知到的异常冷冻室结冰、冷藏室不冷
故障代码机器显示的Error CodeE01、F23
涉及部件可能相关的零部件压缩机、蒸发器、温控板
使用年限机器已使用时间3年
环境信息安装位置、环境温度等厨房、靠近灶台

抽取用的是微调后的小模型,而不是直接调大模型API。原因很简单:大模型抽取慢、贵,而且对于“KGN56AL40C”这种型号编码,大模型经常识别错。我们用一个7B参数的开源模型,在标注了五千条工单数据上做了LoRA微调,抽取准确率从基线的72%提升到了94%。这个投入是值得的,因为抽取质量直接决定了后续检索的精度。

实操心得:标注数据的时候,一定要让一线维修师傅参与,而不是让标注公司随便找人标。我试过让外包标注,他们把“压缩机不启动”和“压缩机不工作”标成了两个不同实体,实际上这俩是一回事。后来我拉了三个老师傅,花了两天时间统一了标注规范,后面模型效果才起来。

3.2 案例库的构建与清洗:垃圾进,垃圾出

检索系统的效果,七分靠数据,三分靠算法。案例库的质量,直接决定了智能体是“老师傅”还是“糊涂蛋”。

我们最初的案例库是从旧工单系统直接导出的,大概有八十万条。但导出来一看,能用的大概只有六成。问题包括:重复工单、测试工单、信息残缺工单、甚至还有师傅随手写的“测试123”。清洗规则我列一下,你可以直接参考。

  • 去重:同一机器序列号、同一故障现象、时间间隔在24小时内的工单,只保留信息最完整的一条。
  • 过滤:故障描述少于10个字的、包含“测试”“作废”“误报”等关键词的,直接剔除。
  • 补全:对于有故障代码但无描述的,通过故障代码表反查补全标准描述。
  • 脱敏:客户姓名、电话、地址全部替换为占位符,保留地域信息用于分析区域故障特征。
  • 标准化:把“不制冷”“不冷”“制冷不行”统一映射到标准术语“制冷效果差”。

清洗完之后,剩下大概四十八万条高质量案例。这个量级对于向量检索来说不算大,Milvus单机就能扛住。但关键词检索那边,Elasticsearch的索引需要优化,我们把型号、故障代码、部件名称设为keyword字段,故障描述设为text字段并配置了自定义IK词典。

3.3 提示词工程:让大模型说“维修话”

大模型生成工单草稿,提示词的设计是核心。我见过太多人写提示词就是“你是一个维修助手,请帮我写工单”,这种提示词出来的结果,要么太啰嗦,要么太笼统。

我们的提示词模板经过十几版迭代,最终定型为角色定义+任务说明+格式约束+参考案例+输出示例五段式。具体内容我脱敏后贴出来。

SYSTEM_PROMPT = """ 你是一名博世家电维修领域的资深技术支持工程师,拥有十五年一线维修经验。 你的任务是:根据维修师傅的原始描述和检索到的相似历史案例,生成一份规范的故障工单草稿。 要求: 1. 工单必须包含:故障现象、故障代码(如有)、初步判断、建议排查步骤、可能涉及配件。 2. 语言简洁专业,使用维修行业标准术语,避免口语化表达。 3. 如果原始描述信息不足,在工单末尾标注“需补充信息:xxx”。 4. 参考案例仅作为判断依据,不要直接复制案例中的客户信息。 5. 输出格式为JSON,字段包括:fault_phenomenon, fault_code, diagnosis, steps, parts。 """

这个提示词的关键在于格式约束和参考案例的定位。格式约束让输出可以直接被工单系统解析,不需要二次处理。参考案例的定位说明,是为了防止大模型把案例里的具体信息(比如“王女士家”)直接抄进新工单。

注意:提示词里的“十五年一线维修经验”不是随便写的。我对比过,写“资深工程师”和写“十五年一线维修经验”,后者生成的工单在细节丰富度上明显更好。大模型对具体数字有更强的角色代入感,这算是个小技巧。

4. 实操过程:从零搭建一个可用的维修智能体

4.1 环境准备与依赖安装

整个系统跑在Ubuntu 22.04上,Python版本3.10。为什么不用3.11或3.12?因为Milvus的Python SDK对3.11的支持当时还不稳定,踩过坑之后退回了3.10。依赖管理用Poetry,比pip+requirements.txt清爽得多。

核心依赖清单如下。

# 后端框架 fastapi==0.104.1 uvicorn==0.24.0 # 向量检索 pymilvus==2.3.4 # 关键词检索 elasticsearch==8.11.0 # 大模型推理 transformers==4.36.0 torch==2.1.0 peft==0.7.0 # 文本处理 jieba==0.42.1 sentence-transformers==2.2.2

安装过程中最容易出问题的是torch和CUDA的版本匹配。我们用的是A100显卡,CUDA 11.8,对应的torch版本必须是2.1.0+cu118。如果你用CPU推理,速度会慢到无法接受——实测一条工单生成要8秒,GPU上只要0.6秒。

4.2 向量化模型的选择与微调

把故障描述转成向量,用的是sentence-transformers的paraphrase-multilingual-MiniLM-L12-v2。选这个模型的原因有三:支持中文、体积小(只有118M)、推理速度快。但直接用预训练模型有个问题——它不懂维修术语。比如“压缩机启动器”和“PTC启动器”,在通用语义空间里距离较远,但在维修场景下它们是强相关的。

所以我们做了领域微调。构造了大概两万对正样本(相似故障描述)和四万对负样本(不相似故障描述),用对比学习的方式微调了三个epoch。微调之后,在自建的测试集上,Top 5召回率从68%提升到了89%。这个提升非常关键,因为检索不准,后面生成得再好也是白搭。

微调的代码不复杂,核心就是构造InputExample然后跑MultipleNegativesRankingLoss。但数据构造很费功夫,我们花了大概三周时间,让维修师傅一对一对地标注“这两条描述是不是同一个故障”。

4.3 混合检索的权重调优

关键词检索和向量检索的结果怎么融合,直接影响到最终效果。我们试过三种方案。

融合方案原理实测效果
串行先关键词检索,再向量检索召回率低,关键词没匹配上就全挂了
并行加权两路各取Top 20,加权合并效果最好,但权重要调
并行RRF用倒数排名融合效果稳定,不需要调权重

最终选了并行RRF。RRF的好处是不需要手动调权重,它对两路检索的排名做倒数融合,排名越靠前的文档得分越高。公式很简单:score = Σ 1/(k + rank),k一般取60。这个方案在测试集上的Top 5准确率是91%,比加权方案高了3个百分点,而且省去了调参的麻烦。

实操心得:RRF的k值不要随便改。我试过k=10和k=100,效果都不如k=60。这个值是经过大量实验验证的,直接抄作业就行。

4.4 工单生成与后处理

检索出Top 5案例后,连同师傅的原始描述一起喂给大模型。大模型用的是Qwen-7B-Chat的量化版本,4-bit量化后显存占用大概6G,一张A100可以同时跑多个实例。

生成出来的JSON,还需要做后处理校验。校验规则包括:故障代码是否在已知代码表中、建议配件是否在博世配件库中存在、排查步骤是否包含安全提示(比如“断电后再操作”)。如果校验不通过,系统会降级到模板生成,保证师傅至少能拿到一份可用的工单。

整个流程从师傅提交描述到返回工单草稿,端到端延迟在1.2秒左右。这个速度师傅是可以接受的,不会觉得“等半天”。

5. 常见问题与排查技巧实录

5.1 检索结果不相关:从数据到算法的排查路径

这是最常见的问题。师傅输入“冰箱不制冷”,检索出来的案例却是“洗衣机不脱水”。排查思路按以下顺序来。

第一步,检查实体抽取结果。如果抽取出来的产品品类是“洗衣机”,那说明抽取模型出问题了。这时候要看原始描述里有没有“冰箱”这个词,如果有但没抽出来,说明模型需要补充训练数据。

第二步,检查向量化结果。把输入文本和检索结果的向量拿出来,算一下余弦相似度。如果相似度低于0.6,说明向量模型没学好。这时候要考虑是不是微调数据不够,或者输入文本太短导致向量表征能力不足。

第三步,检查ES分词。把输入文本用IK分词器切一下,看看切出来的词是不是合理。我遇到过“不制冷”被切成“不”和“制冷”,导致关键词匹配失效。解决办法是在自定义词典里加上“不制冷”这个短语。

第四步,检查RRF融合权重。如果两路检索各自的结果都还行,但融合后变差了,那可能是RRF的k值需要调整。不过这种情况比较少见。

5.2 大模型“胡说八道”:幻觉的抑制与兜底

大模型生成工单时,偶尔会编造不存在的故障代码或配件名称。这个问题在维修场景下是零容忍的,因为师傅可能真的会照着去订配件。

我们的抑制策略分三层。第一层是提示词约束,明确要求“只使用参考案例中出现的故障代码和配件名称”。第二层是后处理校验,生成结果中的故障代码和配件名称必须通过白名单校验,不在白名单里的直接剔除。第三层是置信度阈值,如果大模型对某个判断的置信度低于阈值,就在工单上标注“建议人工确认”,而不是直接给出结论。

实测下来,三层策略叠加后,幻觉率从最初的12%降到了0.8%。剩下的0.8%主要是型号编码的细微错误,比如把“KGN56AL40C”写成“KGN56AL40”,这种通过正则校验也能拦住。

5.3 师傅不愿意用:推广中的真实阻力

技术问题好解决,人的问题最难。系统上线第一个月,使用率只有23%。我找师傅聊了聊,发现几个真实阻力。

一是觉得麻烦。师傅说“我本来写十个字就完事了,现在还要等AI生成,再改一遍,更费时间”。这个反馈让我意识到,AI生成的工单必须比师傅自己写的更快,否则就没有价值。后来我们优化了交互,师傅只需要语音输入一段话,系统自动转文字并生成工单,师傅确认或微调即可。这样操作步骤从“打字-提交-等待-修改”变成了“说话-确认”,时间反而省了。

二是不信任。老师傅觉得“AI懂什么维修”。这个只能靠实际效果说话。我们挑了几个典型故障,让AI生成工单,然后让老师傅盲评。结果老师傅对其中80%的工单表示“写得比我徒弟好”。这个结果在内部群里一发,使用率第二个月就涨到了67%。

三是担心被替代。有些师傅觉得“教会AI,饿死师傅”。这个心态很真实。我们在推广时反复强调,AI是辅助工具,不是替代方案。工单上最终署名的还是师傅本人,AI只是帮他写得更快更好。而且AI检索出来的旧案例,反而让老师傅的经验被更多人看到,提升了他们在团队里的影响力。

5.4 常见问题速查表

问题现象可能原因排查方法解决方案
检索结果完全不相关实体抽取错误检查抽取出的品类、型号补充训练数据,修正抽取模型
相似故障检索不到向量模型领域适配不足计算输入与案例的余弦相似度增加领域微调数据
关键词匹配失效分词器切分错误用IK分词器测试切分结果添加自定义词典
生成工单包含幻觉提示词约束不足检查生成结果中的代码和配件加强后处理校验
端到端延迟过高GPU资源不足或模型过大监控推理耗时量化模型或增加GPU
师傅使用率低交互流程繁琐收集师傅反馈优化交互,支持语音输入

6. 效果评估与持续迭代

6.1 量化指标:工单质量提升了多少

系统上线三个月后,我们做了一次全面的效果评估。评估维度包括工单完整率、配件准确率、首次修复率、师傅满意度。

指标上线前上线后变化
工单完整率54%89%+35%
配件准确率71%92%+21%
首次修复率68%81%+13%
师傅满意度-4.2/5-

工单完整率的提升最明显,因为AI会强制补全必填字段。配件准确率的提升直接带来了成本节约——配件发错一次,来回运费加人工大概200块,按日均3000单算,每天少发错200单,一年省下的钱相当可观。

6.2 持续迭代:案例库的自动更新机制

系统上线不是终点,案例库需要持续更新。我们设计了一个自动入库流程:每天凌晨,系统把前一天已完成的工单做清洗和结构化,然后增量写入案例库。同时,对于检索命中率高但生成质量低的案例,会打上“待优化”标签,由人工复核后决定是否保留。

这个机制的关键是质量闭环。师傅对AI生成工单的修改,本身就是一种反馈信号。如果师傅大幅修改了AI的建议,说明AI判断不准,这条工单就会被标记为负样本,用于后续模型迭代。

6.3 后续扩展方向

这个智能体的框架是通用的,换一个品牌、换一个品类,只要替换案例库和微调数据,就能快速复用。我们已经在规划几个扩展方向。

一是多模态输入。师傅可以直接拍一张故障代码的照片,系统通过OCR识别代码,自动填充工单。这个功能在测试中,识别准确率已经达到96%。

二是语音交互优化。现在师傅需要说普通话,但很多老师傅习惯说方言。我们正在收集方言语音数据,训练一个方言识别模型,让师傅用家乡话也能写工单。

三是预测性维护。基于历史工单数据,分析哪些型号、哪些批次的机器容易出特定故障,提前向客户推送保养提醒。这个方向的数据基础已经具备,就差业务侧的配合了。

最后分享一个小技巧:如果你也在做类似的维修智能体,建议先从单一品类切入,比如只做冰箱。把冰箱的案例库做深做透,跑通整个流程,再扩展到其他品类。我见过太多项目一上来就全品类覆盖,结果每个品类都做得半吊子,师傅用两次就放弃了。聚焦,是落地成功的关键。