汽车维修手册和故障代码文档通常是非结构化的PDF或网页格式,技师在查找特定故障解决方案时,往往需要翻阅数百页资料。传统的关键词搜索经常出现"漏检"(明明文档里有相关内容却搜不到)或"误检"(搜到大量不相关内容)的情况。
我曾在4S店见过技师边修车边用手机查资料,平均每个问题要花费15分钟查找信息。而RAG技术能把这个过程缩短到3秒内——就像给维修手册装上了智能搜索引擎。当技师询问"宝马5系发动机故障灯常亮可能原因"时,系统能精准定位到文档中关于"N20发动机氧传感器故障"的章节,并生成简明扼要的维修建议。
汽车维修文档有其特殊性:包含大量表格、示意图和专业术语。直接用PDF解析工具提取文本会遇到这些问题:
我的经验是组合使用pdfplumber和pymupdf:
python复制import pdfplumber
import re
def clean_text(text):
# 处理中英文混排
text = re.sub(r'([a-zA-Z])([\u4e00-\u9fa5])', r'\1 \2', text)
text = re.sub(r'([\u4e00-\u9fa5])([a-zA-Z])', r'\1 \2', text)
return text
with pdfplumber.open("维修手册.pdf") as pdf:
for page in pdf.pages:
# 优先提取表格
tables = page.extract_tables()
# 再提取文本
text = clean_text(page.extract_text())
直接按页分割文档效果很差,因为一个故障现象的描述可能跨越多页。更好的做法是:
实测有效的分块策略:
维修文档中的示意图往往包含关键信息。我们的解决方案是:
这样当用户问"如何更换刹车片"时,系统既能返回文字说明,也能提供拆卸示意图。
单纯用语义检索会遇到专业术语匹配问题。我们采用三级检索:
python复制from rank_bm25 import BM25Okapi
from sentence_transformers import SentenceTransformer
# 初始化模型
bm25 = BM25Okapi(keyword_docs)
model = SentenceTransformer('BAAI/bge-small-zh-v1.5')
def hybrid_search(query):
# BM25检索
bm25_scores = bm25.get_scores(query)
# 语义检索
query_embedding = model.encode(query)
semantic_scores = np.dot(query_embedding, doc_embeddings.T)
# 加权综合
combined_scores = 0.3*bm25_scores + 0.7*semantic_scores
return combined_scores.argmax()
开源的重排序模型(如bge-reranker)在汽车维修场景需要特别优化:
我们在2000个真实维修问答上的测试显示,经过优化的重排序模块能将准确率从72%提升到89%。
经过数百次测试,我们总结出最有效的prompt模板:
code复制你是一位经验丰富的汽车维修技师,请根据以下维修手册内容回答问题。
必须遵守:
1. 如果手册中没有相关信息,必须回答"根据现有资料无法确定"
2. 涉及安全操作时必须注明"需专业设备检测"
3. 分步骤回答时用"①、②、③"标注
相关资料:{context}
问题:{question}
汽车维修容不得错误信息,我们采用三重校验:
python复制def validate_answer(answer, context):
# 检查页码引用
if "page_" not in answer.metadata:
return False
# 检查关键数字是否篡改
for num in re.findall(r"\d+\.?\d*", answer):
if num not in context:
return False
return True
在4S店实际部署时发现三个性能瓶颈:
我们的解决方案:
将系统封装为微信小程序后,日均查询量达到300+次。我们建立了闭环优化机制:
有个印象深刻案例:用户问"雨刮器异响",最初系统只返回更换雨刮片的建议。经过迭代后,现在能区分:
这种垂直领域的持续优化,才是RAG系统真正创造价值的关键。