用自訂 DSL 讓 agentic workflow 值得信任、可以驗證(第 1/2 段)


🏦 台灣Pay 銀行轉帳 💙 PayPal
Elicit 說明為何及如何用自訂 DSL「Ash PL」打造可信、可驗證的研究 agent
- 00:17 講者 James Brady,分享他的公司如何用自訂的 domain-specific language(DSL)讓 agentic workflow 可信且可驗證
- 07:25 範例程式:替 Elicit 自己做競品分析,搜尋其他學術搜尋引擎、AI 助理、系統性文獻回顧工具,合併結果並豐富來源
- 14:33 接下來進入 demo,並再次提到嚴謹度與速度之間常有取捨
💡 你可以怎麼用:挑 AI 研究工具時,不要只看答案漂不漂亮,也要看它能不能讓你看到每一步、點回原始出處。自己跟 AI 反覆修改東西時,先把最初的目標寫成一段話放在最前面,每改幾輪就拿它對照,看有沒有跑偏。
看全部 41 條重點
🧑🏫 這是 Elicit 的講者 James Brady 的分享。Elicit 是做研究用的 AI 工具,他講的是:公司為了讓 AI agent 做研究的過程能被信任、也能被檢查,自己設計了一套專用的程式語言。就算你不寫程式,也值得看,因為他把「為什麼同一個答案,有的可以信、有的不能信」講得很清楚。
- 00:17 講者 James Brady,分享他的公司如何用自訂的 domain-specific language(DSL)讓 agentic workflow 可信且可驗證↳ 講者 James Brady 要分享:公司自己設計了一種 DSL(專為某個領域打造的小型程式語言),用來寫 agentic workflow(AI agent 做事的步驟流程),讓流程能被信任,也能被檢查。
- 00:17 議程:先說明為何選擇 DSL,再介紹語言設計決策、如何整合進產品,接著 demo,最後總結↳ 這場的順序是:為什麼選 DSL → 這個語言怎麼設計 → 怎麼放進產品 → 實際示範 → 總結。先講動機,再講做法。
- 00:47 提問:兩個系統產出完全相同的結果,你會同樣信任它們嗎?答案是要看系統內部如何產生這個輸出↳ 他先丟出一個問題:兩個系統給你一模一樣的答案,你會一樣相信嗎?他的意思是不一定,要看答案背後是怎麼做出來的。
- 00:47 答案「怎麼產生的」(機制)跟最終輸出本身一樣重要,只是重要的面向不同↳ 重點不只在答案本身,也在產生答案的過程。答案決定你拿到什麼,過程決定你敢不敢拿來用,兩個都要顧。
- 01:17 例子:靜態分析工具說「程式碼沒有安全漏洞,可以上線」,如果背後是較舊的模型,你對這句話的反應會很不一樣↳ 例如一個自動檢查程式碼的工具說「沒有安全漏洞,可以上線」。如果你知道它背後只是舊模型隨便看一下,大概不敢照做。
- 01:49 如果是最新模型,而且做了大量 tool use、批判與重寫,就算訊息一字不差,本質上也是完全不同的東西↳ 如果背後是最新模型,還用了很多 tool use(AI 自己去呼叫搜尋等工具),又自己挑毛病再改寫過,同一句話的份量就完全不同。
- 02:20 系統內部結構沒有唯一正確的設計方式,這是一種設計選擇,取決於領域、使用者和任務↳ AI 系統內部要怎麼安排步驟,沒有唯一正解,要看領域、使用者和任務來決定。
- 02:20 存在速度與嚴謹度(speed vs rigor)的取捨:越深入、越高品質的工作自然就越花時間,沒有標準答案↳ 做得快和做得仔細常常要取捨。像查資料,隨手搜一下很快,逐篇讀完再比對就很慢,選哪個要看你的需求。
- 02:51 提供者的品牌與取向也有影響:Elicit 以超高可靠度、高品質和資料來源可追溯(data provenance)自豪↳ 誰做的工具也會影響你信不信它。Elicit 強調高可靠、高品質,還有 data provenance,也就是每筆資料都能追到出處。
- 03:21 打造研究 agent 時歸納出三個要件(desiderata),這個 research agent 也是之後 demo 的主角↳ 他們在做研究 agent(替你查資料、做研究的 AI 助理)時,整理出三個必要條件(desiderata,意思是「想達成的需求」)。後面示範的就是這個 agent。
- 03:21 要件一:agent 的流程必須可讀(legible),人和其他 agent 都能抽查,例如可以跑 critique agent 來檢查↳ 第一,流程要 legible(看得懂):人可以抽查每一步,也可以讓專門挑錯的 critique agent 來檢查。流程如果是黑箱,就沒辦法驗證。
- 03:52 要件二:反覆修改流程時要保持忠實(fidelity),不能偏離使用者原本想做的事↳ 第二,要有 fidelity(忠實度):你一次又一次要求修改流程時,它不能改著改著就忘了你原本要做什麼。
- 04:22 反覆修改時容易越改越偏,模型變得混亂,只好重來或回頭,這很惱人,而且確實會損害信任↳ 跟 AI 來回修改東西時很常遇到:改幾輪就歪了,模型自己搞混,只好重開或退回前一版。這很煩,也會讓人不敢再信它。
- 04:54 目標是能加入新層次、轉往不同方向,同時保有使用者原始意圖的清晰與一致↳ 理想狀態是:你可以加新東西、換方向,但最初想要的目標一直清楚、前後一致,不會被後來的修改沖掉。
- 04:54 要件三:流程必須被忠實執行,也就是要確保系統真的照著那組步驟做↳ 第三,要確實照計畫執行:把步驟寫出來是一回事,還要能確保系統真的照那些步驟一步步做。
- 05:25 這三個要件自然導向 DSL;講者強調不是每個人都該用 DSL,只是 DSL 對他們而言是好選擇↳ 這三個條件讓他們走向自己設計 DSL。不過講者特別說,不是每個人都該這樣做,只是剛好適合他們。
- 05:25 他們的 DSL 叫 Ash PL,名稱中的「Æ」叫 Ash,是古英文的一個字母,用於 Elicit 產品中的 agentic workflow↳ 他們的語言叫 Ash PL。Æ 是古英文字母,念作 Ash;PL 通常是 programming language(程式語言)的縮寫。Elicit 用它來寫 agent 的流程。
- 05:55 Ash PL 是 Turing incomplete,相對簡單:沒有迴圈、沒有遞迴、沒有 mutation,是純函數式(purely functional)的 reactive 語言↳ Ash PL 刻意做得很陽春:Turing incomplete(能力受限),沒有迴圈和遞迴,也不改動資料;純函數式是同樣輸入必得同樣結果,reactive 是輸入一變,結果就自動更新。
- 05:55 它是 Python 的「有主見的子集」(opinionated subset),不是隨便拿掉 Python 幾個功能而已↳ 它是 Python(常見的程式語言)的「有主見的子集」:只取 Python 的一部分,而且每個取捨都有明確理由,不是隨便砍掉幾個功能。
- 06:25 做法是拿掉用處不大的 Python 語言功能,再加入自身領域專屬的 primitive↳ 具體做法是:拿掉他們用途裡用不太到的 Python 功能,再加上領域專用的 primitive(語言內建、直接叫得出來的基本功能)。
- 06:25 領域是科學研究與實證、高風險決策;內建 primitive 例如檢索學術論文、臨床試驗↳ 他們的領域是科學研究、講求證據、風險很高的決策。所以內建的功能像是「搜尋學術論文」「查臨床試驗」,一行就能呼叫。
- 06:55 Ash PL 看起來很像 Python(因為本來就是它的子集),而且有型別,型別錯誤時可以快速重寫↳ 寫起來很像 Python,而且有型別(每個值都標明是文字、數字還是清單等)。型別對不上時馬上就會發現,可以很快改寫。
- 07:25 範例程式:替 Elicit 自己做競品分析,搜尋其他學術搜尋引擎、AI 助理、系統性文獻回顧工具,合併結果並豐富來源↳ 示範程式拿 Elicit 自己做競品分析:分別搜尋學術搜尋引擎、AI 助理、系統性文獻回顧工具,再把結果合併,並補上更多來源資訊。
- 07:56 核心引擎:由一個元件撰寫 Ash PL,再用一般 Python 程式碼解譯,然後依結果重寫 Ash PL↳ 核心是一個循環:一個元件負責寫 Ash PL 程式,再用一般 Python 程式解譯它(逐句讀懂並執行),然後根據結果改寫程式。
- 08:26 例:寫出的程式有型別錯誤就退回撰寫元件修正,再解譯、拿到結果、再改寫,形成「寫→解譯→改寫」的持續循環↳ 例如程式的型別寫錯了,就退回去讓它改;改好再執行、看結果、再調整。整個系統就是「寫→執行→改」一直循環。
- 08:56 系統架構:使用者在網頁瀏覽器的 UI 操作,UI 與 append-only event log 溝通,用這種方式管理分散式資料結構↳ 使用者在瀏覽器上操作,介面把每個動作記進 append-only event log(只能往後加、不能改的操作紀錄),用它來同步分散在各處的資料。
- 09:26 架構元件包括 Python service、sandbox,以及負責撰寫 Ash PL 的 curator(投影片上以 Claude/Anthropic 的橘色標示)↳ 系統有幾個部分:Python service(後端服務)、sandbox(跟外界隔開的工作空間),還有負責寫 Ash PL 的 curator。投影片上 curator 用 Anthropic 的橘色標示。
- 09:56 使用者點按鈕、輸入查詢會產生 event 並附加到 event log;Python service 是 event sourcing 模式的 message broker↳ 你按按鈕或輸入查詢,就會產生一筆 event(事件紀錄)加進 log。這種做法叫 event sourcing(以事件紀錄為準),Python service 在裡面當 message broker(轉送訊息的中間人)。
- 09:56 sandbox 負責撰寫 Ash PL,Python service 負責解譯;寫與解譯的來回就在這兩者之間發生↳ 分工是:sandbox 這邊負責寫 Ash PL,Python service 負責執行。程式就在這兩者之間來回傳遞、修改。
- 10:27 wrapper 是擋在 curator 前面的抽象層,可以抽換不同的 harness↳ curator 前面還隔了一層 wrapper(包裝層),好處是背後的 harness(驅動 AI 模型做事的外殼程式)可以隨時換掉,不用動到其他地方。
- 10:57 試過的 curator 實作:Agent SDK、Pi 搭配 Claude、Pi 搭配 Codex↳ 他們試過幾種 curator 的做法:Anthropic 的 Agent SDK(開發 agent 的工具包)、Pi 搭配 Claude、Pi 搭配 OpenAI 的 Codex。
- 10:57 curator 用上最好的模型與 harness 很重要;目前用 Pi 搭配 Anthropic 模型,對他們來說是最佳組合↳ 寫程式的 curator 要用最強的模型加上最好的 harness,因為整個流程的品質從這裡開始。目前他們覺得 Pi 搭配 Anthropic 模型最好。
- 11:30 所有 LLM 呼叫都經過 gateway,因為只有 gateway 知道 Anthropic API key↳ 所有對 LLM(大型語言模型)的呼叫都要經過 gateway(統一的出入口),因為 API key(使用 AI 服務的密碼)只放在它那裡。
- 11:30 這主要是安全考量:避免使用者輸入傳到 curator,叫它印出環境變數(ENV)再把結果送出去↳ 這主要是為了安全:怕有人在輸入裡藏指令,叫 curator 把環境變數(常用來放密碼的系統設定)印出來再傳出去。curator 手上沒有 key,就偷不到。
- 12:00 curator 寫好 Ash PL 後「存進 sandbox」,實際上是發出 event 並附加到 event log,Python service 就是這樣看到更新後的程式↳ curator 寫好程式後說是「存進 sandbox」,其實是發一筆 event 加進 log。Python service 看到這筆紀錄,就知道程式更新了。
- 12:30 Python service 會解析程式碼、驗證語法並做型別檢查,有問題就能很便宜地退回 curator,例如「第 52 行有錯字,請重寫」↳ Python service 會先檢查語法和型別,有錯就直接退回,例如「第 52 行打錯字,請重寫」。這種檢查很快,代價也很低。
- 13:00 解析、驗證完得到類似 abstract syntax tree 的結構,再用一般 Python 程式碼走訪這棵樹來解譯,並處理 closure、special form 和各種語言 primitive↳ 檢查完,程式會變成 abstract syntax tree(樹狀的程式結構),再用 Python 一個節點一個節點執行,同時處理 closure(帶著周遭變數的函式)、special form(有特殊規則的語法)等細節。
- 13:32 content address store 非常關鍵,讓他們能做 caching 與 memoization(字幕寫作 memorization);講者說少了它整個系統都無法運作↳ content address store(用內容本身當編號來存資料)是關鍵,讓他們能做 caching(快取)和 memoization(記住算過的答案)。講者說少了它,整套系統跑不起來。
- 13:32 原因:每次都會重寫整個程式,並從頭到尾重新解譯,而不是只解譯改動的部分;如果每輪都真的重做,會非常慢↳ 因為每一輪都會重寫整支程式,再從頭執行一遍,不是只跑改到的地方。如果每次都真的全部重算,會非常慢。
- 14:03 因為語言是純函數式,可以對 expression 做雜湊,已經算過的結果存在 map 裡,再遇到時直接取用(例如算出來是 42)↳ 因為語言是純函數式,同一個算式一定得到同樣結果,所以可以替算式算出專屬編號,把結果存起來。下次遇到同一個編號,就直接拿答案,例如 42。
- 14:33 接下來進入 demo,並再次提到嚴謹度與速度之間常有取捨↳ 接著進入示範。講者再次提醒:做得仔細和做得快,常常要取捨。
📘 術語
DSL (domain-specific language)(領域專用語言):為特定領域打造的語言;Elicit 用它來描述 agentic workflow
agentic workflow(agent 式工作流程):agent 執行任務的一組內部步驟與流程
legible(可讀、可理解):流程能讓人和其他 agent 看懂並抽查
desiderata(必要條件/要件):打造研究 agent 時歸納出的三個需求:可讀、修改時保持忠實、忠實執行
fidelity(忠實度):反覆修改時仍維持使用者原本想做的事,不會偏離
data provenance(資料來源可追溯):Elicit 自豪的特點之一,與高可靠度、高品質並列
critique agent(批判用 agent):可以拿來檢查其他 agent 流程的 agent
Turing incomplete(非圖靈完備):Ash PL 的特性:相對簡單,沒有迴圈、遞迴和 mutation
purely functional(純函數式):沒有 mutation;這個特性讓 memoization 變得容易
opinionated subset(有主見的子集):不是隨機刪減 Python,而是刻意拿掉沒用的功能,再加入領域專屬 primitive
primitive(基本元件):語言內建的領域功能,例如檢索學術論文、臨床試驗
curator(curator(撰寫元件)):負責撰寫 Ash PL 的元件
append-only event log(只能附加的事件日誌):UI 產生的 event 會附加上去,用來管理分散式資料結構
event sourcing(事件溯源):系統採用的模式,由 Python service 擔任其中的 message broker
message broker(訊息中介):Python service 在 event sourcing 模式中扮演的角色
sandbox(沙箱):撰寫 Ash PL 的地方
wrapper(包裝層):擋在 curator 前的抽象層,可以抽換不同 harness
harness(harness(執行框架)):curator 背後的實作,例如 Agent SDK、Pi
gateway(閘道):所有 LLM 呼叫都經過它,只有它知道 API key,是安全考量
abstract syntax tree(抽象語法樹):解析驗證後得到的樹狀結構,解譯器會走訪它
content address store(內容定址儲存):用來做 caching 與 memoization,是系統運作的關鍵
memoization(記憶化):對 expression 做雜湊,算過的結果存進 map,下次直接取用
agentic workflow(agent 式工作流程):agent 執行任務的一組內部步驟與流程
legible(可讀、可理解):流程能讓人和其他 agent 看懂並抽查
desiderata(必要條件/要件):打造研究 agent 時歸納出的三個需求:可讀、修改時保持忠實、忠實執行
fidelity(忠實度):反覆修改時仍維持使用者原本想做的事,不會偏離
data provenance(資料來源可追溯):Elicit 自豪的特點之一,與高可靠度、高品質並列
critique agent(批判用 agent):可以拿來檢查其他 agent 流程的 agent
Turing incomplete(非圖靈完備):Ash PL 的特性:相對簡單,沒有迴圈、遞迴和 mutation
purely functional(純函數式):沒有 mutation;這個特性讓 memoization 變得容易
opinionated subset(有主見的子集):不是隨機刪減 Python,而是刻意拿掉沒用的功能,再加入領域專屬 primitive
primitive(基本元件):語言內建的領域功能,例如檢索學術論文、臨床試驗
curator(curator(撰寫元件)):負責撰寫 Ash PL 的元件
append-only event log(只能附加的事件日誌):UI 產生的 event 會附加上去,用來管理分散式資料結構
event sourcing(事件溯源):系統採用的模式,由 Python service 擔任其中的 message broker
message broker(訊息中介):Python service 在 event sourcing 模式中扮演的角色
sandbox(沙箱):撰寫 Ash PL 的地方
wrapper(包裝層):擋在 curator 前的抽象層,可以抽換不同 harness
harness(harness(執行框架)):curator 背後的實作,例如 Agent SDK、Pi
gateway(閘道):所有 LLM 呼叫都經過它,只有它知道 API key,是安全考量
abstract syntax tree(抽象語法樹):解析驗證後得到的樹狀結構,解譯器會走訪它
content address store(內容定址儲存):用來做 caching 與 memoization,是系統運作的關鍵
memoization(記憶化):對 expression 做雜湊,算過的結果存進 map,下次直接取用
✏️ 小考一題
根據講者,下列哪一項是 Ash PL 的特性?
A. 支援迴圈與遞迴,功能跟完整的 Python 一樣B. 是 JavaScript 的子集,沒有型別C. 直接由 LLM 解譯執行,不經過 Python 程式碼D. Turing incomplete、沒有迴圈與遞迴、純函數式看答案
答案:D。[05:55] 講者說 Ash PL 是 Turing incomplete、沒有迴圈、遞迴和 mutation,是純函數式;[05:55]–[07:25] 說它是 Python 的子集而且有型別;[07:56] 說解譯用的是一般 Python 程式碼
💛 覺得有幫助?支持一下


課本免費、沒有廣告,支持與否都能照常讀 🐰