AI 開發入門之 RAG 技術

目錄

    • 一、從一個簡單的問題開始
    • 二、語言模型“閉卷考試”的困境
    • 三、RAG 是什么—LLM 的現實世界“外掛”
    • 四、RAG 的七步流程
      • 第一步:加載數據(Load)
      • 第二步:切分文本(Chunking)
      • 第三步:向量化(Embedding)
        • 向量化:把句子變成“可以計算距離”的坐標點
        • 向量化模型做了啥?
        • 相似度怎么計算?
        • 總結一下
      • 第四步:存入向量數據庫(Vector Store)
      • 第五步:接收用戶問題(Query)
      • 第六步:檢索相關文段(Retrieve)
      • 第七步:組織 Prompt,交給大模型生成回答(Generate)
    • 總結

如果關注 AI 領域,那么 RAG 這個名詞你肯定不陌生,這篇文章,我們就來揭開它的神秘面紗。為什么需要 RAG,它到底是什么,能解決什么問題。

一、從一個簡單的問題開始

假設你在和一個 AI 聊天助手對話,你問它:

“北京到上海高鐵多久?”

這看起來像個非常簡單的問題,但它考驗的卻是 AI 模型的知識廣度知識時效性

你希望它能回答類似這樣:

“大約 4.5 到 6 小時,具體取決于車次。”

但是,假設這個 AI 模型訓練得比較早,它可能回答是——

“我不知道。”

或者:

“我認為北京和上海之間目前沒有高鐵。”(因為它只看到了 2010 年以前的數據)

這就暴露出一個大語言模型的通病

訓練完就定格了,它不會自己更新知識。


二、語言模型“閉卷考試”的困境

所有的大語言模型(如 GPT、Claude、Gemini)在訓練時都要讀取大量文本,比如:

  • 維基百科
  • 新聞網站
  • Reddit 論壇
  • Github 代碼
  • 開放書籍、論文

訓練結束后,它就像一個“背書高手”,記住了大量的知識。但這也意味著一但遇到新知識實時內容你私有的數據,它就歇菜了。

所以問題就來了:怎么讓模型既有“語言能力”,又能隨時“看資料再回答”呢?

這時候就該 RAG 登場了!


三、RAG 是什么—LLM 的現實世界“外掛”

RAG,全稱是 Retrieval-Augmented Generation,翻譯為“檢索增強生成”。

通過字面意思也能看出來它的核心作用,通過檢索來增強生成(廢話)

用通俗話來講:
它讓 AI 在回答之前,先“查資料”,再用大模型來“組織語言”。

就像你考試的時候如果不確定答案,那就翻課本,然后用自己的話組織一段回答。

想象一個真實的場景,比如你在一家 SaaS 公司,客戶經常問你:

  • “你們的產品怎么綁定企業微信?”
  • “有沒有 API 文檔?”
  • “怎么開具發票?”

這些內容,可能都寫在:

  • 幫助中心文檔
  • FAQ 文檔
  • 客服聊天記錄
  • 內部知識庫

而傳統的 ChatGPT 模型對這些你們內部的這些專屬知識一無所知

這時候你就可以用 RAG,它的基本流程是:

  1. 用戶提問
  2. 在你的知識庫里“檢索”相關文檔段落(比如找到 API 文檔那一段)檢索
  3. 把這些內容和用戶問題一起送進語言模型 增強
  4. 生成一個有針對性的、個性化的回答。生成

這樣的系統既懂你公司,又能寫好回答

所以 RAG 的核心優勢顯而易見:

優點解釋
實時更新你改了文檔,模型就能學會新內容,不需要重新訓練
私有知識可以在不暴露給外部模型的前提下使用公司內部數據
可控性強檢索什么,傳給模型什么,你可以干預整個過程
更少幻覺模型參考真實資料后,不容易瞎編

所以,總的來說,大語言模型就像是通用的大腦,RAG 則讓它接入你自己的知識RAG 不是讓模型更“聰明”,而是讓它更“有見識”。

通過上面的描述,RAG 聽起來很簡單嘛。

但真正的 RAG 系統背后可是有很多技術細節:

  • 文檔如何分段(chunking)
  • 怎樣計算用戶問題和文檔的“語義相似度”(向量檢索)
  • 檢索出幾條內容?怎么拼接 Prompt?
  • 模型是否支持多輪記憶和上下文壓縮?
  • 如何緩存和優化響應速度?

等等,這些都會影響最終效果。

四、RAG 的七步流程

我們已經大致了解了 RAG 的原理,現在我們就從宏觀視角來看看 RAG 的全流程是怎么樣的。

第一步:加載數據(Load)

RAG 的第一步,就是從你現有的資料中**“把內容讀進來”**。比如我們加載一份 FAQ 文檔:

import { TextLoader } from "langchain/document_loaders/fs/text";const loader = new TextLoader("docs/faq.txt");
const rawDocs = await loader.load();

輸出結果是一個標準格式:

[{pageContent: "退訂說明:用戶如需退訂,請登錄控制臺,點擊賬戶管理。",metadata: { source: "faq.txt" }},...
]

這就像是把原始文檔清洗成結構化文本,供后續使用。

第二步:切分文本(Chunking)

為什么要切分?因為文檔太大了,大模型一次吃不下。

我們需要把文檔拆成段落級別的小塊(chunk),通常每塊控制在幾百字以內。

切分工具(在 langchain.js 中):

import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";const splitter = new RecursiveCharacterTextSplitter({chunkSize: 500,chunkOverlap: 50
});
const docs = await splitter.splitDocuments(rawDocs);

第三步:向量化(Embedding)

現在我們已經把文檔切分了,但是有一個問題:

計算機如何知道,兩個句子意思相近?

比如下面這兩個問法:

  • “怎么取消訂閱?”
  • “我不想繼續用了,怎么退?”

我們人類一看就知道是同一個意思。可對計算機來說,它只看到一串字符,完全不懂“語義”。

那怎么辦?

我們需要給它一種能“看出意思相似”的方式,這就是向量化。

向量化:把句子變成“可以計算距離”的坐標點

你可以把“向量化”想象成這樣的過程:

我們給每個句子分配一個“坐標點”,讓相近意思的句子靠得近,差很多的句子離得遠。

比如:

句子向量(簡化表示)
“怎么退訂服務?”[0.9, 0.1, 0.4]
“不想用了怎么辦?”[0.88, 0.12, 0.45]
“產品價格是多少?”[0.1, 0.8, 0.9]

你可以把每個向量想象成一個坐標點在三維空間中:

  • 第一個句子和第二個句子很靠近(表示意思差不多)
  • 第三個句子在遠處(表示是完全不同的問題)

于是我們就可以計算兩個句子之間的“距離”,這個距離越近,它們的意思就越像。

這就是所謂的**“語義相似度計算”**。


向量化模型做了啥?

現在的語言模型已經很強大,它們會從大量語料中學會如何把意思相近的詞語、句子放到更接近的坐標位置上

你只要給它一句話,它就會返回一個長長的向量,比如:

[0.12, -0.03, 0.77, ..., 0.01]  // 長度可能是 1536 維

雖然我們看不懂這個向量長啥樣,但這沒關系——我們只需要知道:它可以拿來計算“相似度”


相似度怎么計算?

最常用的方式就是:

計算兩個向量的夾角是否接近(余弦相似度)

可以理解為:

  • 兩個方向完全一樣的箭頭,表示“非常相似”
  • 兩個方向差很多,說明“幾乎沒關系”

總結一下
概念通俗理解
向量把一個句子的意思表示成一組數字坐標
向量化把句子轉成向量(embedding 模型來做)
相似度比較兩個向量距離近不近,距離越近意思越相近

所以,向量化的本質就是:把語言變成“可以比較距離的東西”,讓計算機能看出語義像不像。


第四步:存入向量數據庫(Vector Store)

我們把每段文本 + 它的向量都存到一個數據庫里,方便后續檢索。

可用的數據庫有:

  • FAISS(本地)
  • Pinecone / Weaviate / Chroma(云服務)
  • Milvus(工業級)

示例(用 FAISS):

import { FaissStore } from "langchain/vectorstores/faiss";const store = await FaissStore.fromDocuments(docs, embeddings);

現在,你就有了一個可以按語義相似度查內容的數據庫了。


第五步:接收用戶問題(Query)

終于輪到用戶提問了,比如:

“怎么退訂你們的服務?”

這個問題會經過同樣的向量化過程,再去數據庫中查最接近的問題片段。


第六步:檢索相關文段(Retrieve)

將用戶問題的向量丟進數據庫,找出前幾段最相似的內容(通常是 top-3 或 top-5):

const results = await store.similaritySearch("怎么退訂服務?", 3);

返回類似:

["退訂說明:請登錄控制臺,點擊賬戶管理頁面...","退訂功能位于控制臺左側菜單欄...",...
]

這就是查資料的部分。


第七步:組織 Prompt,交給大模型生成回答(Generate)

最后,我們把:

  • 用戶問題
  • 檢索到的文檔片段

組織成一個 Prompt,交給 LLM:

const prompt = `
你是一個客服助手,請參考以下內容回答用戶問題:資料:
---
1. ${results[0]}
2. ${results[1]}
3. ${results[2]}
---用戶提問:
怎么退訂服務?請根據資料,用簡潔的語言回答:
`;

然后喂給 OpenAI 或其他模型:

const res = await llm.call(prompt);

得到最終回答:

“您好,您可以登錄控制臺,進入‘賬戶管理’,點擊‘退訂管理’即可操作退訂。”

至此,一個完整的 RAG 流程就完成了。

當然這只是最簡單籠統的流程介紹,具體的每個環節都是很復雜的,比如算法的選取以及參數的調整等等等等…


總結

RAG = 查文檔 + 用大模型答題,RAG 本質上讓 LLM 具備了實時訪問企業知識庫的能力,既規避了幻覺,又能針對性回答個性化問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78228.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78228.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78228.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決yarn install 報錯 error \node_modules\electron: Command failed.

在電腦重裝系統后,重新安裝項目依賴,遇到這一報錯 完整報錯信息如下: error D:\xxxxx\xxxxxx\node_modules\electron: Command failed. Exit code: 1 Command: node install.js Arguments: Directory: D:\xxxxx\xxxxx\node_modules\electron Output: HTTPError: Response cod…

2025年3月電子學會青少年機器人技術(五級)等級考試試卷-理論綜合

青少年機器人技術等級考試理論綜合試卷(五級) 分數:100 題數:30 一、單選題(共20題,共80分) 1. 2025年初,中國科技初創公司深度求索在大模型領域迅速崛起,其開源的大模型成為全球AI領域的焦…

23種設計模式-行為型模式之模版方法模式(Java版本)

Java 模板方法模式(Template Method Pattern)詳解 🧠 什么是模板方法模式? 模板方法模式是一種行為型設計模式,在一個方法中定義一個操作中的算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在…

長城杯鐵人三項初賽-REVERSE復現

前言 記錄記錄 1.LoginToMe int __fastcall main(int argc, const char **argv, const char **envp) {unsigned int v3; // eaxchar s[96]; // [rsp10h] [rbp-70h] BYREFint v6; // [rsp70h] [rbp-10h]int v7; // [rsp78h] [rbp-8h]int i; // [rsp7Ch] [rbp-4h]memset(s, 0, s…

DNS實驗

DNS原理 客戶端發起請求:客戶端向本地 DNS 服務器發送域名解析請求,這是流程的起始點。本地 DNS 服務器查詢根域名服務器:若本地 DNS 服務器緩存中無對應記錄,它向根域名服務器發起查詢,根域名服務器是 DNS 系統頂層&a…

SQLMesh 通知系統深度解析:構建自動化監控體系

SQLMesh 是一款強大的數據編排工具,其內置的靈活通知系統可顯著提升團隊協作效率。本文將系統解讀 SQLMesh 的通知機制,涵蓋配置方法、事件觸發邏輯及高級定制技巧。 一、通知系統的核心架構 1. 通知目標(Notification Targets) …

精益數據分析(20/126):解析經典數據分析框架,助力創業增長

精益數據分析(20/126):解析經典數據分析框架,助力創業增長 在創業和數據分析的學習道路上,每一次深入探索都可能為我們帶來新的啟發。今天,依舊帶著和大家共同進步的想法,我們一起深入研讀《精…

【OSG學習筆記】Day 8: 紋理貼圖——賦予模型細節

在 OSG(Open Scene Graph)中,紋理貼圖是為模型添加細節的關鍵技術,主要涉及紋理加載、UV 映射和多重紋理疊加三部分。 基礎理論 紋理加載 紋理的作用,就是將2D圖像映射到3D模型表面,增強視覺細節。 紋理類型與格式支持: OSG 支持多種圖像格式,包括常見的 .jpg/.jpe…

基于事件驅動的云原生后端架構設計:從理念到落地

??個人主頁??:慌ZHANG-CSDN博客 ????期待您的關注 ???? 一、引言:微服務之后,事件驅動正在成為新范式 隨著業務復雜度的提升,傳統同步式微服務調用模式逐漸暴露出瓶頸:服務間耦合度高、并發能力有限、出錯鏈路復雜。而在互聯網業務、金融交易、物聯網等場景中…

vue3:十一、主頁面布局(修改頂部導航欄樣式-右側:用戶信息+退出登錄+全屏顯示)

一、效果 完成效果,增加頂部導航欄,右側用戶信息(其中個人中心需要后續進行頁面開發,這里只寫了退出登錄功能),以及全屏功能 二、搭建并引入右側組件 將右側內容封裝到單獨的組件,直接引入(像左側導航條等內容也是可以做成這種形式) 1、新建右側組件的頁面 在layout中…

沁恒CHV203中斷嵌套導致修改線程棧-韋東山

調試專題bug實例 2025年01月09日20點場 處理辦法1:就是關閉中斷嵌套 處理辦法2: 使用原來的棧

Qt本地化 - installTranslator不生效

bool QCoreApplication::installTranslator(QTranslator *translationFile)注意這里輸入的是QTranslator對象指針,如果QTranslator是局部變量,一旦離開其作用域就會導致翻譯失效 錯誤代碼示范: void ApplyTranslator(const QString& qmf…

Qt UDP組播實現與調試指南

在Qt中使用UDP組播(Multicast)可以實現高效的一對多網絡通信。以下是關鍵步驟和示例代碼: 一、UDP組播核心機制 組播地址:使用D類地址(224.0.0.0 - 239.255.255.255)TTL設置:控制數據包傳播范圍(默認1,同一網段)網絡接口:指定發送/接收的物理接口二、發送端實現 /…

PCB封裝主要組成元素

PCB(Printed Circuit Board,印刷電路板)封裝是指將電子元件固定在 PCB 上,并實現電氣連接的方式。主要包括以下幾類。 1. 焊盤(Pad) 作用:焊盤是 PCB 封裝中最重要的元素之一,它是…

前端基礎之《Vue(8)—內置組件》

一、Vue2.0中的內置組件 1、<slot> 插槽 2、<keep-alive> 動態組件 被keep-alive所包裹的組件&#xff1a; &#xff08;1&#xff09;不會被銷毀。 &#xff08;2&#xff09;還會多兩個生命周期鉤子&#xff1a;activated()、deactivated()。 &#xff08;3&a…

某大型電解鋁廠電解系統諧波治理裝置改造沃倫森電氣

電解鋁行業諧波治理解決方案——無源濾波裝置優化升級&#xff0c;保障穩定運行 在電解鋁生產過程中&#xff0c;諧波污染問題嚴重影響電網電能質量&#xff0c;甚至可能導致濾波裝置損壞&#xff0c;引發群爆事故。河南登封某大型電解鋁廠通過無源濾波裝置智能化改造&#xff…

在 Ubuntu 環境為 Elasticsearch 引入 `icu_tokenizer

1. 為什么需要 ICU 分析插件 Elasticsearch 默認的 standard tokenizer 遵循 UAX #29 規則&#xff0c;但在 CJK&#xff08;中、日、韓&#xff09;等亞洲語言上僅能按字符切分&#xff0c;無法識別詞邊界&#xff1b;對包含重音符號、大小寫或多腳本混排的文本也缺乏統一歸一…

避免事件“穿透”——Vue 中事件冒泡的理解與解決方案

一、事件冒泡是什么&#xff1f; 事件冒泡指的是&#xff1a;當某個元素上的事件被觸發后&#xff0c;事件會從該元素向其父級、祖先元素一直“冒泡”傳遞&#xff0c;直到 document。這意味著&#xff0c;如果父元素綁定了點擊事件&#xff0c;子元素觸發點擊時也可能順帶觸發…

【Java面試筆記:進階】17.一個線程兩次調用start()方法會出現什么情況?

1. 線程啟動與異常 線程啟動:Java 線程只能啟動一次,通過調用 Thread 對象的 start() 方法。多次啟動的后果:如果嘗試第二次調用 start() 方法,會拋出 IllegalThreadStateException 運行時異常。(1) 代碼示例 public class ThreadStartDemo {public static void main(Stri…

Flask + ajax上傳文件(一)

一、概述 本教程將教你如何使用Flask后端和AJAX前端實現文件上傳功能,包含完整的代碼實現和詳細解釋。 二、環境準備 1. 所需工具和庫 Python 3.xFlask框架jQuery庫Bootstrap(可選,用于美化界面)2. 安裝Flask pip install flask三、項目結構 upload_project/ ├── a…