筆記: AI Agent & MCP & A2A
警語
- 本文是研究了一點最近超夯的 MCP,整理了我自己讀過跟練習過後的筆記,沒有什麼原創性,蠻鼓勵大家去讀最後列出來的參考資料的內容。
- 文章中會出現 LLM 跟 Model,是指同一件事。
- 文章中會出現「工具」,也等同於 Function、Tool。
- 文章中的 Function Calling = Tool Use = Tool Calling
- 最後,仍在學習中,歡迎糾錯。
前情提要
LLM (Large Language Models) 是一種 Pre-trained model,Pre-trained 就是預先訓練好,這樣就會受限於受訓資料,例如某個 Model 是用 2021 年以前的資料訓練的,那他就只有 2021 年以前的能力。
那要怎麼讓 LLM 更強大?
- Fine Tuning: 基於現有的 Model 更近一步地去訓練,成本高,不容易實現。
- RAG: 我們自己提供更精確、更新、更多的資料給 Model,並且限定 Model 只能基於這些資料回答問題
- 資料來源與處理是個問題
- 取決於資料品質的好壞
- Prompt 還是很重要 - Function Calling / Tool use / Tool Calling: 擴增 Model 的能力,讓 Model 可以採用外部的服務或工具,去讀取外部的資料等。
什麼是 AI Agent
根據 ChatGPT 給我的回覆:AI Agent 是一種結合了 LLM、工具使用、記憶與任務規劃能力的自治智能體,主動完成複雜任務。
這句話裡有提到「工具使用」,這就是我們擴展 Model 能力的一種方式,這邊要特別注意,工具 (Function/Tool) 是我們要自己開發的(或用其他人開發的),並不是 LLM 提供的,這個工具也是在我們的環境執行的(或我們呼叫遠端 API 等)。
假設我們是自己開發,那步驟就是:
- 先開發好這些工具
- 定義好這些工具的資料,包括名稱、描述、參數等等
- 當使用者提問時,我們把使用者的問句,加上這些工具的「資料」傳送給 Model,這邊要特別注意,不是工具本身喔,只是傳送工具的資料(名稱、描述、參數等等)給 LLM
- 在過去會需要透過我們自己開發 Prompt 的方式將這些工具描述傳送給 Model,然後請 Model 判斷使用者的提問可以用到哪些工具、參數是什麼等等。
- 現在廠商們開始提供的 function calling / tool use 的功能,例如 OpenAI 的 API 就有提供 tools 等參數的設定,讓我們可以明確地提供工具列表,API 的 response 裡也會明確告訴我們,這次的回覆是要做工具呼叫。 - 如果有合適的工具可以使用,Model 會回傳使用哪幾個工具 (function name) 跟這些工具的參數等。
- 我們的 Agent 就去呼叫這些工具(其實就是呼叫函式)⇒ 注意,這件事是發生在我們的環境裡,不是 Model 那邊。
- 拿到工具回傳的結果後,由於這些結果很有可能是某個 API 的回覆,那格式可能會是 JSON 等只有電腦/工程師才看得懂的樣子,所以我們會再傳給 Model,請 Model 幫我們把這個結果轉化成人類語言。
- 最後我們把 Model 回傳回來的、人類語言的資訊呈現在畫面上。
下圖就是我們自己用 OpenAI API 開發 AI Agent with Tool Use 的時序圖,是我從一篇文章中讀到的,覺得非常清楚,鼓勵大家可以參考原文。
動手做
(讀書會中有讓大家試著做做看一個簡單的 AI Agent,感受一下什麼是 AI Agent,加上 Tool Use 後又是什麼感覺,蠻推薦大家這樣練習看看,這樣在看 MCP 時會更有感覺。)
歡迎大家參考五倍學院龍哥的 AI Agent 實作工作坊,這邊就不提供程式碼了,只需要知道最一開始開發的 AI Chat App 是無法查詢本地時間的,其實去問 Claude Desktop 或是 VSCode Copilot 也都會拿到無法知道本地時間的回覆。(但 ChatGPT with GPT-4o 是可以的)
版本 1: 用 OpenAI 的 API 做一個基本的 AI Chat App,沒有加上 Tool use ⇒ 會無法查詢本地時間
版本 2 with tool use: 加上時間工具的時間,可以查詢本地時間了!
⇒ 如果要換一個 Model 或是換一家 API 呢?甚至有的廠商根本沒有提供 tool use 功能?
這邊看一下各家的格式範例:
OpenAI 的格式
Claude 的格式
Gemini 的格式
Why MCP
Before MCP
根據前文,Claude, GPT 跟 Gemini 要串接 GitHub 的話,要實作三份不同的程式碼
⇒ 每個 Model 說的語言都不同,要串接不同的外部服務,就都要各說一遍
⇒ MxN 問題
After MCP
MCP 就是想要幫我們解決這件事,我們用 MCP Server 把原本的工具包裝起來,我們的 AI Agent 或是 Claude Desktop / VSCode 等工具,只要開發好 MCP Client 就可以調用這些 MCP Server 了,因為 MCP 是一個統一的協定,所以會通用,不需要為每個 Model 都各自開發一次。
⇒ 大家統一說同一種語言,MCP 作為一種 adapter 模式,把上、下不同的介面封裝起來
⇒ MCP 提供一個通用的協定,把 MxN 降為 M + N (M 種 Model, N 個 MCP Server)
也就是只需要為某個 function/tool 開發好一次 MCP server,就可以給所有支援 MCP Client 的 Application 使用(包括 Claude Desktop, VSCode …等)
MCP 架構
- MCP Hosts: 例如 Claude Desktop, VSCode 或我們自己開發的 app/agent 等
- MCP Clients: 負責跟 MCP server 保持一對一連線,通常就內建在 MCP Hosts 裡了
可提供給 Servers 的兩種能力
- Roots: 代表主機應用程式環境的入口點,如本地文件系統中的特定目錄,伺服器可能被授予存取權限。存取需要明確的用戶同意。
- Sampling: 允許伺服器請求主機 AI 模型基於提供的提示生成文字
⇒ Claude Desktop, VSCode 等都內建 MCP Client 了,所以只需要設定一下就好了 - MCP Servers: 就是一隻程式,負責跟 MCP Clients 溝通,也負責處理特定任務,例如讀取資料庫、讀取硬碟、整合 GitHub、串接 Discord 等
⇒ MCP Server 別想得太難,就是一隻跑在本地的小程式,跟 MCP Client 與真正的 Tool/Function 作介接
⇒ 跑在本地,那本地需要有 MCP Server 的 runtime,例如 MCP Server 是用 NodeJS 寫的,那就要有 NodeJS 的 runtime,或 python 亦然,所以有的人也會包成 Docker Image(那也就要有 container runtime)。
⇒串接的對象 (Tool/Function) 可以在本地(STDIN/STDOUT),也可以在遠端(HTTP SSE)
可提供給 Clients 的三種內容
- Resources: File-like data that can be read by clients (like API responses or file contents)
- Prompts: Pre-written templates that help users accomplish specific tasks
- Tools: Functions that can be called by the LLM (with user approval)
動手做: MCP Server 範例
幫 Claude 加上可以查詢本地時間的功能
uv init .
uv venv
uv add "mcp[cli]"
# 開發 demo.py
# 測試
mcp dev demo.py
# 安裝進 Claude
mcp install demo.py
# 也可以安裝進 VSCode --> 如果有設定 chat.mcp.discovery.enabled 為 true 的話,
# VSCode 會自動去偵測並重用定義在其他工具(例如 Claude Desktop) 的 MCP server
# demo.py
from mcp.server.fastmcp import FastMCP
from datetime import datetime
mcp = FastMCP("Hello MCP")
@mcp.tool()
def get_current_datetime():
"""
取得現在時間
"""
return datetime.now().isoformat()
MCP 底層解析
其實原理跟我們自己開發 AI Agent 是一樣的,也還是要想辦法把我們有提供的 MCP 資料列表送給 LLM。之前在開發 AI Agent 時,我們需要自己把有提供的 tools 加上 messages (大部分是使用者的問句)送進 LLM 裡,而各家 Model 的 API 對於怎麼送工具描述列表給他都有各自的格式與做法,且每個 AI Agent 跟每個 Tool 間的呼叫方式可能也不同,MCP 就是想要統一這一塊。
MCP 制定了 MCP Client 跟 MCP Server 之間的溝通,可以參考官方網頁 https://modelcontextprotocol.io/docs/concepts/transports。
至於 MCP Client 到底怎麼跟 LLM 溝通的,根據這部影片 [YT] MCP是怎么对接大模型的?抓取AI提示词,拆解MCP的底层原理,他是用 VSCdoe + Cline 去測試的,就他研究的結果,其實就是 messages 裡列出了 MCP 的描述列表…好像又走回頭路了?但影片中也提到,或許這也是為什麼 MCP 通用性很強大的原因,其實就是幫我們寫好了 Prompt,LLM 本來就可以讀懂 Prompt,不需要做什麼修改,就可以直接整合了,這樣即便整合的 Model 沒有支援 function calling 的功能,也都能做到。
備註: 原本自己開發 AI Agent,需要模型有提供 function call 的功能,否則也是要自己寫 Prompt。
備註: 不確定其他工具,像是 Claude Desktop 的 MCP Client 怎麼跟 LLM 溝通的,這樣說來,這一段的一致性好像也還不是很確定?
MCP Server Market
這些網頁列出了不少已經被開發出來的 MCP Server,可以多參考,但要注意安全。
- https://mcpservers.org/
- https://smithery.ai/
- https://github.com/modelcontextprotocol/servers
- https://modelcontextprotocol.io/examples
MCP & A2A
- MCP: AI Agent如何用好工具、存取資料
- A2A: AI Agent如何彼此協作、分工合作
- 基於現有的 Web 協定,讓 AI Agent 之間可以彼此溝通
但根據 iHower 的說法,底層其實仍然是 MCP
由 Agent A 透過 MCP client (也就是 function calling) 發一個 A2A 格式訊息,到另一個 提供 A2A 格式的 HTTP API Server 去處理。
⇒ Agents As Tools (這樣說來,好像就沒什麼神奇的了 XD)
資安疑慮
把別人寫的東西拉到自己的電腦來跑,always 有風險,npm 套件、docker image 跟 MCP server 都是。
參考資料
- 五倍學院龍哥的 AI Agent 實作工作坊
- Create an Agent with OpenAI Function Calling Capabilities
- https://modelcontextprotocol.io/introduction
- [YT] MCP 是什麼?可以吃嗎?
- [YT] MCP是啥?技术原理是什么?一个视频搞懂MCP的一切。Windows系统配置MCP,Cursor,Cline 使用MCP
- [YT] MCP是怎么对接大模型的?抓取AI提示词,拆解MCP的底层原理
- [YT] 什麼是 MCP? 3 個 n8n AI Agent 情境解析 MCP 使用|🧠 省力知識庫|n8n 範例
- ihower FB https://www.facebook.com/photo/?fbid=10162264877348971&set=a.10150981726703971
- MCP 資安討論 https://www.facebook.com/photo/?fbid=10170817410245328&set=gm.2873205006196726&idorvanity=2205721126278454
- 讓 AI Agent 彼此溝通:Google A2A 和 Anthropic MCP 深度解析