document-extraction について
document-extractionは、LandingAIのAgentic Document Extraction(ADE)で文書を処理する手順をまとめたガイドです。文書データの解析、抽出、分類を行う開発者向けに、Markdownや構造化JSON、スキーマ定義、非同期処理、位置情報を扱います。
主な機能
- 01文書をMarkdownとチャンクに解析
- 02JSON SchemaまたはPydanticでデータ抽出
- 03複数文書の分類と分割
- 04非同期解析ジョブの実行
- 05ページ番号とバウンディングボックスで位置表示
活用シーン
- 01請求書や銀行明細から項目を抽出
- 02大容量または複数ページの文書を処理
- 03混在する文書群を分類して分割
- 04抽出内容の原文書内の位置を特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ andrewyng/ context-hub --skill document-extractionインストール後、Claude Code で/document-extractionを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.env-sample.gitignorereferences/chunk-types.mdextraction-schemas.mdfile-formats.mdtroubleshooting.mduse-cases.md詳細
ドキュメント抽出(ADE)
概要
LandingAI の Agentic Document Extraction(ADE)は、テンプレートやトレーニングを必要とせずにドキュメントを解析、抽出、分類するドキュメント処理 SaaS です。主に次の 3 つの機能を提供します。
- 解析:ドキュメントを階層構造の JSON 表現を含む構造化 Markdown に変換します
- 抽出:JSON スキーマまたは Pydantic モデルを使って、特定の構造化データを抽出します
- 分割:複数ドキュメントを含むバッチを種類ごとに分類して分割します
主なメリット:
- ML のトレーニングやテンプレートは不要です
- レイアウトに依存しない解析(あらゆるドキュメント構造に対応します)
- 20 種類以上のファイル形式に対応します(PDF、画像、スプレッドシート、プレゼンテーション)
- 正確な視覚的グラウンディング(バウンディングボックス、ページ番号)
- さまざまなドキュメントの種類に最適化された複数のモデル
クイックスタート
1. インストール
ユーザーの承認なしにパッケージをグローバルにインストールしないでください。必ず最初にローカルの Python 環境を確認してください。
1. .venv/bin/python — uv-managed (this project)
2. venv/bin/python — standard Python venv
3. uv run python — if pyproject.toml exists
4. poetry run python — if poetry.lock exists
5. python3 — system fallback; warn the user
ローカル環境を使ってインストールします:landingai-ade、python-dotenv
2. API キーの設定
ユーザーが document-extraction スキルと同じディレクトリに、API キーを含む .env ファイルをすでに作成している場合があります。必ず最初にこのパスを確認してください(ls -la .*/skills/document-extraction/.env)。また、この SKILL.md ファイルと同じディレクトリも確認してください。
見つからない場合は、作成方法を案内してください。以下のスクリプトは、一般的な場所にある .env を検索して読み込みます。
.venv/bin/python - << 'EOF'
import os
from pathlib import Path
from dotenv import load_dotenv
# Load API key: prefer existing env var, then .env file lookup
if os.environ.get("VISION_AGENT_API_KEY"):
print("API key found in existing environment variable")
else:
def _find_env():
for d in [Path.cwd().resolve(), *Path.cwd().resolve().parents]:
for candidate in [
# ADD the directory where the document-extraction skill is located
d / '.env',
d / 'document-extraction/.env',
d / 'skills/document-extraction/.env',
]:
if candidate.is_file():
return candidate
return None
env = _find_env()
if env:
load_dotenv(env)
print(f"API key loaded from: {env}")
else:
print("Warning: VISION_AGENT_API_KEY not set and no .env found")
EOF
キーが見つからない場合は、https://va.landing.ai/settings/api-key から API キーを取得するようユーザーに案内してください。
.env-sample を .env にコピーし、API キーを追加します。
cp .env-sample .env
.env を編集して、キーを追加します。
VISION_AGENT_API_KEY=your_actual_api_key_here
注: .env ファイルはセキュリティのため、gitignore の対象です。上級ユーザーは、環境変数を直接設定することもできます:export VISION_AGENT_API_KEY=<your-key>
EU エンドポイント: EU エンドポイントを使用する場合は、クライアントの初期化時に environment="eu" を設定してください。
3. 基本的な解析の例
from dotenv import load_dotenv
load_dotenv() # Load API key from .env
from landingai_ade import LandingAIADE
from pathlib import Path
client = LandingAIADE()
# Parse a document
response = client.parse(
document=Path("document.pdf"),
model="dpt-2-latest"
)
# Access results
print(f"Pages: {response.metadata.page_count}")
print(f"Chunks: {len(response.chunks)}")
print("\nMarkdown output:")
print(response.markdown[:500]) # First 500 chars
# Save Markdown for extraction
with open("output.md", "w", encoding="utf-8") as f:
f.write(response.markdown)
4. 基本的な抽出の例
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from landingai_ade.lib import pydantic_to_json_schema
from pydantic import BaseModel, Field
from pathlib import Path
# Define extraction schema using Pydantic
class Invoice(BaseModel):
invoice_number: str = Field(description="Invoice number")
invoice_date: str = Field(description="Invoice date")
total_amount: float = Field(description="Total amount in USD")
vendor_name: str = Field(description="Vendor name")
# Convert to JSON schema
schema = pydantic_to_json_schema(Invoice)
client = LandingAIADE()
# Extract from parsed markdown
response = client.extract(
schema=schema,
markdown=Path("output.md"), # From parse step
model="extract-latest"
)
# Access extracted data
print(response.extraction)
# Output: {'invoice_number': 'INV-12345', 'invoice_date': '2024-01-15', ...}
# Check extraction metadata (traceability)
print(response.extraction_metadata)
ドキュメントの解析
ローカルファイルの解析
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from pathlib import Path
client = LandingAIADE()
response = client.parse(
document=Path("/path/to/document.pdf"),
model="dpt-2-latest"
)
# Work with chunks
for chunk in response.chunks:
print(f"Type: {chunk.type}, Page: {chunk.grounding.page}")
print(f"Content: {chunk.markdown[:100]}...")
リモート URL の解析
response = client.parse(
document_url="https://example.com/document.pdf",
model="dpt-2-latest"
)
スプレッドシートの解析
スプレッドシート(CSV、XLSX)は、ドキュメントとは異なるレスポンスタイプを返します。主な違いは次のとおりです。
| フィールド | ドキュメント(ParseResponse) | スプレッドシート(SpreadsheetParseResponse) |
|---|---|---|
metadata.page_count | ✓ | ✗(sheet_count、total_rows、total_cells、total_chunks、total_images を使用) |
splits[].pages | ✓ | ✗(シートインデックスの配列である sheets を使用) |
grounding(トップレベル) | ✓ | ✗(スプレッドシートにはありません) |
| チャンクのグラウンディング | 常にあり | 任意(テーブルチャンクでは null、埋め込み画像チャンクではあり) |
response = client.parse(
document=Path("data.xlsx"),
model="dpt-2-latest"
)
# Spreadsheet metadata
print(f"Sheets: {response.metadata.sheet_count}")
print(f"Total rows: {response.metadata.total_rows}")
print(f"Total cells: {response.metadata.total_cells}")
# Splits use 'sheets' instead of 'pages'
for split in response.splits:
print(f"Sheet indices: {split.sheets}")
print(f"Markdown: {split.markdown[:200]}...")
モデルの選択
ドキュメントに適したモデルを選択してください。
| モデル | 最適な用途 | チャンクの種類 |
|---|---|---|
| dpt-2-latest | ロゴ、署名、ID カードを含む複雑なドキュメント | text、table、figure、logo、card、attestation、scan_code、marginalia |
| dpt-2-mini | シンプルでデジタルネイティブなドキュメント(より高速で低コスト) | text、table、figure、marginalia |
| dpt-1 | ⚠️ 2026 年 3 月 31 日に非推奨 — dpt-2 に移行してください | text、table、figure、marginalia |
推奨: コストや速度が重要で、扱うドキュメントがシンプルな場合を除き、dpt-2-latest を使用してください。
バージョンの固定: 本番環境では、再現性を確保するため日付付きバージョン(例:dpt-2-20260302)を使用してください。
大きなファイルの解析(非同期)
最大 1 GB または 6,000 ページのファイルには、Parse Jobs を使用してください。
import time
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from pathlib import Path
client = LandingAIADE()
# Step 1: Create parse job
job = client.parse_jobs.create(
document=Path("large_document.pdf"),
model="dpt-2-latest"
)
job_id = job.job_id
print(f"Job {job_id} created")
# Step 2: Poll for completion
while True:
response = client.parse_jobs.get(job_id)
if response.status == "completed":
print(f"Job {job_id} completed")
break
print(f"Progress: {response.progress * 100:.0f}%")
time.sleep(5)
# Step 3: Access results
# Results are in response.data (or response.output_url for large results)
if response.data:
print(f"Chunks: {len(response.data.chunks)}")
with open("output.md", "w", encoding="utf-8") as f:
f.write(response.data.markdown)
elif response.output_url:
# Results > 1MB are returned as a presigned URL
print(f"Download results from: {response.output_url}")
ジョブステータスのレスポンスフィールド:
job_id、status(pending、processing、completed、failed、cancelled)、progress(0-1)data:完了時のParseResponse(またはSpreadsheetParseResponse)。結果が 1 MB 未満の場合に含まれますoutput_url:結果が 1 MB を超える場合、またはoutput_save_urlが使用された場合の、署名付き S3 URL。有効期限は 1 時間です。GET のたびに新しい URL が生成されます。metadata:同期解析の場合と同じです(filename、page_count、duration_msなど)failure_reason:ジョブが失敗した場合のエラーメッセージ
ゼロデータ保持(ZDR)
組織で ZDR が有効になっている場合、解析結果の保存先となる output_save_url を指定する必要があります。結果は API レスポンスとして返されません。ZDR はデフォルトでは有効になっていません。通常、output_save_url には S3 バケットへの書き込み権限を持つ署名付き URL を使用しますが、HTTP PUT リクエストによるファイルアップロードに対応した他のストレージソリューションも使用できます。
job = client.parse_jobs.create(
document=Path("sensitive_document.pdf"),
model="dpt-2-latest",
output_save_url="https://your-bucket.s3.amazonaws.com/output.json"
)
解析ジョブの一覧表示
オプションのページネーションとステータスフィルターを指定して、すべての非同期解析ジョブを一覧表示します。
# List recent jobs
jobs_response = client.parse_jobs.list(page=0, page_size=10)
for job in jobs_response.jobs:
print(f"{job.job_id}: {job.status} ({job.progress:.0%})")
# Filter by status
completed = client.parse_jobs.list(status="completed", page_size=5)
print(f"Completed jobs: {len(completed.jobs)}, more: {completed.has_more}")
使用可能なステータスフィルター: pending、processing、completed、failed、cancelled
解析出力について
解析では、以下を含む ParseResponse が返されます。
markdown:HTML アンカータグを含む、ドキュメント全体の Markdownchunks:抽出された要素の配列(それぞれに一意の ID、タイプ、コンテンツ、チャンクごとのグラウンディング情報が含まれます)grounding:要素 ID と詳細な位置情報(ページ、バウンディングボックス、グラウンディングタイプ、表のセル位置)を対応付ける辞書です。構造についてはJSON レスポンスを参照してください。metadata:処理情報 —filename、org_id、page_count、duration_ms、credit_usage(浮動小数点数)、job_id、version、failed_pagessplits:チャンクをグループ化する分割オブジェクトの配列です。常に含まれます。デフォルトでは単一の"full"分割が含まれ、split="page"が使用された場合はページごとの分割が含まれます。注: 解析の分割ではclassフィールド(値:"full"または"page")を使用します。これは Split API のclassificationフィールドとは異なります。
一般的なチャンクタイプ: text、table、figure、logo、card、attestation、scan_code、marginalia
チャンクタイプの詳細については、references/chunk-types.mdを参照してください。
chunk.markdown内のアンカータグプレフィックス: すべてのチャンクのmarkdownフィールドには、 チャンク UUID を埋め込んだ HTML アンカータグがプレフィックスとして付きます。<a id='abc123...'></a>\n\nActual content…。これにより、ドキュメント全体の Markdown から個々のチャンクにリンクできます。文字列検索、表示、 または RAG インデックス作成の前に、このタグを取り除いてください。import re _ANCHOR_RE = re.compile(r"<a[^>]*></a>\s*", re.IGNORECASE) def chunk_text(ch) -> str: """Return clean chunk markdown without the anchor prefix.""" return _ANCHOR_RE.sub("", ch.markdown or "").strip() # Example: fingerprint match against a section of the full markdown intro_chunks = [ch for ch in response.chunks if chunk_text(ch)[:80] in intro_markdown]
解析レスポンスの保存
SDK には、parse()、extract()、split() の save_to パラメーターが組み込まれており、JSON レスポンスをフォルダーに自動で保存できます。
from pathlib import Path
# Parse and auto-save response JSON to output/ folder
response = client.parse(
document=Path("document.pdf"),
model="dpt-2-latest",
save_to="output/" # Creates output/document_parse_output.json
)
# Response is still returned normally for immediate use
print(response.markdown[:200])
save_to パラメーターは以下の処理を行います。
- フォルダーが存在しない場合は作成します。
- ファイル名を
{input_filename}_{method}_output.jsonにします(例:document_parse_output.json)。 client.parse()、client.extract()、client.split()で使用できます。- クライアント側の利便機能です。API 呼び出し後、レスポンス全体をローカルに保存します。
手動でシリアライズする場合(カスタムファイル名や選択的な保存など)は、model_dump() を使用してください。
import json
response_dict = response.model_dump()
with open("parse_response.json", "w", encoding="utf-8") as f:
json.dump(response_dict, f, indent=2, ensure_ascii=False)
# Save markdown separately for extraction
with open("document_parsed.md", "w", encoding="utf-8") as f:
f.write(response.markdown)
重要: レスポンス全体をシリアライズするには、必ず model_dump() を使用してください。フィールドを選んで辞書を手動で作成しないでください。splits 配列やグラウンディング情報全体などの重要なデータを取りこぼす可能性があります。
解析パラメーター
response = client.parse(
document=Path("document.pdf"),
model="dpt-2-latest",
split="page", # Optional: organize chunks by page
password="secret", # Optional: decrypt protected files (ZDR only)
save_to="output/", # Optional: auto-save response JSON
)
パスワード保護されたファイルの解析
ゼロデータ保持(ZDR)が有効な組織では、password パラメーターを渡すことで、パスワード保護されたファイルを解析できます。対応形式:PDF、DOC、DOCX、ODT、PPT、PPTX、XLSX。
# Sync parse
response = client.parse(
document=Path("encrypted.pdf"),
password="document_password",
model="dpt-2-latest"
)
# Async parse jobs
job = client.parse_jobs.create(
document=Path("encrypted.pdf"),
password="document_password",
model="dpt-2-latest"
)
注: ZDR が有効でない場合、API は HTTP 422 を返します。パスワードが正しくない場合、API は復号エラーとともに HTTP 422 を返します。暗号化されていないドキュメントでは、このパラメーターは無視されます。
構造化データの抽出
スキーマ定義
JSON Schema または Pydantic モデルを使用して、抽出するデータを定義します。
Pydantic を使用する方法(Python で推奨):
from pydantic import BaseModel, Field
from landingai_ade.lib import pydantic_to_json_schema
class BankStatement(BaseModel):
account_holder: str = Field(description="Account holder name")
account_number: str = Field(description="Account number")
beginning_balance: float = Field(description="Beginning balance in USD")
ending_balance: float = Field(description="Ending balance in USD")
schema = pydantic_to_json_schema(BankStatement)
JSON Schema を使用する方法:
schema = {
"type": "object",
"properties": {
"account_holder": {
"type": "string",
"description": "Account holder name"
},
"account_number": {
"type": "string",
"description": "Account number"
},
"beginning_balance": {
"type": "number",
"description": "Beginning balance in USD"
},
"ending_balance": {
"type": "number",
"description": "Ending balance in USD"
}
},
"required": ["account_holder", "account_number"]
}
抽出ワークフロー
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from pathlib import Path
client = LandingAIADE()
# Step 1: Parse document
parse_response = client.parse(
document=Path("bank_statement.pdf"),
model="dpt-2-latest"
)
# Save markdown
with open("parsed.md", "w", encoding="utf-8") as f:
f.write(parse_response.markdown)
# Step 2: Extract structured data
extract_response = client.extract(
schema=schema, # Your JSON schema
markdown=Path("parsed.md"),
model="extract-latest"
)
# Access extracted data
print(extract_response.extraction)
# Check traceability (which chunks provided each field)
for field, metadata in extract_response.extraction_metadata.items():
print(f"{field}: from chunks {metadata.chunk_ids}")
URL から抽出
markdown_url を使用すると、リモートでホストされている Markdown ファイルから抽出できます。
extract_response = client.extract(
schema=schema,
markdown_url="https://example.com/parsed_document.md",
model="extract-latest"
)
一般的なスキーマパターン
詳しいスキーマパターンについては、references/extraction-schemas.md を参照してください。
ネストされたオブジェクト:
class Address(BaseModel):
street: str
city: str
zip_code: str
class Invoice(BaseModel):
invoice_number: str
billing_address: Address # Nested object
配列(リスト):
class LineItem(BaseModel):
description: str
quantity: int
amount: float
class Invoice(BaseModel):
invoice_number: str
line_items: list[LineItem] # Array of objects
列挙型(制限された値):
class BankStatement(BaseModel):
account_type: str = Field(
description="Account type",
enum=["Checking", "Savings"] # Only these values allowed
)
Null 許容フィールド:
class Patient(BaseModel):
first_name: str
middle_name: str | None = Field(default=None) # Optional field
last_name: str
ドキュメントの分類
種類ごとのフィールドを抽出する前に、ドキュメントを分類します。
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from pydantic import BaseModel, Field
from landingai_ade.lib import pydantic_to_json_schema
from pathlib import Path
# Step 1: Define classification schema
class DocumentType(BaseModel):
document_type: str = Field(
description="Document classification",
enum=["Invoice", "Receipt", "Bank Statement", "Other"]
)
client = LandingAIADE()
# Step 2: Parse document
parse_response = client.parse(
document=Path("document.pdf"),
model="dpt-2-latest"
)
# Step 3: Classify document
classification_schema = pydantic_to_json_schema(DocumentType)
classification_response = client.extract(
schema=classification_schema,
markdown=parse_response.markdown,
model="extract-latest"
)
doc_type = classification_response.extraction["document_type"]
print(f"Classified as: {doc_type}")
# Step 4: Extract based on type
if doc_type == "Invoice":
schema = pydantic_to_json_schema(InvoiceSchema)
elif doc_type == "Receipt":
schema = pydantic_to_json_schema(ReceiptSchema)
else:
print("Unsupported document type")
exit()
# Extract type-specific fields
extract_response = client.extract(
schema=schema,
markdown=parse_response.markdown,
model="extract-latest"
)
ドキュメントの分類と分割
Split API を使用するタイミング
1 つのファイルに複数のドキュメントが含まれており、それらを分割する必要がある場合は、Split API を使用します。
- 金融サービス:銀行取引明細書、公共料金の請求書、本人確認書類を分割します
- 医療:問診票、医療報告書、薬剤リストを分割します
- 会計:複数の請求書と領収書を分割します
- 学術:論文本文と参考文献を分割します
分割分類
split_class を使用して、ドキュメントの分類方法と分割方法を定義します。
from dotenv import load_dotenv
load_dotenv()
from landingai_ade import LandingAIADE
from pathlib import Path
client = LandingAIADE()
# Step 1: Parse multi-document PDF
parse_response = client.parse(
document=Path("batch.pdf"),
model="dpt-2-latest"
)
# Step 2: Define split classes
split_classes = [
{
"name": "Invoice",
"description": "Commercial invoices with itemized charges",
"identifier": "Invoice Number" # Separate by invoice number
},
{
"name": "Receipt",
"description": "Payment receipts showing transaction details",
"identifier": "Receipt Date"
},
{
"name": "Bank Statement",
"description": "Monthly bank account statements"
}
]
# Step 3: Split document
split_response = client.split(
markdown=parse_response.markdown,
split_class=split_classes
)
# Step 4: Process each split
for split in split_response.splits:
print(f"Type: {split.classification}")
print(f"Identifier: {split.identifier}")
print(f"Pages: {split.pages}")
print(f"Content: {split.markdowns[0][:200]}...")
分割クラスの構成要素:
- name(必須):ドキュメントの分類ラベル(例:「Invoice」)
- description(任意):分類のコンテキスト(詳しいほど精度が向上します)
- identifier(任意):各インスタンスを一意に識別するフィールド(一意の値ごとに個別の分割を作成します)
- 上限: リクエストあたり最大 19 個の分割クラス
URL からの分割: リモートでホストされている Markdown ファイルから分割することもできます。
split_response = client.split(
markdown_url="https://example.com/parsed_document.md",
split_class=split_classes
)
出力形式
Markdown
ADE はドキュメントを構造化された Markdown に変換します。
# Document Title
## Section 1
Paragraph text...
| Column 1 | Column 2 |
|----------|----------|
| Data 1 | Data 2 |
<::Caption: Bar chart showing quarterly revenue::>
機能:
- トレーサビリティのための HTML アンカータグ(チャンク ID へのリンク)
- 視覚要素のための特殊な区切り記号:
<::Caption: description::> - スプレッドシートデータのための HTML テーブル
- 構造と階層を保持
JSON レスポンス
Parse は、最上位に 5 つのフィールドを持つ構造化 JSON を返します。
{
"markdown": "# Document...",
"chunks": [
{
"id": "7d58c5cf-e4f5-4a7e-ba34-0cd7bc6a6506",
"type": "text",
"markdown": "Content...",
"grounding": {
"page": 0,
"box": { "left": 0.1, "top": 0.2, "right": 0.9, "bottom": 0.3 }
}
}
],
"splits": [
{
"class": "full",
"identifier": "full",
"pages": [0],
"markdown": "# Document...",
"chunks": ["7d58c5cf-e4f5-4a7e-ba34-0cd7bc6a6506"]
}
],
"grounding": {
"7d58c5cf-e4f5-4a7e-ba34-0cd7bc6a6506": {
"box": { "left": 0.1, "top": 0.2, "right": 0.9, "bottom": 0.3 },
"page": 0,
"type": "chunkText",
"confidence": 0.95,
"low_confidence_spans": []
},
"0-1": {
"box": { "left": 0.15, "top": 0.4, "right": 0.85, "bottom": 0.7 },
"page": 0,
"type": "table"
},
"0-2": {
"box": { "left": 0.15, "top": 0.4, "right": 0.5, "bottom": 0.55 },
"page": 0,
"type": "tableCell",
"position": { "row": 0, "col": 0, "rowspan": 1, "colspan": 1,
"chunk_id": "ef24b1ea-..." }
}
},
"metadata": {
"filename": "document.pdf",
"org_id": "org-123",
"page_count": 5,
"duration_ms": 1500,
"credit_usage": 2.0,
"job_id": "abc-123",
"version": "dpt-2-20260302",
"failed_pages": []
}
}
最上位の grounding は、要素 ID(チャンクの場合は UUID、テーブル/セルの場合は {page}-{base62})をキーとするディクショナリです。各値には box、page、type が含まれ、さらに confidence と low_confidence_spans が含まれる場合があります(信頼度スコアを参照)。テーブルセルのエントリには position フィールドも含まれます(グラウンディングとトレーサビリティを参照)。
グラウンディングのタイプ対応表
グラウンディングのタイプには、チャンクのタイプと区別するために chunk という接頭辞が付いています。table と tableCell はグラウンディング専用のタイプであり、対応するチャンクタイプはありません。
| グラウンディングタイプ | チャンクタイプ | 説明 |
|---|---|---|
chunkText | text | テキストコンテンツ |
chunkTable | table | テーブルチャンク(全体の位置) |
chunkFigure | figure | 図と画像 |
chunkMarginalia | marginalia | ヘッダー、フッター、ページ番号 |
chunkLogo | logo | 企業ロゴ(DPT-2) |
chunkCard | card | ID カード、免許証(DPT-2) |
chunkAttestation | attestation | 署名、スタンプ(DPT-2) |
chunkScanCode | scan_code | QR コード、バーコード(DPT-2) |
table | (グラウンディング専用) | テーブルチャンク内の HTML <table> 要素 |
tableCell | (グラウンディング専用) | テーブル内の個々のセル |
Extract は次を返します。
{
"extraction": {
"invoice_number": "INV-12345",
"total": 1250.00
},
"extraction_metadata": {
"invoice_number": {
"chunk_ids": ["chunk-uuid-1"]
},
"total": {
"chunk_ids": ["chunk-uuid-2"],
"cell_ids": ["2-a5"]
}
},
"metadata": {
"filename": "markdown.md",
"org_id": "org-123",
"duration_ms": 850,
"credit_usage": 1.0,
"job_id": "abc-456",
"version": "extract-20251024",
"schema_violation_error": null,
"fallback_model_version": null
}
}
Extract のメタデータフィールド:
schema_violation_error:抽出結果がスキーマに一致する場合はnullです。抽出データがスキーマに完全には準拠しない場合は、詳細なエラーメッセージが含まれます(HTTP 206 レスポンス)。抽出では引き続き部分データが返され、クレジットが消費されます。fallback_model_version:通常はnullです。指定されたバージョンで最初の抽出に失敗し、フォールバックが使用された場合、実際に使用されたモデルのバージョンが含まれます。
グラウンディングとトレーサビリティ
解析された各要素には、最上位の grounding 辞書に正確な位置情報が含まれます。
- ページ参照:0 始まりのページ番号
- バウンディングボックス:位置を示す正規化座標(0~1)
left、top、right、bottom- ピクセルに変換するには、画像の寸法を乗算します
- 要素 ID:チャンクには UUID、テーブルとテーブルセルには
{page}-{base62}- テーブル/セル ID は、ページごとに連番の base62 方式で付与されます:
0-1、0-2、...、0-9、0-a、...、0-z、0-A、...、0-Z、0-10など - 番号はページごとにリセットされます(例:ページ 1 の最初のテーブル →
1-1)
- テーブル/セル ID は、ページごとに連番の base62 方式で付与されます:
- グラウンディングの型:各エントリーには、接頭辞付きの名前を使う
typeフィールドがあります(例:chunkText、chunkTable)。グラウンディング型の対応表を参照してください。 - テーブルセルの位置:
tableCellエントリーには、row、col(いずれも 0 始まり)、rowspan、colspan、および親テーブルのチャンク UUID であるchunk_idを含むpositionオブジェクトがあります - 抽出メタデータ:各フィールドの提供元となったチャンク/セルを示します
チャンクごとのグラウンディング(各チャンクオブジェクト内)には、box と page のみが含まれます。最上位の grounding 辞書には、type と、テーブルセルの場合は position も追加されます。
例:
# Per-chunk grounding (basic location)
for chunk in response.chunks:
print(f"Chunk {chunk.id} on page {chunk.grounding.page}")
bbox = chunk.grounding.box
print(f"Location: ({bbox.left}, {bbox.top}) to ({bbox.right}, {bbox.bottom})")
# Top-level grounding (detailed, with type and position)
# NOTE: grounding values are Pydantic models — use attribute access, not dict access
for elem_id, info in response.grounding.items():
print(f"{elem_id}: type={info.type}, page={info.page}")
if info.type == "tableCell" and info.position:
print(f" Cell at row={info.position.row}, col={info.position.col}")
重要:
response.groundingはDict[str, Grounding]です。外側のコンテナは辞書なので.items()や.get()を使用できますが、各値は Pydantic モデルです。辞書アクセス(info["type"])ではなく、属性アクセス(info.type、info.box.left)を使用してください。
信頼度スコア {#confidence-scores}
最上位の grounding エントリーには、信頼度情報が含まれる場合があります。
confidence(float | None):チャンクの文字起こしに対する全体的な信頼度スコア(0.0~1.0)low_confidence_spans(list | None):信頼度の低い特定のテキスト範囲。それぞれに以下が含まれます。confidence(float):範囲単位の信頼度スコアtext(str):信頼度の低いテキストspan(list):チャンク内の位置を示すマーカー
# Access confidence scores from top-level grounding
for elem_id, info in response.grounding.items():
if info.confidence is not None:
print(f"{elem_id}: confidence={info.confidence:.2f}")
for span in info.low_confidence_spans or []:
print(f" Low confidence ({span.confidence:.2f}): "
f"'{span.text}'")
注意:
- 信頼度情報は最上位の groundingにのみ存在し、チャンクごとの grounding にはありません
- すべての grounding エントリーに信頼度情報が含まれるわけではありません(例:
table/tableCell型には含まれない場合があります) - 信頼度スコアを使って、人による確認が必要なチャンクを特定してください
ベストプラクティス
モデルの選択
- ほとんどのドキュメントには dpt-2-latest を使用してください(複雑なレイアウト、ロゴ、署名など)
- シンプルなデジタルネイティブのドキュメントには dpt-2-mini を使用してください(より高速で低コスト)
- 再現性を確保するため、本番環境ではバージョンを固定してください(例:
dpt-2-20260302) - 抽出には extract-latest を使用してください(最新モデルが自動的に使用されます)
- dpt-1 は使用しないでください — 2026 年 3 月 31 日に非推奨となりました。dpt-2 に移行してください
スキーマ設計
- 具体的にする:
numberではなく、説明的なフィールド名(invoice_numberなど)を使用します - 説明を追加する:「USD 表記」「YYYY-MM-DD 形式」など、形式の要件を含めます
- シンプルに保つ:少数のフィールドから始め、必要に応じて追加します
- 複雑さを抑える:最適なパフォーマンスを得るため、プロパティは 30 個未満にします
- ドキュメントの構造に合わせる:フィールドを、ドキュメント内に現れる順に並べます
スキーマの詳細なパターンについては、references/extraction-schemas.mdを参照してください。
エラー処理
try:
response = client.parse(document=Path("doc.pdf"), model="dpt-2-latest")
except Exception as e:
print(f"Parse error: {e}")
# Handle error (check file format, file size, API key, etc.)
try:
extract_response = client.extract(schema=schema, markdown=response.markdown)
except Exception as e:
print(f"Extract error: {e}")
# Handle error (check schema validity, markdown format, etc.)
部分的な結果の処理(HTTP 206)
Parse API と Extract API はどちらも、処理が部分的に成功した場合に HTTP 206(Partial Content)を返すことがあります。
Parse 206:一部のページの解析に失敗しています。metadata.failed_pages を確認してください。
response = client.parse(document=Path("doc.pdf"), model="dpt-2-latest")
if response.metadata.failed_pages:
print(f"Failed pages: {response.metadata.failed_pages}")
# Remaining pages were parsed successfully
Extract 206:抽出は完了しましたが、データがスキーマに完全には一致していません。metadata.schema_violation_error を確認してください。
response = client.extract(schema=schema, markdown=markdown)
err = response.metadata.schema_violation_error
if err:
print(f"Schema violation: {err}")
# Extraction still returns partial data; credits are consumed
注意: 206 レスポンスでもクレジットを消費します。API は生成できた中で最良の結果を返します。
パフォーマンス
- 大きなファイル:50 ページ超または 10 MB 超のファイルには Parse Jobs API(非同期)を使用します
- バッチ処理:可能であれば、ドキュメントを並列処理します
- 解析結果をキャッシュする:複数回の抽出で再解析を避けるため、Markdown を保存します
- 解析を最適化する:ページ単位の構成が必要な場合は、
split="page"パラメーターを使用します
ファイル形式
- ネイティブドキュメントには、変換が不要な PDF を推奨します
- OCR の精度を高めるため、高解像度の画像(300 DPI 以上)を使用してください
- パスワードで保護されたファイル:
passwordパラメーターを使用してください(ZDR が必要です)。ZDR を使用しない場合は、解析前にパスワード保護を解除してください - DOCX/PPTX ファイルは、変換後のレイアウトが変わる場合があるため、変換をテストしてください
ファイル形式の詳細については、references/file-formats.md を参照してください
ユースケース
請求書処理、フォームデータの抽出、複数ドキュメントの分類、表の抽出、PyMuPDF による図の切り抜きなど、実際の例については references/use-cases.md を参照してください。
トラブルシューティング
HTTP エラーコード、解析の失敗、抽出精度の問題、スキーマ検証エラー、パフォーマンスに関するガイダンスについては、references/troubleshooting.md を参照してください。
リンク
公式ドキュメント
API キー
参考ファイル
- 抽出スキーマのパターン - スキーマの詳細な例
- チャンクタイプのリファレンス - チャンクタイプの完全なガイド
- ファイル形式 - 対応形式と注意事項
- ユースケース - 請求書、フォーム、表、図の抽出に関する実例
- トラブルシューティング - HTTP エラーコードと一般的な問題