釋放數(shù)據(jù)潛力:利用 MCP 資源讓大模型讀懂你的服務(wù)器

本文已收錄在Github關(guān)注我,緊跟本系列專欄文章,咱們下篇再續(xù)!

  • ?? 魔都架構(gòu)師 | 全網(wǎng)30W技術(shù)追隨者
  • ?? 大廠分布式系統(tǒng)/數(shù)據(jù)中臺實(shí)戰(zhàn)專家
  • ?? 主導(dǎo)交易系統(tǒng)百萬級流量調(diào)優(yōu) & 車聯(lián)網(wǎng)平臺架構(gòu)
  • ?? AIGC應(yīng)用開發(fā)先行者 | 區(qū)塊鏈落地實(shí)踐者
  • ?? 以技術(shù)驅(qū)動創(chuàng)新,我們的征途是改變世界!
  • ?? 實(shí)戰(zhàn)干貨:編程嚴(yán)選網(wǎng)

0 前言

向LLM暴露服務(wù)器上的數(shù)據(jù)和內(nèi)容

資源(Resources)是MCP核心概念,允許服務(wù)器將數(shù)據(jù)和內(nèi)容暴露,供客戶端讀取,并作為大模型交互的上下文使用。

注意

資源是由應(yīng)用控制的,即客戶端應(yīng)用可自行決定資源的使用方式和時機(jī)。不同 MCP 客戶端可能不同方式處理資源,如:

  • Claude Desktop 要求用戶手動選擇資源后才能用
  • 其他客戶端可能會基于啟發(fā)式方法自動選擇資源
  • 有些實(shí)現(xiàn)甚至允許 AI 模型自行決定使用哪些資源。

因此,服務(wù)器開發(fā)者在實(shí)現(xiàn)資源支持時,應(yīng)考慮各種交互方式。如希望自動將數(shù)據(jù)暴露給模型,應(yīng)使用由模型控制的工具。

1 概述

資源可代表 MCP 服務(wù)器希望提供給客戶端的任何類型的數(shù)據(jù),包括但不限于:

  • 文件內(nèi)容
  • 數(shù)據(jù)庫記錄
  • API 響應(yīng)
  • 實(shí)時系統(tǒng)數(shù)據(jù)
  • 截圖和圖像
  • 日志文件
  • 其他各種數(shù)據(jù)

每個資源都有一個唯一 URI 標(biāo)識,內(nèi)容可以是文本或二進(jìn)制數(shù)據(jù)。

2 URI

資源通過 URI 唯一標(biāo)識,格式如下:

[protocol]://[host]/[path]

示例:

  • file:///home/user/documents/report.pdf
  • postgres://database/customers/schema
  • screen://localhost/display1

URI 的協(xié)議和路徑結(jié)構(gòu)由 MCP 服務(wù)器自行定義,服務(wù)器可定制自己的 URI 方案。

3 類型

資源內(nèi)容可分為兩種類型:

3.1 文本

包含 UTF-8 編碼的文本數(shù)據(jù),適合以下內(nèi)容:

  • 源代碼
  • 配置文件
  • 日志文件
  • JSON/XML 數(shù)據(jù)
  • 純文本

3.2 二進(jìn)制

包含使用 base64 編碼的原始二進(jìn)制數(shù)據(jù),適合以下內(nèi)容:

  • 圖像
  • PDF
  • 音頻文件
  • 視頻文件
  • 其他非文本格式

4 發(fā)現(xiàn)方式

客戶端可通過兩種方式發(fā)現(xiàn)可用資源:

4.1 直接資源列表

服務(wù)器通過 resources/list 接口提供明確的資源清單,每個資源包含以下信息:

{
  uri: string;           // 資源唯一標(biāo)識
  name: string;          // 可讀名稱
  description?: string;  // 可選描述信息
  mimeType?: string;     // 可選 MIME 類型
}

4.2 資源模板

對于動態(tài)資源,服務(wù)器可暴露 URI 模板,客戶端可根據(jù)模板生成合法的資源 URI:

{
  uriTemplate: string;   // 遵循 RFC 6570 的 URI 模板
  name: string;          // 可讀名稱
  description?: string;  // 可選描述
  mimeType?: string;     // 可選 MIME 類型
}

5 讀取資源內(nèi)容

客戶端使用資源 URI 通過 resources/read 請求讀取資源,服務(wù)器返回資源內(nèi)容列表:

{
  contents: [
    {
      uri: string;        // 資源 URI
      mimeType?: string;  // 可選 MIME 類型

      // 二選一:
      text?: string;      // 文本內(nèi)容
      blob?: string;      // 二進(jìn)制內(nèi)容(base64 編碼)
    }
  ]
}

服務(wù)器可在一次 resources/read 請求中返回多個資源,如讀取目錄時可返回其中的所有文件。

6 更新

MCP 支持實(shí)時資源更新,主要有兩種機(jī)制:

6.1 列表變更

當(dāng)服務(wù)器的資源列表發(fā)生變化時,通過 notifications/resources/list_changed 通知客戶端。

6.2 內(nèi)容變更

客戶端可以訂閱某個資源的變更:

  1. 客戶端發(fā)送 resources/subscribe 請求并附帶資源 URI;
  2. 服務(wù)器在資源內(nèi)容變更時,發(fā)送 notifications/resources/updated 通知;
  3. 客戶端通過 resources/read 獲取最新內(nèi)容;
  4. 客戶端可以發(fā)送 resources/unsubscribe 取消訂閱。

7 示例

簡單的 MCP 服務(wù)器實(shí)現(xiàn)資源支持的例子:

// 提供資源列表
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: "file:///logs/app.log",
        name: "應(yīng)用日志",
        mimeType: "text/plain"
      }
    ]
  };
});

// 讀取資源內(nèi)容
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const uri = request.params.uri;

  if (uri === "file:///logs/app.log") {
    const logContents = await readLogFile();
    return {
      contents: [
        {
          uri,
          mimeType: "text/plain",
          text: logContents
        }
      ]
    };
  }

  throw new Error("未找到資源");
});
@app.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="file:///logs/app.log",
            name="應(yīng)用日志",
            mimeType="text/plain"
        )
    ]

@app.read_resource()
async def read_resource(uri: AnyUrl) -> str:
    if str(uri) == "file:///logs/app.log":
        log_contents = await read_log_file()
        return log_contents

    raise ValueError("未找到資源")

# 啟動服務(wù)器
async with stdio_server() as streams:
    await app.run(
        streams[0],
        streams[1],
        app.create_initialization_options()
    )

8 最佳實(shí)踐

實(shí)現(xiàn)資源支持時,建議:

  1. 使用清晰、具描述性的資源名稱和 URI;
  2. 添加有用的描述,幫助大模型理解資源;
  3. 在已知的情況下設(shè)置合適的 MIME 類型;
  4. 為動態(tài)內(nèi)容實(shí)現(xiàn)資源模板;
  5. 對頻繁變更的資源使用訂閱機(jī)制;
  6. 出錯時返回清晰明了的錯誤信息;
  7. 對資源列表進(jìn)行分頁處理(如有必要);
  8. 在適當(dāng)情況下緩存資源內(nèi)容;
  9. 處理資源前先驗(yàn)證 URI;
  10. 文檔中注明自定義的 URI 方案。

9 安全

在暴露資源時,請注意以下安全措施:

  • 驗(yàn)證所有資源 URI 的合法性;
  • 實(shí)施適當(dāng)?shù)脑L問控制策略;
  • 清理文件路徑,防止目錄遍歷攻擊;
  • 謹(jǐn)慎處理二進(jìn)制數(shù)據(jù);
  • 對資源讀取設(shè)置速率限制;
  • 審計資源訪問記錄;
  • 傳輸過程中加密敏感數(shù)據(jù);
  • 驗(yàn)證 MIME 類型是否符合預(yù)期;
  • 為耗時較長的讀取操作設(shè)置超時機(jī)制;
  • 適時清理過期或無效資源。

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內(nèi)容