コンテンツにスキップ

構造化抽出

請求書、メール、議事録、スクレイピングしたページなどの自由形式テキストから構造化レコードを取り出します。strict な JSON Schema を使えば、出力は毎回クリーンにパースできます。

from openai import OpenAI
client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...")
text = """
From: Jane Doe <jane@example.com>
Re: Coffee next week
Phone: +1 555-123-4567
"""
response = client.chat.completions.create(
model="deepseek-ai/deepseek-v4-flash",
messages=[
{"role": "system", "content": "Extract contact info from the user's text."},
{"role": "user", "content": text},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "contact",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"phone": {"type": ["string", "null"]},
},
"required": ["name", "email", "phone"],
"additionalProperties": False,
},
},
},
)
import json
contact = json.loads(response.choices[0].message.content)
print(contact)
# {'name': 'Jane Doe', 'email': 'jane@example.com', 'phone': '+1 555-123-4567'}

OpenAI Python SDK は Pydantic モデルからスキーマを自動生成できます:

from pydantic import BaseModel
from typing import Optional
class Contact(BaseModel):
name: str
email: str
phone: Optional[str]
response = client.chat.completions.parse(
model="deepseek-ai/deepseek-v4-flash",
messages=[
{"role": "system", "content": "Extract contact info."},
{"role": "user", "content": text},
],
response_format=Contact,
)
contact = response.choices[0].message.parsed
print(contact.name, contact.email)
  • すべてのフィールドを required にし、任意項目は ["string", "null"] で表現 — strict モードは欠落を拒否しますが nullable は許可します。
  • additionalProperties: false を指定して余計なフィールドを防ぐ。
  • 複数件 (例: 複数の連絡先) は {"type": "array", "items": {...}} で外側オブジェクトにラップ。