![]()
前一課將助手擴展至雲端。本課則將它們「拉下」至單一機器。到結束時,你會擁有一個運作中的工程助理,能夠推理、調用工具、讀取你的檔案和搜索文件——完全不需要任何雲端推論調用。
為什麼你會需要這樣?在真實工程工作中,這裡有三個常見理由:
關鍵是你用一個在 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 -->|top-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 翻譯而成。雖然我們致力於確保準確性,但請注意,機器自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於重要資訊,建議進行專業人工翻譯。我們不對因使用本翻譯而產生的任何誤解或誤釋承擔責任。