スキーマ駆動のデータ抽出
プロンプトに JSON スキーマを指定し、構造化された出力形式を保証します。
「スキーマ駆動のデータ抽出」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Prompt Engineering学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Prompt Engineeringコースには全4レッスンが含まれています。
なぜスキーマ駆動型の抽出なのか
モデルに重要なデータを抽出してくださいと伝えるだけでは、一貫性のない予測不能な出力になります。一方、JSONスキーマを提示してこの正確なスキーマに一致するデータを抽出してくださいと指示すれば、毎回、機械可読で一貫性があり、型安全な出力を得られます。
スキーマ駆動型の抽出は、請求書、契約書、医療記録、会議メモなど、非構造化テキストから構造化データを確実に抽出する必要があるドキュメントを処理する本番システムで使われているパターンです。
プロンプト内でスキーマを指定する
スキーマはプロンプトに直接記述します。モデルはスキーマを出力の契約として使用します。
import anthropic, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
INVOICE_SCHEMA = '''
{
"invoice_number": "string",
"vendor_name": "string",
"vendor_address": "string or null",
"invoice_date": "YYYY-MM-DD",
"due_date": "YYYY-MM-DD or null",
"line_items": [
{
"description": "string",
"quantity": "number",
"unit_price": "number",
"total": "number"
}
],
"subtotal": "number",
"tax": "number or null",
"total_amount": "number",
"currency": "3-letter ISO code e.g. USD"
}
'''
def extract_invoice(invoice_text):
prompt = f'Extract structured data from this invoice.\nReturn JSON matching this schema exactly:\n{INVOICE_SCHEMA}\n\nInvoice:\n{invoice_text}'
r = client.messages.create(model='claude-opus-4-5', max_tokens=500, messages=[{'role': 'user', 'content': prompt}])
return json.loads(r.content[0].text)
print('Invoice schema defined.')請求書の抽出例
実際の請求書テキストから構造化データを抽出するために、スキーマを適用します。
invoice_text = '''
INVOICE #INV-2025-0342
From: Acme Software Ltd.
123 Tech Street, San Francisco, CA 94105
Date: March 15, 2025
Due: April 14, 2025
Items:
- Annual Pro License (5 seats) x1 @ $2,400.00 = $2,400.00
- Setup & Onboarding x2 @ $300.00 = $600.00
Subtotal: $3,000.00
Tax (8.5%): $255.00
TOTAL DUE: $3,255.00 USD
'''
result = extract_invoice(invoice_text)
print(f'Invoice: {result["invoice_number"]}')
print(f'Vendor: {result["vendor_name"]}')
print(f'Total: {result["currency"]} {result["total_amount"]}')
print(f'Line items: {len(result["line_items"])}')会議メモの抽出
より構造化されていないドキュメントタイプである会議メモに、スキーマ駆動型の抽出を適用します。
MEETING_SCHEMA = '''
{
"meeting_title": "string",
"date": "YYYY-MM-DD",
"attendees": ["string"],
"decisions": ["string"],
"action_items": [
{
"task": "string",
"owner": "string or null",
"due_date": "YYYY-MM-DD or null"
}
],
"next_meeting": "string or null"
}
'''
meeting_notes = '''
Product Sync - March 20, 2025
Attendees: Sarah (PM), Jake (Engineering), Priya (Design)
Decided to push the v2.0 launch to April 15.
Will not include the analytics dashboard in v2.0.
Actions:
- Jake to fix the login bug by March 25
- Priya to finalize mockups by March 22
- Sarah to send updated roadmap to stakeholders (no date set)
Next sync: March 27, same time.
'''
print(f'Meeting schema: {len(MEETING_SCHEMA)} chars')
print(f'Notes length: {len(meeting_notes)} chars')製品仕様の抽出
カタログの説明文から、構造化された製品仕様を抽出します。
PRODUCT_SCHEMA = '''
{
"product_name": "string",
"sku": "string or null",
"category": "string",
"price": {"amount": "number", "currency": "string"},
"dimensions": {
"length_cm": "number or null",
"width_cm": "number or null",
"height_cm": "number or null",
"weight_kg": "number or null"
},
"colors": ["string"],
"materials": ["string"],
"features": ["string"],
"in_stock": true | false
}
'''
product_text = 'AlphaDesk Pro standing desk. SKU: AD-PRO-001. $899. Available in white and black. 120x60x75cm, 35kg. Steel frame, bamboo top. Features: memory height, anti-collision, app control. In stock.'
prompt = f'Extract product specs. Return JSON:\n{PRODUCT_SCHEMA}\n\nProduct: {product_text}'
r = client.messages.create(model='claude-opus-4-5', max_tokens=400, messages=[{'role': 'user', 'content': prompt}])
print(json.loads(r.content[0].text))オプションフィールドへの対応
スキーマでは、オプションフィールドを適切に処理する必要があります。データがない場合はフィールドを省略するのではなく、デフォルト値としてnullを使用します。これにより、出力構造の一貫性が保たれます。
prompt_optional = '''
Extract the data. For fields not present in the source text,
use null — do NOT omit the field.
Every field in the schema must appear in the output.
Schema:
{
"company": "string",
"ceo": "string or null",
"founded": "YYYY or null",
"revenue": "string or null",
"employees": "number or null"
}
Text: Vertex AI Solutions is a B2B SaaS company.
'''
# Expected output: ceo, founded, revenue, employees all set to null
# NOT omitted — null fields are still present in the JSON
print(prompt_optional)同じスキーマによる複数ドキュメントの抽出
同じスキーマを多くのドキュメントに一貫して適用できます。これが、規模に応じて非構造化ドキュメントから構造化データベースを構築する方法です。
def extract_many(documents, schema):
results = []
for i, doc in enumerate(documents):
try:
r = client.messages.create(
model='claude-opus-4-5', max_tokens=400,
messages=[{'role': 'user', 'content': f'Extract data. Return JSON matching schema:\n{schema}\n\nDocument:\n{doc}'}]
)
parsed = json.loads(r.content[0].text)
parsed['_source_doc'] = i
parsed['_extraction_ok'] = True
results.append(parsed)
except (json.JSONDecodeError, Exception) as e:
results.append({'_source_doc': i, '_extraction_ok': False, '_error': str(e)})
return results
invoices = ['Invoice from Acme, March 2025, $500', 'Invoice from Beta Corp, April 2025, $1200']
results = extract_many(invoices, INVOICE_SCHEMA)
print(f'Processed: {len([r for r in results if r["_extraction_ok"]])} success, {len([r for r in results if not r["_extraction_ok"]])} failed')抽出後のスキーマ検証
Pythonのjsonschemaライブラリまたはカスタムバリデーターを使用して、抽出したデータを期待されるスキーマに対して検証します。
def validate_extracted(data, required_fields, type_checks):
errors = []
# Check required fields
for field in required_fields:
if field not in data or data[field] is None:
errors.append(f'Required field missing or null: {field}')
# Check types
for field, expected_type in type_checks.items():
if field in data and data[field] is not None:
if not isinstance(data[field], expected_type):
errors.append(f'{field}: expected {expected_type.__name__}, got {type(data[field]).__name__}')
return errors
extracted = {'invoice_number': 'INV-001', 'total_amount': 3255.0, 'vendor_name': 'Acme', 'invoice_date': '2025-03-15'}
required = ['invoice_number', 'total_amount', 'vendor_name']
types = {'total_amount': float, 'invoice_number': str, 'line_items': list}
errors = validate_extracted(extracted, required, types)
print('Validation errors:', errors)スキーマの反復的な改善
スキーマは、反復的なテストを通じて進化します。プロセスは次のとおりです。
- ドメイン知識に基づいて初期スキーマを定義します
- サンプルドキュメント20件に対して抽出を実行します
- 出力を確認します。どのフィールドが一貫して間違っている、または欠落しているでしょうか
- スキーマの説明を改善し、フィールド定義を追加します
- 同じ20件のドキュメントに対して再実行します
- 品質が基準値を満たすまで繰り返します
スキーマへのフィールド説明の追加
フィールドが曖昧な場合は、モデルを導くための説明コメントを追加します。
ANNOTATED_SCHEMA = '''
{
"invoice_number": "string // The unique identifier for this invoice, e.g., INV-2025-001",
"invoice_date": "YYYY-MM-DD // Date the invoice was issued",
"due_date": "YYYY-MM-DD or null // Payment due date; null if not specified",
"subtotal": "number // Amount before tax, as a decimal number",
"tax": "number or null // Tax amount as a decimal; null if tax is not listed",
"total_amount": "number // Final amount to pay, including tax",
"payment_terms": "string or null // e.g., Net 30, Due on receipt; null if not mentioned"
}
'''
print('Annotated schema adds context per field.')
print(f'Schema length: {len(ANNOTATED_SCHEMA)} chars')抽出フィールドの信頼度スコア
本番システムでは、フィールドごとに信頼度スコアを含めます。信頼度の低い抽出結果は、人によるレビューに回すことができます。
SCHEMA_WITH_CONFIDENCE = '''
{
"fields": {
"invoice_number": {"value": "string", "confidence": "high|medium|low"},
"total_amount": {"value": "number", "confidence": "high|medium|low"},
"due_date": {"value": "YYYY-MM-DD or null", "confidence": "high|medium|low"}
},
"overall_confidence": "high|medium|low",
"extraction_notes": "string or null // Any ambiguities encountered"
}
'''
prompt = f'Extract invoice data with confidence scores.\nReturn JSON:\n{SCHEMA_WITH_CONFIDENCE}\n\nInvoice: Payment due within 30 days. Total is approximately $500.'
r = client.messages.create(model='claude-opus-4-5', max_tokens=300, messages=[{'role': 'user', 'content': prompt}])
result = json.loads(r.content[0].text)
print('Overall confidence:', result.get('overall_confidence'))
print('Notes:', result.get('extraction_notes'))クイックチェック
必須フィールドが元のドキュメントに存在しない場合、スキーマ駆動型の抽出プロンプトでは、そのフィールドについて何を返すようモデルに指示すべきですか。
スキーマ駆動型の抽出 — 重要ポイント
スキーマ駆動型の抽出は、本番環境で信頼性の高いドキュメント処理を行うための標準です。
- 正確なJSONスキーマをプロンプトに指定します。モデルはそれを出力の契約として使用します
- 曖昧なフィールドにはフィールド説明を追加し、モデルの解釈を導きます
- 必ず「フィールドがない場合はnullを返し、省略しない」と指示します
- 多くのドキュメントに同じスキーマを適用し、一貫性のあるデータベース対応の出力を生成します
- 人によるレビューへの振り分けを可能にするため、フィールドごとに信頼度スコアを含めます
- 抽出のたびに、プログラムで抽出データを検証します
- スキーマを反復的に改善します。20件のサンプルを抽出し、確認し、改善する作業を繰り返します
よくある質問
「スキーマ駆動のデータ抽出」レッスンは無料ですか?
はい。「スキーマ駆動のデータ抽出」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。
「スキーマ駆動のデータ抽出」で何を学びますか?
プロンプトに JSON スキーマを指定し、構造化された出力形式を保証します。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Prompt Engineeringを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「スキーマ駆動のデータ抽出」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Prompt Engineeringレッスンでコードを書いて実行できますか?
はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 固有表現抽出のプロンプト
- スキーマ駆動のデータ抽出
- テキスト分類器としての LLM
- 分類における確信度と不確実性