iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
Vibe Coding

從零打造 AI 全端應用:Vibe Coding 結合 n8n 視覺化工作流實戰系列 第 19 篇

# Day 19:馴服 AI 的輸出:強制解析 JSON 格式與 Schema 驗證

  • 分享至 

  • xImage
  •  

Day 19:馴服 AI 的輸出:強制解析 JSON 格式與 Schema 驗證

嗨,大家今天過得好嗎?歡迎來到鐵人賽 Day 19。

昨天我們幫 AI 裝上了記憶體,讓它能跟使用者進行連續對話。但如果你真的拿 iOS App 去戳它,你大概率會遇到一個慘劇:App 拿到回應後,畫面一片空白,Xcode 控制台噴出紅色的 DecodingError。

為什麼?因為 LLM 天生是個「話癆」。
當你對它說:「預算加 5000,顯卡升級」,它可能滿心歡喜地回覆:

"沒問題!我幫您把預算提高到 35000 元了。以下是為您重新配置的 JSON 菜單:
json* *{ "cpu": "...", ... }* *
希望這個配置能讓您的 3A 遊戲體驗更好!"

這對人類來說很友善,但對於我們 Day 8 寫在 Swift 裡的 JSONDecoder 來說,這根本是一坨無法解析的亂碼字串。只要格式不對,強型別的 Swift 就會毫不留情地當機。

很多新手遇到這個問題,直覺會在 Prompt 加上一句:「請只回傳 JSON,絕對不要包含任何其他文字!」
但我可以很負責任地告訴你:這招防君子不防小人 (AI)。 只要上下文一長,AI 一定會忘記這個規定。今天,我們要用工程師的手段,從系統層面徹底馴服 AI。

祭出殺手鐧:Structured Output Parser (結構化輸出解析器)

在 n8n 的 Advanced AI 節點中,對付這種不守規矩的 LLM,最強大的武器叫做 Output Parser (輸出解析器)。

這個機制利用了 OpenAI / Gemini 近期支援的 "Structured Outputs" (結構化輸出) 或 "Function Calling" 底層能力,強制規定 AI 只能按照我們給定的 Schema (綱要) 來回傳資料,連一個多餘的廢話字元都塞不進去。

實作步驟:

  1. 回到你的 n8n 畫布,找到我們核心的 Basic LLM Chain 節點。
  2. 點擊節點下方第三個缺口(Output Parser 旁邊的 + 號)。
  3. 搜尋並選擇 Structured Output Parser 節點。

接上去之後,點開這個 Parser 的設定,這裡就是我們建立「API 契約」的地方。

定義 JSON Schema:與 Swift 完美對接

在 Parser 的設定中,你會看到一個 JSON Schema 的文字框。這裡要填入的,必須與我們在 SwiftUI 定義的 HardwareMenu 模型 100% 吻合。

還記得我們 Swift 的 Model 長這樣嗎?

struct HardwareMenu: Codable {
    let cpu: String
    let gpu: String
    let totalPrice: Int
    let reason: String
}

請在 n8n 的 JSON Schema 框框裡,填入這段對應的標準 JSON Schema:

{
  "type": "object",
  "properties": {
    "cpu": {
      "type": "string",
      "description": "推薦的 CPU 型號"
    },
    "gpu": {
      "type": "string",
      "description": "推薦的 GPU 型號"
    },
    "totalPrice": {
      "type": "integer",
      "description": "CPU 與 GPU 的加總價格"
    },
    "reason": {
      "type": "string",
      "description": "50 字以內的推薦理由"
    }
  },
  "required": ["cpu", "gpu", "totalPrice", "reason"]
}

踩坑警告:型別地雷 (Type Mismatch)

這個 Schema 裡藏著一個很容易讓新手踩雷的細節,那就是 totalPrice 的 type。

在 JSON Schema 裡,如果你把 totalPrice 的 type 寫成 "string",AI 就會回傳 "35000"。但我們的 Swift 裡定義的是 Int!這會導致 Swift 解碼失敗。
所以這裡必須嚴格定義為 "integer" 或 "number"。這不僅是規範輸出的格式,也是在引導 AI 的底層邏輯,讓它知道這裡只能填數字。

見證奇蹟的時刻

設定完 Schema 之後,你在 Basic LLM Chain 裡的 Prompt 甚至不需要再苦口婆心地勸 AI「請只回傳 JSON」。你只要專注在商業邏輯的描述就好。

現在,按下 Execute Node 測試一次。
不管你怎麼刁難 AI、跟它閒聊,你看右邊 Output 產出的資料,絕對是完美、乾淨,且只有這四個 Key 的標準 JSON 物件。 連包裹 JSON 的 Markdown 符號 (```json) 都被 n8n 在底層給自動過濾掉了。

更棒的是,如果你接了這個 Parser,n8n 會自動把這包 JSON 直接變成後續節點可以用的變數格式(不再是純字串)。這代表我們的 Webhook Response 終於可以把這份標準 JSON 完美回傳給 iOS App 了!

小結

這 19 天以來,我們從 0 到 1 打造了一個極度強悍的 AI 後端引擎:
✅ 有 Webhook 接收資料
✅ 有 PostgreSQL 時價資料庫與安全查詢
✅ 有 API 即時匯率
✅ 有動態 Prompt 注入與上下文記憶
✅ 有嚴格的 JSON Schema 輸出防護

我們的 n8n 後端到這邊,基本上已經算是「大功告成」了。
明天,我們要把視角切回前端!當真實的 API 串上線後,網路延遲、TimeOut 或是 LLM 回答過慢的問題將會浮現。我們要用 Vibe Coding 在 SwiftUI 實作「強韌的錯誤處理與 UX 優化」,讓我們的專案達到商業級別的水準!

我們 Day 20 見!


上一篇
Day 18:給 AI 掛上記憶體:在流程中實作上下文對話狀態 (Session Memory)
下一篇
Day 20:處理 AI 的「慢」:實作非同步 Timeout 與前端錯誤處理最佳實踐
系列文
從零打造 AI 全端應用:Vibe Coding 結合 n8n 視覺化工作流實戰 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言