magentic:把 LLM 呼叫寫成 Python 函式簽章
Seamlessly integrate LLMs as Python functions
秒懂
- 它是什麼?
- magentic 用 @prompt 與 @chatprompt 裝飾器,讓函式的參數與回傳型別註記直接決定送給模型的提示與輸出結構。它的價值在於把「呼叫模型」降級成一般函式呼叫,代價是函式庫本身仍在 0.x 階段,且行為高度綁定 pydantic 的型別系統。
- 適合誰用?
- 如果你已經在用 pydantic 定義資料模型,而且希望 LLM 呼叫長得像普通 Python 函式、能被型別檢查器與 IDE 理解,magentic 的裝飾器模型值得放進評估清單。若你需要的是跨語言的服務化推論、或已經有一套以 LangChain 為中心建構的工具鏈,改用 magentic 意味著重寫呼叫層,收益未必抵得過成本。
- 可以商用嗎?
- 可以。MIT 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
- 還在維護嗎?
- 活躍度在下降。儲存庫最近一次提交在 6 個月前。
- 用什麼語言寫的?
- 主要是 Python(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
它想解決的是提示與程式碼之間的型別斷層
一般寫法是把提示字串拼好、送出、再從回應裡撈出想要的欄位。這個過程沒有型別,IDE 幫不上忙,linter 也看不出問題。magentic 的切入點是:既然 Python 函式已經有參數名稱與回傳型別註記,為什麼不讓這些資訊直接生成提示與輸出結構。README 的範例把這件事講得很白,dudeify(phrase: str) -> str 這個函式沒有函式體,因為它永遠不會被執行,呼叫時參數被填進模板,模型產生的內容就是回傳值。當回傳型別換成 pydantic 的 BaseModel 子類,例如 Superhero 帶有 name、age、power、enemies 四個欄位,模型就得照著這個結構回傳,呼叫端拿到的是已驗證的物件而不是一段待解析的文字。這個設計的適用對象很明確:已經在專案裡使用 pydantic,而且希望 LLM 相關程式碼跟其他 Python 模組遵循同一套型別慣例的團隊。
資料流:從裝飾器到 FunctionCall 物件
執行路徑可以拆成幾層。最外層是裝飾器,@prompt 收單一字串模板,@chatprompt 收一串訊息物件,README 列出 SystemMessage、UserMessage、AssistantMessage,並說明大括號欄位會在所有訊息中被填入,FunctionResultMessage 除外。呼叫時,模板中的 {movie} 這類佔位符由實際引數替換。接著是輸出契約:回傳型別註記被轉成模型必須遵守的結構描述,若模型沒照著來,文件提到 LLM-Assisted Retries 會把錯誤回饋給模型重試,這是把驗證失敗轉成再一次提示的機制。再往上一層是函式呼叫,當 @prompt 的 functions 參數帶入 search_twitter、search_youtube 這類普通函式,模型可以選擇呼叫哪一個,此時回傳的不是字串而是 FunctionCall 物件,裡面記著函式與模型給的引數,要由呼叫端自己執行。@prompt_chain 則把這個迴圈自動化,它會解析 FunctionCall、執行函式、把結果送回模型,直到產出最終答案。值得注意的是,用這三個裝飾器建立的函式可以再當成 functions 傳給其他裝飾器,README 說這讓元件能各自測試與改進,這是整個設計裡最實用的一點。
安裝與供應商設定
安裝指令只有兩條,pip install magentic 或 uv add magentic。預設走 OpenAI,README 說設定 OPENAI_API_KEY 環境變數即可,要換供應商則指向 configuration 文件,該文件列出 OpenAI、Anthropic 與 Ollama 等選項。這裡有個實務上的落差:README 只給了環境變數這一個具體鍵名,其餘供應商的設定方式得離開 README 去讀網站文件,本文無法從現有材料確認那些鍵名的實際拼法,因此不在此列出。同樣地,觀測性部分 README 提到使用 OpenTelemetry,並有 Pydantic Logfire 的原生整合,但沒有給出任何初始化程式碼或環境變數,要啟用追蹤必須另外查閱 logging-and-tracing 文件。串流方面,README 介紹 StreamedStr 與 AsyncStreamedStr 兩個類別,讓輸出可以在生成過程中就被處理,而不是等整段回應回來。這些都指向同一個事實:README 是一份導覽,不是完整參考。
0.x 版號與 API 表面積是主要成本
從版本紀錄看,v0.40.0 在 2025 年 6 月,v0.41.0 在同年 10 月,v0.41.1 在 2026 年 3 月。三個版本都在 0.x 之下,語意化版本在 0.x 階段不保證相容性,這是採用前必須自己承擔的判斷。README 的功能清單很長:結構化輸出、串流、重試、OpenTelemetry、型別註記、多供應商設定、聊天提示、平行函式呼叫、視覺輸入、格式化、非同步。功能越多,對應的公開 API 就越多,升級時要檢查的介面也越多。另一個容易被忽略的限制是型別系統的邊界。回傳型別必須是 pydantic 能表達的型別,README 直接連到 pydantic 的型別文件。這意味著如果你的輸出是高度動態的結構,例如欄位名稱取決於執行期資料,硬套 pydantic 模型會變成跟框架對抗,而不是用它省事。這種情況下直接呼叫供應商的 SDK 反而更直接。
什麼時候不該用它:與 LangChain 的路線差異
拿 LangChain 對比最能看出取向差別。LangChain 以鏈、工具、記憶體與檢索器為一級抽象,重心在把多個元件組成一條可設定的流程,提示與輸出解析只是其中一環。magentic 的重心相反,它把 LLM 呼叫壓縮成一個帶型別註記的 Python 函式,函式呼叫與鏈式解析是為了讓這個函式能遞迴地被其他函式使用。差別在於控制流的位置:LangChain 的流程由框架物件描述,magentic 的流程就是 Python 的函式呼叫與回傳。如果你的系統已經圍繞 LangChain 的檢索器與記憶體抽象建構,改用 magentic 等於把呼叫層重寫一遍,而檢索、向量儲存這些部分 magentic 並沒有對應的一級抽象,你得自己想辦法接。反過來說,如果你的需求只是「在既有 Python 服務裡插入幾個有型別的模型呼叫」,LangChain 的抽象層會顯得比問題本身還大。這個取捨跟功能多寡無關,跟你的程式碼裡控制流由誰決定有關。
授權與維護面的實際考量
授權是 MIT,這是寬鬆授權,允許修改、再散布與商業使用,條件是保留著作權與授權聲明。這裡不提供法律意見,只指出實務影響:MIT 不會要求你開源自己的衍生程式碼,對內部服務或商業產品都不構成授權上的阻礙,但如果你把專案原始碼整段複製進自家倉庫,聲明檔必須一起帶走。維護成本方面,材料顯示專案仍在活躍推送,最後一次推送與 v0.41.1 發布同日,並非封存狀態。真正的成本不在套件本身,而在它連帶的依賴鏈:pydantic 是硬依賴,因為輸出結構直接建立在它的型別系統上;pydantic 的主版本升級向來是生態系裡需要排程的事件,magentic 會跟著受影響。另外,由於重試與結構化輸出依賴模型能力,換供應商或換模型時,同一個函式可能從穩定變成偶發失敗,這類回歸不會在單元測試裡靠 mock 抓到,需要對真實模型跑整合測試。
編輯結論
如果你已經在用 pydantic 定義資料模型,而且希望 LLM 呼叫長得像普通 Python 函式、能被型別檢查器與 IDE 理解,magentic 的裝飾器模型值得放進評估清單。若你需要的是跨語言的服務化推論、或已經有一套以 LangChain 為中心建構的工具鏈,改用 magentic 意味著重寫呼叫層,收益未必抵得過成本。動手前先確認三件事:你的回傳型別是否都能用 pydantic 表達,你的供應商是否在 configuration 文件列出的選項內,以及你是否接受 0.x 版號下 API 隨時變動。最後一項不是空話,v0.41.0 到 v0.41.1 之間只隔了數月,版本節奏本身就是風險訊號。
社群筆記