Поделиться через


Клиентская библиотека REST Azure DocumentIntelligence (ранее — FormRecognizer) для JavaScript версии 1.0.0

Извлекает содержимое, макет и структурированные данные из документов.

Для использования этой библиотеки используется документация клиента REST

ПРИМЕЧАНИЕ. Распознаватель документов был перебран в аналитику документов. Ознакомьтесь с руководством по миграции из @azure/ai-form-recognizer в @azure-rest/ai-document-intelligence.

Ключевые ссылки:

Эта версия клиентской библиотеки по умолчанию используется для "2024-11-30" версии службы.

В этой таблице показана связь между версиями пакета SDK и поддерживаемыми версиями API службы:

Версия пакета SDK Поддерживаемая версия API службы
1.0.0 2024-11-30

Воспользуйтесь более старой библиотекой @azure/ai-form-recognizer с помощью старых версий API службы для устаревших моделей, таких как "prebuilt-businessCard" и "prebuilt-document". Дополнительные сведения см. вжурнала изменений .

В следующей таблице описывается связь каждого клиента и поддерживаемых версий 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

Начало работы

Поддерживаемые в настоящее время среды

  • Версии LTS Node.js

Необходимые условия

  • Для использования этого пакета необходимо подписку Azure.

Установка пакета @azure-rest/ai-document-intelligence

Установите клиентскую клиентскую клиентскую библиотеку REST клиента REST Для JavaScript с npm:

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

Создание и проверка подлинности DocumentIntelligenceClient

Чтобы использовать учетных данных маркера Azure Active Directory (AAD), укажите экземпляр требуемого типа учетных данных, полученного из библиотеки @azure/identity.

Чтобы выполнить проверку подлинности с помощью AAD, необходимо сначала npm установить @azure/identity

После установки можно выбрать тип учетных данных из @azure/identity использования. Например, DefaultAzureCredential можно использовать для проверки подлинности клиента.

Задайте значения идентификатора клиента, идентификатора клиента и секрета клиента приложения AAD в качестве переменных среды: 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 в чате или сценарии использования автоматизации.

Служба следует спецификации GFM (GitHub Flavored Markdown) для формата Markdown. Также представлено новое свойство contentFormat contentFormat со значением "text" или "markdown", чтобы указать формат содержимого результата.

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
});

Разделять параметры

В предыдущих версиях API, поддерживаемых старой библиотекой @azure/ai-form-recognizer, операция разделения документов и классификации ("/documentClassifiers/{classifierId}:analyze") всегда пыталась разделить входной файл на несколько документов.

Чтобы включить более широкий набор сценариев, служба представляет параметр запроса split с новой версией службы "2023-10-31-preview". Поддерживаются следующие значения:

  • split: "auto"

    Разрешить службе определить, где разделиться.

  • split: "none"

    Весь файл рассматривается как один документ. Разделение не выполняется.

  • 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. Кроме того, ведение журнала можно включить во время выполнения путем вызова setLogLevel в @azure/logger:

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

setLogLevel("info");

Дополнительные инструкции по включению журналов см. в документации по пакету @azure/loger.