![]()
上一課將代理擴展到雲端。本課將它們帶回單一機器。完成後,你將擁有一個可運作的工程助理,它能推理、呼叫工具、讀取你的檔案以及搜尋你的文件 — 完全不須任何雲端推論呼叫。
為甚麼你會需要這樣?在真實工程工作中,經常會遇上三個原因:
限制是你將最先進的雲端模型換成在 CPU、GPU 或 NPU 上執行的小型語言模型 (SLM)。本課聚焦於在此限制內建立良好的代理,而非假裝這限制不存在。
本課將涵蓋:
完成本課後,你將知道如何:
本課假設你已完成先前課程,並熟悉:
你還需要:
requirements.txt 中的套件,加上本課需要的 foundry-local-sdk、openai 和 chromadb。最先進的雲端模型擁有數千億參數和資料中心支撐。SLM 則有數十億參數,且必須能裝載在筆電 RAM 中。此差異設定了明確預期。
SLM 擅長:
SLM 較弱:
所以,對本地代理的成功策略是:讓 SLM 負責協調,讓工具執行繁重工作。 模型不需知道你的程式碼庫 — 它只需知道何時呼叫 read_file 及 search_docs。這正好發揮 SLM 的強項。
flowchart LR
U[開發者] --> A[本地 SLM 代理]
A -->|決定使用哪個工具| T1[讀取文件]
A -->|決定使用哪個工具| T2[搜索文件 RAG]
A -->|決定使用哪個工具| T3[代碼分析]
T1 --> A
T2 --> A
T3 --> A
A --> R[回答,完全在設備上完成]
Microsoft Foundry Local 是一個輕量級運行時,完全在你的機器上下載、管理、服務模型。它最重要的功能是提供OpenAI相容 HTTP 端點 — 意味著 OpenAI SDK 和 Microsoft 代理框架的 OpenAI 用戶端僅需更改 base_url 即可使用。你學過的所有代理開發知識直接遷移;唯一不同是端點從雲端換成了 localhost。
Foundry Local 還會自動選擇最佳的模型建置版本,符合你的硬體 — CPU 版、CUDA/GPU 版或 NPU 版 — 無需你針對每台機器手動優化。
安裝 Foundry Local(請參閱你的作業系統的文件),然後確認其運作:
# 安裝(例子;請依照你平台的文件操作)
winget install Microsoft.FoundryLocal # Windows(視窗系統)
# brew install microsoft/foundrylocal/foundrylocal # macOS(蘋果作業系統)
# 下載並執行 Qwen 模型,然後啟動本地服務
foundry model run qwen2.5-7b-instruct
foundry service status
服務運行後,你就擁有一個本地 OpenAI 相容端點(通常是 http://localhost:PORT/v1)。此 notebook 使用 foundry-local-sdk 自動發現端點,無需硬編碼端口。
一個代理只有能呼叫工具才是真正的代理。許多 SLM 能聊天,但產生不穩定、格式錯誤的工具呼叫。Qwen 模型專門訓練函數呼叫,能穩定產生格式正確的工具呼叫結構 — 這正是讓本地聊天模型變成本地代理的關鍵。
流程是你已熟悉的標準工具呼叫迴圈,只是現在在設備上執行:
sequenceDiagram
participant U as 使用者
participant A as Qwen 代理(本地)
participant T as 本地工具
U->>A: 「auth.py 做什麼?」
A->>A: 決定:呼叫 read_file
A->>T: read_file("auth.py")
T-->>A: 檔案內容
A->>A: 理解內容
A-->>U: 解釋
文件搜尋是本地代理發揮價值的關鍵。你不必指望 SLM 記住你的框架文件,而是將文件嵌入到本地向量資料庫,讓代理按需檢索相關片段。
我們使用 Chroma,一個嵌入式向量存儲,不需伺服器管理且在同一進程運行。流程完全本地:本地嵌入模型 → 本地向量 → 本地檢索 → 本地 SLM。
flowchart TB
D[你的文件 / 代碼] --> E[本地嵌入模型]
E --> V[(Chroma 向量資料庫 - 硬碟上)]
Q[代理查詢] --> QE[本地嵌入查詢]
QE --> V
V -->|前 k 名區塊| A[Qwen 代理]
A --> Ans[有根據的答案]
這是第5課 Agentic RAG 的相同模式 — 唯一改變的是所有元件都運行在你的機器上。
MCP 是一種通訊協定,不是雲端服務。MCP 伺服器可以作為本地進程在 stdio 上運行,透過標準協定向你的代理暴露工具。這讓你可以離線重用越來越多的 MCP 伺服器生態系統 — 檔案系統存取、git 操作、資料庫查詢。
安全狀況與雲端不同,但不表示無風險:本地 MCP 伺服器仍以你的用戶權限運行,所以範圍需限制在它能接觸的內容(專案目錄,而非整個家目錄),且其輸出應視為輸入加以驗證。
本地優先不表示僅限本地。成熟系統會依敏感度和難度導向:
| 情況 | 執行位置 |
|---|---|
| 敏感代碼/資料,或離線狀態 | 本地 SLM |
| 簡單、有界任務 | 本地 SLM(便宜、快速) |
| 非敏感資料的複雜多跳推理 | 雲端模型 |
| 任何情況,停機時 | 本地 SLM(平滑降級) |
這與第16課的模型路由概念相呼應 — 差別在於“模型”之一是你的本機。一個健壯設計在雲端不可用時回退至本地,使代理品質下降而非完全失效。
flowchart LR
Q[請求] --> S{敏感或離線?}
S -->|是| L[本地 SLM]
S -->|否| C{需要深度推理?}
C -->|否| L
C -->|是| Cloud[雲端模型]
L --> Out[回應]
Cloud --> Out
開啟 code_samples/17-local-agent-foundry-local.ipynb 並實作。你將建立一個完全在你的工作站運行的本地工程助理,它可以:
整個過程不使用任何雲端推論。
助理透過 OpenAI 相容端點連接 Foundry Local,所以代理程式碼幾乎與雲端課程相同 — 唯一變動是客戶端:
from foundry_local import FoundryLocalManager
from openai import OpenAI
# Foundry Local 發現/下載模型,並提供本地端點給我們。
manager = FoundryLocalManager(\"qwen2.5-7b-instruct\")
client = OpenAI(base_url=manager.endpoint, api_key=manager.api_key) # api_key 是本地佔位符
工具是普通的 Python 函數,限制在專案目錄:
def read_file(path: str) -> str:
\"\"\"Read a file, but only inside the sandboxed project directory.\"\"\"
full = (PROJECT_ROOT / path).resolve()
if PROJECT_ROOT not in full.parents and full != PROJECT_ROOT:
return \"Access denied: path is outside the project directory.\"
return full.read_text(encoding=\"utf-8\")
注意沙盒檢查 — 即使是本地,一個可讀取任意路徑的工具也是風險。此 notebook 將所有工具限制在單一專案根目錄範圍內。
在進入作業前測試你的理解。
1. 舉出兩個將代理部署於本地而非雲端的具體理由。
2. 在本地代理中,建議 SLM 與工具間的勞動分配是什麼?為什麼?
3. 是什麼使你能用 Foundry Local 重用雲端代理程式碼?
4. 為何我們特地用 Qwen 函數呼叫模型,而非任一 SLM?
5. 在本地 RAG 流程中,哪些元件在本機執行?
6. 本地 MCP 伺服器在你的機器上運行,是否即代表安全?你應該採取甚麼預防措施?
7. 請描述包含本地模型的合理混合路由規則。
8. 執行本課本地代理的現實最低 RAM 需求是?增加 RAM 有何用處?
將本地工程助理擴展成一個本地文件審查助理,針對你選擇的小型專案(也可使用本倉庫任一 lesson 資料夾)。
你需要提交:
新增一個 find_todos 工具,掃描專案中的 TODO/FIXME 註解,並回傳檔案與行號,且同樣進行沙盒檢查如同 read_file。
然後寫一個簡短段落說明你會將什麼移至雲端、什麼保留在本地以供此審查員使用,以及原因。評估重點在於本地元件是否正確串接,以及混合推理是否合理 — 而非模型品質。
在本課中,你建立了一個完全在你自己的機器上運行的代理:
這完成了部署弧線:第16課將代理規模擴展至 Microsoft Foundry,本課則將其縮小至單一工作站。下一課將轉向保持部署代理的安全。
免責聲明: 本文件由 AI 翻譯服務 Co-op Translator 翻譯而成。雖然我們致力於確保準確性,但請注意,機器自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於重要資訊,建議進行專業人工翻譯。我們不對因使用本翻譯而產生的任何誤解或誤釋承擔責任。