Back to blog
    微調 JSON 輸出:讓語言模型始終輸出有效 JSON
    jsonstructured-outputfine-tuningreliabilitytool-callingfunction-calling

    微調 JSON 輸出:讓語言模型始終輸出有效 JSON

    語言模型的 JSON 可靠性問題及其解決方案。了解為何小型模型在 JSON 格式上失敗、微調如何將有效 JSON 率從 64% 提升至 99%,以及如何構建訓練資料集以實現可靠的結構化輸出。

    EErtas Team·

    結構化輸出是實際生產 AI 應用程式的基礎。如果你正在構建任何需要將 LLM 輸出連接到下游系統的東西——API、資料庫、工作流程自動化——你需要 JSON。你需要它每次都有效。

    問題是:小型模型在 JSON 格式上失敗的頻率高得驚人。

    失敗有多嚴重

    在 Llama 3.1 8B 基礎模型上的基準測試:

    任務有效 JSON 率
    簡單鍵值提取64.2%
    嵌套對象41.7%
    帶驗證的數組38.9%
    複雜的多層架構22.4%

    這些數字對於生產使用來說太低了。即使是 64% 的成功率也意味著每三個請求中就有一個失敗,需要重試、回退或手動干預。

    為什麼小型模型在 JSON 上苦苦掙扎

    小型模型有三個使 JSON 生成困難的問題:

    1. 嚴格的語法要求

    JSON 沒有容錯空間。一個缺失的逗號、一個未轉義的引號或一個錯誤放置的括號就會破壞解析器。自然語言是容忍錯誤的;JSON 不是。小型模型習慣於生成自然語言並不斷「修正」自己——這種能力在 JSON 中會產生反效果。

    2. 上下文追蹤

    有效的 JSON 需要正確的括號配對、正確的逗號放置以及從開頭到結尾一致的架構遵循。對於長輸出,小型模型失去對其所在結構位置的追蹤,並開始以語義上合理但語法上無效的方式關閉對象。

    3. Token 邊界

    JSON 中的某些字符序列在訓練資料中出現的頻率低於自然語言——特別是嵌套結構和轉義字符。模型對這些 token 序列的信心較低,並且更可能生成替代序列。

    微調如何修復這個問題

    微調直接解決了這三個問題。你在你的目標架構的有效 JSON 範例上訓練模型,模型學習:

    • 哪些 token 序列對你的特定架構有效
    • 如何正確追蹤括號深度
    • 如何在整個輸出中保持架構一致性

    在 2,000 個訓練範例之後,同樣的 Llama 3.1 8B 模型達到了 99.2% 的有效 JSON 率——跨越簡單和複雜架構。

    建構訓練資料集

    第一步:定義你的架構

    首先精確定義你需要的 JSON 輸出。使用 JSON Schema 語法:

    {
      "type": "object",
      "properties": {
        "entity_type": {
          "type": "string",
          "enum": ["person", "organization", "location", "date"]
        },
        "value": {"type": "string"},
        "confidence": {"type": "number", "minimum": 0, "maximum": 1},
        "context": {"type": "string"}
      },
      "required": ["entity_type", "value", "confidence"]
    }

    對你的所有目標輸出格式執行此操作。如果你有十種不同的輸出類型,定義十個架構。

    第二步:生成多樣化的範例

    創建覆蓋你的輸入空間的訓練範例。對於每種架構類型:

    {"messages": [{"role": "user", "content": "從以下文字中提取命名實體:\n\n'蘋果公司首席執行官 Tim Cook 昨天在加利福尼亞庫比蒂諾宣布了新產品。'"}, {"role": "assistant", "content": "{\"entities\": [{\"entity_type\": \"organization\", \"value\": \"Apple Inc.\", \"confidence\": 0.98, \"context\": \"首席執行官\"}, {\"entity_type\": \"person\", \"value\": \"Tim Cook\", \"confidence\": 0.99, \"context\": \"CEO\"}, {\"entity_type\": \"location\", \"value\": \"Cupertino, California\", \"confidence\": 0.97, \"context\": \"公告地點\"}]}"}]}

    包含邊緣案例:

    • 未找到實體(空數組)
    • 同一類型的多個實體
    • 跨越多個句子的實體
    • 模糊的實體(低置信度分數)

    第三步:使用 jsonschema 驗證

    在添加到訓練集之前,針對你的架構驗證每個訓練範例:

    import jsonschema
    import json
    
    def validate_training_example(example, schema):
        try:
            output = json.loads(example["messages"][-1]["content"])
            jsonschema.validate(output, schema)
            return True
        except (json.JSONDecodeError, jsonschema.ValidationError) as e:
            print(f"無效的訓練範例:{e}")
            return False
    
    # 過濾到有效範例
    valid_examples = [ex for ex in examples if validate_training_example(ex, schema)]

    永遠不要在無效範例上訓練。 即使是幾個格式錯誤的訓練範例也可能向模型教授錯誤的模式。

    第四步:覆蓋失敗案例

    有目的地為你知道基礎模型失敗的案例創建範例:

    • 需要轉義的字符串值(引號、反斜線、換行符)
    • 深度嵌套的對象(3 層以上)
    • 包含空對象或空值的數組
    • 具有長字符串值的架構

    這些失敗案例通常只佔你的訓練集的 10-20%,但它們不成比例地提高了可靠性。

    訓練參數

    JSON 可靠性微調的推薦設置:

    參數
    基礎模型Llama 3.1 8B 或 Qwen 2.5 7B
    LoRA rank16
    Alpha32
    學習率2e-4
    批次大小8
    Epochs3
    訓練範例1,000-3,000

    較小的 rank(16)對於 JSON 格式通常就足夠了——你在教授語法模式,而不是域知識。更多的訓練範例通常比更高的 rank 有更多好處。

    作為補充的受約束解碼

    微調之外,受約束解碼是另一種保證 JSON 有效性的技術。它通過在生成時強制執行語法規則——物理上不可能生成無效 JSON——來工作。

    工具如 Outlines(Python 庫)和 llama.cpp 的語法支援(--grammar 標誌)實現了這一點。

    何時使用微調 vs 受約束解碼:

    • 微調: 當你想要模型理解架構並生成語義有意義的輸出時。微調模型在不需要外部約束的情況下正確填充字段,因為它已經學習了架構。

    • 受約束解碼: 作為後備或額外的安全網。在微調的模型上添加受約束解碼提供了防禦性保障,但不能替代正確的格式訓練。

    • 兩者都用: 對於高可靠性要求,在微調模型上使用受約束解碼。99% 變成 99.99%。

    對工具使用和函數調用的影響

    JSON 可靠性不僅僅是格式問題——它是工具使用的基礎。

    當模型生成工具調用時,它正在生成 JSON(函數名稱、參數、值)。微調後 JSON 可靠性的提升直接轉化為工具調用可靠性的提升。

    在類似工具調用任務的基準測試中:

    • 基礎 Llama 3.1 8B:71% 的工具調用格式正確
    • 微調後(在 JSON 訓練資料上):97% 的工具調用格式正確

    如果你正在建構依賴工具使用的代理,JSON 微調是你可以進行的最高影響力的改進之一。


    Ship AI that runs on your users' devices.

    Ertas early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading