Skip to main content
Glama

從 MCP 到 Multi-Agent:用一台本機 GPU 走完 30 天

iThome 鐵人賽 2026 · 全程零 API 成本,所有程式碼都在本機模型上真的跑過。

這個 repo 是整個系列的程式碼與實測數據。文章本身發表在 iThome, 不放在這裡(同一份內容放兩個地方會變成重複內容)。

outputs/ 底下那 11 份 .txt 是關鍵:文章裡每一段「執行結果」都不是手打的, 是用 scripts/run_day.sh 從真機抓回來、再原封不動貼上去的。 你可以拿它們跟自己機器上跑出來的數字對照。


這個系列在做什麼

30 天疊出一個叫 devbench 的東西:一個本機開發者工作台。 它從一個 MCP Server 開始,長成一群會分工的 Agent。

Day 1-5    Python 地基      型別 / async / 裝飾器 —— 全部是 MCP SDK 的語法基石
Day 6-10   MCP 協定         三大原語 / JSON-RPC / 傳輸層 / 寫出第一個 Server
Day 11-20  Agent 框架       安全治理 / ADK / LangGraph / ReAct / Plan-and-Execute
Day 21-30  Multi-Agent      Supervisor / 記憶 / 評估 / OpenClaw / NVIDIA PAIR

兩條伏筆

① 一個 endpoint 走到底。 從 Day 5 起,全專案只有 src/ironman/config.py 一個地方知道推論端點在哪。 Day 29 裝上 NVIDIA PAIR 之後,同一個 port 會變成整個區網的推論叢集, 而前面 28 天的程式碼一行都不用改。 tests/test_config.py 有一條測試在守這件事——誰把端點寫死,CI 就擋誰。

② Day 1-4 不是無關的 Python 教學。

Day

語法主題

在 Day 10 的回收處

2

型別提示 / dataclass / Pydantic

tool 的 input schema 就是 model_json_schema()

3

async / await / asyncio

MCP 協定全非同步

4

裝飾器 / context manager / generator

@mcp.tool()、lifespan、streaming 的真面目


Related MCP server: agentic-mcp-server

環境

這個系列跑在一台 NVIDIA GB10(DGX Spark 級) 上:

Ubuntu 24.04.4 LTS / aarch64 · 20 核 · 121 GB 統一記憶體
NVIDIA GB10, driver 580.142
Ollama 0.32.14

但你不需要同款機器。除了 Day 28-29 的多節點實測之外, 任何跑得動 Ollama 的機器都能完整重現——把模型換小一點就行。

模型選型

不是拍腦袋決定的,是 Day 1 實測六個模型跑出來的結果 (完整數據見 outputs/day01.txt):

角色

模型

為什麼

主力

nemotron-3.5-lightning:30b

86.4 tok/s,而且是唯一答對「MCP 是什麼」的模型

小模型

llama3.2:3b

59.7 tok/s,夠小才開得起高並行(Day 3 / 22 / 29)

對照組

gpt-oss:20b

交叉驗證 tool schema 沒有綁死單一模型


開始

# 1. 裝 uv(user-level,不碰系統 Python)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. 建環境
git clone git@github.com:jrlinjr/local-mcp-agent-30days.git
cd local-mcp-agent-30days
uv sync

# 3. 確認 Ollama 通了、模型都在
uv run ironman doctor

# 4. 隨便問一句
uv run ironman chat "用一句話說明 MCP" --stream

跑每一天

uv run python days/day01_bench/main.py          # 模型選型實測
uv run python days/day02_typing/main.py         # dataclass vs Pydantic
uv run python days/day03_async/main.py          # 並行度掃描
uv run python days/day04_decorators/main.py     # 手刻 @tool 裝飾器
uv run python days/day05_first_llm/main.py      # 第一支 LLM 呼叫
uv run python days/day07_primitives/main.py     # MCP 三大原語
uv run python days/day08_jsonrpc/raw_client.py  # 手刻 JSON-RPC(不用 SDK)
uv run python days/day08_jsonrpc/raw_client.py --sdk   # 手刻 client 打官方 server
uv run python days/day09_transport/main.py      # stdio vs Streamable HTTP
uv run python days/day10_mcp_server/client_demo.py     # devbench MCP Server

uv run pytest -q                                # 全部測試

把 devbench 掛進 Claude Code

repo 根目錄已經有一份 .mcp.json:

{
  "mcpServers": {
    "devbench": {
      "command": "uv",
      "args": ["run", "python", "days/day10_mcp_server/server.py"]
    }
  }
}

在專案目錄開 Claude Code 就會自動載入,devbench 的四個工具直接可用。


遠端開發:本機編輯,遠端執行

如果你的 GPU 機器不是你打字的那台(我就是), scripts/ 底下兩支腳本讓你不用在筆電裝任何東西:

cp .env.example .env.local    # 填入你的遠端主機(.env.local 不進版控)
bash scripts/sync.sh          # 本機 → 遠端(rsync,本機是唯一權威來源)
bash scripts/run_day.sh 03    # 在遠端跑 day03,輸出抓回 outputs/day03.txt

主機名刻意不寫死在版控裡——它是內部基礎設施資訊,不該出現在公開 repo。 run_day.sh 抓回來的輸出會先過 scripts/scrub.py,把絕對路徑與主機名換成 <專案根目錄> 之類的中性字樣,因為那些輸出會被原封不動貼進文章。


把關機制

uv run pytest -q                      # 36 項端到端測試,不 mock
python3 scripts/verify_outputs.py     # 文章數字 vs outputs/ 逐字比對

verify_outputs.py 掃過每篇文章的程式碼區塊,把有數字的實測宣稱(tok/s、秒數、byte 數、pid、JSON-RPC 訊息框)挑出來,到 outputs/ 裡逐字比對,找不到就失敗。程式重跑之後數字會變,這條檢查會逼我把文章一起更新,而不是留著舊值。

文章不在這個 repo 裡,所以 clone 下來跑它會說「沒有文章可查核」,那是正常的。留著它是為了說清楚 outputs/ 裡那些數字是怎麼被把關的。

tests/test_config.py 裡有一條測試在守伏筆一:全專案只有 config.py 可以寫死推論端點,誰違反誰就掛。

scripts/scrub.py 在擷取輸出時自動抹掉絕對路徑與主機名——那些輸出會被原封不動貼進文章,不該帶著我的使用者名稱跑出去。


每日索引

文章發表於 iThome 鐵人賽 2026。這裡列出對應的程式碼與實測輸出。

Day

主題

程式碼

實測輸出

1

開賽宣言:模型選型實測

day01_bench

day01.txt

2

型別提示、dataclass 與 Pydantic

day02_typing

day02.txt

3

async / await 與 asyncio

day03_async

day03.txt

4

裝飾器、Context Manager、Generator

day04_decorators

day04.txt

5

用 uv 建專案 + 呼叫第一支 LLM API

day05_first_llm

day05.txt

6

MCP 是什麼:Host / Client / Server

觀念篇

—

7

MCP 三大原語:Tools、Resources、Prompts

day07_primitives

day07.txt

8

JSON-RPC 2.0 與 MCP 訊息生命週期

day08_jsonrpc

day08.txt · day08_sdk.txt

9

傳輸協定:stdio vs Streamable HTTP

day09_transport

day09.txt

10

實作:用 Python SDK 寫一個 MCP Server

day10_mcp_server

day10.txt · 測試


目錄

src/ironman/       共用地基
  config.py        ★ 唯一的設定來源(Day 29 的伏筆)
  models.py        Day 2 的資料模型,後面一路沿用
  llm.py           ★ 全系列唯一打 Ollama 的地方
  cli.py           uv run ironman ...
days/              每一天的可執行範例
outputs/           真實執行輸出(文章裡每個數字的來源)
tests/             端到端測試,不 mock
scripts/           遠端執行、輸出清洗、數字查核

版本注意

MCP Python SDK 用的是 2.x。v1 的 from mcp.server.fastmcp import FastMCP 已改名為 from mcp.server.mcpserver import MCPServer, 且回應物件的欄位從 camelCase 改成 snake_case (protocolVersion → protocol_version)。 網路上多數教學還停在 v1,照抄會直接爆——Day 10 有完整說明。


授權

程式碼採用 MIT License,隨你使用、修改、散布。

文章本身不在這個 repo 裡(發表於 iThome),著作權另計。 若你在自己的文章或簡報引用這裡的實測數據,附上出處連結就好。

Available Tools

4 tools
git_logA
Read-onlyIdempotent

查看專案最近的 git commit 紀錄。

Inputs: count. Returns: result

list_filesA
Read-onlyIdempotent

依照 glob 樣式列出專案內的檔案。

Inputs: limit, pattern. Returns: result

read_fileA
Read-onlyIdempotent

讀取專案內的一個檔案並回傳內容(附行號)。

Inputs: path (required), max_lines. Returns: result

run_testsA

在專案內執行 pytest 並回傳結果摘要。

Inputs: target. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool performs a distinct operation: listing files, running tests, viewing git history, and reading file contents. There is no overlap or ambiguity between any pair of tools.

    Naming Consistency4/5

    The verb_noun pattern is mostly consistent (list_files, run_tests, read_file), but git_log deviates slightly as it reads more like a noun compound than a verb phrase. Overall, naming is clear and predictable.

    Tool Count5/5

    Four tools is a well-scoped set for a development inspection environment. Each tool serves a clear purpose without redundancy, and the count feels neither too thin nor bloated.

    Completeness4/5

    The tool set covers the core read-only workflows: enumerating, reading, testing, and version tracking. Missing write/edit capabilities could be a gap in some augmentation contexts, but for a benchmark or inspection tool, this surface is mostly sufficient.

    Related MCP Connectors

    Related MCP Servers