
RAG 系統上線后最常被吐槽的是檢索不準。明明知識庫里有答案用戶換一種口語化問法向量檢索卻召回一堆無關段落大模型只能基于錯誤上下文硬答于是“答非所問”“回答不專業”就都來了。問題往往出在 Embedding 模型的能力邊界而不是生成模型本身不聰明。面向 2026 年RAG 優化已經不只是調切塊長度或換個大模型。越來越多團隊開始走同一條路線借助 Qwen3 構造高質量訓練數據對 Embedding 模型做領域微調讓向量檢索更貼近真實業務語言最終讓大模型回答更專業。這篇博客會把這條鏈路拆開講清楚RAG 為什么檢索不準、Embedding 微調的基本原理、Qwen3 在數據生成和難負樣本構造里的角色、訓練代碼怎么寫、接入 Milvus 和 LlamaIndex 時要注意什么、上線后效果怎么評估以及生產落地上最容易踩的坑。1. 先理解 RAG 檢索不準的根因再決定要不要微調 Embedding1.1 檢索不準往往不是“模型笨”而是“召回偏了”RAG 的完整鏈路通常分三塊知識庫切塊、文本向量化、向量檢索與排序。大多數團隊投入精力最少、出錯卻最多的是中間那塊 Embedding。Embedding 模型做的事情是把一段文本壓縮成一個向量讓語義相近的文本在向量空間里距離更近。例如“怎么申請工傷認定”和“工傷認定申請流程”應該是近鄰而“工傷鑒定標準”雖然包含“工傷”兩個字卻不應在用戶問流程時排在前面。問題在于通用 Embedding 模型是在互聯網開放語料上訓練的它擅長處理“通用語言”但面對一個行業的簡稱、系統名稱、產品術語、客服話術、中英混排、業務單據編號時向量空間的分布可能完全不對。觀察下面這種典型 badcase用戶 Query檢索結果是期望結果我們公司發票沖紅后稅號會變嗎發票管理辦法關于紅字發票的規定本項目發票沖紅的具體操作指南XX 系統登錄報 5001 錯誤怎么辦系統使用手冊目錄XX 系統 5001 錯誤碼說明如果把這兩組 Query 和文檔片段丟給通用 Embedding 模型會發現相似度分數往往沒有明顯區分度。問題不是切塊沒切好而是模型根本不知道“5001 錯誤碼”在這個系統里等價于“登錄鑒權失敗”。1.2 通用 Embedding 模型的“領域盲區”長什么樣行業內比較常見的開源 Embedding 模型包括 BGE 系列、BGE-M3、GTE 系列、M3E 等。它們在中英文通用檢索任務上表現很好但一進垂直領域就會暴露幾個問題。第一專業術語語義稀疏。比如“貨描不符”“質保單”“T0 回款”這些詞在訓練語料里出現頻次不高模型很容易把它們當成普通詞語處理向量表征不夠穩定。第二口語化和反問句式泛化弱。RAG 系統的真實用戶不會按照文檔目錄說話他們經常輸入“這個單子咋走流程”“為什么不能提現”和正式文檔的語言風格差異很大。第三同義詞和縮寫關聯弱。“結算單”和“Settlement Note”“結算憑證”在業務里可能指向同一類文件但通用模型不一定能建立這種等價關系。用戶搜索“qwen3 embedding 微調”時看到的很多教程本質上都是在解決這類“領域盲區”。如果只是換一個更大的通用模型通常只能緩解問題不能根治。要讓檢索真正貼近業務就要讓 Embedding 模型見過業務數據并針對業務 Query 和文檔做過對比學習。1.3 什么時候該微調什么時候先不要動 Embedding微調 Embedding 不是 RAG 優化的第一步甚至不是第二步。在投入 GPU 訓練之前可以按下面順序排查。排查項檢查方式如果存在問題切塊粒度查看召回文檔是否在中間截斷調整 chunk_size / overlap或按標題、段落結構切塊元數據過濾是否能用業務字段排除明顯無關文檔增加創建時間、部門、文檔類型等過濾條件Query 改寫用戶原問是否太口語化、太短用大模型把 Query 改寫成標準檢索詞再走向量檢索Rerank 模型召回 top50 后是否仍然把錯誤文檔排在前面加入專門的 Rerank 模型做精排Embedding 領域適配上述手段都做過后 badcase 仍重復出現再考慮微調 Embedding 模型換句話說微調 Embedding 適合在“檢索鏈路已經比較完整、但深層語義匹配能力不足”的階段啟動。它的前置條件有三個一是有一個可重復復現的 badcase 集合二是有辦法評估召回效果不靠肉眼感覺三是有能力構造一批覆蓋業務場景的訓練數據。如果知識庫總共只有幾百個文檔檢索效果差主要因為切塊太粗或者沒有元數據過濾那么先優化這些環節性價比更高。2. 微調 Embedding 的原理對比學習、難負樣本和 Qwen3 的定位2.1 Embedding 模型訓練的本質是“拉近正例推開負例”Embedding 模型本身不是被“教”出所有業務知識的它是在一個表示學習任務上被優化的。微調時我們不再訓練模型回復一句話而是訓練它把 Query 和對應的文檔片段映射到同一個向量空間中的相近位置。最常用的訓練目標是對比學習損失例如 InfoNCE。核心思想是給一個 Query讓模型優化相似度使得它和正確文檔的距離更近同時和一批錯誤文檔的距離更遠。假設一個 batch 里有 N 個 Query對應的正文檔是同一個 batch 里的 N 個文檔那么可以構造 N×N 的相似度矩陣對角線是正樣本其余位置是負樣本。MultipleNegativesRankingLoss 就是這么工作的。一個簡單理解score(query_i, positive_i) - 盡量高 score(query_i, negative_j) - 盡量低2.2 難負樣本比正樣本更影響微調效果很多人第一次構造 Embedding 訓練集會在每個 Query 后面配一個正確文檔、一個隨機文檔然后開始訓練。等訓練完上線發現效果幾乎沒變。原因很簡單隨機文檔和 Query 大多完全不相關模型很容易把它們分開訓練信號很弱。真正需要訓練的是“看起來相關、實際不對”的難負樣本。舉個例子Query發票沖紅后購買方還能抵扣嗎正樣本發票沖紅操作指南里關于購買方抵扣的相關段落難負樣本發票開具流程里關于“紅字發票信息表”的段落難負樣本包含“發票”“沖紅”“抵扣”等多個關鍵詞向量上離 Query 很近但語義和用戶問的不是一回事。只有把這種樣本作為負例壓下去模型才學會區分“操作流程”和“概念解釋”。這是為什么微調 Embedding 必須有一個質量較高的負樣本構造環節而不能只在文件系統里隨機抽幾個文件當負樣本。2.3 Qwen3 在這條鏈路里的真實角色標題里寫“通過 Qwen3 對 Embedding 進行訓練微調”容易讓人誤以為直接把 Qwen3 結構拿來當向量模型訓練。這里必須澄清一下技術定位。Qwen3 是生成式大模型它的輸出是文本不是文本向量。當前更穩妥、也更常見的做法是用 Qwen3 生成領域 Query把“文檔段落”轉成“用戶可能會問的問題”用 Qwen3 把這些 Query 和候選文檔做相關性打分找出“分數高但實際不相關”的難負樣本用 Qwen3 改寫 Query制造更多表達方式不同、語義相同的正樣本用 Qwen3 檢查訓練數據質量去掉噪聲樣本。也就是說Qwen3 是在“數據生產”和“數據清洗”環節起作用真正被微調的對象是專用 Embedding 模型比如 BGE-M3、bge-large-zh、GTE 等。如果團隊非要用 Qwen 系列模型做 Embedding也不是不行需要自己接 pooling 層和相似度目標對比訓練成本和難度都會明顯上升。對于大多數 RAG 項目更理性的選擇是用 Qwen3 生成數據 微調輕量專用 Embedding 模型這樣訓練成本低、上線快、維護也容易。3. 用 Qwen3 構造高質量 Embedding 微調數據集3.1 先設計統一數據格式微調 Embedding 的數據集一般使用 JSONL 格式每行一個訓練樣本。常見結構是帶一個正樣本和多個負樣本{ query: 發票沖紅后購買方還能抵扣嗎, positive: 購買方取得紅字發票信息表后可在增值稅發票綜合服務平臺上進行相應抵扣處理具體以當地稅務機關要求為準。, negatives: [ 發票開具流程中銷售方需在開票系統內填開紅字發票信息表并上傳。, 普通發票丟失后如何處理納稅人應當向稅務機關報告。 ] }推薦把訓練數據寫成這種格式而不是只用 query-positive 二元組。因為一條 Query 配多個負樣本訓練效率更高模型也能更快學會區分“業務概念”和“業務操作”。3.2 用 Qwen3 從文檔段落生成用戶 Query數據構造的第一步是把知識庫文檔的每個段落變成一個或多個用戶 Query。可以調用 Qwen3 的 OpenAI 兼容接口也可以在本機用 vLLM 部署 Qwen3 后按相同接口調用。下面是一個用于生成 Query 的 Prompt 示例你是知識庫檢索訓練數據的構造助手。 我會給你一段文檔內容請你模擬真實用戶生成 5 個不同角度的檢索 Query。 要求 1. Query 必須是用戶會直接輸入的真實問法避免照抄原文措辭。 2. 至少包含 2 個口語化或短問法。 3. 不要生成與這段內容語義偏差過大的問題。 4. 輸出格式為 JSON 數組每個元素是一個字符串。 文檔內容 {chunk_text}對應的 Python 調用示例import json import openai client openai.OpenAI( base_urlhttp://your-qwen3-server:8000/v1, api_keyEMPTY ) def generate_queries(chunk_text: str) - list[str]: prompt f你是知識庫檢索訓練數據的構造助手。 我會給你一段文檔內容請你模擬真實用戶生成 5 個不同角度的檢索 Query。 要求 1. Query 必須是用戶會直接輸入的真實問法避免照抄原文措辭。 2. 至少包含 2 個口語化或短問法。 3. 不要生成與這段內容語義偏差過大的問題。 4. 輸出格式為 JSON 數組每個元素是一個字符串。 文檔內容 {chunk_text} resp client.chat.completions.create( modelqwen3, messages[{role: user, content: prompt}], temperature0.7, max_tokens512, ) content resp.choices[0].message.content content content.replace(json, ).replace(, ).strip() return json.loads(content)調用時需要注意真實用戶 Query 和文檔原文的措辭差異越大對 Embedding 微調的收益越高。如果 Qwen3 生成的問題基本都是照抄文檔里的句子那訓練數據對檢索沒有增量價值。3.3 構造難負樣本從批量召回結果里篩選構造難負樣本最實用的方法是“用當前 Embedding 模型先跑一遍檢索然后讓 Qwen3 判斷相關性”。具體流程對每一條 Query用當前線上 Embedding 模型從知識庫召回 top 20 個文檔片段。把這 20 個片段中相似度分數較高、但在業務上不代表正確答案的片段挑出來。讓 Qwen3 逐條判斷“這個片段是否確實回答了 Query”給出 0 或 1 標簽。標簽為 0、但向量相似度靠前的片段作為難負樣本加入訓練集。這個流程比隨機負樣本有效因為模型“錯得最厲害”的地方正是它需要被糾正的地方。Prompt 示例請判斷下面的文檔片段能否回答用戶問題。只能回答 0 或 1。 用戶問題 {query} 文檔片段 {chunk_text} 能否回答批量處理時要注意并發限制和請求失敗重試。比如本地部署 Qwen3 時如果接口偶爾超時可以加上重試邏輯并把結果記錄到單獨的日志文件里方便后續排查數據質量問題。3.4 數據清洗和人工抽驗不要拿到 Qwen3 生成結果就直接訓練。常見問題包括Query 和 positive 完全不匹配模型學不到有效信號negative 實際上也回答了 Query造成標簽噪聲多條 Query 完全重復導致模型過擬合到某一種表達文檔片段過長或過短超過模型 max_len 限制訓練時被截斷。建議先做一輪自動化清洗腳本def filter_sample(sample, min_len10, max_len512): q_len len(sample[query]) p_len len(sample[positive]) if q_len min_len or p_len min_len: return False if p_len max_len * 3: return False if sample[query] in sample[positive]: return False return True然后抽出 5% 到 10% 的樣本人工判斷標簽是否合理。如果人工抽驗的準確率低于 90%建議重新調整 Qwen3 的 Prompt而不是直接擴大數據量。數據規模上Embedding 微調的最小有效集通常在幾千條左右。先保證 2000 到 5000 條高質量樣本比一次生成 5 萬條低質量樣本更有效。4. 選擇開源 Embedding 模型和訓練環境4.1 可微調的 Embedding 模型選型不是所有 Embedding 模型都適合微調。使用云廠商 API 的 Embedding 模型通常不開放權重只能通過官方接口調用無法針對業務數據做訓練。要微調必須選擇開源權重模型。常見可選模型如下模型特點適合場景注意點BGE-M3支持多語言、長文本、多粒度檢索中英文混合知識庫、長文檔 RAG參數較多訓練顯存相對高bge-large-zh中文效果穩定社區資料多中文業務知識庫需注意 query 指令前綴bge-base-zh參數少訓練快數據量不大、端側場景效果上限低于 largeGTE 系列部分模型支持中英和多任務需要統一向量模型的場景需確認授權和版本M3E中文效果不錯部署簡單中文知識庫快速驗證遇到復雜語義邊界時可能要換模型推薦第一次做 Embedding 微調時選擇 BGE 系列或 BGE-M3。它們有兩個優勢一是社區案例多排錯資料容易找二是官方模型通常配套了推薦的指令格式訓練和推理時不容易踩配置坑。另外要確認模型版本。不同版本的 Embedding 模型輸出維度不同如果后續要遷移已經建好的向量庫需要特別注意維度是否能對上。4.2 訓練框架和依賴準備Embedding 微調可以用三種方式實現sentence-transformers 庫適合快速跑通最小實驗FlagEmbedding 庫BGE 官方微調工具適合深度定制和難負樣本訓練直接用 transformers 自定義 loss適合徹底控制訓練流程。為了快速跑通推薦先用 sentence-transformers。安裝命令pip install -U sentence-transformers pip install torch --index-url https://download.pytorch.org/whl/cu121如果要用 FlagEmbedding還需要額外安裝依賴。實際項目里要注意 PyTorch、CUDA、transformers 之間的版本兼容不要照抄教程里的版本號先在當前環境驗證一次。4.3 訓練超參數和顯存控制Embedding 模型的參數量比 Qwen3 這類生成模型小很多訓練門檻相對低。但“全參訓練”和“LoRA 微調”的顯存差別仍然明顯。參數含義常見取值范圍設置建議learning_rate學習率2e-5 到 5e-5數據量小就偏低避免災難性遺忘batch_size每個 batch 的 Query 數量16 到 64顯存不足時優先減小 batch_sizemax_len文本最大長度256 到 1024根據知識庫 chunk 長度設置num_epochs訓練輪數1 到 5優先 2 輪過擬合很容易warmup_ratio預熱比例0.05 到 0.1穩定訓練初期 loss全參微調對 Embedding 模型來說通常可行但如果你只有一個 24G 顯存的 GPU又想訓練 BGE-M3 這類大模型建議用 LoRA。sentence-transformers 已經支持通過 PEFT 給 Embedding 模型加 LoRA 適配器訓練時先凍結主干參數只訓練低秩矩陣顯存占用會明顯下降。5. 微調訓練實戰用對比學習跑通最小案例5.1 用 sentence-transformers 訓練 MultipleNegativesRankingLoss這里以一個最小可運行腳本為例。假設訓練數據文件是train.jsonl每條數據包含query、positive、negatives三個字段。import json from sentence_transformers import SentenceTransformer, models, losses, InputExample from torch.utils.data import DataLoader from sentence_transformers.datasets import SentenceLabelDataset base_model BAAI/bge-base-zh-v1.5 word_embedding_model models.Transformer(base_model, max_seq_length512) pooling_model models.Pooling( word_embedding_model.get_word_embedding_dimension(), pooling_mode_cls_tokenTrue, pooling_mode_mean_tokensFalse, pooling_mode_max_tokensFalse, ) model SentenceTransformer(modules[word_embedding_model, pooling_model]) examples [] with open(train.jsonl, encodingutf-8) as f: for line in f: item json.loads(line) texts [item[query], item[positive]] item.get(negatives, []) examples.append(InputExample(textstexts)) train_dataloader DataLoader(examples, shuffleTrue, batch_size32) train_loss losses.MultipleNegativesRankingLoss(model) model.fit( train_objectives[(train_dataloader, train_loss)], epochs2, warmup_steps100, output_path./embedding_model_finetuned, save_best_modelTrue, )這段代碼的核心是MultipleNegativesRankingLoss。每個 InputExample 的第一條文本會被當成 Query第二條是正樣本后面的所有文本是負樣本。損失函數會盡量提高 Query 和正樣本的相似度同時降低它和負樣本的相似度。需要注意這里沒有給 Query 加指令前綴。如果模型是 BGE 系列官方推薦的推理方式是給 Query 加指令但訓練時是否加指令取決于數據構造方式。推薦做法是保持訓練和推理一致在訓練腳本里統一處理。5.2 使用 FlagEmbedding 訓練 BGE-M3 的另一種方式如果選擇 BGE-M3FlagEmbedding 提供了更直接的訓練接口。示例代碼from FlagEmbedding import FlagModel model FlagModel( BAAI/bge-m3, query_instruction_for_retrieval為這個句子生成表示以用于檢索相關文章, use_fp16True )FlagEmbedding 完整訓練腳本一般包含數據加載、損失計算、評估三個模塊。由于版本差異較大建議直接參考官方倉庫的examples/finetune/embedder目錄里面提供了帶難負樣本的訓練入口。這里不推薦把別人的訓練命令原樣復制到生產環境。必須先確認自己的模型名、數據格式、指令前綴和輸出維度再運行訓練。5.3 訓練日志怎么判斷是否正常訓練時主要觀察兩個信號。第一loss 是否在下降。MultipleNegativesRankingLoss最開始時通常會在 4 到 6 這個區間訓練一段時間后降到 1 以下。如果 loss 一直不降或者出現 NaN優先檢查數據里是否有超長文本、空文本以及學習率是否設置過高。第二離線檢索效果是否提升。loss 下降不代表檢索效果一定變好。建議在訓練腳本里加入一個小型 eval 集每次 checkpoint 后計算 Recall10。如果 loss 下降但 Recall 不漲可能負樣本太簡單或數據噪聲太多。訓練輸出的目錄里會保存模型權重和 tokenizer。加載微調后模型時要用同一個目錄不能混用原版模型和微調權重。from sentence_transformers import SentenceTransformer model SentenceTransformer(./embedding_model_finetuned) emb model.encode(發票沖紅后還能抵扣嗎, normalize_embeddingsTrue)6. 把微調后的 Embedding 接回 RAG 檢索鏈路6.1 全量重建向量庫這一步不能省微調后的模型和舊 Embedding 模型生成的向量分布不一致兩者不能在同一個向量索引里混用。上線前必須全量重建知識庫向量不能用“只對新增文檔生成向量”的方式做增量替換否則新舊向量之間距離比較沒有意義。重建流程從知識庫導出所有 chunk。用微調后的 Embedding 模型批量生成向量。將向量寫入新的 Collection 或新的向量索引。線上檢索流量切到新索引。保留舊索引至少一個版本便于回滾。批量生成向量時可以控制 batch size避免 GPU 顯存溢出from sentence_transformers import SentenceTransformer model SentenceTransformer(./embedding_model_finetuned) chunks [...] # 所有知識庫 chunk batch [] embeddings [] for chunk in chunks: batch.append(chunk) if len(batch) 64: vecs model.encode(batch, normalize_embeddingsTrue) embeddings.extend(vecs) batch [] if batch: vecs model.encode(batch, normalize_embeddingsTrue) embeddings.extend(vecs)6.2 寫入 Milvus 或本地 Faiss 索引以 Milvus 為例需要先創建 Collection并指定向量維度。BGE-M3 的維度是 1024bge-base-zh 是 768具體以模型輸出為準。from pymilvus import ( connections, CollectionSchema, FieldSchema, DataType, Collection ) connections.connect(host127.0.0.1, port19530) fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue), FieldSchema(nametext, dtypeDataType.VARCHAR, max_length8192), FieldSchema(namevector, dtypeDataType.FLOAT_VECTOR, dim1024), ] schema CollectionSchema(fields) collection Collection(qa_knowledge_new, schema) data [ list(range(len(chunks))), chunks, embeddings, ] collection.insert(data) collection.create_index(vector, {index_type: IVF_FLAT, metric_type: IP, params: {nlist: 1024}})檢索時要用同一種向量計算方式query_vec model.encode([query], normalize_embeddingsTrue)[0] result collection.search( data[query_vec.tolist()], anns_fieldvector, param{metric_type: IP, params: {nprobe: 16}}, limit20, output_fields[text], )6.3 在 LlamaIndex 中接入自定義 Embedding 模型如果用 LlamaIndex 搭 RAG接入自定義模型非常簡單from llama_index.core import Settings from llama_index.embeddings.huggingface import HuggingFaceEmbedding Settings.embed_model HuggingFaceEmbedding( model_name./embedding_model_finetuned, embed_batch_size64, )設置好后文檔索引和 Query 檢索都會使用同一個embed_model。這一步最容易踩的坑是索引文檔時用了微調后模型但 Query 檢索時誤用了默認模型導致查詢向量和文檔向量不在同一空間。6.4 不要丟掉 Rerank 環節微調 Embedding 能提高“正確文檔是否能進 top 20”的概率但不保證正確文檔一定排在第一位。生產級 RAG 仍然應該在向量召回后加一個 Rerank 模型對召回結果做精排序。推薦鏈路是Query - 向量召回 top50 - Rerank 精排 top5 - LLM 生成Embedding 微調和 Rerank 不是二選一。前者負責提高召回上限后者負責提高排序精度。兩者結合效果通常比只做其中一項更穩定。7. 效果評估與常見問題排查7.1 構造最小離線評估集評估集不需要很大但需要覆蓋真實用戶 Query。建議準備 200 到 500 條真實或近似真實的 Query并為每條 Query 標注 1 到 3 個正確文檔。常用指標指標說明計算方式RecallK正確文檔是否出現在前 K 條結果里命中數 / 總 Query 數MRR第一個正確結果所在排名的倒數按排名取倒數后求平均Hit Rate1第一條結果是否就是正確答案命中數 / 總 Query 數評估的時候要把微調前和微調后的模型分別跑同一批評估集保留結果。不要只憑“感覺變準了”就上線。7.2 微調后常見的失敗模式問題現象可能原因排查方式處理建議loss 下降但 Recall 不漲難負樣本太少或太簡單檢查訓練數據中每條 Query 的負樣本數量增加難負樣本構造邏輯上線后效果反而變差向量庫未全量重建確認新舊向量是否混用全量重建并校驗向量維度訓練時顯存不足batch_size 或 max_len 過大查看 GPU 顯存占用降低 batch_size改用 LoRA檢索時 Query 結果不對推理時和訓練時指令前綴不一致對比訓練和推理代碼統一指令前綴和預處理邏輯負樣本實際也是正確答案Qwen3 相關判斷不準人工抽驗負樣本標簽調整 Qwen3 打分 Prompt 或加入人工復核微調后通用能力下降訓練數據過于單一觀察泛化指標混入一定比例通用檢索數據7.3 上線前回歸清單上線前建議按下面清單逐項檢查[ ] 訓練數據和評估集是否分開評估集里沒有出現訓練數據[ ] Qwen3 生成的 Query 是否覆蓋了真實用戶高頻問法[ ] 負樣本是否包含至少一部分“向量相似但語義無關”的難負樣本[ ] 訓練腳本中 query 指令和推理腳本中 query 指令是否一致[ ] 微調后模型輸出維度是否和原始模型一致[ ] 向量庫是否全量重建舊索引是否可回滾[ ] 離線評估指標是否記錄并對比過基線[ ] 是否保留了原 Embedding 模型和原向量索引方便快速回滾。8. 生產環境落地建議微調不是唯一的優化手段8.1 建議的優化順序在團隊資源有限的情況下RAG 優化順序可以按下面排列先治理知識庫切塊和元數據加入 Query 改寫解決用戶口語化和指代不清引入 Rerank 模型把 top50 變 top5收集真實 badcase分析檢索失敗原因再用 Qwen3 構造數據微調 Embedding 模型。這套順序的核心是先用成本低、見效快的手段把明顯問題解決掉再通過微調處理更深層的語義匹配問題。如果一開始就啟動 Embedding 微調很容易把切塊錯誤、元數據缺失的問題也歸因到模型上導致訓練數據很臟最終效果也不穩定。8.2 建立數據回流和定期重訓機制Embedding 微調不是一次性的。業務新名詞不斷出現用戶提問方式也在變化訓練數據需要持續更新。生產環境可以設計一個小閉環從線上日志采集“低分但用戶點擊/反饋有用的 Query”把用戶反饋和 badcase 匯總到標注隊列每兩周或每月用 Qwen3 補充新 Query 和新難負樣本重新訓練 Embedding 模型并跑離線評估評估通過后全量重建向量庫并灰度上線。這里的難點是“自動判斷用戶是否滿意”。如果沒有顯式反饋可以用業務指標兜底例如搜索無結果率、同一會話的再提問次數等。8.3 成本控制和 LoRA 選擇Embedding 模型訓練成本通常遠低于生成模型。但如果知識庫很大向量重建的推理成本會比訓練成本更高。因此訓練前要預估 GPU 總時長訓練后做一次“向量重建成本”評估。LoRA 微調在 Embedding 模型上的收益沒有大語言模型那么夸張因為 Embedding 模型的參數量本來就小。但對于 BGE-M3 這類 5 億參數以上的模型LoRA 仍然是顯存不足時的首選。選擇 LoRA 時要關注訓練后是否能導出合并權重避免推理時額外依賴適配器加載邏輯。8.4 再往前走Rerank、Agentic RAG 和圖譜增強Embedding 微調只是 RAG 優化的一個環節。當檢索召回率已經穩定可以考慮下一步用領域數據微調一個小的 Rerank 模型替代通用 Rerank引入 Agentic RAG讓模型根據用戶意圖主動選擇多路檢索在知識庫中補充實體關系圖譜處理“實體關系型問題”對多輪對話場景增加 Query 改寫和歷史上下文壓縮。這些方向都需要先有“穩定可評估的檢索鏈路”作為基座。Embedding 微調的真正價值是讓基座更貼近業務而不是替代其他優化模塊。最后給新手的練習建議不要一上來就微調一個大模型先用一個小型中文知識庫構造 2000 條數據微調 bge-base-zh并在 Milvus 里對比微調前后 Recall10。這個閉環跑通后再逐步加深對難負樣本、LoRA、Rerank 和數據回流的理解會比直接堆模塊更有效。