RAG 從入門到放棄?丐版 demo 實戰筆記(go+python)

背景

我當前有一個業務系統,希望能添加一個機器人助手。直接使用大模型,由于缺少相關的業務數據,效果并不理想,了解一下 RAG

什么是 RAG

RAG(Retrieval Augmented Generation),搜索引擎 + 大模型

簡單來說就是從一個數據源中先撈出一部分數據,有個前置的篩選操作(通常是向量數據庫),然后將搜索出的數據組成 prompt 喂給大模型,最終獲取大模型的返回值,進行過濾輸出。

Top-K 結果
用戶輸入問題
查詢向量化
Embedding Model
向量數據庫
近似搜索 ANN
檢索片段
+ 原始文本
構建提示詞
Prompt Engineering
系統指令 + 上下文 + 問題
大模型生成答案
LLM Generation
返回帶引用的回答
Sources / 頁碼

什么時候要用到 RAG

其實大多數的業務系統可以不上 RAG,通常情況下的業務系統都是通過數據庫記錄數據,很少有需要做數據推理、解釋、總結的相關功能,如果真遇到了需要語義匹配(例如:任務表中有任務描述)等剛需場景再考慮上。

  • 數據規模大:需要參考的知識庫太大,超過了模型上下文限制。
  • 時效性與準確性:數據經常更新,每次更新都要重新訓練模型,成本就太高了。
  • 多租戶/版本數據隔離:非公開數據(例:常見的SaaS系統都有用戶角色控制權限,數據僅某些角色可見)。
  • 長尾:出現頻率低、種類多的一些罕見任務或小眾需求。

題外話:發現了一個開源庫 vanna 可以直接和數據庫進行對話。

這個我也測試了一下,其原理簡單說就是

  1. 訓練:數據庫結構(DDL)、字段說明、示例 SQL 等扔進向量庫,建成私有知識庫。
  2. 提問:用自然語言問問題時,系統先檢索最相關的上下文,再喂給 LLM 生成可直接執行的 SQL,本地運行并返回結果/圖表。整個過程數據不出本地,且每次成功查詢會自動回注向量庫,持續自我優化。

CODE SHOW

使用 AI 編程簡單做了一個小 demo,github源碼

技術架構

客戶端請求
Go API服務 :8080
本地嵌入服務 :5000
本地LLM服務 :5001
MySQL數據庫 :3306
Qdrant向量數據庫 :6333
BGE-M3嵌入模型
Ollama + Llama3/DeepSeek
用戶表
APK表
權限表
向量存儲
權限過濾

核心特性

  • 完全本地化:使用本地嵌入模型和LLM,無需依賴外部API
  • 權限控制:基于用戶角色和單位的多級權限管理
  • 向量檢索:使用Qdrant向量數據庫進行語義搜索
  • 智能問答:結合檢索到的上下文進行個性化回答

核心實現

RAG服務核心邏輯

// 處理用戶查詢的核心流程
func (r *RAGService) Query(userID int, question string) (string, error) {// 1. 獲取用戶信息和權限user, err := r.authSvc.GetUserByID(userID)userAccess := r.getUserAccessContext(user)// 2. 個性化查詢重寫personalizedQuery := r.personalizeQuery(question, user)// 3. 向量檢索(帶權限過濾)apkIDs, contexts, err := r.retrieveAPKs(personalizedQuery, userAccess)// 4. 構建提示詞并生成答案prompt := r.buildPrompt(user, question, contexts)return r.generateAnswer(prompt)
}// 個性化查詢處理
func (r *RAGService) personalizeQuery(query string, user *User) string {if strings.Contains(query, "我") || strings.Contains(query, "我的") {return fmt.Sprintf("%s 上傳者ID:%d", query, user.ID)}if strings.Contains(query, "我們單位") {return fmt.Sprintf("%s 單位ID:%d", query, user.UnitID)}return query
}

向量檢索與權限過濾

// 帶權限過濾的向量檢索
func (r *RAGService) retrieveAPKs(query string, userAccess []string) ([]int, []string, error) {vector, err := r.embeddingSvc.GetEmbedding(query)// 構建權限過濾器filter := &qdrant.Filter{Must: []*qdrant.Condition{{ConditionOneOf: &qdrant.Condition_Field{Field: &qdrant.FieldCondition{Key: "access_scope",Match: &qdrant.Match{MatchValue: &qdrant.Match_Keywords{Keywords: &qdrant.RepeatedStrings{Strings: userAccess},},},},},}},}// 執行向量搜索resp, err := pointsClient.Search(ctx, &qdrant.SearchPoints{CollectionName: "apk_vectors",Vector:         vector,Filter:         filter,Limit:          3,})// 處理搜索結果...
}

本地服務集成

// 嵌入服務調用
func (e *EmbeddingService) GetEmbedding(text string) ([]float32, error) {requestBody, _ := json.Marshal(map[string][]string{"texts": {text}})resp, _ := http.Post(e.baseURL+"/embed", "application/json", bytes.NewBuffer(requestBody))var result struct { Embeddings [][]float32 `json:"embeddings"` }json.NewDecoder(resp.Body).Decode(&result)return result.Embeddings[0], nil
}// LLM服務調用
func (r *RAGService) generateAnswer(prompt string) (string, error) {requestBody, _ := json.Marshal(map[string]interface{}{"prompt": prompt,"model":  "deepseek-coder:6.7b",})resp, _ := http.Post("http://localhost:5001/generate", "application/json", bytes.NewBuffer(requestBody))var result struct { Response string `json:"response"` }json.NewDecoder(resp.Body).Decode(&result)return result.Response, nil
}

API接口示例

# 添加APK
curl -X POST http://localhost:8080/apks \-H "Content-Type: application/json" \-d '{"name": "支付寶", "uploader_id": 1, "visible_units": [101, 102]}'# 智能問答
curl -X POST http://localhost:8080/query \-H "Content-Type: application/json" \-d '{"user_id": 1, "question": "我在哪天上傳了支付寶?"}'

快速啟動

# 1. 啟動依賴服務
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=apk_rag -d mysql:latest# 2. 啟動本地模型服務
ollama serve && ollama pull llama3
python local_embedding.py &
python local_llm.py &# 3. 啟動Go服務
go run .

技術棧

組件技術選型作用
后端服務Go + GinAPI服務和業務邏輯
嵌入模型BGE-M3文本向量化
LLM服務Ollama + Llama3/DeepSeek文本生成
向量數據庫Qdrant向量存儲和檢索
關系數據庫MySQL結構化數據存儲

實際做 RAG 開發中的一些感悟

其實大多數業務系統是不需要使用 RAG 的,先搞清楚自己到底要不要上 RAG

上述 demo 極為簡單,是丐版,離真正的生產使用還差了好遠。如果真的考慮做一個 RAG 系統,可以考慮考慮以下問題(實際生產中的問題更多):

  1. RAG 有一步是數據向量化,是不是可以不用向量化,我直接通過 elastic search 之類的服務做存儲,然后搜出來數據,自己組裝 prompt 丟給大模型。向量化有什么作用?
  2. 什么是 embedding
  3. 向量存儲方案選型?
  4. 模型怎么選,選哪個?
  5. 文檔怎么切?
  6. 如何同當前系統進行結合?
  7. 輸出結果不理想怎么辦,如何調優?
  8. 如何去評估 RAG 的效果好不好?
  9. 拒答閾值怎么定?
  10. 生產級加固,成本和延遲,可觀測性?

最難的點還是在于如何精準的搜索到最相關的上下文

總結

實際生產中,首先得再問一下,是否真的有必要上 RAG

大模型的 RAG 入門并不難,難的是各種細節的調整(數據處理等)。

擼了一個丐版的 RAGdemo,向量化 → 近似召回 → Prompt 拼裝 → 大模型生成。

最后提一嘴,最后調用大模型的參數量越大越好,上下文長度越長越好。

參考

  • vanna,和你的數據庫聊天
  • LLM RAG值得做嗎?
  • 👀10分鐘搞懂RAG架構:離線索引+在線檢索的閉環秘密
  • AI方面的常見術語&&描述

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

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

相關文章

《IDEA 突然“三無”?三秒找回消失的綠色啟動鍵、主菜單和項目樹!》

目錄 一、左上角綠色啟動鍵憑空消失 1.1 解決辦法 二、頂部 File / Edit / View... 整條主菜單欄 罷工 2.1 解決辦法 三、左側 Project 工具窗口 集體失聯,只剩 External Libraries 孤零零 3.1 解決辦法 昨天下午擼代碼,不知道按到了哪兒&#xff…

軟件工程實踐二:Spring Boot 知識回顧

文章目錄一、創建項目(Spring Boot 向導)二、項目最小代碼示例三、運行與驗證四、標準目錄結構與說明五、Maven 依賴最小示例(僅供參考)六、常用配置(application.yml 示例)七、返回 JSON 與統一異常八、Va…

【系列文章】Linux中的并發與競爭[04]-信號量

【系列文章】Linux中的并發與競爭[04]-信號量 該文章為系列文章:Linux中的并發與競爭中的第4篇 該系列的導航頁連接: 【系列文章】Linux中的并發與競爭-導航頁 文章目錄【系列文章】Linux中的并發與競爭[04]-信號量一、信號量二、實驗程序的編寫2.1驅動…

Elasticsearch啟動失敗?5步修復權限問題

文章目錄🚨 為什么會出現這個問題?? 解決方案:修復數據目錄權限并確保配置生效步驟 1:確認數據目錄存在且權限正確步驟 2:確認 elasticsearch.yml 中的配置步驟 3:**刪除或清空 /usr/share/elasticsearch/…

Docker push 命令:鏡像發布與管理的藝術

Docker push 命令:鏡像發布與管理的藝術1. 命令概述2. 命令語法3. 核心參數解析4. 推送架構圖解5. 完整工作流程6. 實戰場景示例6.1 基礎推送操作6.2 企業級推送流程6.3 多架構鏡像推送7. 鏡像命名規范詳解8. 安全最佳實踐8.1 內容信任機制8.2 最小權限原則9. 性能優…

智能合約測試框架全解析

概述 智能合約測試庫是區塊鏈開發中至關重要的工具,用于確保智能合約的安全性、正確性和可靠性。以下是主流的智能合約測試庫及其詳細解析。 一、主流測試框架對比 測試框架開發語言主要特點適用場景Hardhat WaffleJavaScript/TypeScript強大的調試功能&#xf…

【大模型算法工程師面試題】大模型領域新興的主流庫有哪些?

文章目錄 大模型領域新興主流庫全解析:國產化適配+優劣對比+選型指南(附推薦指數) 引言 一、總覽:大模型工具鏈選型框架(含推薦指數) 二、分模塊詳解:優劣對比+推薦指數+選型建議 2.1:訓練框架(解決“千億模型怎么訓”) 2.2:推理優化(解決“模型跑起來慢”) 2.3:…

端口打開與服務可用

端口打開與服務可用“端口已打開但服務不可用” 并非矛盾,而是網絡訪問中常見的分層問題。要理解這一點,需要先明確 “端口打開” 和 “服務可用” 的本質區別:1. 什么是 “端口打開”?“端口打開” 通常指 操作系統的網絡層監聽該…

ByteDance_FrontEnd

約面了,放輕松,好好面 盲點 基礎知識 Function 和 Object 都是函數,而函數也是對象。 Object.prototype 是幾乎所有對象的原型鏈終點(其 proto 是 null)。 Function.prototype 是所有函數的原型(包括 Obje…

go語言,彩色驗證碼生成,加減法驗證,

代碼結構相關代碼 captcha/internal/captcha/generator.go package captchaimport (_ "embed" // 👈 啟用 embed"image""image/color""image/draw""image/png""io""math/rand""golang.…

PuTTY軟件訪問ZYNQ板卡的Linux系統

PuTTY 是一款非常經典、輕量級、免費的 SSH、Telnet 和串行端口連接客戶端,主要運行于 Windows 平臺。它是在開源許可下開發的,因其小巧、簡單、可靠而成為系統管理員、網絡工程師和開發人員的必備工具。網上有非常多的下載資源。 我們使用PuTTY軟件對ZY…

做一個RBAC權限

在分布式應用場景下,我們可以利用網關對請求進行集中處理,實現了低耦合,高內聚的特性。 登陸權限驗證和鑒權的功能都可以在網關層面進行處理: 用戶登錄后簽署的jwt保存在header中,用戶信息則保存在redis中網關應該對不…

【算法】day1 雙指針

1、移動零(同向分3區域) 283. 移動零 - 力扣(LeetCode) 題目: 思路:注意原地操作。快排也是這個方法:左邊小于等于 tmp,右邊大于 tmp,最后 tmp 放到 dest。 代碼&#…

Linux 日志分析:用 ELK 搭建個人運維監控平臺

Linux 日志分析:用 ELK 搭建個人運維監控平臺 🌟 Hello,我是摘星! 🌈 在彩虹般絢爛的技術棧中,我是那個永不停歇的色彩收集者。 🦋 每一個優化都是我培育的花朵,每一個特性都是我放飛…

Linux網絡:socket編程UDP

文章目錄前言一,socket二,服務端socket3-1 創建socket3-2 綁定地址和端口3-3 接收數據3-4 回復數據3-5關閉socket3-6 完整代碼三,客戶端socket3-1 為什么客戶端通常不需要手動定義 IP 和端口前言 學習 socket 編程的意義在于:它讓…

【從零到公網】本地電腦部署服務并實現公網訪問(IPv4/IPv6/DDNS 全攻略)

從零到公網:本地電腦部署服務并實現公網訪問(IPv4/IPv6/DDNS 全攻略) 適用場景:本地 API 服務、大模型推理服務、NAS、遠程桌面等需要公網訪問的場景 關鍵詞:公網 IP、端口映射、內網穿透、IPv6、Cloudflare DDNS 一、…

模塊二 落地微服務

11 | 服務發布和引用的實踐 服務發布和引用常見的三種方式:Restful API、XML配置以及IDL文件。今天我將以XML配置方式為例,給你講解服務發布和引用的具體實踐以及可能會遇到的問題。 XML配置方式的服務發布和引用流程 1. 服務提供者定義接口 服務提供者發…

C++程序員速通C#:從Hello World到數據類型

C程序員光速入門C#(一):總覽、數據類型、運算符 一.Hello world! 隨著.NET的深入人心,作為一個程序員,當然不能在新技術面前停而止步,面對著c在.net中的失敗,雖然有一絲遺憾,但是我們應該認識到…

Linux相關概念和易錯知識點(44)(IP地址、子網和公網、NAPT、代理)

目錄1.IP地址(1)局域網和公網①局域網a.網關地址b.局域網通信②運營商子網③公網(2)NAPT①NAPT過程②理解NAPT③理解源IP和目的IPa.目的IPb.源IP③最長前綴匹配④NAT技術缺陷2.代理服務(1)正向代理&#xf…

工業智能終端賦能自動化生產線建設數字化管理

在當今數字化浪潮的推動下,自動化生產線正逐漸成為各行各業提升效率和降低成本的重要選擇。隨著智能制造的深入發展,工業智能終端的引入不僅為生產線帶來了技術革新,也賦予了數字化管理新的動力。一、工業智能終端:一體化設計&…