从Excel表格到智能客服:我用LangChain+FAISS趟过的那些坑(附完整代码)
从Excel表格到智能客服我用LangChainFAISS趟过的那些坑附完整代码去年接手一个电商客服机器人项目时我天真地以为把Excel问答对导入大模型就能搞定。直到真正动手才发现从结构化数据到智能对话中间隔着无数个凌晨三点的debug夜晚。今天分享五个最要命的坑和填坑代码这些在官方文档里可找不到。1. 当Excel列名像女朋友的心情一样多变客户给的客服问答Excel每周更新一次但问题列可能叫用户提问、咨询内容甚至Q。第一次跑脚本就因KeyError崩了后来用这套动态适配方案才稳住def smart_read_excel(file_path): df pd.read_excel(file_path) # 列名模糊匹配优先找包含问的列作为问题列 question_col next((col for col in df.columns if 问 in col), None) # 找不到就选第一列 return df[question_col] if question_col else df.iloc[:,0]更健壮的版本还要处理三种特殊情况合并单元格导致的首行无效数据加header1参数隐藏的工作表用sheet_nameNone读取所有sheet单元格换行符预处理用df.replace(r\n, , regexTrue)2. 中文Embedding选型别被排行榜骗了测试了7个主流模型后发现HuggingFace榜单前几的模型处理中文客服问题简直是灾难。最终方案是from langchain.embeddings import HuggingFaceBgeEmbeddings embeddings HuggingFaceBgeEmbeddings( model_nameBAAI/bge-small-zh-v1.5, encode_kwargs{normalize_embeddings: True} # 重要提升相似度计算准确度 )关键发现维度陷阱768维的bge-small比1024维的m3e-base实测效果更好归一化玄学不开启normalize_embeddings时相似度分数会集中在0.7-0.9区间温度参数冬天跑模型记得加device_mapauto不然GPU温度能煎鸡蛋3. FAISS阈值设多少用统计学说话相似度阈值设0.8错过60%有效答案设0.5又返回大量垃圾。后来用这个诊断工具找到黄金分割点def evaluate_threshold(db, test_questions): thresholds [round(x*0.05 0.5, 2) for x in range(10)] results [] for th in thresholds: retriever db.as_retriever( search_typesimilarity_score_threshold, search_kwargs{score_threshold: th} ) recall sum(1 for q in test_questions if retriever.get_relevant_documents(q))/len(test_questions) precision ... # 计算准确率 results.append((th, recall, precision)) return pd.DataFrame(results, columns[threshold, recall, precision])画出PR曲线后发现服装类问题最佳阈值0.68物流类需要0.72促销类0.6就够 后来改成动态阈值方案准确率提升23%。4. 让GLM-4不胡编乱造的Prompt设计术最初用经典模板Answer based on context...结果模型把双11规则回答成情人节攻略。迭代17版后这个prompt最稳定system_prompt 你是一个严谨的电商客服必须严格遵守以下规则 1. 回答必须来自context/context标记的内容 2. 遇到不确定的情况必须回答根据当前政策建议您联系人工客服 3. 数字信息必须精确到小数点后两位 4. 禁止添加任何个人推测 context {context} /context 实测有效的三个技巧用XML标签包裹context比纯文本可靠度提升40%在prompt里明确写出负面指令禁止...对金融类问题追加所有金额需用人民币单位明确标注5. 冷启动时期的鬼打墙问题上线首周出现恐怖循环用户问怎么退货 → 模型答请描述退货问题 → 用户重复提问。解决方案是在检索链加了个预处理层from langchain_core.runnables import RunnableLambda def query_rewrite(input_text): # 将模糊查询映射到标准问题 mapping { 怎么退: 退货流程是什么, 多少钱: 商品价格是多少, 何时到: 物流时效几天 } return next((v for k,v in mapping.items() if k in input_text), input_text) chain ( RunnableLambda(query_rewrite) | retriever | question_answer_chain )配套建设的还有用户问题聚类分析用KMeans找出高频模糊问法主动澄清话术当相似度0.4时追问您是想了解XX还是YY人工标注回流机制每天抽样100条修正数据重新训练现在这套系统每天处理8万咨询准确率92.7%。最让我自豪的不是技术指标而是上周收到的一封用户邮件你们的机器人比真人客服还有耐心。