Azure.AI.DocumentIntelligence (.NET)
사전 구축 및 사용자 지정 모델을 사용하여 문서에서 텍스트, 표, 구조화된 데이터를 추출합니다.
설치
dotnet add package Azure.AI.DocumentIntelligence
dotnet add package Azure.Identity
현재 버전: v1.0.0 (GA)
환경 변수
DOCUMENT_INTELLIGENCE_ENDPOINT=https://<resource-name>.cognitiveservices.azure.com/
DOCUMENT_INTELLIGENCE_API_KEY=<your-api-key>
BLOB_CONTAINER_SAS_URL=https://<storage>.blob.core.windows.net/<container>?<sas-token>
AZURE_TOKEN_CREDENTIALS=prod
인증
Microsoft Entra 토큰 자격 증명
using Azure.Identity;
using Azure.AI.DocumentIntelligence;
string endpoint = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_ENDPOINT");
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
var client = new DocumentIntelligenceClient(new Uri(endpoint), credential);
참고: Entra ID는 지역 엔드포인트가 아닌 사용자 지정 하위 도메인(예: https://<resource-name>.cognitiveservices.azure.com/)이 필요합니다.
API 키
string endpoint = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_ENDPOINT");
string apiKey = Environment.GetEnvironmentVariable("DOCUMENT_INTELLIGENCE_API_KEY");
var client = new DocumentIntelligenceClient(new Uri(endpoint), new AzureKeyCredential(apiKey));
클라이언트 유형
| 클라이언트 | 용도 |
|---|
DocumentIntelligenceClient | 문서 분석, 문서 분류 |
DocumentIntelligenceAdministrationClient | 사용자 지정 모델 및 분류기 구축/관리 |
사전 구축 모델
| 모델 ID | 설명 |
|---|
prebuilt-read | 텍스트, 언어, 필기 추출 |
prebuilt-layout | 텍스트, 표, 선택 표시, 구조 추출 |
prebuilt-invoice | 청구서 필드(공급업체, 항목, 합계) 추출 |
prebuilt-receipt | 영수증 필드(판매자, 항목, 합계) 추출 |
prebuilt-idDocument | 신분증 문서 필드(이름, 생년월일, 주소) 추출 |
prebuilt-businessCard | 명함 필드 추출 |
prebuilt-tax.us.w2 | W-2 세금 양식 필드 추출 |
prebuilt-healthInsuranceCard.us | 건강 보험증 필드 추출 |
핵심 워크플로
1. 청구서 분석
using Azure.AI.DocumentIntelligence;
Uri invoiceUri = new Uri("https://example.com/invoice.pdf");
Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(
WaitUntil.Completed,
"prebuilt-invoice",
invoiceUri);
AnalyzeResult result = operation.Value;
foreach (AnalyzedDocument document in result.Documents)
{
if (document.Fields.TryGetValue("VendorName", out DocumentField vendorNameField)
&& vendorNameField.FieldType == DocumentFieldType.String)
{
string vendorName = vendorNameField.ValueString;
Console.WriteLine($"Vendor Name: '{vendorName}', confidence: {vendorNameField.Confidence}");
}
if (document.Fields.TryGetValue("InvoiceTotal", out DocumentField invoiceTotalField)
&& invoiceTotalField.FieldType == DocumentFieldType.Currency)
{
CurrencyValue invoiceTotal = invoiceTotalField.ValueCurrency;
Console.WriteLine($"Invoice Total: '{invoiceTotal.CurrencySymbol}{invoiceTotal.Amount}'");
}
if (document.Fields.TryGetValue("Items", out DocumentField itemsField)
&& itemsField.FieldType == DocumentFieldType.List)
{
foreach (DocumentField item in itemsField.ValueList)
{
var itemFields = item.ValueDictionary;
if (itemFields.TryGetValue("Description", out DocumentField descField))
Console.WriteLine($" Item: {descField.ValueString}");
}
}
}
2. 레이아웃 추출 (텍스트, 표, 구조)
Uri fileUri = new Uri("https://example.com/document.pdf");
Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(
WaitUntil.Completed,
"prebuilt-layout",
fileUri);
AnalyzeResult result = operation.Value;
foreach (DocumentPage page in result.Pages)
{
Console.WriteLine($"Page {page.PageNumber}: {page.Lines.Count} lines, {page.Words.Count} words");
foreach (DocumentLine line in page.Lines)
{
Console.WriteLine($" Line: '{line.Content}'");
}
}
foreach (DocumentTable table in result.Tables)
{
Console.WriteLine($"Table: {table.RowCount} rows x {table.ColumnCount} columns");
foreach (DocumentTableCell cell in table.Cells)
{
Console.WriteLine($" Cell ({cell.RowIndex}, {cell.ColumnIndex}): {cell.Content}");
}
}
3. 영수증 분석
Operation<AnalyzeResult> operation = await client.AnalyzeDocumentAsync(
WaitUntil.Completed,
"prebuilt-receipt",
receiptUri);
AnalyzeResult result = operation.Value;
foreach (AnalyzedDocument document in result.Documents)
{
if (document.Fields.TryGetValue("MerchantName", out DocumentField merchantField))
Console.WriteLine($"Merchant: {merchantField.ValueString}");
if (document.Fields.TryGetValue("Total", out DocumentField totalField))
Console.WriteLine($"Total: {totalField.ValueCurrency.Amount}");
if (document.Fields.TryGetValue("TransactionDate", out DocumentField dateField))
Console.WriteLine($"Date: {dateField.ValueDate}");
}
4. 사용자 지정 모델 구축
var adminClient = new DocumentIntelligenceAdministrationClient(
new Uri(endpoint),
new AzureKeyCredential(apiKey));
string modelId = "my-custom-model";
Uri blobContainerUri = new Uri("<blob-container-sas-url>");
var blobSource = new BlobContentSource(blobContainerUri);
var options = new BuildDocumentModelOptions(modelId, DocumentBuildMode.Template, blobSource);
Operation<DocumentModelDetails> operation = await adminClient.BuildDocumentModelAsync(
WaitUntil.Completed,
options);
DocumentModelDetails model = operation.Value;
Console.WriteLine($"Model ID: {model.ModelId}");
Console.WriteLine($"Created: {model.CreatedOn}");
foreach (var docType in model.DocumentTypes)
{
Console.WriteLine($"Document type: {docType.Key}");
foreach (var field in docType.Value.FieldSchema)
{
Console.WriteLine($" Field: {field.Key}, Confidence: {docType.Value.FieldConfidence[field.Key]}");
}
}
5. 문서 분류기 구축
string classifierId = "my-classifier";
Uri blobContainerUri = new Uri("<blob-container-sas-url>");
var sourceA = new BlobContentSource(blobContainerUri) { Prefix = "TypeA/train" };
var sourceB = new BlobContentSource(blobContainerUri) { Prefix = "TypeB/train" };
var docTypes = new Dictionary<string, ClassifierDocumentTypeDetails>()
{
{ "TypeA", new ClassifierDocumentTypeDetails(sourceA) },
{ "TypeB", new ClassifierDocumentTypeDetails(sourceB) }
};
var options = new BuildClassifierOptions(classifierId, docTypes);
Operation<DocumentClassifierDetails> operation = await adminClient.BuildClassifierAsync(
WaitUntil.Completed,
options);
DocumentClassifierDetails classifier = operation.Value;
Console.WriteLine($"Classifier ID: {classifier.ClassifierId}");
6. 문서 분류
string classifierId = "my-classifier";
Uri documentUri = new Uri("https://example.com/document.pdf");
var options = new ClassifyDocumentOptions(classifierId, documentUri);
Operation<AnalyzeResult> operation = await client.ClassifyDocumentAsync(
WaitUntil.Completed,
options);
AnalyzeResult result = operation.Value;
foreach (AnalyzedDocument document in result.Documents)
{
Console.WriteLine($"Document type: {document.DocumentType}, confidence: {document.Confidence}");
}
7. 모델 관리
DocumentIntelligenceResourceDetails resourceDetails = await adminClient.GetResourceDetailsAsync();
Console.WriteLine($"Custom models: {resourceDetails.CustomDocumentModels.Count}/{resourceDetails.CustomDocumentModels.Limit}");
DocumentModelDetails model = await adminClient.GetModelAsync("my-model-id");
Console.WriteLine($"Model: {model.ModelId}, Created: {model.CreatedOn}");
await foreach (DocumentModelDetails modelItem in adminClient.GetModelsAsync())
{
Console.WriteLine($"Model: {modelItem.ModelId}");
}
await adminClient.DeleteModelAsync("my-model-id");
주요 형식 참조
| 형식 | 설명 |
|---|
DocumentIntelligenceClient | 분석용 기본 클라이언트 |
DocumentIntelligenceAdministrationClient | 모델 관리 |
AnalyzeResult | 문서 분석 결과 |
AnalyzedDocument | 결과 내의 단일 문서 |
DocumentField | 값과 신뢰도가 포함된 추출된 필드 |
DocumentFieldType | String, Date, Number, Currency 등 |
DocumentPage | 페이지 정보 (줄, 단어, 선택 표시) |
DocumentTable | 셀이 포함된 추출된 표 |
DocumentModelDetails | 사용자 지정 모델 메타데이터 |
BlobContentSource | 학습 데이터 소스 |
구축 모드
| 모드 | 사용 사례 |
|---|
DocumentBuildMode.Template | 고정 레이아웃 문서 (양식) |
DocumentBuildMode.Neural | 가변 레이아웃 문서 |
모범 사례
- 프로덕션에는 DefaultAzureCredential 사용
- 클라이언트 인스턴스 재사용 — 클라이언트는 스레드로부터 안전함
- 장기 실행 작업 처리 — 단순성을 위해
WaitUntil.Completed 사용
- 필드 신뢰도 확인 — 항상
Confidence 속성 확인
- 적절한 모델 사용 — 일반 문서에는 사전 구축, 특수 문서에는 사용자 지정
- 사용자 지정 하위 도메인 사용 — Entra ID 인증에 필요
오류 처리
using Azure;
try
{
var operation = await client.AnalyzeDocumentAsync(
WaitUntil.Completed,
"prebuilt-invoice",
documentUri);
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Error: {ex.Status} - {ex.Message}");
}
관련 SDK
| SDK | 용도 | 설치 |
|---|
Azure.AI.DocumentIntelligence | 문서 분석 (이 SDK) | dotnet add package Azure.AI.DocumentIntelligence |
Azure.AI.FormRecognizer | 레거시 SDK (더 이상 사용되지 않음) | 대신 DocumentIntelligence 사용 |
참조 링크