偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

企業(yè)級(jí) RAG 系統(tǒng)實(shí)戰(zhàn):10 個(gè)項(xiàng)目踩過的坑(附代碼工程示例)

人工智能
從這篇開始,我會(huì)把日常閑暇時(shí)觀摩的一些海外優(yōu)質(zhì)內(nèi)容整理和加工后,附上自己的不同觀察和思考也通過文章或者視頻的形式發(fā)布出來,給各位做個(gè)參考。主要聚焦在 Reddit、Medium、X、Youtube 等平臺(tái)。這篇就以 Reddit 上 r/AI_Agents 中一個(gè)月前發(fā)布的一篇有 905 upvotes 的帖子做個(gè)翻譯整理。

25 年以來寫了 55 篇技術(shù) Blog,字?jǐn)?shù)也累計(jì)超過 50 萬字。每篇內(nèi)容背后都是幾十甚至上百個(gè)小時(shí)的項(xiàng)目工程實(shí)踐的經(jīng)驗(yàn)提煉,雖然原創(chuàng)性沒話說,但還是產(chǎn)出效率太低,以及也難免受限于個(gè)人的經(jīng)驗(yàn)和水平。

So,從這篇開始,我會(huì)把日常閑暇時(shí)觀摩的一些海外優(yōu)質(zhì)內(nèi)容整理和加工后,附上自己的不同觀察和思考也通過文章或者視頻的形式發(fā)布出來,給各位做個(gè)參考。主要聚焦在 Reddit、Medium、X、Youtube 等平臺(tái)。這篇就以 Reddit 上 r/AI_Agents 中一個(gè)月前發(fā)布的一篇有 905 upvotes 的帖子做個(gè)翻譯整理。

圖片

Blog 原地址:https://www.reddit.com/r/AI_Agents/comments/1nbrm95/building_rag_systems_at_enterprise_scale_20k_docs/ 

這篇試圖說清楚:

原帖的中文翻譯(人話版)、原帖中四個(gè)工程要點(diǎn)的代碼示例及實(shí)際應(yīng)用建議、以及帖子評(píng)論區(qū)精華部分的內(nèi)容節(jié)選。

以下,enjoy:

1、原帖子翻譯

企業(yè)級(jí) RAG 系統(tǒng)實(shí)戰(zhàn)(2萬+文檔):10 個(gè)項(xiàng)目踩過的坑

原文來自 Reddit,作者在受監(jiān)管行業(yè)(制藥、金融、法律)為中型企業(yè)(100-1000 人)構(gòu)建了 10+ 個(gè) RAG 系統(tǒng)

過去一年我一直在做企業(yè)級(jí) RAG 系統(tǒng),服務(wù)的客戶包括制藥公司、銀行、律所、咨詢公司。說實(shí)話,這玩意兒比任何教程說的都難太多了。我想分享一些真正重要的東西,而不是網(wǎng)上那些基礎(chǔ)教程。

先說背景:這些公司手里都有 1 萬到 5 萬份文檔,堆在 SharePoint 或者 2005 年的文檔管理系統(tǒng)里。不是什么精心整理的數(shù)據(jù)集,也不是知識(shí)庫(kù)——就是幾十年積累下來的業(yè)務(wù)文檔,現(xiàn)在需要能被搜索到。

1.1文檔質(zhì)量檢測(cè):沒人說的關(guān)鍵環(huán)節(jié)

這是我最大的發(fā)現(xiàn)。大多數(shù)教程都假設(shè)你的 PDF 是完美的。現(xiàn)實(shí)是:企業(yè)文檔就是一坨垃圾。

我有個(gè)制藥客戶,他們有 1995 年的研究論文,是打字機(jī)打出來再掃描的。OCR 基本不行。還混著現(xiàn)代的臨床試驗(yàn)報(bào)告,500 多頁,里面嵌了各種表格和圖表。你試試對(duì)這兩種文檔用同一套分塊策略,保證給你返回一堆亂七八糟的結(jié)果。

我花了幾周調(diào)試,搞不懂為什么有些文檔效果很差,有些又很好。最后意識(shí)到:必須先給文檔質(zhì)量打分,再?zèng)Q定怎么處理

  • 干凈的 PDF(文本提取完美)→ 完整的層級(jí)化處理
  • 一般的文檔(有點(diǎn) OCR 問題)→ 基礎(chǔ)分塊 + 清理
  • 垃圾文檔(掃描的手寫筆記)→ 簡(jiǎn)單固定分塊 + 標(biāo)記人工復(fù)查

我做了個(gè)簡(jiǎn)單的評(píng)分系統(tǒng),看文本提取質(zhì)量、OCR 瑕疵、格式一致性,然后根據(jù)分?jǐn)?shù)把文檔送到不同的處理流程。

"This single change fixed more retrieval issues than any embedding model upgrade."

這一個(gè)改動(dòng)解決的檢索問題,比升級(jí) embedding 模型管用得多。

1.2固定大小分塊基本是錯(cuò)的

所有教程都說:"把所有東西切成 512 token,加點(diǎn)重疊就行!"

現(xiàn)實(shí)是:文檔是有結(jié)構(gòu)的。研究論文的方法論部分和結(jié)論部分不一樣。財(cái)報(bào)有執(zhí)行摘要,也有詳細(xì)表格。如果無視結(jié)構(gòu),你會(huì)得到切到一半的句子,或者把不相關(guān)的概念混在一起。

我必須構(gòu)建層級(jí)化分塊(Hierarchical Chunking),保留文檔結(jié)構(gòu):

  • 文檔級(jí)(標(biāo)題、作者、日期、類型)
  • 章節(jié)級(jí)(摘要、方法、結(jié)果)
  • 段落級(jí)(200-400 tokens)
  • 句子級(jí)(用于精確查詢)

核心思路:查詢的復(fù)雜度決定檢索的層級(jí)。寬泛的問題在段落級(jí)檢索。精確的問題比如"表 3 里的劑量是多少?"需要句子級(jí)精度。

我用簡(jiǎn)單的關(guān)鍵詞檢測(cè)——像"exact"(精確)、"specific"(具體)、"table"(表格)這些詞會(huì)觸發(fā)精準(zhǔn)模式。如果置信度低,系統(tǒng)會(huì)自動(dòng)下鉆到更精確的分塊。

1.3元數(shù)據(jù)架構(gòu)比你的 Embedding 模型更重要

這部分我花了 40% 的開發(fā)時(shí)間,但 ROI 是最高的。

大多數(shù)人把元數(shù)據(jù)當(dāng)成事后想起來的東西。但企業(yè)查詢的上下文非常復(fù)雜。一個(gè)制藥研究員問"兒科研究",需要的文檔和問"成人群體"的完全不同。

我為不同領(lǐng)域構(gòu)建了專門的元數(shù)據(jù)模式:

制藥文檔:

  • 文檔類型(研究論文、監(jiān)管文件、臨床試驗(yàn))
  • 藥物分類
  • 患者人口統(tǒng)計(jì)(兒科、成人、老年)
  • 監(jiān)管類別(FDA、EMA)
  • 治療領(lǐng)域(心血管、腫瘤)

金融文檔:

  • 時(shí)間周期(2023 Q1、2022 財(cái)年)
  • 財(cái)務(wù)指標(biāo)(收入、EBITDA)
  • 業(yè)務(wù)部門
  • 地理區(qū)域

別用 LLM 提取元數(shù)據(jù)——它們不靠譜。簡(jiǎn)單的關(guān)鍵詞匹配效果好得多。查詢里有"FDA"?就過濾 regulatory_category: "FDA"。提到"兒科"?應(yīng)用患者群體過濾器。

從每個(gè)領(lǐng)域 100-200 個(gè)核心術(shù)語開始,根據(jù)匹配不好的查詢逐步擴(kuò)展。領(lǐng)域?qū)<彝ǔ:軜芬鈳兔ㄟ@些列表。

1.4語義搜索失效的時(shí)候(劇透:很多)

純語義搜索失效的頻率比大家承認(rèn)的高得多。在制藥和法律這種專業(yè)領(lǐng)域,我看到的失敗率是 15-20%,不是大家以為的 5%。

讓我抓狂的主要失敗模式:

縮寫混淆: "CAR" 在腫瘤學(xué)里是"嵌合抗原受體",但在影像論文里是"計(jì)算機(jī)輔助放射學(xué)"。相同的 embedding,完全不同的意思。這讓我頭疼死了。

精確技術(shù)查詢: 有人問"表 3 里的確切劑量是多少?"語義搜索會(huì)找到概念上相似的內(nèi)容,但會(huì)錯(cuò)過具體的表格引用。

交叉引用鏈: 文檔之間不斷互相引用。藥物 A 的研究引用了藥物 B 的交互數(shù)據(jù)。語義搜索完全丟失這些關(guān)系網(wǎng)絡(luò)。

解決方案: 構(gòu)建混合方法。用圖層(Graph Layer)在處理時(shí)跟蹤文檔關(guān)系。語義搜索之后,系統(tǒng)會(huì)檢查檢索到的文檔是否有相關(guān)文檔有更好的答案。

對(duì)于縮寫,我做了上下文感知的擴(kuò)展,用領(lǐng)域?qū)S玫目s寫數(shù)據(jù)庫(kù)。對(duì)于精確查詢,關(guān)鍵詞觸發(fā)會(huì)切換到基于規(guī)則的檢索來獲取特定數(shù)據(jù)點(diǎn)。

1.5為什么我選開源模型(具體是 Qwen)

大多數(shù)人以為 GPT-4o 或 o3-mini 總是更好。但企業(yè)客戶有些奇怪的約束:

  • 成本: 5 萬份文檔 + 每天幾千次查詢,API 費(fèi)用會(huì)爆炸
  • 數(shù)據(jù)主權(quán): 制藥和金融不能把敏感數(shù)據(jù)發(fā)到外部 API
  • 領(lǐng)域術(shù)語: 通用模型會(huì)在沒訓(xùn)練過的專業(yè)術(shù)語上產(chǎn)生幻覺

Qwen QWQ-32B 在領(lǐng)域微調(diào)后效果出奇的好:

  • 比 GPT-4o 便宜 85%(大批量處理)
  • 一切都在客戶基礎(chǔ)設(shè)施上
  • 可以在醫(yī)療/金融術(shù)語上微調(diào)
  • 響應(yīng)時(shí)間穩(wěn)定,沒有 API 限流

微調(diào)方法很直接——用領(lǐng)域問答對(duì)做監(jiān)督訓(xùn)練。創(chuàng)建像"藥物 X 的禁忌癥是什么?"這樣的數(shù)據(jù)集,配上實(shí)際的 FDA 指南答案。基礎(chǔ)的監(jiān)督微調(diào)比 RAFT 這種復(fù)雜方法效果更好。關(guān)鍵是要有干凈的訓(xùn)練數(shù)據(jù)。

1.6表格處理:隱藏的噩夢(mèng)

企業(yè)文檔里到處都是復(fù)雜表格——財(cái)務(wù)模型、臨床試驗(yàn)數(shù)據(jù)、合規(guī)矩陣。標(biāo)準(zhǔn) RAG 要么忽略表格,要么把它們提取成非結(jié)構(gòu)化文本,丟失所有關(guān)系。

"Tables contain some of the most critical information... If you can't handle tabular data, you're missing half the value."

表格包含了最關(guān)鍵的信息。如果處理不好表格數(shù)據(jù),你就丟了一半的價(jià)值。

財(cái)務(wù)分析師需要特定季度的精確數(shù)字。研究人員需要臨床表格里的劑量信息。

我的方法:

  • 把表格當(dāng)成獨(dú)立實(shí)體,有自己的處理流程
  • 用啟發(fā)式方法檢測(cè)表格(間距模式、網(wǎng)格結(jié)構(gòu))
  • 簡(jiǎn)單表格:轉(zhuǎn)成 CSV。復(fù)雜表格:在元數(shù)據(jù)中保留層級(jí)關(guān)系
  • 雙重 embedding 策略:既 embed 結(jié)構(gòu)化數(shù)據(jù),也 embed 語義描述

在銀行項(xiàng)目里,到處都是財(cái)務(wù)表格。還得跟蹤匯總表和詳細(xì)分解表之間的關(guān)系。

1.7生產(chǎn)基礎(chǔ)設(shè)施的現(xiàn)實(shí)檢驗(yàn)

教程假設(shè)資源無限、運(yùn)行時(shí)間完美。生產(chǎn)環(huán)境意味著并發(fā)用戶、GPU 內(nèi)存管理、穩(wěn)定的響應(yīng)時(shí)間、運(yùn)行時(shí)間保證。

大多數(shù)企業(yè)客戶已經(jīng)有閑置的 GPU 基礎(chǔ)設(shè)施——未使用的算力或其他數(shù)據(jù)科學(xué)工作負(fù)載。這讓本地部署比預(yù)期的容易。

通常部署 2-3 個(gè)模型:

  • 主生成模型(Qwen 32B)用于復(fù)雜查詢
  • 輕量級(jí)模型用于元數(shù)據(jù)提取
  • 專門的 embedding 模型

盡可能用量化版本。Qwen QWQ-32B 量化到 4-bit 只需要 24GB VRAM,但保持了質(zhì)量??梢栽趩螐?RTX 4090 上運(yùn)行,不過 A100 對(duì)并發(fā)用戶更好。

最大的挑戰(zhàn)不是模型質(zhì)量——而是防止多個(gè)用戶同時(shí)訪問系統(tǒng)時(shí)的資源競(jìng)爭(zhēng)。用信號(hào)量限制并發(fā)模型調(diào)用,加上合適的隊(duì)列管理。

1.8真正重要的經(jīng)驗(yàn)教訓(xùn)

  1. 文檔質(zhì)量檢測(cè)優(yōu)先: 不能用同一種方式處理所有企業(yè)文檔。先構(gòu)建質(zhì)量評(píng)估,再做其他事。
  2. 元數(shù)據(jù) > embeddings: 元數(shù)據(jù)不好,檢索就不好,不管你的向量有多棒?;〞r(shí)間做領(lǐng)域?qū)S玫哪J健?/span>
  3. 混合檢索是必須的: 純語義搜索在專業(yè)領(lǐng)域失敗太頻繁。需要基于規(guī)則的后備方案和文檔關(guān)系映射。
  4. 表格很關(guān)鍵: 如果處理不好表格數(shù)據(jù),就丟失了企業(yè)價(jià)值的一大塊。
  5. 基礎(chǔ)設(shè)施決定成?。?/span> 客戶更在乎可靠性,而不是花哨功能。資源管理和運(yùn)行時(shí)間比模型復(fù)雜度更重要。

1.9說點(diǎn)真話

"Enterprise RAG is way more engineering than ML."

企業(yè) RAG 更多是工程,而不是機(jī)器學(xué)習(xí)。

大多數(shù)失敗不是因?yàn)槟P筒缓谩堑凸懒宋臋n處理的挑戰(zhàn)、元數(shù)據(jù)的復(fù)雜性、生產(chǎn)基礎(chǔ)設(shè)施的需求。

現(xiàn)在需求真的很瘋狂。每個(gè)有大量文檔庫(kù)的公司都需要這些系統(tǒng),但大多數(shù)人根本不知道處理真實(shí)世界的文檔有多復(fù)雜。

反正這玩意兒比教程說的難太多了。企業(yè)文檔的各種邊緣情況會(huì)讓你想把筆記本扔出窗外。但如果搞定了,ROI 還是很可觀的——我見過團(tuán)隊(duì)把文檔搜索從幾小時(shí)縮短到幾分鐘。

2、四個(gè)工程要點(diǎn)代碼示例

上面譯文看完可能還不夠直觀,我挑了四個(gè)覺得比較重要的工程要點(diǎn),并結(jié)合對(duì)應(yīng)的業(yè)界常用的開源組件進(jìn)行核心代碼邏輯的展示,供各位參考。

2.1文檔質(zhì)量評(píng)分系統(tǒng)

原帖最大的創(chuàng)新點(diǎn)是在處理文檔前先給它打分,根據(jù)質(zhì)量路由到不同 pipeline。作者說這一個(gè)改動(dòng)解決的檢索問題比升級(jí) embedding 模型還多。

核心是識(shí)別三種文檔:Clean(80+分)的文檔文本提取完美,可以完整層級(jí)化處理;Decent(50-80 分)的文檔有 OCR 瑕疵,需要基礎(chǔ)分塊加清理;Garbage(<50 分)的掃描手寫筆記只能固定分塊并人工復(fù)查。

評(píng)分維度包括文本提取質(zhì)量(權(quán)重 50%)、格式一致性(30%)和表格完整性(20%),通過采樣前 3 頁來快速評(píng)估整個(gè)文檔。下面以 PaddleOCR 為例,做個(gè)代碼邏輯演示:

from paddleocr import PaddleOCR
import numpy as np

class DocumentQualityScorer:
    def __init__(self):
        self.ocr = PaddleOCR(use_angle_cls=True, lang='ch')
    def score_document(self, pdf_images):
    """對(duì)文檔打分并選擇pipeline"""
    scores = []
    for img in pdf_images[:3]:  # 采樣前3頁
        result = self.ocr.ocr(img, cls=True)
        if not result or not result[0]:
            scores.append(0)
            continue

        # 提取置信度
        confidences = [line[1][1] for line in result[0]]
        avg_conf = np.mean(confidences)
        scores.append(avg_conf * 100)

    overall = np.mean(scores)

    # 分類并路由
    if overall >= 80:
        return "clean", CleanPipeline()
    elif overall >= 50:
        return "decent", DecentPipeline()
    else:
        return "garbage", GarbagePipeline()

這段代碼的核心邏輯是采樣前 3 頁圖像進(jìn)行 OCR,提取每個(gè)文本塊的置信度分?jǐn)?shù)(PaddleOCR 會(huì)為每個(gè)識(shí)別的文字塊返回 0-1 的 confidence 值),然后通過平均值轉(zhuǎn)換為 0-100 的分?jǐn)?shù)。閾值 80 和 50 來自作者在多個(gè)項(xiàng)目中總結(jié)的經(jīng)驗(yàn)值:置信度高于 80%的文檔基本可以認(rèn)為文本提取完美,50-80%之間有一些瑕疵但可用,低于 50%說明 OCR 質(zhì)量很差。

只采樣 3 頁而不是全文是因?yàn)榍皫醉撏ǔD艽碚w風(fēng)格,處理全文太慢(100 頁文檔需要 10+分鐘),實(shí)測(cè) 3 頁的準(zhǔn)確率已經(jīng) 95%以上。這里用置信度 * 100 是為了將 0-1 的浮點(diǎn)數(shù)轉(zhuǎn)為 0-100 的分?jǐn)?shù),便于理解和設(shè)置閾值。

在實(shí)際使用時(shí),建議先在數(shù)據(jù)集上標(biāo)注 100 個(gè)文檔(人工判斷 Clean/Decent/Garbage),然后跑評(píng)分畫散點(diǎn)圖看三類文檔的分?jǐn)?shù)分布,調(diào)整閾值讓分類準(zhǔn)確率超過 90%。常見的坑是彩色掃描件 OCR 置信度可能很高但實(shí)際是垃圾,需要加入"是否為圖片 PDF"的判斷;表格很多的文檔(如財(cái)報(bào))會(huì)被低估,可以提高表格評(píng)分的權(quán)重到 30%。性能優(yōu)化方面,可以改為均勻采樣(第 1 頁、中間頁、最后頁各 1 頁)來提高代表性,多頁圖像可以并行 OCR 加速處理,同一文檔的評(píng)分結(jié)果應(yīng)該緩存避免重復(fù)計(jì)算。

2.2層級(jí)化分塊策略

原帖批判了"固定 512 token 分塊"的做法,提出 4 層結(jié)構(gòu):Document(2048 tokens)→ Section(1024 tokens)→ Paragraph(512 tokens)→ Sentence(128 tokens)。關(guān)鍵洞察是查詢復(fù)雜度應(yīng)該決定檢索層級(jí):寬泛?jiǎn)栴}如"這篇講什么"適合段落級(jí)或章節(jié)級(jí)檢索,精確問題如"表 3 第 2 行是多少"需要句子級(jí)定位。每一層都生成獨(dú)立的 embedding 存儲(chǔ)在向量數(shù)據(jù)庫(kù),檢索時(shí)根據(jù)查詢特征自動(dòng)選擇合適的層級(jí),從而避免大海撈針的問題。下面以 LlamaIndex 為例進(jìn)行演示:

from llama_index.core.node_parser import HierarchicalNodeParser
from llama_index.core import Document

class AdaptiveRetriever:
    def __init__(self):
        self.parser = HierarchicalNodeParser.from_defaults(
            chunk_sizes=[2048, 1024, 512, 128]
        )
        self.precision_keywords = ['exact', 'table', 'figure', '表', '圖', '第']

    
    def retrieve(self, query, doc_text, vector_store):
    """層級(jí)化分塊并自適應(yīng)檢索"""
    # 生成4層節(jié)點(diǎn)
    doc = Document(text=doc_text)
    nodes = self.parser.get_nodes_from_documents([doc])

    # 判斷查詢類型選擇層級(jí)
    has_precision = any(kw in query.lower() for kw in self.precision_keywords)
    word_count = len(query.split())

    if has_precision:
        level = 'sentence'
    elif word_count > 15:
        level = 'section'
    else:
        level = 'paragraph'

    return vector_store.search(query, filter={'layer': level}, top_k=5)

HierarchicalNodeParser 會(huì)根據(jù) chunk_sizes 參數(shù)自動(dòng)將文檔切分成 4 層,每層的大小是近似值而不是嚴(yán)格限制,因?yàn)榍蟹謺r(shí)會(huì)保持語義邊界完整。參數(shù)[2048, 1024, 512, 128]適合英文,中文建議調(diào)整為[3000, 1500, 600, 150]因?yàn)橹形男畔⒚芏雀摺?/p>

查詢路由的邏輯是:如果包含精確關(guān)鍵詞(table、figure、第 X 章等)就用句子級(jí),如果查詢很長(zhǎng)(超過 15 個(gè)詞)說明是復(fù)雜概念問題就用章節(jié)級(jí),否則默認(rèn)段落級(jí)。這個(gè)啟發(fā)式規(guī)則來自原帖討論區(qū)的經(jīng)驗(yàn),實(shí)測(cè)準(zhǔn)確率在 85%左右。層級(jí)存儲(chǔ)在 vector_store 時(shí)通過 metadata 的 layer 字段區(qū)分,檢索時(shí)用 filter 過濾只在對(duì)應(yīng)層級(jí)搜索。

實(shí)際使用時(shí)不是每次查詢都需要 4 層,大部分情況 paragraph 層足夠用,可以先在 paragraph 層檢索,如果置信度低再下鉆到 sentence 層做二次檢索。document 層主要用于"文檔級(jí)"問題如"這篇講什么"或生成摘要。

特殊文檔類型需要特別處理:表格和代碼塊應(yīng)該提前提取單獨(dú) chunk 避免被切碎,標(biāo)題要合并到后續(xù)內(nèi)容而不是單獨(dú)成 chunk,列表要保持完整性不在中間切斷。性能優(yōu)化方面,chunk_sizes 的 overlap 建議設(shè)置為 size 的 5-10%來防止切斷完整語義,太大浪費(fèi)存儲(chǔ)太小丟失上下文。對(duì)于技術(shù)文檔(代碼多)可以用更大的 chunk 如[4096, 2048, 1024, 256]。

2.3混合檢索問題

原帖指出純語義搜索在專業(yè)領(lǐng)域失敗率 15-20%,需要三路并行:語義檢索(向量相似度)理解語義但可能漏掉精確匹配,關(guān)鍵詞檢索(BM25)精確匹配但不理解同義詞,元數(shù)據(jù)過濾(結(jié)構(gòu)化字段)過濾無關(guān)文檔。然后用 RRF(Reciprocal Rank Fusion)算法融合結(jié)果,公式是對(duì)于文檔 d 在結(jié)果列表中的排名 rank_d,融合分?jǐn)?shù)等于各路結(jié)果的權(quán)重除以(60 + rank_d)之和。常數(shù) 60 是 RRF 標(biāo)準(zhǔn)參數(shù),用于平衡頭部和尾部結(jié)果,權(quán)重一般設(shè)置為語義 0.7、關(guān)鍵詞 0.3,具體場(chǎng)景可調(diào)整。以 Qdrant 為例做個(gè)代碼示例:

from qdrant_client import QdrantClient

class HybridRetriever:
    def __init__(self):
        self.client = QdrantClient("localhost", port=6333)
    def search(self, query, top_k=10):
    """三路檢索 + RRF融合"""
    # 語義檢索(dense vector)
    semantic = self.client.search(
        collection_name="docs",
        query_vector=("dense", embed(query)),
        limit=top_k * 2
    )

    # 關(guān)鍵詞檢索(sparse vector)
    keyword = self.client.search(
        collection_name="docs",
        query_vector=("sparse", extract_keywords(query)),
        limit=top_k * 2
    )

    # RRF 融合
    scores = {}
    for rank, r in enumerate(semantic, 1):
        scores[r.id] = scores.get(r.id, 0) + 0.7 / (60 + rank)
    for rank, r in enumerate(keyword, 1):
        scores[r.id] = scores.get(r.id, 0) + 0.3 / (60 + rank)

    # 排序返回
    return sorted(scores.items(), key=lambda x: x[1], reverse=True)[:top_k]

Qdrant 支持在同一文檔上同時(shí)存儲(chǔ) dense 和 sparse 兩種向量,dense 是傳統(tǒng)的語義 embedding(如 OpenAI、BGE),sparse 是關(guān)鍵詞的稀疏表示類似 BM25 的詞頻向量。RRF 融合算法的核心是用排名的倒數(shù)而不是原始分?jǐn)?shù)來融合,這樣可以處理不同檢索器分?jǐn)?shù)尺度不統(tǒng)一的問題。權(quán)重 0.7 和 0.3 是通用場(chǎng)景的經(jīng)驗(yàn)值(語義為主),精確查詢多的場(chǎng)景可以設(shè)為 0.5/0.5 均衡,概念查詢多可以設(shè)為 0.8/0.2 更偏語義。limit 設(shè)為 top_k * 2 是因?yàn)槿诤虾髸?huì)有重復(fù),多取一些保證最終有足夠結(jié)果。元數(shù)據(jù)過濾(如 doc_type='clinical_trial')應(yīng)該在數(shù)據(jù)庫(kù)層面用 Filter 實(shí)現(xiàn)而不是在應(yīng)用層過濾,性能更好。

混合檢索在專業(yè)術(shù)語多的領(lǐng)域(醫(yī)療、法律、金融)是必須的,純語義搜索會(huì)漏掉縮寫、代號(hào)、產(chǎn)品型號(hào)等精確匹配。用戶查詢包含需要精確匹配的內(nèi)容(如法規(guī)編號(hào)、技術(shù)規(guī)格)時(shí)也必須啟用。但通用聊天場(chǎng)景可選,純語義已經(jīng)夠用,開啟混合檢索會(huì)增加 20-30%延遲。性能優(yōu)化方面,三路檢索可以并行執(zhí)行減少延遲,高頻查詢的結(jié)果應(yīng)該緩存。

在實(shí)踐中建議通過 A/B 測(cè)試來調(diào)整權(quán)重:記錄用戶點(diǎn)擊率,看哪個(gè)權(quán)重組合的 top3 點(diǎn)擊率最高。如果你的文檔有豐富的元數(shù)據(jù)(如時(shí)間、類別、作者),元數(shù)據(jù)過濾能顯著提升準(zhǔn)確率,例如"2024 年兒科臨床試驗(yàn)"這種查詢,先用元數(shù)據(jù)過濾掉無關(guān)文檔再做語義檢索。

2.4置信度驅(qū)動(dòng)的智能路由

來自原帖討論區(qū)的具體參數(shù):0.7 相似度閾值加上 20-30 個(gè)觸發(fā)詞。邏輯是初始用段落級(jí)檢索獲得最高分?jǐn)?shù),如果高置信度(大于 0.85)說明段落級(jí)足夠,如果中置信度(0.7-0.85)且包含精確關(guān)鍵詞就切換到句子級(jí),如果低置信度(0.5-0.7)就下鉆到句子級(jí)細(xì)粒度檢索,如果極低置信度(小于 0.5)就降級(jí)到關(guān)鍵詞搜索兜底。這是一個(gè)簡(jiǎn)單但有效的"智能路由",避免所有查詢都用同樣粒度檢索,既節(jié)省計(jì)算又提高準(zhǔn)確率。以下是純 python 的實(shí)現(xiàn)示例:

class ConfidenceRouter:
    def __init__(self):
        self.precision_kw = ['exact', 'table', 'figure', '表', '圖', '第']
        self.high_conf = 0.85
        self.med_conf = 0.70
        self.low_conf = 0.50
    def route(self, query, search_engine):
    """置信度驅(qū)動(dòng)的檢索路由"""
    # 初始檢索(段落級(jí))
    initial = search_engine.search(query, level='paragraph', top_k=10)
    if not initial:
        return []

    max_score = max(r.score for r in initial)
    has_precision = any(kw in query.lower() for kw in self.precision_kw)

    # 決策
    if max_score >= self.high_conf:
        return initial  # 高置信度,段落級(jí)足夠
    elif max_score >= self.med_conf:
        if has_precision:
            return search_engine.search(query, level='sentence', top_k=10)
        return initial
    elif max_score >= self.low_conf:
        return search_engine.search(query, level='sentence', top_k=10)
    else:
        return search_engine.keyword_search(query, top_k=10)  # 兜底

閾值 0.85/0.7/0.5 來自原帖討論區(qū)作者在多個(gè)項(xiàng)目中驗(yàn)證的經(jīng)驗(yàn)值,這些數(shù)字在實(shí)際項(xiàng)目中肯定不是拍腦袋定的,而是要通過標(biāo)注數(shù)據(jù)找出的準(zhǔn)確率突變點(diǎn)。精確關(guān)鍵詞列表有 20-30 個(gè)詞,包括 exact、table、figure 以及中文的"表、圖、第"等,還可以用正則匹配"表 3"、"第 5 章"這種模式。決策邏輯是先用段落級(jí)試探,根據(jù)最高分?jǐn)?shù)和是否有精確詞來決定是否需要更細(xì)粒度,這樣大部分查詢(約 70%)在段落級(jí)就能解決,只有 30%需要下鉆到句子級(jí)或降級(jí)到關(guān)鍵詞。降級(jí)到關(guān)鍵詞搜索是兜底策略,雖然粗糙但總比返回空結(jié)果好,在語義搜索完全失敗時(shí)至少能匹配到一些相關(guān)詞。

實(shí)際使用的時(shí)候,建議在數(shù)據(jù)上標(biāo)注 100 個(gè)左右查詢,畫出相似度分?jǐn)?shù)的分布圖,找到準(zhǔn)確率突變點(diǎn)來設(shè)置閾值,不要直接照搬 0.7/0.85 這些數(shù)字。精確關(guān)鍵詞列表需要持續(xù)維護(hù),從 bad case 中收集(用戶重新搜索說明上次結(jié)果不滿意),定期 review 刪除誤判率高的詞,也可以用 TF-IDF 找領(lǐng)域特有的精確詞。

建議記錄詳細(xì)日志包括 query、max_score、選擇的 strategy(paragraph/sentence/keyword)、has_precision_kw 以及用戶點(diǎn)擊率,通過日志分析持續(xù)優(yōu)化閾值和觸發(fā)詞。A/B 測(cè)試時(shí)可以對(duì)比不同閾值組合的 top3 點(diǎn)擊率,選擇表現(xiàn)最好的。常見問題是閾值設(shè)置過高導(dǎo)致過多下鉆到句子級(jí)增加延遲,或設(shè)置過低導(dǎo)致很多查詢?cè)诙温浼?jí)就返回但準(zhǔn)確率不夠,需要根據(jù)業(yè)務(wù)場(chǎng)景平衡準(zhǔn)確率和性能。

3、技術(shù)問答討論

原帖已經(jīng)信息密度很高,但評(píng)論區(qū)里藏著更多實(shí)戰(zhàn)細(xì)節(jié)。我從 108 條討論中精選了 17 條核心問答,涵蓋以下四大主題:

技術(shù)實(shí)現(xiàn)細(xì)節(jié):為什么 VLM 處理 PDF 比 HTML 轉(zhuǎn)換更靠譜、小模型 7B-13B 能干什么不能干什么、遞歸搜索怎么實(shí)現(xiàn)和觸發(fā)、10-20 頁文檔全文讀 vs 分塊檢索的選擇標(biāo)準(zhǔn);

成本和性能數(shù)據(jù):GPT-4o vs Qwen 的詳細(xì)成本計(jì)算、H100 上跑 Qwen 32B 的真實(shí)性能數(shù)據(jù)、A100 部署成本和選型理由;

商業(yè)模式和團(tuán)隊(duì)運(yùn)作:60-70%代碼復(fù)用率怎么做到;2 人團(tuán)隊(duì)如何服務(wù) 10+企業(yè)客戶、如何找客戶和合作伙伴模式、授權(quán)許可 vs 定制開發(fā)的商業(yè)模式)

以及重要的澄清和補(bǔ)充:元數(shù)據(jù)提取 LLM vs 規(guī)則的使用邊界、混合檢索的自動(dòng)選擇挑戰(zhàn)、法律和工程領(lǐng)域從業(yè)者的跨行業(yè)驗(yàn)證)。

這些帖子評(píng)論區(qū)內(nèi)容我做了完整翻譯、提煉要點(diǎn)、補(bǔ)充國(guó)內(nèi)場(chǎng)景對(duì)照,并標(biāo)注實(shí)用性,放在知識(shí)星球中作為會(huì)員專屬資料,感興趣的也可以自行去看原帖。

為了直觀期間,看個(gè)例子,討論區(qū)第 6 條關(guān)于成本對(duì)比的節(jié)選:

圖片圖片

評(píng)論:

你說 Qwen 比 GPT-4o 便宜 85%。我也在做類似項(xiàng)目想評(píng)估成本。GPT-4o 大概每月多少錢?

作者回答:

GPT-4o 價(jià)格是輸入$2.50/百萬 tokens、輸出$10.00/百萬 tokens。典型企業(yè) RAG 場(chǎng)景,假設(shè)首次處理 5 萬文檔(一次性 embedding),每月 1 萬次查詢,平均每次 1K 輸入、500 輸出。GPT-4o 成本: 初始 embedding 約$125,月度查詢約$100($75 輸入+$25 輸出),總計(jì)中等使用量每月$200-300+,規(guī)模上去后快速增長(zhǎng)。Qwen QWQ-32B 成本: 輸入$0.15-0.50/百萬 tokens、輸出$0.45-1.50/百萬 tokens(Groq 報(bào)價(jià)$0.29 輸入/$0.39 輸出),同樣工作量:初始 embedding 約$15-25,月度查詢約$15-20,總計(jì)每月$30-50,而不是$200-300+。這就是 85%成本節(jié)省的來源。

作者直接給出了完整的公式和每個(gè)環(huán)節(jié)的費(fèi)用拆解,包括具體的 token 價(jià)格、使用量假設(shè)和總成本計(jì)算,這些實(shí)際項(xiàng)目中可以直接拿來做預(yù)算。類似這樣有具體數(shù)字、可落地的實(shí)戰(zhàn)經(jīng)驗(yàn),在 17 條精華問答里還有很多。

4、寫在最后

帖子作者說"企業(yè) RAG 是 70% 工程 + 20% 領(lǐng)域知識(shí) + 10% 模型",我深表認(rèn)同,但想再加一個(gè)維度:企業(yè) RAG = 70% 工程 + 20% 領(lǐng)域知識(shí) + 10% 模型 + ∞ 耐心。

畢竟,企業(yè) RAG 不是一個(gè)純技術(shù)問題,對(duì)行業(yè)的理解、對(duì)臟數(shù)據(jù)的處理能力、對(duì)工程細(xì)節(jié)的把控,都是繞不開的必修課。

責(zé)任編輯:龐桂玉 來源: 韋東東
相關(guān)推薦

2025-07-03 06:39:16

2024-04-01 08:05:27

Go開發(fā)Java

2024-06-26 10:37:05

2024-05-06 00:00:00

緩存高并發(fā)數(shù)據(jù)

2023-02-15 18:12:43

開發(fā)企業(yè)級(jí)CLI

2025-04-29 10:17:42

2017-07-17 15:46:20

Oracle并行機(jī)制

2024-12-30 09:12:17

2014-11-24 10:33:32

Windows 10

2025-04-21 04:50:00

2018-01-10 13:40:03

數(shù)據(jù)庫(kù)MySQL表設(shè)計(jì)

2025-02-13 09:01:03

2015-03-24 16:29:55

默認(rèn)線程池java

2010-11-11 09:54:31

2023-03-29 07:49:05

企業(yè)級(jí)項(xiàng)目研發(fā)

2013-03-28 09:35:31

企業(yè)級(jí)系統(tǒng)

2020-07-31 07:45:43

架構(gòu)系統(tǒng)企業(yè)級(jí)

2011-05-19 10:57:47

架構(gòu)

2018-09-11 09:14:52

面試公司缺點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)