azure-ai-formrecognizer-java について
Azure AI Document Intelligence SDK を使った文書分析アプリ開発向けの Java スキルです。OCR と構造化抽出を扱い、プレビュー版の旧 API を対象とする例で、既成モデルやカスタムモデル、分類、モデル管理を説明します。
主な機能
- 01テキスト、表、選択マークの分析
- 02一般的な文書のフィールド抽出
- 03カスタムモデルの構築と合成
- 04文書分類器の構築と実行
- 05管理クライアントによるモデル管理
- 06ポーリングと HTTP エラーの処理
活用シーン
- 01PDF からテキストや表を抽出
- 02請求書やレシートのフィールド読取
- 03文書の種類別分類
- 04カスタムモデルの学習と適用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-ai-formrecognizer-javaインストール後、Claude Code で/azure-ai-formrecognizer-javaを入力して読み込まれたか確認します。
詳細
Azure Document Intelligence (Form Recognizer) SDK for Java
Azure AI Document Intelligence SDK for Java を使用して、ドキュメント分析アプリケーションを構築します。
バージョンとドキュメントの取り扱い上の注意
これらの例は、旧式の azure-ai-formrecognizer API とプレリリース依存関係を対象としています。新しい Document Intelligence SDK と同等であると想定せず、使用前に選択したアーティファクト/サービス API とサポートされているモデル ID を確認してください。特に本人確認書類や金融記録をアップロードする前に、必ず許可を得てください。有効期間が短く、スコープが限定された SAS URL を使用し、クエリ文字列や抽出した内容を決してログに記録しないでください。モデルの構築/削除操作は、課金対象のリソースを変更します。OCR のフィールドと信頼度には不確実性があります。各ネストされた Items フィールドについて null/型を確認してから型付きゲッターを呼び出し、結果を元のドキュメントと照合して検証してください。また、処理開始時のエラーだけでなく、ポーリング中の終端エラーやタイムアウトにも対処してください。クライアントの宣言はそれぞれ独立した代替スニペットであり、1 つのコンパイル可能なファイルではありません。
インストール
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-formrecognizer</artifactId>
<version>4.2.0-beta.1</version>
</dependency>
クライアントの作成
DocumentAnalysisClient
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClient;
import com.azure.ai.formrecognizer.documentanalysis.DocumentAnalysisClientBuilder;
import com.azure.core.credential.AzureKeyCredential;
DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
.credential(new AzureKeyCredential("{key}"))
.endpoint("{endpoint}")
.buildClient();
DocumentModelAdministrationClient
import com.azure.ai.formrecognizer.documentanalysis.administration.DocumentModelAdministrationClient;
import com.azure.ai.formrecognizer.documentanalysis.administration.DocumentModelAdministrationClientBuilder;
DocumentModelAdministrationClient adminClient = new DocumentModelAdministrationClientBuilder()
.credential(new AzureKeyCredential("{key}"))
.endpoint("{endpoint}")
.buildClient();
DefaultAzureCredential を使用する場合
import com.azure.identity.DefaultAzureCredentialBuilder;
DocumentAnalysisClient client = new DocumentAnalysisClientBuilder()
.endpoint("{endpoint}")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
事前構築済みモデル
| モデル ID | 用途 |
|---|---|
prebuilt-layout | テキスト、テーブル、選択マークを抽出 |
prebuilt-document | キーと値のペアを含む一般的なドキュメント |
prebuilt-receipt | レシートデータの抽出 |
prebuilt-invoice | 請求書フィールドの抽出 |
prebuilt-businessCard | 名刺の解析 |
prebuilt-idDocument | ID ドキュメント(パスポート、免許証) |
prebuilt-tax.us.w2 | 米国の W2 税務フォーム |
基本的なパターン
レイアウトの抽出
import com.azure.ai.formrecognizer.documentanalysis.models.*;
import com.azure.core.util.BinaryData;
import com.azure.core.util.polling.SyncPoller;
import java.io.File;
File document = new File("document.pdf");
BinaryData documentData = BinaryData.fromFile(document.toPath());
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocument("prebuilt-layout", documentData);
AnalyzeResult result = poller.getFinalResult();
// Process pages
for (DocumentPage page : result.getPages()) {
System.out.printf("Page %d: %.2f x %.2f %s%n",
page.getPageNumber(),
page.getWidth(),
page.getHeight(),
page.getUnit());
// Lines
for (DocumentLine line : page.getLines()) {
System.out.println("Line: " + line.getContent());
}
// Selection marks (checkboxes)
for (DocumentSelectionMark mark : page.getSelectionMarks()) {
System.out.printf("Checkbox: %s (confidence: %.2f)%n",
mark.getSelectionMarkState(),
mark.getConfidence());
}
}
// Tables
for (DocumentTable table : result.getTables()) {
System.out.printf("Table: %d rows x %d columns%n",
table.getRowCount(),
table.getColumnCount());
for (DocumentTableCell cell : table.getCells()) {
System.out.printf("Cell[%d,%d]: %s%n",
cell.getRowIndex(),
cell.getColumnIndex(),
cell.getContent());
}
}
URL から分析
String documentUrl = "https://example.com/invoice.pdf";
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-invoice", documentUrl);
AnalyzeResult result = poller.getFinalResult();
レシートの分析
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-receipt", receiptUrl);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
Map<String, DocumentField> fields = doc.getFields();
DocumentField merchantName = fields.get("MerchantName");
if (merchantName != null && merchantName.getType() == DocumentFieldType.STRING) {
System.out.printf("Merchant: %s (confidence: %.2f)%n",
merchantName.getValueAsString(),
merchantName.getConfidence());
}
DocumentField transactionDate = fields.get("TransactionDate");
if (transactionDate != null && transactionDate.getType() == DocumentFieldType.DATE) {
System.out.printf("Date: %s%n", transactionDate.getValueAsDate());
}
DocumentField items = fields.get("Items");
if (items != null && items.getType() == DocumentFieldType.LIST) {
for (DocumentField item : items.getValueAsList()) {
Map<String, DocumentField> itemFields = item.getValueAsMap();
System.out.printf("Item: %s, Price: %.2f%n",
itemFields.get("Name").getValueAsString(),
itemFields.get("Price").getValueAsDouble());
}
}
}
一般的なドキュメントの分析
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("prebuilt-document", documentUrl);
AnalyzeResult result = poller.getFinalResult();
// Key-value pairs
for (DocumentKeyValuePair kvp : result.getKeyValuePairs()) {
System.out.printf("Key: %s => Value: %s%n",
kvp.getKey().getContent(),
kvp.getValue() != null ? kvp.getValue().getContent() : "null");
}
カスタムモデル
カスタムモデルの構築
import com.azure.ai.formrecognizer.documentanalysis.administration.models.*;
String blobContainerUrl = "{SAS_URL_of_training_data}";
String prefix = "training-docs/";
SyncPoller<OperationResult, DocumentModelDetails> poller = adminClient.beginBuildDocumentModel(
blobContainerUrl,
DocumentModelBuildMode.TEMPLATE,
prefix,
new BuildDocumentModelOptions()
.setModelId("my-custom-model")
.setDescription("Custom invoice model"),
Context.NONE);
DocumentModelDetails model = poller.getFinalResult();
System.out.println("Model ID: " + model.getModelId());
System.out.println("Created: " + model.getCreatedOn());
model.getDocumentTypes().forEach((docType, details) -> {
System.out.println("Document type: " + docType);
details.getFieldSchema().forEach((field, schema) -> {
System.out.printf(" Field: %s (%s)%n", field, schema.getType());
});
});
カスタムモデルを使用した分析
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginAnalyzeDocumentFromUrl("my-custom-model", documentUrl);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
System.out.printf("Document type: %s (confidence: %.2f)%n",
doc.getDocType(),
doc.getConfidence());
doc.getFields().forEach((name, field) -> {
System.out.printf("Field '%s': %s (confidence: %.2f)%n",
name,
field.getContent(),
field.getConfidence());
});
}
モデルの合成
List<String> modelIds = Arrays.asList("model-1", "model-2", "model-3");
SyncPoller<OperationResult, DocumentModelDetails> poller =
adminClient.beginComposeDocumentModel(
modelIds,
new ComposeDocumentModelOptions()
.setModelId("composed-model")
.setDescription("Composed from multiple models"));
DocumentModelDetails composedModel = poller.getFinalResult();
モデルの管理
// List models
PagedIterable<DocumentModelSummary> models = adminClient.listDocumentModels();
for (DocumentModelSummary summary : models) {
System.out.printf("Model: %s, Created: %s%n",
summary.getModelId(),
summary.getCreatedOn());
}
// Get model details
DocumentModelDetails model = adminClient.getDocumentModel("model-id");
// Delete model
adminClient.deleteDocumentModel("model-id");
// Check resource limits
ResourceDetails resources = adminClient.getResourceDetails();
System.out.printf("Models: %d / %d%n",
resources.getCustomDocumentModelCount(),
resources.getCustomDocumentModelLimit());
ドキュメントの分類
分類器の構築
Map<String, ClassifierDocumentTypeDetails> docTypes = new HashMap<>();
docTypes.put("invoice", new ClassifierDocumentTypeDetails()
.setAzureBlobSource(new AzureBlobContentSource(containerUrl).setPrefix("invoices/")));
docTypes.put("receipt", new ClassifierDocumentTypeDetails()
.setAzureBlobSource(new AzureBlobContentSource(containerUrl).setPrefix("receipts/")));
SyncPoller<OperationResult, DocumentClassifierDetails> poller =
adminClient.beginBuildDocumentClassifier(docTypes,
new BuildDocumentClassifierOptions().setClassifierId("my-classifier"));
DocumentClassifierDetails classifier = poller.getFinalResult();
ドキュメントの分類
SyncPoller<OperationResult, AnalyzeResult> poller =
client.beginClassifyDocumentFromUrl("my-classifier", documentUrl, Context.NONE);
AnalyzeResult result = poller.getFinalResult();
for (AnalyzedDocument doc : result.getDocuments()) {
System.out.printf("Classified as: %s (confidence: %.2f)%n",
doc.getDocType(),
doc.getConfidence());
}
エラー処理
import com.azure.core.exception.HttpResponseException;
try {
client.beginAnalyzeDocumentFromUrl("prebuilt-receipt", "invalid-url");
} catch (HttpResponseException e) {
System.out.println("Status: " + e.getResponse().getStatusCode());
System.out.println("Error: " + e.getMessage());
}
環境変数
FORM_RECOGNIZER_ENDPOINT=https://<resource>.cognitiveservices.azure.com/
FORM_RECOGNIZER_KEY=<your-api-key>
トリガーフレーズ
- "ドキュメントインテリジェンス Java"
- "フォーム認識 SDK"
- "PDF からテキストを抽出"
- "Java でドキュメントを OCR"
- "請求書とレシートを分析"
- "カスタムドキュメントモデル"
- "ドキュメントの分類"
使用する場合
このスキルは、概要で説明されているワークフローまたはアクションを実行する場合に適用できます。
制限事項
- 上記で説明されている範囲にタスクが明確に該当する場合に限り、このスキルを使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。