Compartir a través de


Biblioteca cliente REST de Azure DocumentIntelligence (anteriormente FormRecognizer) para JavaScript: versión 1.0.0

Extrae contenido, diseño y datos estructurados de documentos.

Confíe en gran medida en nuestros documentos de cliente REST de para usar esta biblioteca

NOTA: Form Recognizer se ha cambiado de nombre a Inteligencia de documentos. Consulte la Guía de migración de de @azure/ai-form-recognizer a @azure-rest/ai-document-intelligence.

Vínculos clave:

Esta versión de la biblioteca cliente tiene como valor predeterminado la versión de "2024-11-30" del servicio.

En esta tabla se muestra la relación entre las versiones del SDK y las versiones de API admitidas del servicio:

Versión del SDK Versión de API admitida del servicio
1.0.0 2024-11-30

Confíe en la biblioteca de @azure/ai-form-recognizer anterior a través de las versiones anteriores de la API de servicio para los modelos retirados, como "prebuilt-businessCard" y "prebuilt-document". Para obtener más información, vea Changelog.

En la tabla siguiente se describe la relación de cada cliente y sus versiones de API admitidas:

Versión de la API de servicio Clientes admitidos Paquete
2024-11-30 DocumentIntelligenceClient 1.0.0 de la versión de @azure-rest/ai-document-intelligence
2023-07-31 DocumentAnalysisClient y DocumentModelAdministrationClient ^5.0.0 de la versión de @azure/ai-form-recognizer
2022-08-01 DocumentAnalysisClient y DocumentModelAdministrationClient ^4.0.0 de la versión de @azure/ai-form-recognizer

Empezar

Entornos admitidos actualmente

  • Versiones LTS de Node.js

Prerrequisitos

  • Debe tener una suscripción de Azure para usar este paquete.

Instalación del paquete @azure-rest/ai-document-intelligence

Instale la biblioteca cliente REST rest DocumentIntelligence(anteriormenteFormRecognizer) de Azure DocumentIntelligence para JavaScript con npm:

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

Creación y autenticación de un DocumentIntelligenceClient

Para usar una credencial de token de Azure Active Directory (AAD), proporcione una instancia del tipo de credencial deseado obtenido de la biblioteca de @azure/identity.

Para autenticarse con AAD, primero debe npm instalar @azure/identity

Después de la instalación, puede elegir qué tipo de credenciales de de @azure/identity usar. Por ejemplo, DefaultAzureCredential se puede usar para autenticar al cliente.

Establezca los valores del identificador de cliente, el identificador de inquilino y el secreto de cliente de la aplicación de AAD como variables de entorno: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET

Uso de una credencial de token

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

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

Uso de una CLAVE de API

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

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

Modelos de documento

Análisis del diseño precompilado (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" },
  });

Análisis del diseño precompilado (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" },
  });

Continuar creando el sondeo a partir de la respuesta inicial

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'
//   }
// }

Análisis por lotes

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

Formato de contenido de Markdown

Admite la salida con formato de contenido Markdown junto con el texto sin formato predeterminado . Por ahora, esto solo se admite para "diseño precompilado". El formato de contenido de Markdown se considera un formato más descriptivo para el consumo de LLM en un escenario de uso de chat o automatización.

El servicio sigue la especificación GFM (GitHub Flavored Markdown) para el formato Markdown. También presenta una nueva propiedad contentFormat con el valor "text" o "markdown" para indicar el formato de contenido del resultado.

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

Campos de consulta

Cuando se especifica esta marca de característica, el servicio extraerá aún más los valores de los campos especificados a través del parámetro de consulta queryFields para complementar los campos existentes definidos por el modelo como reserva.

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

Opciones de división

En las versiones anteriores de la API compatibles con la biblioteca de @azure/ai-form-recognizer anterior, la operación de división de documentos y clasificación ("/documentClassifiers/{classifierId}:analyze") siempre intentó dividir el archivo de entrada en varios documentos.

Para habilitar un conjunto más amplio de escenarios, el servicio presenta un parámetro de consulta "dividido" con la nueva versión del servicio "2023-10-31-preview". Se admiten los siguientes valores:

  • split: "auto"

    Deje que el servicio determine dónde dividir.

  • split: "none"

    Todo el archivo se trata como un único documento. No se realiza ninguna división.

  • split: "perPage"

    Cada página se trata como un documento independiente. Cada página vacía se mantiene como su propio documento.

#Build clasificadores de documentos

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'
//  }

Obtención de la salida de PDF generada a partir del análisis de documentos

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

Obtención de la imagen recortada generada de la ilustración especificada a partir del análisis de documentos

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

Obtener información

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

Enumerar modelos de documento

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

Solución de problemas

Registro

Habilitar el registro puede ayudar a descubrir información útil sobre errores. Para ver un registro de solicitudes y respuestas HTTP, establezca la variable de entorno AZURE_LOG_LEVEL en info. Como alternativa, el registro se puede habilitar en tiempo de ejecución llamando a setLogLevel en el @azure/logger:

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

setLogLevel("info");

Para obtener instrucciones más detalladas sobre cómo habilitar los registros, puede consultar los documentos del paquete de @azure/registrador.