![]()
前一課將代理擴展至雲端。本課則將它們帶回到單一裝置上。結束時,你將擁有一個可以推理、呼叫工具、閱讀你的檔案並搜尋文件的工程助理 — 不需任何雲端推論呼叫。
為什麼會需要這樣?真實的工程工作中,這裡有三個常見原因:
代價是你用一個運行在 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 Agent Framework 的 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)。筆記本使用 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\")
注意沙盒檢查 — 即使本地,讀取任意路徑的工具也是風險。筆記本將每個工具限縮在單一專案根目錄。
在進入作業前測試你的理解。
1. 請舉出兩個在本地而非雲端執行代理的具體原因。
2. 在本地代理中,SLM 與工具之間建議的任務分工是什麼,為什麼?
3. 是什麼讓我們能用 Foundry Local 重用雲端代理程式碼?
4. 為什麼我們特別使用 Qwen 函式呼叫模型,而非任何 SLM?
5. 在本地 RAG 流程中,哪些元件運行於本機?
6. 本地 MCP 伺服器運行於你的機器,是否自動代表安全?你還應該採取哪些預防措施?
7. 請描述包含本地模型的合理混合路由規則。
8. 執行本課本地代理的現實最低 RAM 要求是多少?更多 RAM 有什麼好處?
將本地工程助理擴展成一個你選擇的小型專案的 本地文件審查員(若喜歡可使用本倉庫的任何課程資料夾)。
你的提交應該:
新增一個 find_todos 工具,掃描專案中所有 TODO / FIXME 註解並回傳,包含檔案及行號 — 並保持與 read_file 相同的沙盒檢查。
然後寫一段短文說明你會把什麼移至雲端,什麼會保留在本地給這位評論者,以及原因。你的評分將基於本地組件是否正確連接以及你的混合推理是否合理——而非模型品質。
在本課程中你建構了一個完全在你自己的機器上運行的代理:
本課程完成了部署過程:第16課將代理擴展到 Microsoft Foundry,本課將它們縮小到單一工作站。下一課將聚焦於保持已部署代理的安全。
免責聲明: 此文件已使用 AI 翻譯服務 Co-op Translator 進行翻譯。雖然我們努力追求準確性,但請注意自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應視為權威來源。對於關鍵資訊,建議採用專業人工翻譯。我們不對因使用此翻譯所產生的任何誤解或誤譯承擔責任。