JSON Mode の概要

DeepSeek V4 Flash と Pro はどちらも JSON Mode をサポートしており、response_format パラメータを設定することで、モデルに JSON Schema に厳密に準拠した構造化データを出力させることができます。これは、データ抽出、API レスポンス、自動化ワークフローなどのシナリオで重要です。

基本的な使い方

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get('DEEPSEEK_API_KEY'),
    base_url='https://api.deepseek.com'
)

response = client.chat.completions.create(
    model='deepseek-v4-flash',
    messages=[{
        "role": "system",
        "content": "あなたは情報抽出アシスタントです。テキストから構造化情報を抽出してください。"
    }, {
        "role": "user",
        "content": "張三、28歳、ソフトウェアエンジニア、北京在住、月給35000"
    }],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "job": {"type": "string"},
                    "city": {"type": "string"},
                    "salary": {"type": "number"}
                },
                "required": ["name", "age", "job", "city", "salary"],
                "additionalProperties": False
            }
        }
    }
)

import json
result = json.loads(response.choices[0].message.content)
print(result)
# {'name': '張三', 'age': 28, 'job': 'ソフトウェアエンジニア', 'city': '北京', 'salary': 35000}

strict モードの詳細

"strict": true を設定すると、DeepSeek は以下を保証します:

  • 出力は常に有効な JSON である。
  • 必須フィールドは必ず存在する。
  • additionalProperties 以外のフィールドは出現しない。
  • フィールドの型は Schema 定義に厳密に一致する。

strict モードを使用する際の注意点:Schema 内のオブジェクト型には additionalProperties: false を含める必要があり、すべてのプロパティを required に定義する必要があります。

複雑なネスト Schema

{
  "type": "json_schema",
  "json_schema": {
    "name": "code_review",
    "strict": True,
    "schema": {
      "type": "object",
      "properties": {
        "overall_score": {"type": "number", "minimum": 0, "maximum": 100},
        "issues": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "file": {"type": "string"},
              "line": {"type": "integer"},
              "severity": {"type": "string", "enum": ["critical", "major", "minor"]},
              "description": {"type": "string"},
              "suggestion": {"type": "string"}
            },
            "required": ["file", "severity", "description", "suggestion"],
            "additionalProperties": False
          }
        },
        "summary": {"type": "string"}
      },
      "required": ["overall_score", "issues", "summary"],
      "additionalProperties": False
    }
  }
}

Pydantic 統合

Pydantic モデルを自動的に JSON Schema に変換し、エンドツーエンドの型安全性を実現します:

from pydantic import BaseModel, Field
from typing import List, Optional

class Issue(BaseModel):
    file: str
    line: int
    severity: str = Field(pattern="^(critical|major|minor)$")
    description: str
    suggestion: str

class CodeReview(BaseModel):
    overall_score: int = Field(ge=0, le=100)
    issues: List[Issue]
    summary: str

# Schema を自動生成
schema = CodeReview.model_json_schema()

# リクエスト送信時に使用
response = client.chat.completions.create(
    model='deepseek-v4-pro',
    messages=[{"role": "user", "content": f"このコードをレビューしてください:\n{code}"}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "code_review",
            "strict": True,
            "schema": schema
        }
    }
)

# Pydantic モデルに直接デシリアライズ
review = CodeReview.model_validate_json(response.choices[0].message.content)

本番環境のベストプラクティス

  • System Prompt の併用: system prompt で出力形式とフィールドの意味を説明する。
  • 常に strict を使用: 本番環境では strict=true を必ず有効にし、形式異常を防ぐ。
  • 検証レイヤー: strict でもコード内で再度検証する(防御的プログラミング)。
  • フォールバック処理: JSON 解析が失敗した場合、生の出力を記録し開発者に通知する。
  • enum 制約: 有限のオプションを持つフィールドには enum を使用し、値の正当性を保証する。