Partilhar via


Tutorial: Vetorizar a partir de um layout de documento estruturado

O Azure AI Search pode extrair e indexar texto e imagens de documentos PDF armazenados no Armazenamento de Blobs do Azure. Este tutorial mostra como criar um pipeline de indexação multimodal que fragmenta dados com base na estrutura do documento e usa incorporações multimodais para vetorizar texto e imagens do mesmo documento. As imagens cortadas são armazenadas em um repositório de conhecimento e o texto e o conteúdo visual são vetorizados e ingeridos em um índice pesquisável. O chunking baseia-se no modelo de layout Azure Document Intelligence nas ferramentas Foundry, que reconhece a estrutura do documento.

Neste tutorial, você usa:

  • Um documento PDF de 36 páginas que combina conteúdo visual rico, como gráficos, infográficos e páginas digitalizadas, com texto tradicional.

  • Um indexador e um conjunto de habilidades para criar um pipeline de indexação que inclua o enriquecimento da IA por meio de habilidades.

  • A habilidade Layout do Documento para extrair texto e imagens normalizadas com o seu locationMetadata de vários documentos, como números de página ou regiões delimitadoras.

  • A funcionalidade de embeddings multimodais do Azure Vision para vetorizar texto e imagens.

  • Um índice de pesquisa configurado para armazenar texto extraído e conteúdo de imagem. Alguns conteúdos são vetorizados para pesquisa de semelhança baseada em vetores.

Prerequisites

Limitations

  • A funcionalidade de Layout de Documento tem disponibilidade regional limitada. Quando criares o recurso Foundry, escolhe uma região que forneça embeddings multimodais. Para uma lista de regiões suportadas, consulte Regiões suportadas pela funcionalidade de Layout de Documentos.

  • A funcionalidade de embeddings multimodais do Azure Vision também tem disponibilidade regional limitada. Para uma lista atualizada de regiões que fornecem embeddings multimodais, consulte a documentação do Azure Vision.

Preparar dados

As instruções a seguir se aplicam ao Armazenamento do Azure, que fornece os dados de exemplo e também hospeda o repositório de conhecimento. Uma identidade de serviço de pesquisa precisa de acesso de leitura ao Armazenamento do Azure para recuperar os dados de exemplo e precisa de acesso de gravação para criar o repositório de conhecimento. O serviço de pesquisa cria o contentor para imagens recortadas durante o processamento do conjunto de aptidões, usando o nome fornecido numa variável de ambiente.

  1. Faça o download do seguinte PDF de exemplo: sustainable-ai-pdf

  2. No Armazenamento do Azure, crie um novo contêiner chamado sustainable-ai-pdf.

  3. Carregue o arquivo de dados de exemplo.

  4. Crie atribuições de função e especifique uma identidade gerenciada em uma cadeia de conexão:

    1. Atribua o Storage Blob Data Reader para recuperação de dados pelo indexador. Atribua o Contribuidor de Dados de Blob de Armazenamento e o Colaborador de Dados da Tabela de Armazenamento para criar e carregar o repositório de conhecimento. Você pode usar uma identidade gerenciada atribuída pelo sistema ou uma identidade gerenciada atribuída pelo usuário para sua atribuição de função de serviço de pesquisa.

    2. Para conexões feitas usando uma identidade gerenciada atribuída pelo sistema, obtenha uma cadeia de conexão que contenha um ResourceId, sem chave de conta ou senha. O ResourceId deve incluir a ID de assinatura da conta de armazenamento, o grupo de recursos da conta de armazenamento e o nome da conta de armazenamento. A cadeia de conexão é semelhante ao exemplo a seguir:

      "credentials" : { 
          "connectionString" : "ResourceId=/subscriptions/00000000-0000-0000-0000-00000000/resourceGroups/MY-DEMO-RESOURCE-GROUP/providers/Microsoft.Storage/storageAccounts/MY-DEMO-STORAGE-ACCOUNT/;" 
      }
      
    3. Para conexões feitas usando uma identidade gerenciada atribuída pelo usuário, obtenha uma cadeia de conexão que contenha um ResourceId, sem chave de conta ou senha. O ResourceId deve incluir a ID de assinatura da conta de armazenamento, o grupo de recursos da conta de armazenamento e o nome da conta de armazenamento. Forneça uma identidade usando a sintaxe mostrada no exemplo a seguir. Defina userAssignedIdentity como a identidade gerenciada atribuída pelo usuário. A cadeia de conexão é semelhante ao exemplo a seguir:

      "credentials" : { 
          "connectionString" : "ResourceId=/subscriptions/00000000-0000-0000-0000-00000000/resourceGroups/MY-DEMO-RESOURCE-GROUP/providers/Microsoft.Storage/storageAccounts/MY-DEMO-STORAGE-ACCOUNT/;" 
      },
      "identity" : { 
          "@odata.type": "#Microsoft.Azure.Search.DataUserAssignedIdentity",
          "userAssignedIdentity" : "/subscriptions/00000000-0000-0000-0000-00000000/resourcegroups/MY-DEMO-RESOURCE-GROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/MY-DEMO-USER-MANAGED-IDENTITY" 
      }
      

Preparar modelos

Este tutorial assume que tens um recurso Foundry existente através do qual a habilidade chama o modelo de embedding multimodal 4.0 do Azure Vision. O serviço de pesquisa se conecta ao modelo durante o processamento do conjunto de habilidades usando sua identidade gerenciada. Esta seção fornece orientações e links para atribuir funções para acesso autorizado.

A mesma atribuição de função é também usada para aceder ao modelo de layout Azure Document Intelligence através de um recurso Foundry.

  1. Inicia sessão no portal Azure (não no portal da Foundry) e encontra o recurso da Foundry. Certifica-te de que está numa região que forneça a API multimodal 4.0 e o modelo de layout Azure Document Intelligence.

  2. Selecione Controlo de acesso (IAM) .

  3. Selecione Adicionar e, em seguida, Adicionar atribuição de função.

  4. Procure por Usuário de Serviços Cognitivos e selecione-o.

  5. Escolha Identidade gerenciada e atribua a identidade gerenciada do serviço de pesquisa.

Configurar o arquivo REST

Para este tutorial, sua conexão de cliente REST local com o Azure AI Search requer um ponto de extremidade e uma chave de API. Você pode obter esses valores no portal do Azure. Para obter métodos de conexão alternativos, consulte Conectar-se a um serviço de pesquisa.

Para conexões autenticadas que ocorrem durante o processamento do indexador e do conjunto de habilidades, o serviço de pesquisa usa as atribuições de função definidas anteriormente.

  1. Inicie o Visual Studio Code e crie um novo arquivo.

  2. Forneça valores para variáveis usadas no pedido. Para @storageConnection, verifique se a string de conexão não termina com um ponto-e-vírgula ou aspas. Para @imageProjectionContainer, forneça um nome de contentor único no armazenamento de blobs. O Azure AI Search cria esse contêiner para você durante o processamento de habilidades.

    @searchUrl = PUT-YOUR-SEARCH-SERVICE-ENDPOINT-HERE
    @searchApiKey = PUT-YOUR-ADMIN-API-KEY-HERE
    @storageConnection = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE
    @cognitiveServicesUrl = PUT-YOUR-AZURE-AI-FOUNDARY-ENDPOINT-HERE
    @modelVersion = 2023-04-15
    @imageProjectionContainer=sustainable-ai-pdf-images
    
  3. Guarde o ficheiro usando uma extensão de ficheiro .rest ou .http. Para obter ajuda com o cliente REST, consulte Guia de início rápido: pesquisa de texto completo usando REST.

Para obter o endpoint e a chave da API do Azure AI Search:

  1. Entre no portal do Azure, navegue até a página Visão geral do serviço de pesquisa e copie a URL. Um ponto final de exemplo poderá ser parecido com https://mydemo.search.windows.net.

  2. Em Configurações>Teclas, copie uma chave de administrador. As chaves de administrador são usadas para adicionar, modificar e excluir objetos. Existem duas chaves de administração intercambiáveis. Copie qualquer uma delas.

    Captura de ecrã do URL e das chaves de API no portal do Azure.

Criar uma fonte de dados

Create Data Source (REST) cria uma conexão de fonte de dados que especifica quais dados indexar.

### Create a data source using system-assigned managed identities
POST {{searchUrl}}/datasources?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}

  {
    "name": "doc-intelligence-multimodal-embedding-ds",
    "description": "A data source to store multimodal documents",
    "type": "azureblob",
    "subtype": null,
    "credentials":{
      "connectionString":"{{storageConnection}}"
    },
    "container": {
      "name": "sustainable-ai-pdf",
      "query": null
    },
    "dataChangeDetectionPolicy": null,
    "dataDeletionDetectionPolicy": null,
    "encryptionKey": null,
    "identity": null
  }

Envie o pedido. A resposta deve ser semelhante a:

HTTP/1.1 201 Created
Transfer-Encoding: chunked
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
Location: https://<YOUR-SEARCH-SERVICE-NAME>.search.windows-int.net:443/datasources('doc-extraction-multimodal-embedding-ds')?api-version=2025-11-01-preview -Preview
Server: Microsoft-IIS/10.0
Strict-Transport-Security: max-age=2592000, max-age=15724800; includeSubDomains
Preference-Applied: odata.include-annotations="*"
OData-Version: 4.0
request-id: 4eb8bcc3-27b5-44af-834e-295ed078e8ed
elapsed-time: 346
Date: Sat, 26 Apr 2025 21:25:24 GMT
Connection: close

{
  "name": "doc-extraction-multimodal-embedding-ds",
  "description": null,
  "type": "azureblob",
  "subtype": null,
  "indexerPermissionOptions": [],
  "credentials": {
    "connectionString": null
  },
  "container": {
    "name": "sustainable-ai-pdf",
    "query": null
  },
  "dataChangeDetectionPolicy": null,
  "dataDeletionDetectionPolicy": null,
  "encryptionKey": null,
  "identity": null
}

Criar um índice

Criar índice (REST) cria um índice de pesquisa no seu serviço de pesquisa. Um índice especifica todos os parâmetros e seus atributos.

Para JSON aninhado, os campos de índice devem ser idênticos aos campos de origem. Atualmente, o Azure AI Search não oferece suporte a mapeamentos de campo para JSON aninhado, portanto, os nomes de campo e os tipos de dados devem corresponder completamente. O índice a seguir se alinha aos elementos JSON no conteúdo bruto.

### Create an index
POST {{searchUrl}}/indexes?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}

{
    "name": "doc-intelligence-multimodal-embedding-index",
    "fields": [
        {
            "name": "content_id",
            "type": "Edm.String",
            "retrievable": true,
            "key": true,
            "analyzer": "keyword"
        },
        {
            "name": "text_document_id",
            "type": "Edm.String",
            "searchable": false,
            "filterable": true,
            "retrievable": true,
            "stored": true,
            "sortable": false,
            "facetable": false
        },          
        {
            "name": "document_title",
            "type": "Edm.String",
            "searchable": true
        },
        {
            "name": "image_document_id",
            "type": "Edm.String",
            "filterable": true,
            "retrievable": true
        },
        {
            "name": "content_text",
            "type": "Edm.String",
            "searchable": true,
            "retrievable": true
        },
        {
            "name": "content_embedding",
            "type": "Collection(Edm.Single)",
            "dimensions": 1024,
            "searchable": true,
            "retrievable": true,
            "vectorSearchProfile": "hnsw"
        },
        {
            "name": "content_path",
            "type": "Edm.String",
            "searchable": false,
            "retrievable": true
        },
        {
            "name": "offset",
            "type": "Edm.String",
            "searchable": false,
            "retrievable": true
        },
        {
            "name": "location_metadata",
            "type": "Edm.ComplexType",
            "fields": [
                {
                "name": "page_number",
                "type": "Edm.Int32",
                "searchable": false,
                "retrievable": true
                },
                {
                "name": "bounding_polygons",
                "type": "Edm.String",
                "searchable": false,
                "retrievable": true,
                "filterable": false,
                "sortable": false,
                "facetable": false
                }
            ]
        }         
    ],
    "vectorSearch": {
        "profiles": [
            {
                "name": "hnsw",
                "algorithm": "defaulthnsw",
                "vectorizer": "demo-vectorizer"
            }
        ],
        "algorithms": [
            {
                "name": "defaulthnsw",
                "kind": "hnsw",
                "hnswParameters": {
                    "m": 4,
                    "efConstruction": 400,
                    "metric": "cosine"
                }
            }
        ],
        "vectorizers": [
            {
                "name": "demo-vectorizer",
                "kind": "aiServicesVision",
                "aiServicesVisionParameters": {
                    "resourceUri": "{{cognitiveServicesUrl}}",
                    "authIdentity": null,
                    "modelVersion": "{{modelVersion}}"
                }
            }
        ]     
    },
    "semantic": {
        "defaultConfiguration": "semanticconfig",
        "configurations": [
            {
                "name": "semanticconfig",
                "prioritizedFields": {
                    "titleField": {
                        "fieldName": "document_title"
                    },
                    "prioritizedContentFields": [
                    ],
                    "prioritizedKeywordsFields": []
                }
            }
        ]
    }
}

Pontos principais:

  • As incorporações de texto e imagem são armazenadas no campo content_embedding e devem ser configuradas com dimensões apropriadas, como 1024, e um perfil de pesquisa vetorial.

  • location_metadata captura o polígono delimitador e metadados do número da página para cada bloco de texto e imagem normalizada, permitindo uma pesquisa por localização precisa ou sobreposições na interface de utilizador.

  • Para obter mais informações sobre pesquisa vetorial, consulte Vetores na Pesquisa de IA do Azure.

  • Para obter mais informações sobre classificação semântica, consulte Classificação semântica no Azure AI Search.

Criar um conjunto de competências

Create Skillset (REST) cria um conjunto de habilidades em seu serviço de pesquisa. Um conjunto de habilidades define as operações que fragmentam e incorporam conteúdo antes da indexação. Este conjunto de habilidades usa a habilidade Layout de Documento para extrair texto e imagens, preservando metadados de localização que são úteis para citações em aplicativos RAG. Utiliza a competência de embeddings multimodais do Azure Vision para vetorizar conteúdos de imagem e texto.

### Create a skillset
POST {{searchUrl}}/skillsets?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}

{
  "name": "doc-intelligence-multimodal-embedding-skillset",
  "description": "A sample skillset for multimodal using multimodal embedding",
  "skills": [
    {
      "@odata.type": "#Microsoft.Skills.Util.DocumentIntelligenceLayoutSkill",
      "name": "document-layout-skill",
      "description": "Azure Document Intelligence skill for document cracking",
      "context": "/document",
      "outputMode": "oneToMany",
      "outputFormat": "text",
      "extractionOptions": ["images", "locationMetadata"],
      "chunkingProperties": {     
          "unit": "characters",
          "maximumLength": 2000, 
          "overlapLength": 200
      },
      "inputs": [
        {
          "name": "file_data",
          "source": "/document/file_data"
        }
      ],
      "outputs": [
        { 
          "name": "text_sections", 
          "targetName": "text_sections" 
        }, 
        { 
          "name": "normalized_images", 
          "targetName": "normalized_images" 
        } 
      ]
    },
    { 
      "@odata.type": "#Microsoft.Skills.Vision.VectorizeSkill", 
      "name": "text-embedding-skill",
      "description": "Vision Vectorization skill for text",
      "context": "/document/text_sections/*", 
      "modelVersion": "2023-04-15", 
      "inputs": [ 
        { 
          "name": "text", 
          "source": "/document/text_sections/*/content" 
        } 
      ], 
      "outputs": [ 
        { 
          "name": "vector",
          "targetName": "text_vector"
        } 
      ] 
    },    
    { 
      "@odata.type": "#Microsoft.Skills.Vision.VectorizeSkill", 
      "name": "image-embedding-skill",
      "description": "Vision Vectorization skill for images",
      "context": "/document/normalized_images/*", 
      "modelVersion": "2023-04-15", 
      "inputs": [ 
        { 
          "name": "image", 
          "source": "/document/normalized_images/*" 
        } 
      ], 
      "outputs": [ 
        { 
          "name": "vector",
          "targetName": "image_vector"
        } 
      ] 
    },
    {
      "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
      "name": "shaper-skill",
      "context": "/document/normalized_images/*",
      "inputs": [
        {
          "name": "normalized_images",
          "source": "/document/normalized_images/*",
          "inputs": []
        },
        {
          "name": "imagePath",
          "source": "='my_container_name/'+$(/document/normalized_images/*/imagePath)",
          "inputs": []
        }
      ],
      "outputs": [
        {
          "name": "output",
          "targetName": "new_normalized_images"
        }
      ]
    }      
  ], 
   "indexProjections": {
      "selectors": [
        {
          "targetIndexName": "doc-intelligence-multimodal-embedding-index",
          "parentKeyFieldName": "text_document_id",
          "sourceContext": "/document/text_sections/*",
          "mappings": [    
            {
            "name": "content_embedding",
            "source": "/document/text_sections/*/text_vector"
            },                      
            {
              "name": "content_text",
              "source": "/document/text_sections/*/content"
            },
            {
              "name": "location_metadata",
              "source": "/document/text_sections/*/locationMetadata"
            },                
            {
              "name": "document_title",
              "source": "/document/document_title"
            }   
          ]
        },        
        {
          "targetIndexName": "{{index}}",
          "parentKeyFieldName": "image_document_id",
          "sourceContext": "/document/normalized_images/*",
          "mappings": [    
            {
            "name": "content_embedding",
            "source": "/document/normalized_images/*/image_vector"
            },                                           
            {
              "name": "content_path",
              "source": "/document/normalized_images/*/new_normalized_images/imagePath"
            },                    
            {
              "name": "document_title",
              "source": "/document/document_title"
            },
            {
              "name": "location_metadata",
              "source": "/document/normalized_images/*/locationMetadata"
            }             
          ]
        }
      ],
      "parameters": {
        "projectionMode": "skipIndexingParentDocuments"
      }
  },
  "cognitiveServices": {
    "@odata.type": "#Microsoft.Azure.Search.AIServicesByIdentity",
    "subdomainUrl": "{{cognitiveServicesUrl}}",
    "identity": null
  },
  "knowledgeStore": {
    "storageConnectionString": "",
    "identity": null,
    "projections": [
      {
        "files": [
          {
            "storageContainer": "{{imageProjectionContainer}}",
            "source": "/document/normalized_images/*"
          }
        ]
      }
    ]
  }
}

Este conjunto de habilidades extrai texto e imagens, vetoriza ambos e molda os metadados da imagem para projeção no índice.

Pontos principais:

  • O content_text campo é preenchido com texto extraído e fragmentado usando a Habilidade de Layout de Documento

  • content_path Contém o caminho relativo para o arquivo de imagem dentro do contêiner de projeção de imagem designado. Este campo é gerado apenas para imagens extraídas de documentos quando extractOption está definido como ["images", "locationMetadata"] ou ["images"], e pode ser mapeado a partir do documento enriquecido a partir do campo /document/normalized_images/*/imagePathde origem.

  • A competência de embeddings multimodal do Azure Vision permite a incorporação de dados textuais e visuais usando o mesmo tipo de competência, diferenciado por input (texto vs imagem). Para mais informações, consulte a capacidade de representações multimodais do Azure Vision.

Criar e executar um indexador

Criar indexador cria um indexador no seu serviço de pesquisa. Um indexador se conecta à fonte de dados, carrega dados, executa um conjunto de habilidades e indexa os dados enriquecidos.

### Create and run an indexer
POST {{searchUrl}}/indexers?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}

{
  "dataSourceName": "doc-intelligence-multimodal-embedding-ds",
  "targetIndexName": "doc-intelligence-multimodal-embedding-index",
  "skillsetName": "doc-intelligence-multimodal-embedding-skillset",
  "parameters": {
    "maxFailedItems": -1,
    "maxFailedItemsPerBatch": 0,
    "batchSize": 1,
    "configuration": {
      "allowSkillsetToReadFileData": true
    }
  },
  "fieldMappings": [
    {
      "sourceFieldName": "metadata_storage_name",
      "targetFieldName": "document_title"
    }
  ],
  "outputFieldMappings": []
}

Executar consultas

Pode começar a pesquisar assim que o primeiro documento for carregado.

### Query the index
POST {{searchUrl}}/indexes/doc-intelligence-multimodal-embedding-index/docs/search?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}
  
  {
    "search": "*",
    "count": true
  }

Envie o pedido. Esta é uma consulta de pesquisa de texto completo não especificada que retorna todos os campos marcados como recuperáveis no índice, juntamente com uma contagem de documentos. A resposta deve ser semelhante a:

{
  "@odata.count": 100,
  "@search.nextPageParameters": {
    "search": "*",
    "count": true,
    "skip": 50
  },
  "value": [
  ],
  "@odata.nextLink": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes/doc-intelligence-multimodal-embedding-index/docs/search?api-version=2025-11-01-preview "
}

100 documentos são devolvidos na resposta.

Para filtros, você também pode usar operadores lógicos (e, ou, não) e operadores de comparação (eq, ne, gt, lt, ge, le). As comparações de cadeias são sensíveis às maiúsculas e minúsculas. Para obter mais informações e exemplos, consulte Exemplos de consultas de pesquisa simples.

Note

O $filter parâmetro só funciona em campos que foram marcados como filtráveis durante a criação do índice.

### Query for only images
POST {{searchUrl}}/indexes/doc-intelligence-multimodal-embedding-index/docs/search?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}
  
  {
    "search": "*",
    "count": true,
    "filter": "image_document_id ne null"
  }
### Query for text or images with content related to energy, returning the id, parent document, and text (only populated for text chunks), and the content path where the image is saved in the knowledge store (only populated for images)
POST {{searchUrl}}/indexes/doc-intelligence-multimodal-embedding-index/docs/search?api-version=2025-11-01-preview   HTTP/1.1
  Content-Type: application/json
  api-key: {{searchApiKey}}
  
  {
    "search": "energy",
    "count": true,
    "select": "content_id, document_title, content_text, content_path"
  }

Repor e executar novamente

Os indexadores podem ser redefinidos para limpar o histórico de execução, o que permite uma nova execução completa. As seguintes solicitações POST são para redefinição, seguidas de reexecução.

### Reset the indexer
POST {{searchUrl}}/indexers/doc-intelligence-multimodal-embedding-indexer/reset?api-version=2025-11-01-preview   HTTP/1.1
  api-key: {{searchApiKey}}
### Run the indexer
POST {{searchUrl}}/indexers/doc-intelligence-multimodal-embedding-indexer/run?api-version=2025-11-01-preview   HTTP/1.1
  api-key: {{searchApiKey}}
### Check indexer status 
GET {{searchUrl}}/indexers/doc-intelligence-multimodal-embedding-indexer/status?api-version=2025-11-01-preview   HTTP/1.1
  api-key: {{searchApiKey}}

Limpeza de recursos

Quando estiver a trabalhar na sua própria subscrição, ao terminar um projeto, é uma boa ideia remover os recursos de que já não necessita. Os recursos deixados em funcionamento podem custar-lhe dinheiro. Você pode excluir recursos individualmente ou excluir o grupo de recursos para excluir todo o conjunto de recursos.

Você pode usar o portal do Azure para excluir índices, indexadores e fontes de dados.

Ver também

Agora que você está familiarizado com um exemplo de implementação de um cenário de indexação multimodal, confira: