1 minute read     Posted on:     Updated on:     Views: Loading...

RAG(Retrieval-Augmented Generation)

大語言模型裝了全世界的知識,不過有些私人的知識是不會放上網路的
這時候要怎麼讓他能夠擁有 你的知識 是很重要的,所以 RAG 本身就是在做這件事情

How RAG Works

你的私人知識必須先進行 Embedding,把這些知識存入資料庫(Indexing)
當你在與 AI 聊天的時候,他會去資料庫檢索最相似的片段(Retrieval)
最後在把你的回答與知識庫裡面的資料合成返回給你(Generation)

也因此,RAG 非常適合充當知識庫查詢的角色
不過需要注意到的是,RAG 只能做讀取的操作,他沒有能力去做寫入

MCP(Model Context Protocol)

Model Context Protocol 是由 Anthropic 在 2024 年推出的開放標準協議
旨在解決 AI 模型跟外部溝通連結的問題

前面提到 RAG(Retrieval-Augmented Generation) 他只能做讀取
而 MCP(Model Context Protocol) 可以做到讀寫

不過 MCP Resources 是靜態的不能改

比方說我之前在工作的時候用了 Figma MCP
讓他可以去讀設計稿,確保我的後端設計符合設計稿
也有用 Claude in Chrome MCP, 讓他自己去操作網頁,以我的例子來說是讓他自己寫 POC,把東西修到可以跑之後再讓我實際操作

Resources, Tools and Prompts

MCP 跟外部系統交互的能力,可以分成 Resources, Tools 以及 Prompts

  • Resources
    • 這是一個靜態的資源,AI 可以透過一個固定的 URL 去存取。AI 沒辦法去做寫入的操作,並且他是被動的
  • Tools
    • Tool 就是給 AI 一個工具,他能夠被主動呼叫執行。他可以自己根據需要,自動的去呼叫
  • Prompts
    • 他是一個提前定義好的 prompts, AI 可以根據這個模板去動作

Differences Between RAG and MCP

我在看到 RAG 跟 MCP Resources 的時候我覺得很奇怪
因為這兩個看起來東西滿相似的

都是提供給 AI 靜態的資源讓他可以使用
不過差別在於說,有沒有處理

當你使用 MCP 的時候,實際上是給你一本書籍的概念
你要的東西應該在這本書裡面,但是你實際上還是要去翻一下內容
而 RAG 則是很精確地跟你說他在哪一本書第幾頁第幾行

並且你用 MCP,如果資料量很大,那 Token 消耗的就會比較多
相比 RAG 則是預處理會花比較多時間

Build a Second Brain

我原本是用 MCP(Model Context Protocol) 來做
不過針對這種 use case, RAG(Retrieval-Augmented Generation) 會更適合

RAG 首先我會需要一個地方存 Embedding 的資料
我還要有方法能夠定時的更新我的 RAG 資料
並且我還要 expose RAG 服務給 AI

我後來決定 MCP 跟 RAG 我都用

  • MCP 用來存取完整部落格資源
  • RAG 用來在眾多文章資源中,精準篩選出我需要的資料,RAG 的工具透過 MCP 呼叫存取

The Codebase

MCP 要怎麼寫,其實很簡單
他本質上就是個後端的 app(他用 JSON-RPC 來溝通)
你需要實作幾隻 API

其中比較重要的是,POST 系列的 API

剩下是 OPTIONS 以及 GET,前者確認該伺服器有哪些 method 可以用,後者確保伺服器是健康的

  • initialize
    • 初始化 MCP server, 以及回傳伺服器資訊
      1
      2
      3
      4
      5
      6
      7
      8
      
      {
        protocolVersion: "2024-11-05",
        capabilities: {
        resources: {},
        tools: {},
        },
        serverInfo: { name: "blog-hybrid-mcp-ts", version: "1.0.0" },
      }
      
  • notifications/initialized
    • 他是初始握手確認通知,回個 {} 就可以了
  • resources 系列
    • resources 就是 mcp 靜態 資源, 有分 list 以及 read
    • resources/list
      • 就是列出該 mcp 上面有哪些靜態資源,以我的例子,就是找出所有部落格文章
    • resources/read
      • 你可以給個參數,讀取特定靜態資源,比方說讀取特定文章
  • tools 系列
    • tools 就是 mcp 動態 工具, 有分 list 以及 call
    • tools/list
      • 就是列出該 mcp 上面有哪些動態工具
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        
        {
          tools: [
            {
              name: searchRagCall,
              description: "use this RAG to search from ambersuncreates.com",
              inputSchema: {
              type: "object",
              properties: {
                query: {
                type: "string",
                description: "what you want to ask about",
                },
              },
              required: ["query"],
              },
            },
          ],
        }
        
    • tools/call
      • 你可以給個參數,呼叫特定動態工具,比方說呼叫 RAG 工具

Cloudflare Worker

解決了 MCP 的程式碼,我們還沒解決 RAG 的部分
RAG 本身是透過 tools/call 去呼叫的,而所有的 MCP 程式碼都是放在 Cloudflare Worker 上

資料存儲則是使用 D1 Database 與 Vectorize Index
我的部署是這樣子的
每當我更新部落格,CI 會觸發兩件事情

  1. 更新 Cloudflare Worker 的程式碼(可參考 deploy_worker.yaml 的流程)
  2. 更新 Embedding 資料(可參考 update_rag.yaml 的流程)

那因為剛好我的 domain 是掛在 cloudflare 上面,所以可以剛好掛個 subdomain 上去我的 mcp
也就是 https://mcp.ambersuncreates.com

單純 GET 得到的就會是

1
{"status":"ok","message":"Blog Hybrid MCP Worker (TS) is running"}

Claude Code Integration

你把 mcp 直接裝去之後他會就會動了,就是這麼簡單

然後就長這樣

Leave a comment