AI-101 Day 44:Function Calling / 結構化輸出
🎓 AI-101 | Day 44:Function Calling / 結構化輸出⋯叫 AI 吐機器讀得到嘅嘢

模型嘅輸出係散文。散文係俾人睇嘅。
但如果接住去讀嗰個係程式,散文就係災難⋯程式要嘅係一個固定形狀:邊個欄位、咩型別、有冇漏。
呢個就係今日呢一課。
😬 最多人用、亦都最脆弱嘅做法
喺 prompt 度加一句:「請用 JSON 格式回覆。」
九成時間 work。而九成,喺生產環境入面即係壞咗。
佢會俾你:前面加一段「好的,以下是您要的 JSON:」、包住個 ```json 圍欄、最後一項多咗個逗號、或者索性用散文答你。你就要寫一堆字串處理去猜佢今次係邊種。
我自己就撞過。呢個星期我哋一個每朝跑嘅腳本,就係叫模型「回一個 JSON array」,然後直接解析⋯有一朝佢解析唔到,而個系統當時淨係識話「搜尋壞咗」。真正壞嘅唔係搜尋,係我當咗一句請求等於一個保證。
🔧 正路做法一:Function Calling(工具呼叫)
你唔係求佢,你係俾一份規格佢:呢個工具叫咩名、做咩、參數係咩 shape(用 JSON Schema 寫)。
然後模型輸出嘅唔再係散文,係一個結構化嘅請求:「我要用 `search_flights`,參數係 {from:"LHR", to:"HKG", date:"2026-09-01"}」。
同 Day 40、Day 43 一樣嘅重點:模型自己乜都執行唔到。 佢由頭到尾只係吐文字,講「我想call呢個」。真係去 call 嘅係外面嗰個程式。
🔒 正路做法二:限制解碼(constrained decoding)⋯呢個先係真嘢
真正壞嘅唔係搜尋,係我當咗一句請求等於一個保證。
呢樣好多人未聽過,但佢係關鍵。
模型每一步係喺成個詞彙表入面揀下一個 token。限制解碼做嘅事,係喺每一步將「會令個輸出唔合法」嗰啲 token 嘅機率直接壓成零。
即係話:唔係「叫佢跟 schema,然後祈禱」,而係佢想唔跟都做唔到。出面嗰個 JSON 一定 parse 得到,唔係大機會,係必然。
(實作上叫 JSON mode / structured outputs;開源世界有 GBNF grammar、Outlines 呢啲。原理一樣:用個 schema 去閂住個解碼器。)
⚠️ 但呢度有個好易誤會嘅位:形狀啱 ≠ 內容啱
限制解碼保證你收到嘅係合法 JSON。佢唔保證入面啲數係真。
一個完美合法嘅 `{"invoice_no": "INV-2024-0831", "amount": 12500}`⋯個 schema 過到,但個單號可能係佢作出嚟。呢個係 Day 41 講 benchmark 嗰個道理嘅另一面:一個綠色嘅剔,唔等於一件啱嘅事。
所以 parse 完之後,仲要驗返啲值:嗰個編號真係存在?個銀碼對唔對得返單據?呢一步冇人幫你做。
🧩 三樣實用嘅:
- 🎯 工具描述係寫俾模型睇,唔係寫俾人睇⋯佢主要靠 description 揀用邊個工具,唔係靠個名。寫得含糊,佢就會揀錯
- 📉 工具唔好多⋯每個工具嘅 schema 每次都要塞入 context,又燒 token 又令佢揀得差。少而唔重疊,好過齊全
- ✅ required 就真係要 required⋯可有可無嘅欄位,佢就會可有可無咁填
📌 Takeaway:「請回覆 JSON」係一個請求;schema + 限制解碼係一個保證。兩者差嘅唔係方便,係你個系統會唔會喺某朝突然壞咗。