次の方法で共有


JavaScript 用 Azure DocumentIntelligence (旧称 FormRecognizer) REST クライアント ライブラリ - バージョン 1.0.0

ドキュメントからコンテンツ、レイアウト、構造化データを抽出します。

このライブラリを使用するには、REST クライアント ドキュメント に大きく依存してください

注: Form Recognizer はドキュメント インテリジェンスにブランド変更されました。 から への 移行ガイドを確認してください。

主要なリンク:

このバージョンのクライアント ライブラリの既定値は、サービスの "2024-11-30" バージョンです。

次の表は、SDK バージョンとサポートされている API バージョンのサービス間の関係を示しています。

SDK のバージョン サポートされている API バージョンのサービス
1.0.0 2024-11-30

"prebuilt-businessCard""prebuilt-document"など、廃止されたモデルについては、古いサービス API バージョンを通じて古い @azure/ai-form-recognizer ライブラリに依存してください。 詳細については、「Changelog」を参照してください。

次の表は、各クライアントの関係と、サポートされている API バージョンを示しています。

サービス API のバージョン サポートされているクライアント パッケージ
2024-11-30 DocumentIntelligenceClient @azure-rest/ai-document-intelligence バージョンの 1.0.0
2023-07-31 DocumentAnalysisClient と DocumentModelAdministrationClient @azure/ai-form-recognizer バージョンの ^5.0.0
2022-08-01 DocumentAnalysisClient と DocumentModelAdministrationClient @azure/ai-form-recognizer バージョンの ^4.0.0

はじめ

現在サポートされている環境

  • Node.js の LTS バージョン

前提 条件

@azure-rest/ai-document-intelligence パッケージをインストールする

次の npmを使用して、JavaScript 用の Azure DocumentIntelligence(旧称FormRecognizer) REST クライアント REST クライアント ライブラリをインストールします。

npm install @azure-rest/ai-document-intelligence

DocumentIntelligenceClient を作成して認証する

Azure Active Directory (AAD) トークン資格情報を使用するには、@azure/ID ライブラリから取得した目的の資格情報の種類のインスタンスを指定します。

AAD で認証するには、最初に @azure/identity をインストール npm 必要があります

セットアップ後、使用する @azure/identity から 資格情報 の種類を選択できます。 たとえば、DefaultAzureCredential 使用してクライアントを認証できます。

AAD アプリケーションのクライアント ID、テナント ID、クライアント シークレットの値を環境変数として設定します(AZURE_CLIENT_ID、AZURE_TENANT_ID、AZURE_CLIENT_SECRET

トークン資格情報の使用

import DocumentIntelligence from "@azure-rest/ai-document-intelligence";

const client = DocumentIntelligence(
  process.env["DOCUMENT_INTELLIGENCE_ENDPOINT"],
  new DefaultAzureCredential()
);

API キーの使用

import DocumentIntelligence from "@azure-rest/ai-document-intelligence";

const client = DocumentIntelligence(process.env["DOCUMENT_INTELLIGENCE_ENDPOINT"], {
  key: process.env["DOCUMENT_INTELLIGENCE_API_KEY"],
});

ドキュメント モデル

事前構築済みレイアウトの分析 (urlSource)

const initialResponse = await client
  .path("/documentModels/{modelId}:analyze", "prebuilt-layout")
  .post({
    contentType: "application/json",
    body: {
      urlSource:
        "https://raw.githubusercontent.com/Azure/azure-sdk-for-js/6704eff082aaaf2d97c1371a28461f512f8d748a/sdk/formrecognizer/ai-form-recognizer/assets/forms/Invoice_1.pdf",
    },
    queryParameters: { locale: "en-IN" },
  });

事前構築済みレイアウトの分析 (base64Source)

import fs from "fs";
import path from "path";

const filePath = path.join(ASSET_PATH, "forms", "Invoice_1.pdf");
const base64Source = fs.readFileSync(filePath, { encoding: "base64" });
const initialResponse = await client
  .path("/documentModels/{modelId}:analyze", "prebuilt-layout")
  .post({
    contentType: "application/json",
    body: {
      base64Source,
    },
    queryParameters: { locale: "en-IN" },
  });

最初の応答からポーラーを作成し続ける

import {
  getLongRunningPoller,
  AnalyzeResultOperationOutput,
  isUnexpected,
} from "@azure-rest/ai-document-intelligence";

if (isUnexpected(initialResponse)) {
  throw initialResponse.body.error;
}
const poller = getLongRunningPoller(client, initialResponse);
const result = (await poller.pollUntilDone()).body as AnalyzeResultOperationOutput;
console.log(result);
// {
//   status: 'succeeded',
//   createdDateTime: '2023-11-10T13:31:31Z',
//   lastUpdatedDateTime: '2023-11-10T13:31:34Z',
//   analyzeResult: {
//     apiVersion: '2023-10-31-preview',
//     .
//     .
//     .
//     contentFormat: 'text'
//   }
// }

バッチ分析

import { parseResultIdFromResponse, isUnexpected } from "@azure-rest/ai-document-intelligence";

// 1. Analyze a batch of documents
const initialResponse = await client
  .path("/documentModels/{modelId}:analyzeBatch", "prebuilt-layout")
  .post({
    contentType: "application/json",
    body: {
      azureBlobSource: {
        containerUrl: batchTrainingFilesContainerUrl(),
      },
      resultContainerUrl: batchTrainingFilesResultContainerUrl(),
      resultPrefix: "result",
    },
  });

if (isUnexpected(initialResponse)) {
  throw initialResponse.body.error;
}
const resultId = parseResultIdFromResponse(initialResponse);
console.log("resultId: ", resultId);

// (Optional) You can poll for the batch analysis result but be aware that a job may take unexpectedly long time, and polling could incur additional costs.
// const poller = getLongRunningPoller(client, initialResponse);
// await poller.pollUntilDone();

// 2. At a later time, you can retrieve the operation result using the resultId
const output = await client
  .path("/documentModels/{modelId}/analyzeResults/{resultId}", "prebuilt-layout", resultId)
  .get();
console.log(output);

Markdown コンテンツの形式

Markdown コンテンツ形式の出力と、既定のプレーン テキストをサポートします。 現時点では、これは "事前構築済みレイアウト" でのみサポートされています。 Markdown コンテンツ形式は、チャットまたは自動化の使用シナリオで LLM を使用するためのよりわかりやすい形式と見なされます。

サービスは、Markdown 形式の GFM 仕様 (GitHub Flavored Markdown) に従います。 また、結果のコンテンツ形式を示す値 "text" または "markdown" を持つ新しい contentFormat プロパティも導入します。

import DocumentIntelligence from "@azure-rest/ai-document-intelligence";
const client = DocumentIntelligence(process.env["DOCUMENT_INTELLIGENCE_ENDPOINT"], {
  key: process.env["DOCUMENT_INTELLIGENCE_API_KEY"],
});

const initialResponse = await client
  .path("/documentModels/{modelId}:analyze", "prebuilt-layout")
  .post({
    contentType: "application/json",
    body: {
      urlSource:
        "https://raw.githubusercontent.com/Azure/azure-sdk-for-js/6704eff082aaaf2d97c1371a28461f512f8d748a/sdk/formrecognizer/ai-form-recognizer/assets/forms/Invoice_1.pdf",
    },
    queryParameters: { outputContentFormat: "markdown" }, // <-- new query parameter
  });

クエリ フィールド

この機能フラグを指定すると、サービスは queryFields クエリ パラメーターを使用して指定されたフィールドの値をさらに抽出し、モデルによってフォールバックとして定義されている既存のフィールドを補完します。

await client.path("/documentModels/{modelId}:analyze", "prebuilt-layout").post({
  contentType: "application/json",
  body: { urlSource: "..." },
  queryParameters: {
    features: ["queryFields"],
    queryFields: ["NumberOfGuests", "StoreNumber"],
  }, // <-- new query parameter
});

分割オプション

以前の @azure/ai-form-recognizer ライブラリでサポートされていた以前の API バージョンでは、ドキュメントの分割と分類操作 ("/documentClassifiers/{classifierId}:analyze") では、常に入力ファイルを複数のドキュメントに分割しようとしました。

より広範なシナリオのセットを有効にするために、サービスでは、新しい "2023-10-31-preview" サービス バージョンを含む "分割" クエリ パラメーターが導入されています。 次の値がサポートされています。

  • split: "auto"

    サービスが分割する場所を決定します。

  • split: "none"

    ファイル全体が 1 つのドキュメントとして扱われます。 分割は実行されません。

  • split: "perPage"

    各ページは個別のドキュメントとして扱われます。 各空のページは、独自のドキュメントとして保持されます。

ドキュメント分類子の #Build

import {
  DocumentClassifierBuildOperationDetailsOutput,
  getLongRunningPoller,
  isUnexpected,
} from "@azure-rest/ai-document-intelligence";

const containerSasUrl = (): string =>
  process.env["DOCUMENT_INTELLIGENCE_TRAINING_CONTAINER_SAS_URL"];
const initialResponse = await client.path("/documentClassifiers:build").post({
  body: {
    classifierId: `customClassifier${getRandomNumber()}`,
    description: "Custom classifier description",
    docTypes: {
      foo: {
        azureBlobSource: {
          containerUrl: containerSasUrl(),
        },
      },
      bar: {
        azureBlobSource: {
          containerUrl: containerSasUrl(),
        },
      },
    },
  },
});

if (isUnexpected(initialResponse)) {
  throw initialResponse.body.error;
}
const poller = getLongRunningPoller(client, initialResponse);
const response = (await poller.pollUntilDone())
  .body as DocumentClassifierBuildOperationDetailsOutput;
console.log(response);
//  {
//    operationId: '31466834048_f3ee629e-73fb-48ab-993b-1d55d73ca460',
//    kind: 'documentClassifierBuild',
//    status: 'succeeded',
//    .
//    .
//    result: {
//      classifierId: 'customClassifier10978',
//      createdDateTime: '2023-11-09T12:45:56Z',
//      .
//      .
//      description: 'Custom classifier description'
//    },
//    apiVersion: '2023-10-31-preview'
//  }

ドキュメント分析から生成された PDF 出力を取得する

const filePath = path.join(ASSET_PATH, "layout-pageobject.pdf");

const base64Source = await fs.readFile(filePath, { encoding: "base64" });

const initialResponse = await client
  .path("/documentModels/{modelId}:analyze", "prebuilt-read")
  .post({
    contentType: "application/json",
    body: {
      base64Source,
    },
    queryParameters: { output: ["pdf"] },
  });

if (isUnexpected(initialResponse)) {
  throw initialResponse.body.error;
}

const poller = getLongRunningPoller(client, initialResponse);

await poller.pollUntilDone();

const output = await client
  .path(
    "/documentModels/{modelId}/analyzeResults/{resultId}/pdf",
    "prebuilt-read",
    parseResultIdFromResponse(initialResponse)
  )
  .get()
  .asNodeStream(); // output.body would be NodeJS.ReadableStream

if (output.status !== "200" || !output.body) {
  throw new Error("The response was unexpected, expected NodeJS.ReadableStream in the body.");
}

const pdfData = await streamToUint8Array(output.body);
fs.promises.writeFile(`./output.pdf`, pdfData);
// Or you can consume the NodeJS.ReadableStream directly

ドキュメント分析から、指定した図の生成されたトリミングされた画像を取得する

const filePath = path.join(ASSET_PATH, "layout-pageobject.pdf");

const base64Source = fs.readFileSync(filePath, { encoding: "base64" });

const initialResponse = await client
  .path("/documentModels/{modelId}:analyze", "prebuilt-layout")
  .post({
    contentType: "application/json",
    body: {
      base64Source,
    },
    queryParameters: { output: ["figures"] },
  });

if (isUnexpected(initialResponse)) {
  throw initialResponse.body.error;
}

const poller = getLongRunningPoller(client, initialResponse, { ...testPollingOptions });

const result = (await poller.pollUntilDone()).body as AnalyzeResultOperationOutput;
const figures = result.analyzeResult?.figures;
assert.isArray(figures);
assert.isNotEmpty(figures?.[0]);
const figureId = figures?.[0].id || "";
assert.isDefined(figureId);

const output = await client
  .path(
    "/documentModels/{modelId}/analyzeResults/{resultId}/figures/{figureId}",
    "prebuilt-layout",
    parseResultIdFromResponse(initialResponse),
    figureId
  )
  .get()
  .asNodeStream(); // output.body would be NodeJS.ReadableStream

if (output.status !== "200" || !output.body) {
  throw new Error("The response was unexpected, expected NodeJS.ReadableStream in the body.");
}

const imageData = await streamToUint8Array(output.body);
fs.promises.writeFile(`./figures/${figureId}.png`, imageData);
// Or you can consume the NodeJS.ReadableStream directly

情報を取得する

const response = await client.path("/info").get();
if (isUnexpected(response)) {
  throw response.body.error;
}
console.log(response.body.customDocumentModels.limit);
// 20000

ドキュメント モデルの一覧表示

import { paginate } from "@azure-rest/ai-document-intelligence";
const response = await client.path("/documentModels").get();
if (isUnexpected(response)) {
  throw response.body.error;
}

const modelsInAccount: string[] = [];
for await (const model of paginate(client, response)) {
  console.log(model.modelId);
}

トラブルシューティング

伐採

ログ記録を有効にすると、エラーに関する有用な情報を明らかにするのに役立つ場合があります。 HTTP 要求と応答のログを表示するには、AZURE_LOG_LEVEL 環境変数を infoに設定します。 または、@azure/loggersetLogLevel を呼び出すことによって、実行時にログを有効にすることもできます。

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

ログを有効にする方法の詳細な手順については、@azure/logger パッケージのドキュメントを参照してください。