:從知識庫構(gòu)建到效果評估全復盤)
前陣子我們團隊做了一個“AI大模型之旅——智能客服實戰(zhàn)”項目算是把大模型從一個“聊著玩的玩具”真真切切推進到了“能頂一班崗的業(yè)務(wù)系統(tǒng)”階段。這個項目表面上是在做客服實際上是在解決一個很扎心的問題業(yè)務(wù)的知識散落在文檔、工單、群聊和同事腦子里用戶的問題五花八門人工客服累到脫發(fā)老板又天天催著提質(zhì)增效。我們想用大模型把這塊硬骨頭啃下來。這篇文章就是這次實戰(zhàn)的完整復盤包括方案怎么選、坑怎么踩、效果怎么評估。如果你正在規(guī)劃智能客服或者手里有大量知識文檔想做成問答形式這篇文章應該能幫你少走不少彎路。我盡量把每一步為什么這么做講清楚而不只是貼一堆代碼。1. 項目定位與整體架構(gòu)1.1 客服場景的真實痛點先說背景。我們這邊是某內(nèi)容平臺的運營團隊日常面對的用戶問題集中在賬號、訂單、活動和產(chǎn)品使用幾個方向。人工客服每天處理幾百個重復問題老客服閉著眼睛都能背答案但新客服培訓一個月還是容易答錯。早期的FAQ系統(tǒng)勉強能用但用戶體驗很差——用戶說一句話系統(tǒng)只能按關(guān)鍵詞粗暴匹配稍微換個說法就答非所問最后用戶還是選擇“轉(zhuǎn)人工”。我在項目啟動前蹲點了客服工單系統(tǒng)整整兩天發(fā)現(xiàn)幾個關(guān)鍵現(xiàn)象重復問題占比超過六成其中大量是“同一個問題的不同問法”。老客服回答問題時習慣引用內(nèi)部文檔但文檔分散在多個系統(tǒng)檢索本身就很費時間。很多問題是組合型的比如“我買了會員為什么在另一個設(shè)備上看不了”這需要把會員規(guī)則、設(shè)備綁定邏輯、常見原因串起來回答??头幕貜惋L格高度依賴個人經(jīng)驗同一問題不同人的口徑不完全一致。這些痛點決定了項目的目標不是做一個人工智能聊天機器人來替代客服而是做一個能消化內(nèi)部知識、給用戶準確答案、必要時順利轉(zhuǎn)人工的輔助系統(tǒng)。這個定位直接決定了后面的技術(shù)路線。1.2 為什么選RAG而不是微調(diào)大模型項目立項時團隊內(nèi)部有過一次很激烈的討論要不要微調(diào)一個開源模型。我們甚至給某實驗室的大模型嘗試過LoRA微調(diào)但結(jié)果并不理想。核心原因有幾點。第一客服回答要求的是“知識準確性”而微調(diào)模型本質(zhì)上是在學習“說話風格”和“特定任務(wù)模式”它對知識本身的掌握并不牢固特別是低頻、冷門的業(yè)務(wù)規(guī)則。第二業(yè)務(wù)知識更新太快今天剛上線的活動規(guī)則明天就要能回答微調(diào)的訓練鏈路根本來不及。第三合規(guī)和安全層面業(yè)務(wù)數(shù)據(jù)不能隨意進訓練集微調(diào)后模型參數(shù)里“記住”了什么誰也說不清出了問題很難排查。所以最終方案確定為RAG也就是檢索增強生成。用大白話講用戶問一個問題我們先去知識庫里把最相關(guān)的片段撈出來把這些片段和問題一起塞給大模型讓它基于這些素材來組織回答。這樣模型的“記憶能力”被檢索系統(tǒng)替代它只負責“閱讀理解和表達”準確率、可追溯性、更新效率都大大提升。這里我個人的強烈建議是能用RAG解決的場景不要輕易碰微調(diào)。RAG相當于開卷考試微調(diào)相當于閉卷背誦客服場景明顯是開卷更合適。1.3 技術(shù)方案選型與團隊分工在技術(shù)選型上我們畫了一張很樸素的架構(gòu)圖不需要花哨的東西數(shù)據(jù)層業(yè)務(wù)文檔、FAQ、歷史工單沉淀出的標準問答對統(tǒng)一入庫。索引層文檔清洗、切片、向量化存入向量數(shù)據(jù)庫。檢索層對用戶問題做向量檢索配合關(guān)鍵詞檢索再加一個重排環(huán)節(jié)。生成層大模型API接收“問題 檢索片段 歷史對話”生成最終回答。應用層一個封裝好的服務(wù)接口對接客服工作臺和用戶端對話框。模型選擇上我們優(yōu)先采用了大模型API而不是自部署開源模型。原因很現(xiàn)實客服并發(fā)有高峰比如活動期間咨詢量翻倍自部署要處理擴容、顯存、穩(wěn)定性一堆問題API按量付費起步更快。效果方面當時主流的商用模型對中文理解已經(jīng)非常成熟直接調(diào)用它們能把前期成本集中在數(shù)據(jù)工程上。后期如果流量穩(wěn)定、成本敏感再考慮蒸餾或私有化部署。團隊分工大致是數(shù)據(jù)工程師負責清洗切片算法工程師負責檢索鏈路后端同學負責接口編排和會話管理。關(guān)鍵是數(shù)據(jù)和算法不能割裂知識庫的質(zhì)量直接決定效果上限算法只是把上限盡量兌現(xiàn)。2. 知識庫構(gòu)建數(shù)據(jù)是一切的起點2.1 數(shù)據(jù)摸底與清洗是第一道坎很多團隊做RAG項目習慣先研究模型選型回頭才發(fā)現(xiàn)數(shù)據(jù)一團糟。我們這次特意把數(shù)據(jù)工程放在最前面而且實踐證明這個順序非常正確。先摸底。我們把客服系統(tǒng)的歷史工單導出來把產(chǎn)品幫助中心的文檔爬下來把面向內(nèi)部的知識庫文章整理了一遍發(fā)現(xiàn)幾個問題有些文檔內(nèi)容過期了寫著舊版功能的操作路徑有些FAQ答案是錯的回答口徑跟最新規(guī)則不一致還有些文檔排版混亂大段大段的內(nèi)容里面混雜著說明、示例和注意事項。清洗規(guī)則基本是這幾條過期內(nèi)容標記歸檔不進入向量庫避免污染檢索結(jié)果。明顯錯誤的FAQ直接修正或刪除。HTML標簽、Markdown語法、多余空行統(tǒng)一清理保證切片輸入干凈。短文本補全上下文避免碎片化信息沒頭沒尾。有一件事特別提醒千萬別把Excel里的單元格直接當文檔片段塞進向量庫必須轉(zhuǎn)成完整句子。比如某個單元格寫“退款時效3個工作日”如果不加主語模型檢索到之后也可能不確定這是指“審核時效”還是“到賬時效”容易答偏。2.2 切片策略既能撈得著又別撈太碎RAG系統(tǒng)里切片Chunk大小這個參數(shù)最容易被忽略但它對回答質(zhì)量的影響非常直接。片切大了檢索結(jié)果里冗余信息多大模型容易被帶偏片切小了上下文斷裂模型找不到完整的邏輯。我們試驗了幾種切法固定字數(shù)切分比如512字一刀切實現(xiàn)簡單但經(jīng)常把一句話攔腰切斷檢索出來的片段語義不完整。按段落切分對結(jié)構(gòu)良好的文檔效果不錯但長段落還是很長。按標題層級切分 固定窗口重疊先按文檔結(jié)構(gòu)切塊如果某塊仍然太長再按句子邊界切并且每個切塊保留前后一部分重疊內(nèi)容。這個方案我們實測效果最好。具體實現(xiàn)時重疊窗口設(shè)為大約50到100字。這個重疊非常重要它能避免檢索命中的內(nèi)容正好落在切片邊界上導致漏掉關(guān)鍵信息。另一個經(jīng)驗不同來源的文檔建議分開切片配置。FAQ問題通常一句話就能答完適合小切片操作指南類文檔步驟多適合按步驟塊切。統(tǒng)一用一套參數(shù)會犧牲不少效果。2.3 向量化模型和向量庫的選擇向量化是把文本變成一串數(shù)字語義相近的文本在數(shù)字空間里也相近。我們對比過幾款主流的Embedding模型包括當時很火的開源中文模型最后選了一個中文效果穩(wěn)定、維度適中比如768維、支持私有化部署的模型。為什么強調(diào)中文效果因為客服場景大量問法口語化比如“我買完咋不能用了”和“購買后無法使用”其實是同一個意思英文語料訓練出來的模型對這種口語化表達的理解明顯弱一些。向量數(shù)據(jù)庫方面我們從Chroma起步做原型驗證后來遷移到了Milvus。如果是個人項目或者團隊數(shù)據(jù)量在百萬條以下Chroma、SQLite-Vec、Qdrant都能對付數(shù)據(jù)量上來了、需要高并發(fā)檢索和動態(tài)過濾Milvus這類分布式向量庫會省心很多。不過向量庫的選擇不要早期就糾結(jié)先跑通全鏈路再說。插入一條實戰(zhàn)心得向量化后的數(shù)據(jù)建議把原文、來源鏈接、業(yè)務(wù)分類ID一起存進元數(shù)據(jù)字段。這樣后續(xù)做“引用溯源”非常方便用戶收到回答時能看到依據(jù)也能快速回溯是哪條知識出了問題。3. 檢索與生成核心鏈路搭建3.1 別迷信純向量檢索混合檢索更穩(wěn)一開始我們天真地以為向量檢索能解決所有匹配問題。測了幾輪發(fā)現(xiàn)向量檢索對“語義相似但表達完全不同”的問題確實強比如“賬號被盜怎么辦”和“我的號好像被登了”能匹配上但它對“精確關(guān)鍵詞”不夠敏感比如用戶問“iOS 17.2 無法登錄”如果知識庫里只有“IOS系統(tǒng)登錄異?!边@種泛化表述向量檢索的得分會被拉低而純關(guān)鍵詞檢索卻能輕松命中。所以最終用了混合檢索向量檢索負責語義擴展BM25關(guān)鍵詞檢索負責精確匹配兩邊結(jié)果做融合再一起送進重排模型。融合策略可以簡單粗暴向量檢索召回Top50BM25召回Top50去重后按融合分數(shù)取Top10。融合分數(shù)一般是加權(quán)相加權(quán)重根據(jù)實際效果調(diào)整我們用的比例大約向量0.6、關(guān)鍵詞0.4。重排環(huán)節(jié)是效果提升的隱藏神器。我們先用粗排召回幾十條候選再用一個重排序模型也可用大模型本身做rerank但成本高一些對這些候選做精排最后只取Top3到Top5喂給生成模型。這么做最大的收益是把真正相關(guān)的內(nèi)容頂?shù)角懊姘涯切八葡嚓P(guān)實無關(guān)”的片段壓下去。實際體驗下來重排之后回答準確率有明顯提升強烈建議不要省這一步。3.2 提示詞工程讓模型“基于材料回答”很多人以為提示詞只是寫幾句話其實它是整個系統(tǒng)里唯一能直接駕馭模型行為的地方值得反復打磨。我們的系統(tǒng)提示詞大概壓了這幾個要求角色設(shè)定你是某平臺的智能客服助手需要禮貌、簡潔、準確地回答用戶問題。知識限定只能依據(jù)“參考資料”里的內(nèi)容回答參考資料不夠時明確說明“未找到相關(guān)信息”絕不編造。格式要求先給出結(jié)論性回答再列出操作步驟或原因必要時用編號列表。溯源要求回答末尾附上參考文檔標題方便用戶和客服核對。這里給一個實際用過的Prompt結(jié)構(gòu)示例你是[某內(nèi)容平臺]的智能客服助手。請嚴格依據(jù)下方給出的參考資料回答用戶的問題。 要求 1. 如果參考資料包含答案請直接給出準確、完整的回答可結(jié)合多個片段綜合整理。 2. 如果參考資料不包含答案請回復“抱歉這個問題我還無法準確回答可以轉(zhuǎn)人工處理”不要自行推測。 3. 回答要口語化、清晰步驟可用編號列出。 4. 回答結(jié)束后換行用“參考文檔”列出引用到的資料標題。 參考資料 {retrieved_chunks} 用戶問題{question} 歷史對話{chat_history}注意我把歷史對話放在最下面而不是跟參考資料混在一起是為了讓模型區(qū)分“用戶說了什么”和“文檔說了什么”。系統(tǒng)提示詞每次請求都會帶上檢索到的片段直接填進占位符。這里有一個真實踩過的坑如果你把“如果不知道就回答不知道”送給大模型它確實會照做但有時候會過度保守——明明資料里有答案它卻因為表達方式不完全匹配而選擇了“不知道”。解決辦法是提示詞里加上一句“參考資料和問題可能并非完全字面匹配請結(jié)合語義判斷是否包含答案”模型的理解力足夠處理這個約束。3.3 上下文管理與流式輸出客服對話不是一問一答就結(jié)束用戶經(jīng)常追問“那如何退款呢”“電腦端也能操作嗎”所以我們必須管理多輪上下文。多輪對話的典型問題是上下文爆炸。我們早期把全部歷史對話都塞進請求很快就把上下文窗口撐滿了而且模型容易被早期閑聊帶偏。后來改成策略性截斷只保留最近三到五輪同時在每輪前判斷當前用戶問題是否需要歷史信息。比如用戶說“好的謝謝”我們就知道這是結(jié)束語不需要帶入歷史用戶說“那怎么操作呢”代詞“那”明顯指向上一輪的話題必須帶上歷史。這里有個小技巧做一問一答時我們在檢索前會把“多輪問題”改寫成一個“獨立問題”比如“那怎么操作”改寫成“會員在另一臺設(shè)備上登錄怎么操作”改寫后的查詢再去檢索命中率會提升不少。流式輸出這塊我建議直接把大模型API的流式返回接到前端??头鼍袄锶绻脩粢壬?0秒鐘才看到一整段文字體驗會差很多。逐字輸出能制造“正在思考”的錯覺而且用戶可以邊看邊判斷要不要打斷。后端用SSEServer-Sent Events把增量token推到前端代碼并不復雜。4. 效果評估與持續(xù)優(yōu)化4.1 怎么評價客服回答質(zhì)量智能客服上線前團隊內(nèi)部對“什么是好的回答”爭論了很久。有人說回答正確就行有人說用戶滿意度更重要但我們很快意識到正確率是最底層的及格線用戶感知到的“服務(wù)質(zhì)量”還包含響應速度、語氣、是否有耐心、是否給出了后續(xù)操作路徑。最后我們定了一套組合評估維度準確性回答內(nèi)容是否與標準答案一致是否存在知識性錯誤。完整性用戶問題的各個子需求是否都被覆蓋。友好度語氣是否自然有沒有冷冰冰的機器感??刹僮餍圆僮鞑襟E是否清晰用戶看了是否知道下一步做什么。合規(guī)性是否出現(xiàn)不該說的敏感內(nèi)容或過度承諾。線上監(jiān)控主要看四個指標首次解決率用戶問完一個問題后沒再追問、轉(zhuǎn)人工率、用戶點贊點踩率、平均響應時長。我們每周拉一次數(shù)據(jù)轉(zhuǎn)人工率從初期的接近五成逐步降到了兩成出頭這個下降趨勢就是系統(tǒng)優(yōu)化的方向標。4.2 離線評測集怎么搭才知道效果好壞優(yōu)化過程中最怕的事情是“感覺變好了但說不清哪里變好”。所以在項目初期我們就從歷史工單里抽了300條真實問題人工寫好標準答案做成固定評測集。每次修改提示詞或者換模型都用同一套評測集跑一遍對比前后效果。評測集的設(shè)計有幾個細節(jié)覆蓋高頻問題也要包含10%左右的低頻、刁鉆問題防止系統(tǒng)只會做高頻。每個問題標注難度等級和所屬業(yè)務(wù)分類方便看薄弱環(huán)節(jié)。部分問題設(shè)計成開放式的沒有唯一答案評測時判斷“是否合理、是否提到了關(guān)鍵點”。評測集里的問題定期擴充尤其是把線上新增的、用戶問得多但系統(tǒng)答不好的問題加進去。我們跑評測的方式是批量調(diào)用接口把回答保存下來然后人工逐條打分。這個過程很枯燥但非常必要。后來我們嘗試過用大模型當自動裁判跟人工評分的重合度大概在80%左右只能做初篩最終仍以人工為準。為了讓評測更高效我們把打分維度簡化成三個等級好可以直接對外展示、中方向?qū)Φ强梢愿?、差錯誤或答非所問。這樣兩個人分別打分不一致的地方拿出來討論很快就知道短板在哪里。4.3 三個有代表性的優(yōu)化案例舉三個我們在優(yōu)化過程中遇到的真實案例可能對你有啟發(fā)。第一個是關(guān)于“口語化問法”的問題。用戶問“我昨天買的東西怎么還沒發(fā)”知識庫里只有“發(fā)貨時效說明”向量檢索能關(guān)聯(lián)上一些但回答很生硬直接貼了規(guī)則原文。我們通過提示詞加了引導“請結(jié)合用戶提到的場景如已購買/未發(fā)貨給出針對性回答”然后模型就會先識別“已購買未發(fā)貨”的場景組織出更有人情味的回復。第二個是關(guān)于“多問題復合”的問題。用戶問“我誤購了年度會員能退嗎退款多久到賬”這是一個知識庫片段無法回答的復合問題。我們的解法是在檢索前做一次問題拆分先用大模型判斷是否包含多個子問題如果是就把子問題拆開分別檢索再合并結(jié)果一起送給生成模型。這個功能上線后復合問題的答非所問率顯著下降。第三個是關(guān)于“用戶情緒”的問題。用戶帶著情緒咨詢“你們的會員也太坑了吧我要退錢”直接給標準規(guī)則回答會讓用戶火上澆油。我們在提示詞里加了“如果用戶表達不滿先表達理解與安撫再給出解決方案”的規(guī)則實測轉(zhuǎn)人工率下降的同時用戶好評率反而提升了。這就是把“擬人化”落實到提示詞層面的價值。5. 常見問題排查與避坑記錄5.1 檢索側(cè)召回結(jié)果不對答案當然錯如果你遇到“該答對的答不對答非所問”大概率問題在檢索側(cè)而不在生成側(cè)。我們排查檢索效果時先單獨看檢索鏈路把用戶問題輸入檢索模塊人工判斷召回的Top3片段是不是真的相關(guān)。如果片段不相關(guān)大模型再聰明也沒用。典型的“召回不中”原因有這幾類用戶問題太口語化或夾雜錯別字原始查詢向量化效果差。對策是做一個查詢改寫模塊先把口語轉(zhuǎn)書面語再做檢索。知識庫切片太小檢索到的片段只包含部分信息不足以支撐完整回答。對策是適當增大切片重疊窗口。關(guān)鍵詞檢索和向量檢索的結(jié)果沒有很好融合導致某一路的強信號被淹沒。對策是調(diào)融合權(quán)重或者用RRFReciprocal Rank Fusion這種簡單有效的方式融合。排查時有一個好習慣把所有檢索結(jié)果都打到日志里。用戶問什么、召回了哪些片段、每個片段多少分、最終選了哪幾個全都記錄下來。出了問題直接翻日志五分鐘定位到是檢索還是生成的問題。5.2 生成側(cè)幻覺是怎么一步步壓下去的大模型幻覺是智能客服系統(tǒng)最頭疼的問題。我們試過很多方法最有效的是下面這幾條組合拳。第一知識約束。提示詞里明確說“只能依據(jù)參考資料回答”并且不是簡單說一句而是反復強調(diào)“如果資料沒有相關(guān)內(nèi)容必須說不知道”。這條最基礎(chǔ)也最重要。第二引用溯源。要求模型在回答末尾標注引用的文檔標題。這樣做倒不完全是給用戶看的而是給審核人員看的。一旦某一批回答被點踩我們能馬上追溯到是哪份文檔的問題而不是把鍋都甩給模型。第三低置信度攔截。我們對生成結(jié)果做一個后置校驗如果檢索到的片段跟問題的相關(guān)性得分都很低寧可讓系統(tǒng)轉(zhuǎn)人工也不要硬答。這個“寧可不說”的策略對用戶體驗的提升非常明顯。早期我們追求回答率什么都要回答結(jié)果錯誤答案滿天飛后來改成低分拒答總體滿意度反而上來了。第四定期知識庫審計。業(yè)務(wù)規(guī)則更新后舊知識不撤就會出現(xiàn)新舊口徑打架的情況。我們每個月做一次知識庫清理并且把元數(shù)據(jù)里的“生效時間”字段用起來檢索時過濾掉失效文檔。5.3 工程側(cè)并發(fā)、延遲與穩(wěn)定性上線初期我們遇到過一次線上事故活動期間咨詢量突增調(diào)用大模型API的并發(fā)飆升直接打滿了后端的連接池導致大量請求超時。后來做了三件事一是異步化處理。用戶請求進來先返回“正在排隊”的提示后臺排隊調(diào)用模型完成后通過WebSocket推送結(jié)果。這個方案犧牲了一點實時性但大大緩解了壓力。二是緩存復用。高頻、重復的問題比如“怎么改密碼”答案基本是穩(wěn)定的我們在Redis里做了一層緩存命中緩存的請求根本不調(diào)用大模型既省錢又快。三是降級方案。如果大模型API連續(xù)失敗或超時系統(tǒng)直接推薦“轉(zhuǎn)人工”而不是給用戶一個空白頁面。流式輸出也帶來一個問題客戶端連接中途斷開后端還在生成怎么辦。我們用了一個簡單的信號機制前端斷開時通知后端取消生成任務(wù)避免白白消耗token。穩(wěn)定性的核心就一句話大模型是系統(tǒng)的一個組件不是上帝的化身。所有依賴大模型的環(huán)節(jié)都要有降級預案否則它一次抽搐客服系統(tǒng)就全癱。5.4 上下文會話管理中的“記憶丟失”還有一個經(jīng)常被忽視的細節(jié)用戶在多輪對話中途去查了一下網(wǎng)頁回來繼續(xù)聊這時系統(tǒng)如何理解上下文我們的做法是給每個會話窗口設(shè)置一個有效期比如30分鐘內(nèi)有連續(xù)對話則視為同一會話超過30分鐘則開啟新會話。這個功能看起來簡單但能避免很多會話串臺導致的問題。另外一個實際場景是“打斷式追問”——用戶先問會員價格又追加“那學生有沒有優(yōu)惠”。我們的上下文改寫模塊會把“學生有沒有優(yōu)惠”補全為“學生購買會員有沒有優(yōu)惠”然后單獨檢索再結(jié)合上一輪的會員價格信息一起回答。這里的經(jīng)驗是改寫后的獨立問題不僅用于檢索最好也展示給用戶看比如“為您查詢學生購買會員優(yōu)惠問題”讓用戶知道系統(tǒng)理解對了有助于建立信任感。6. 寫在最后的體會做完這個“AI大模型之旅——智能客服實戰(zhàn)”我最深的體會是大模型項目真正的技術(shù)壁壘不在于模型本身而在于你如何把業(yè)務(wù)知識喂給模型如何約束模型不說錯話如何評估效果并持續(xù)改進。我們踩過不少坑最核心的幾個建議濃縮如下先做好數(shù)據(jù)清洗和切片再談模型選型知識庫的底子決定效果上限。檢索鏈路不要省混合檢索加精排比單純換更大的模型效果提升更明顯。提示詞要像產(chǎn)品需求文檔一樣迭代每次只改一個變量用評測集驗證效果。對不確定的問題讓系統(tǒng)學會“認慫”轉(zhuǎn)人工比硬答更被用戶認可。上線前一定要做好降級方案大模型接口的抖動你是控制不了的但你的系統(tǒng)可以兜底。如果你也要做類似的項目不用追求一開始就搞一個多龐大的系統(tǒng)。先把一條最小鏈路跑通取50條真實問題、搭一個簡單的向量索引、調(diào)用模型接口、自己手動測二十個問題感受一下哪里別扭再逐步添磚加瓦。這條路我們已經(jīng)替你走通了你按著這個節(jié)奏來大概率能做得比我們更快。