把 LM 呼叫搬進 OTP:Elixir 版 DSPy 現身
GitHub(deepfates/imp)· 2026-09-28
Imp 把每一次呼叫語言模型的動作,變成一個由 supervisor 監督、自己保有狀態的 OTP process,而不是一次性、叫完就結束的函式呼叫。imp 0.5 是這個套件在 Hex(Elixir 的套件註冊網站)上的第一個版本,官方定位是「DSPy 完整移植到 BEAM」。對還在用一般 SDK 包裝 LM 呼叫的 Elixir 開發者來說,這是第一次有人把 DSPy 的宣告式寫法,跟 BEAM 的容錯模型直接接起來。
背景
在 Elixir 上要串 LM,原本沒有原生框架,多數團隊的做法是把 OpenAI 或 Anthropic 的 SDK 包成一個普通函式,丟字串進去、拿字串出來。這種呼叫沒有型別、沒有自己的狀態、也不在 OTP 的監督樹裡,一旦某一步逾時或回傳格式跑掉,通常得靠外層手寫例外處理,或是整條呼叫鏈直接中斷。要做重試、要記錄每一步呼叫過哪些工具、要幫慢請求設逾時、要換模型或調整提示詞,全部得自己手動兜起來,跟 Elixir 語言「一個 process 掛了不拖垮全局」的哲學完全脫節。
更麻煩的是,這些函式呼叫彼此獨立,沒有共同的狀態容器,想追蹤一支多步驟 agent 目前跑到哪一步、上一步輸出了什麼,通常得自己另外拉一個 GenServer 或資料庫來記錄,等於在 BEAM 上手工重造監督與狀態管理,而這本來就是 OTP 該做的事。DSPy 在 Python 世界解決了宣告式定義與自動優化的問題,但那套框架建立在 Python 的執行模型上,本來就沒辦法直接搬進 BEAM。
核心改動
Imp 的做法,是把 DSPy 的 signature 與 module 概念,原封不動地對應到 BEAM 的 process 模型上。一個 signature 是一段型別化的宣告,例如官方範例裡的 "issue -> kind: enum[bug,feature,question], summary",描述輸入輸出長什麼樣子,再交給 Imp.predict 執行;module 則是把多個 signature 組合成一支可以拿標註範例去改進的程式。差別在於,每次執行不是普通函式呼叫,而是啟動一個受 supervisor 監督的 OTP process,自己保有狀態、能收訊息,失敗了可以被監督樹接住重啟,不會拖垮呼叫它的其他程式。
# 傳統函式呼叫
result = OpenAI.chat(prompt: "分類這個 issue: " <> text)
# Imp 的宣告式呼叫
triage =
"issue -> kind: enum[bug,feature,question], summary"
|> Imp.signature("Triage a GitHub issue.")
|> Imp.predict(lm: lm)在自動優化上,Imp 移植了 DSPy 那一套做法,其中三種最具代表性。GEPA 會讀取失敗案例,交給一個更強的反思模型重寫提示詞指令;MIPROv2 則是同時搜尋指令與範例的組合,找出對整支程式表現最好的配置;SIMBA 不需要額外的反思模型,而是直接比較程式自己跑出來的多次嘗試,從表現較好與較差的差異裡歸納出可套用的規則。其餘幾種——LabeledFewShot 挑選現成的範例、BootstrapFewShot 有系統地篩出好用的示範,以及直接做 fine-tuning、GRPO 微調模型權重——原理上都是圍繞「用標註範例讓程式自己變好」這條主線的不同手法。
這些優化器能跑起來,靠的還是底層那層 OTP process:Imp 的 process 內建逾時控管與透明的工具呼叫追蹤,一支 agent 呼叫外部工具逾時或卡住,可以由監督機制接手處理,每一次工具呼叫也會被即時記下來,而不是像包裝過的 SDK 函式那樣呼叫完就什麼紀錄都沒有。除了優化器,Imp 也支援 MCP 匯入外部工具、ACP 把整支程式匯出成 Zed 相容的 agent,以及針對超出 context window 的輸入設計的 RLM 模式,另外還有用沙盒表達式執行的 CodeAct、program-of-thought 兩種形式可以選。
影響範圍
值得關注的有兩群人:一群是已經在用 Elixir 做 agent 或 LLM 應用的團隊,想要故障可恢復、能被監督樹接住的 LM pipeline;另一群是本來就用 DSPy、但苦於 Python 沒有原生併發容錯模型的人,可以拿 Imp 當對照參考。想用 MCP 把公司內部既有的工具掛進 signature 裡直接用,或是想把整支 Imp 程式用 ACP 匯出成 Zed 相容的 agent,都可以直接照官方文件的接法試;輸入量常常超過 context window 的場景,例如整份 log 或整個 repo 丟進去做摘要,RLM 模式就是專門為這種情況設計的,值得優先評估。動手試之前,有幾件事要先檢查:版本需求是 Elixir 1.19 以上,編譯期還需要 C/C++ compiler(因為依賴 jaxon、erlexec 這類原生套件),第一次編譯也需要網路連線,模型供應商的連線則統一透過 ReqLLM 這層處理。另外 imp 0.5 只是它在 Hex 上的第一個版本,官方文件也明講 API 之後可能還會變、優化器也需要更大規模的實測,要接上生產環境的關鍵路徑之前,這點得有心理準備。