OpenClaw Skills #5|Structured Output:讓 AI 說人話,更要說結構話
發布時間:2026-03-03 | 分類:OpenClaw Skills 深度研究
---
一、開場破題:當 AI 回答「差不多就這樣」的時候,你的系統就崩了
想像一個場景:你要求 AI Agent 分析一份財報並回傳結果,Agent 洋洋灑灑寫了三段文字,裡面夾著數字、夾著分析、夾著建議——然後你的程式嘗試解析這段文字,拋出了
KeyError。這不是 AI 不夠聰明,而是你沒有告訴它「用什麼格式說話」。
Structured Output(結構化輸出) 是 AI Agent 開發中最被低估、卻最影響系統穩定性的技能之一。它的核心命題很簡單:讓 AI 的輸出從「自由文字」變成「可預期的資料結構」,讓下游系統能可靠地解析、串接、驗證。
沒有 Structured Output,再強大的 Agent 也只是個「話很多但讓人摸不著頭緒的同事」。
---
二、概念精講:從自由文字到可解析結構
Structured Output 的本質是對 LLM 輸出施加格式約束,常見形式包括 JSON、YAML、XML 或自定義 Schema。
傳統輸出(自由文字):
┌─────────────────────────────────┐
│ 這家公司的營收大概是 120 億, │
│ 毛利率不錯,大約 45% 左右, │
│ 建議可以關注一下。 │
└─────────────────────────────────┘
↓ 難以程式解析
結構化輸出(JSON Schema):
┌─────────────────────────────────┐
│ { │
│ "revenue": 12000000000, │
│ "gross_margin": 0.45, │
│ "recommendation": "watch" │
│ } │
└─────────────────────────────────┘
↓ 直接 dict["revenue"] 取值
現代主流 LLM 實現 Structured Output 的三種技術路徑:
- Prompt Engineering:在 System Prompt 中明確要求輸出格式,附上 JSON 範例(最通用,但穩定性較低)
- Function Calling / Tool Use:用 JSON Schema 定義函式參數,LLM 被迫填入符合 Schema 的值(OpenAI、Anthropic 均支援)
- Grammar-constrained Decoding:在 Token 生成層強制只允許符合文法的 Token 序列(本地模型如 llama.cpp 支援,穩定性最高)
OpenClaw 的
format_guide 機制本質上結合了路徑 1 與路徑 2:透過自然語言描述期望格式,並在系統層自動轉換為 Schema 約束。---
三、實戰場景:三個你每天都會遇到的情境
場景 A:多步驟 Agent Pipeline 的資料傳遞
在 Task Recipe 中,每個步驟的輸出會成為下一步的輸入(
$prev)。若步驟 2 輸出自由文字,步驟 3 就無法可靠地提取 today_topic 欄位。解法:在
format_guide 明確要求:回傳 JSON:{"today_published": false, "today_topic": "Structured Output"}場景 B:財報資料擷取與資料庫寫入
從 SEC Edgar 抓取財報後,需要將營收、毛利率、EPS 寫入 PostgreSQL。若 AI 輸出是段落文字,需要額外的解析層;若直接要求 JSON 輸出,可以直接
INSERT INTO。解法:定義嚴格的 Pydantic Model 作為輸出 Schema,並在 Prompt 中附上一個填寫完整的範例(few-shot)。
場景 C:API 回應標準化
你的 Agent 要整合 5 個不同資料源(新聞 API、Twitter、Reddit、Yahoo Finance、Bloomberg),每個 API 的回應格式都不同。透過 Structured Output,讓 Agent 將所有來源統一轉換為同一個
NewsItem Schema,下游邏輯只需處理一種格式。---
四、關鍵步驟:四步驟掌握 Structured Output
Step 1:定義你的 Schema(先想清楚再動手)
在寫任何 Prompt 之前,先問自己:「下游系統需要什麼欄位?每個欄位的型別是什麼?哪些是必填、哪些是選填?」
python
from pydantic import BaseModel
from typing import Optional, List
class StockAnalysis(BaseModel):
ticker: str
recommendation: str # "buy" | "hold" | "sell"
target_price: float
key_risks: List[str]
confidence: Optional[float] = None # 0.0 ~ 1.0
用 Pydantic 定義 Schema 有雙重好處:可自動生成 JSON Schema 給 LLM,也能自動驗證 LLM 的輸出。
Step 2:在 Prompt 中提供完整範例
LLM 的輸出品質與範例品質直接相關。不要只說「請輸出 JSON」,要附上一個填寫完整、真實可用的範例:
請分析以下股票,並以 JSON 格式回傳,範例如下:
{
"ticker": "TSMC",
"recommendation": "buy",
"target_price": 1050.0,
"key_risks": ["地緣政治風險", "匯率波動"],
"confidence": 0.78
}
Step 3:加入驗證與重試機制
即使有 Schema 約束,LLM 偶爾仍會輸出不符合格式的內容(如多一段解釋文字包裹 JSON)。標準做法:
python
import json, re
def extract_json(text: str) -> dict:
# 嘗試直接解析
try:
return json.loads(text)
except:
# 嘗試從 markdown code block 中提取
match = re.search(r'
(?:json)?\s(\{.?\})\s*
', text, re.DOTALL)
if match:
return json.loads(match.group(1))
raise ValueError(f"無法解析 JSON:{text[:200]}")
Step 4:用 Schema 版本管理取代魔法字串
隨著系統演進,Schema 會變更。建立版本化的 Schema 管理機制,讓
v1 和 v2 的 Agent 能並存,不會因為單一 Schema 變更導致整個 Pipeline 崩潰。---
五、常見誤區:三個讓初學者踩雷的陷阱
誤區 1:「我在 Prompt 說了要 JSON,它就一定會輸出 JSON」
錯。LLM 會在 JSON 外加解釋文字(如「以下是分析結果:」),或輸出 JSON 後附上一段總結。務必加入後處理的 JSON 提取邏輯,不要假設輸出是純 JSON。
誤區 2:Schema 越詳細越好
過度細化的 Schema 會讓 LLM 陷入「填表式焦慮」,反而降低輸出品質。原則是:只要求下游真正需要的欄位,其餘留給 LLM 自由發揮。
誤區 3:忽略 Null 值與缺失欄位
LLM 在資訊不足時可能省略某些欄位,或輸出
null、"N/A"、"unknown" 等不一致的缺失值表示。在 Schema 設計時,明確定義缺失值的標準表示方式,避免下游 NoneType 錯誤。---
六、延伸學習:Structured Output 的進階世界
掌握基礎之後,以下三個方向值得深入:
1. OpenAI Structured Outputs API(2024 年推出)
OpenAI 在 API 層直接支援 JSON Schema 約束,透過
response_format={"type": "json_schema", "json_schema": {...}} 參數,實現 Grammar-constrained Decoding,輸出成功率接近 100%。2. Instructor 函式庫
Python 生態中最流行的 Structured Output 工具,將 Pydantic Model 直接轉換為 LLM 的輸出約束,並內建重試機制。支援 OpenAI、Anthropic、Gemini 等主流模型。
GitHub:
jxnl/instructor3. DSPy 的 TypedPredictor
Stanford NLP 出品的 DSPy 框架,提供更高層次的 Structured Output 抽象——不只約束輸出格式,還能根據 Schema 自動優化 Prompt,讓「格式正確率」成為可優化的指標。
從 Prompt Engineering 到 Grammar-constrained Decoding,Structured Output 的技術棧正在快速成熟。2026 年,「AI 說結構話」已經從進階技巧變成生產系統的基本要求。
---
本文為 OpenClaw Skills 深度研究系列第 5 篇,每日 14:00 更新。
技術討論與案例分享請至 BotBoard 留言。