Indexación de blobs y archivos de Markdown en Búsqueda de Azure AI

Nota

Búsqueda de Azure AI está disponible a través del portal de Azure, las API REST y los SDK de Azure. También respalda Foundry IQ, la capa de conocimiento administrada que transforma el contenido empresarial en bases de conocimiento reutilizables y compatibles con permisos para agentes en el portal de Microsoft Foundry.

Importante

Estas características y funcionalidades admiten conexiones a otros servicios de servicios Microsoft y de terceros. El uso de estos servicios está sujeto a sus respectivos términos y podría dar lugar a procesamiento o almacenamiento de datos fuera del límite de cumplimiento de Azure, así como a los datos que fluyen a los límites de cumplimiento de Azure.

Es su responsabilidad gestionar si sus datos saldrán fuera de los límites geográficos y de cumplimiento normativo de su organización, así como cualquier implicación relacionada, y garantizar que se hayan establecido los permisos, límites y aprobaciones adecuados.

Es responsable de revisar y probar cuidadosamente las aplicaciones que compile en el contexto de sus casos de uso específicos y de tomar todas las decisiones y personalizaciones adecuadas. Esto incluye implementar sus propias mitigaciones de IA responsables, como metaprompts, filtros de contenido u otros sistemas de seguridad, y garantizar que las aplicaciones cumplan los estándares de calidad, confiabilidad, seguridad y confiabilidad adecuados. Para obtener más información, consulte la nota de transparencia Búsqueda de Azure AI.

En Búsqueda de Azure AI, los indexadores para Azure Blob Storage, Azure Files y Microsoft OneLake admiten un modo de análisis markdown para archivos Markdown. Los archivos Markdown se pueden indexar de dos maneras:

  • Modo de análisis uno a varios, que genera varios documentos de búsqueda por cada archivo Markdown.
  • Modo de análisis uno a uno, que crea un documento de búsqueda por archivo Markdown.

Sugerencia

Después de revisar este artículo, continúe con Tutorial: Buscar datos de Markdown desde Azure Blob Storage.

Requisitos previos

Parámetros del modo de análisis de Markdown

Los parámetros del modo de análisis se especifican en una definición del indexador al crear o actualizar un indexador.

POST https://[service name].search.windows.net/indexers?api-version=2026-04-01
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": {
      "parsingMode": "markdown",
      "markdownParsingSubmode": "oneToMany",
      "markdownHeaderDepth": "h6"
    }
  },
}

El indexador de blobs proporciona un submode parámetro para determinar la estructura de salida de los documentos de búsqueda. El modo de análisis Markdown proporciona las siguientes opciones de submodos:

modo de análisis submodo Buscar documento Descripción
markdown oneToMany Varios por blob (valor predeterminado) Divide Markdown en varios documentos de búsqueda, cada uno de los cuales representa una sección de contenido (sin encabezado) del archivo Markdown. Puede omitir el submodo a menos que desee un análisis uno a uno.
markdown oneToOne Uno por blob Interpreta el Markdown en un documento de búsqueda, con secciones asignadas a encabezados específicos en el archivo Markdown.

Para oneToMany submodo, debe revisar Indexación de un blob para generar muchos documentos de búsqueda para comprender cómo controla el indexador de blobs la desambiguación de la clave de documento para varios documentos de búsqueda generados a partir del mismo blob.

En las secciones posteriores se describe cada submodeo con más detalle. Si no está familiarizado con los clientes y conceptos del indexador, consulte Creación de un indexador de búsqueda. También debe estar familiarizado con los detalles de la configuración básica del indexador de blobs, que no se repite aquí.

Parámetros de análisis opcionales de Markdown

Los parámetros distinguen entre mayúsculas y minúsculas.

Nombre del parámetro Valores permitidos Descripción
markdownHeaderDepth h1, h2, h3, h4, , h5, h6 (default) Este parámetro determina el nivel de encabezado más profundo que se considera al analizar, lo que permite un control flexible de la estructura del documento (por ejemplo, cuando markdownHeaderDepth se establece h1en , el analizador solo reconoce encabezados de nivel superior que comienzan por "#" y todos los encabezados de nivel inferior se tratan como texto sin formato). Si no se especifica, el valor predeterminado es h6.

Esta configuración se puede cambiar después de crear el indexador. Sin embargo, la estructura de los documentos de búsqueda resultantes podría cambiar en función del contenido de Markdown.

Elementos Markdown admitidos

El análisis de Markdown solo divide el contenido en función de los encabezados. Todos los demás elementos, como listas, bloques de código y tablas, se tratan como texto sin formato y se pasan a un campo de contenido.

Contenido de Markdown de ejemplo

El siguiente contenido de Markdown se usa para los ejemplos de esta página:

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Usar el modo de análisis uno a muchos

El modo de análisis uno a varios analiza los archivos Markdown en varios documentos de búsqueda, donde cada documento corresponde a una sección de contenido específica del archivo Markdown en función de los metadatos de encabezado en ese punto del documento. Markdown se analiza en función de los encabezados en documentos de búsqueda, que contienen el siguiente contenido:

  • content: Una cadena que contiene el Markdown sin procesar que se encuentra en una ubicación específica, basada en los metadatos del encabezado en ese punto del documento.

  • sections: objeto que contiene subcampos para los metadatos de encabezado hasta el nivel de encabezado deseado. Por ejemplo, cuando markdownHeaderDepth se establece en h3, contiene campos de cadena h1, h2 y h3. Estos campos se indexan mediante la creación de reflejo de esta estructura en el índice, o mediante asignaciones de campos con el formato /sections/h1, /sections/h2, etc. Consulte las configuraciones de índice e indexador en los ejemplos siguientes para ver ejemplos en contexto. Los subcampos incluidos son:

    • h1 - Cadena que contiene el valor del encabezado h1. Cadena vacía si no se establece en este punto del documento.
    • (Opcional) h2- Cadena que contiene el valor del encabezado h2. Cadena vacía si no se establece en este punto del documento.
    • (Opcional) h3- Cadena que contiene el valor del encabezado h3. Cadena vacía si no se establece en este punto del documento.
    • (Opcional) h4- Cadena que contiene el valor del encabezado h4. Cadena vacía si no se establece en este punto del documento.
    • (Opcional) h5- Cadena que contiene el valor del encabezado h5. Cadena vacía si no se establece en este punto del documento.
    • (Opcional) h6- Cadena que contiene el valor del encabezado h6. Cadena vacía si no se establece en este punto del documento.
  • ordinal_position: valor entero que indica la posición de la sección dentro de la jerarquía de documentos. Este campo se usa para ordenar las secciones de su secuencia original tal como aparecen en el documento, empezando por una posición ordinal de 1 e incrementando secuencialmente para cada encabezado.

Esquema de índice para el análisis sintáctico de uno a varios

Una configuración de índice de ejemplo podría tener un aspecto similar al siguiente:

{
  "name": "my-markdown-index",
  "fields": [
  {
    "name": "id",
    "type": "Edm.String",
    "key": true
  },
  {
    "name": "content",
    "type": "Edm.String",
  },
  {
    "name": "ordinal_position",
    "type": "Edm.Int32"
  },
  {
    "name": "sections",
    "type": "Edm.ComplexType",
    "fields": [
    {
      "name": "h1",
      "type": "Edm.String"
    },
    {
      "name": "h2",
      "type": "Edm.String"
    }]
  }]
}

Definición del indexador para el análisis de uno a varios

Si los nombres de campo y los tipos de datos se alinean, el indexador de blobs puede deducir la asignación sin una asignación de campos explícita presente en la solicitud, por lo que una configuración del indexador correspondiente a la configuración de índice proporcionada podría tener este aspecto:

POST https://[service name].search.windows.net/indexers?api-version=2026-04-01
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": { "parsingMode": "markdown" }
  },
}

Nota

submode No es necesario establecer explícitamente aquí porque oneToMany es el valor predeterminado.

Resultado del indexador para el análisis de uno a varios

Este archivo Markdown daría como resultado tres documentos de búsqueda después de la indexación, debido a las tres secciones de contenido. El documento de búsqueda resultante de la primera sección de contenido del documento de Markdown proporcionado contendrá los siguientes valores para content, sections, h1y h2:

{
  {
    "content": "Content for section 1.\r\n",
    "sections": {
      "h1": "Section 1",
      "h2": ""
    },
    "ordinal_position": 1
  },
  {
    "content": "Content for subsection 1.1.\r\n",
    "sections": {
      "h1": "Section 1",
      "h2": "Subsection 1.1"
    },
    "ordinal_position": 2
  },
  {
    "content": "Content for section 2.\r\n",
    "sections": {
      "h1": "Section 2",
      "h2": ""
    },
    "ordinal_position": 3
  }
}

Asignar campos de uno a varios en un índice de búsqueda

Las asignaciones de campos asocian un campo de origen a un campo de destino en situaciones en las que los nombres y tipos de campo no son idénticos. Pero las asignaciones de campo también se pueden usar para hacer coincidir partes de un documento de Markdown y "elevarlas" a campos de nivel superior del documento de búsqueda.

En el ejemplo siguiente se muestra este escenario. Para obtener más información sobre las asignaciones de campos en general, vea Asignaciones de campos.

Supongamos un índice de búsqueda con los campos siguientes: raw_content de tipo , Edm.String de tipo h1_headerEdm.Stringy h2_header de tipo Edm.String. Para asignar el Markdown a la forma deseada, use las siguientes asignaciones de campos.

"fieldMappings" : [
    { "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
    { "sourceFieldName" : "/sections/h1", "targetFieldName" : "h1_header" },
    { "sourceFieldName" : "/sections/h2", "targetFieldName" : "h2_header" },
  ]

El documento de búsqueda resultante en el índice tendría el siguiente aspecto:

{
  {
    "raw_content": "Content for section 1.\r\n",
    "h1_header": "Section 1",
    "h2_header": "",
  },
  {
    "raw_content": "Content for section 1.1.\r\n",
    "h1_header": "Section 1",
    "h2_header": "Subsection 1.1",
  },
  {
    "raw_content": "Content for section 2.\r\n",
    "h1_header": "Section 2",
    "h2_header": "",
  }
}

Utilizar el modo de análisis uno a uno

En el modo de análisis uno a uno, todo el documento markdown se indexa como un único documento de búsqueda, conservando la jerarquía y la estructura del contenido original. Este modo es más útil cuando los archivos que se van a indexar comparten una estructura común, de modo que pueda usar esta estructura común en el índice para que los campos pertinentes se puedan buscar.

Dentro de la definición del indexador, establezca parsingMode a "markdown" y use el parámetro opcional markdownHeaderDepth para definir la profundidad máxima de fragmentación del encabezado. Si no se especifica, el valor predeterminado es h6, capturando todas las profundidades de encabezado posibles.

Markdown se analiza en función de los encabezados en documentos de búsqueda, que contienen el siguiente contenido:

  • document_content: contiene el texto de Markdown completo como una sola cadena. Este campo actúa como una representación sin procesar del documento de entrada.

  • sections: matriz de objetos que contiene la representación jerárquica de las secciones dentro del documento markdown. Cada sección se representa como un objeto dentro de esta matriz y captura la estructura del documento de una manera anidada correspondiente a los encabezados y su contenido respectivo. Los campos son accesibles mediante mapeos de campos haciendo referencia a la ruta, por ejemplo /sections/content. Los objetos de esta matriz tienen las siguientes propiedades:

    • header_level: cadena que indica el nivel del encabezado (h1, h2, h3, etc.) en la sintaxis de Markdown. Este campo ayuda a comprender la jerarquía y la estructuración del contenido.

    • header_name: cadena que contiene el texto del encabezado tal como aparece en el documento markdown. Este campo proporciona una etiqueta o un título para la sección.

    • content: una cadena que contiene contenido de texto que sigue inmediatamente el encabezado, hasta el siguiente encabezado. Este campo captura la información detallada o la descripción asociada al encabezado. Si no hay contenido directamente bajo un encabezado, el valor es una cadena vacía.

    • ordinal_position: valor entero que indica la posición de la sección dentro de la jerarquía de documentos. Este campo se usa para ordenar las secciones de su secuencia original tal como aparecen en el documento, empezando por una posición ordinal de 1 e incrementando secuencialmente para cada bloque de contenido.

    • sections: Una matriz que contiene objetos que representan subsecciones anidadas en la sección actual. Esta matriz sigue la misma estructura que la matriz de nivel sections superior, lo que permite la representación de varios niveles de contenido anidado. Cada objeto de subsección también incluye las propiedades header_level, header_name, content y ordinal_position, que posibilitan una estructura recursiva que representa la jerarquía del contenido de Markdown.

Este es el ejemplo de Markdown que usamos para explicar los esquemas de índice diseñados en torno a cada modo de análisis.

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Esquema de índice para el análisis uno a uno

Si no utiliza asignaciones de campos, la estructura del índice debe reflejar la estructura del contenido de Markdown. Dada la estructura del ejemplo Markdown con sus dos secciones y una sola subsección, el índice debe tener un aspecto similar al del ejemplo siguiente:

{
  "name": "my-markdown-index",
  "fields": [
  {
    "name": "id",
    "type": "Edm.String",
    "key": true
  },
  {
    "name": "document_content",
    "type": "Edm.String"
  },
  {
    "name": "sections",
    "type": "Collection(Edm.ComplexType)",
    "fields": [
    {
      "name": "header_level",
      "type": "Edm.String"
    },
    {
      "name": "header_name",
      "type": "Edm.String"
    },
    {
      "name": "content",
      "type": "Edm.String"
    },
    {
      "name": "ordinal_position",
      "type": "Edm.Int32"
    },
    {
      "name": "sections",
      "type": "Collection(Edm.ComplexType)",
      "fields": [
      {
        "name": "header_level",
        "type": "Edm.String"
      },
      {
        "name": "header_name",
        "type": "Edm.String"
      },
      {
        "name": "content",
        "type": "Edm.String"
      },
      {
        "name": "ordinal_position",
        "type": "Edm.Int32"
      }]
    }]
  }]
}

Definición del indexador para el análisis uno a uno

POST https://[service name].search.windows.net/indexers?api-version=2026-04-01
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": {
      "parsingMode": "markdown",
      "markdownParsingSubmode": "oneToOne",
    }
  }
}

Salida del indexador para el análisis uno a uno

Dado que el Markdown que queremos indexar solo llega hasta una profundidad de h2 ("##"), necesitamos sections campos anidados a una profundidad de 2 para que coincida. Esta configuración daría lugar a los siguientes datos en el índice:

  "document_content": "# Section 1\r\nContent for section 1.\r\n## Subsection 1.1\r\nContent for subsection 1.1.\r\n# Section 2\r\nContent for section 2.\r\n",
  "sections": [
    {
      "header_level": "h1",
      "header_name": "Section 1",
      "content": "Content for section 1.",
      "ordinal_position": 1,
      "sections": [
        {
          "header_level": "h2",
          "header_name": "Subsection 1.1",
          "content": "Content for subsection 1.1.",
          "ordinal_position": 2,
        }]
    }],
    {
      "header_level": "h1",
      "header_name": "Section 2",
      "content": "Content for section 2.",
      "ordinal_position": 3,
      "sections": []
    }]
  }

Como puede ver, la posición ordinal se incrementa en función de la ubicación del contenido del documento.

Si los niveles de encabezado se omiten en el contenido, la estructura del documento resultante refleja los encabezados presentes en el contenido de Markdown y no contiene necesariamente secciones anidadas consecutivas desde h1 hasta h6. Por ejemplo, cuando el documento comienza en h2, el primer elemento de la matriz de secciones de nivel superior es h2.

Mapear campos uno a uno en un índice de búsqueda

Para extraer campos del documento con nombres personalizados, puede utilizar el mapeo de campos. Con el mismo ejemplo de Markdown que antes, tenga en cuenta la siguiente configuración de índice:

{
  "name": "my-markdown-index",
  "fields": [
    {
      "name": "document_content",
      "type": "Edm.String",
    },
    {
      "name": "document_title",
      "type": "Edm.String",
    },
    {
      "name": "opening_subsection_title",
      "type": "Edm.String"
    },
    {
      "name": "summary_content",
      "type": "Edm.String",
    }
  ]
}

La extracción de campos específicos de Markdown analizados se controla de forma similar a la forma en que las rutas de acceso del documento están en outputFieldMappings, excepto que la ruta de acceso comienza por /sections en lugar de /document. Por lo tanto, por ejemplo, /sections/0/content se asignaría al contenido debajo del elemento en la posición 0 de la matriz de secciones.

Un ejemplo de un caso de uso seguro podría tener un aspecto similar al siguiente: todos los archivos Markdown tienen un título de documento en el primer h1, un título de subsección en el primer h2y un resumen en el contenido del párrafo final debajo de la última h1. Puede usar las siguientes asignaciones de campos para indexar solo ese contenido:

"fieldMappings" : [
  { "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
  { "sourceFieldName" : "/sections/0/header_name", "targetFieldName" : "document_title" },
  { "sourceFieldName" : "/sections/0/sections/header_name", "targetFieldName" : "opening_subsection_title" },
  { "sourceFieldName" : "/sections/1/content", "targetFieldName" : "summary_content" },
]

Aquí, extraería solo las partes pertinentes de ese documento. Para usar esta funcionalidad de forma más eficaz, los documentos que planea indexar deben compartir la misma estructura de encabezado jerárquica.

El documento de búsqueda resultante en el índice tendría el siguiente aspecto:

{
  "content": "Content for section 1.\r\n",
  "document_title": "Section 1",
  "opening_subsection_title": "Subsection 1.1",
  "summary_content": "Content for section 2."
}

Nota

Estos ejemplos especifican cómo usar estos modos de análisis completamente con o sin asignaciones de campos, pero puede aplicar ambos en un escenario si se adapta a sus necesidades.

Gestión de documentos obsoletos durante la reindexación de Markdown

Al usar el modo de análisis uno a varios, volver a indexar un archivo Markdown modificado puede dar lugar a documentos obsoletos o duplicados si se quitan secciones. Este comportamiento es específico del modo uno a varios y no se aplica al análisis uno a uno.

Información general sobre el comportamiento

Modo de análisis uno a varios

En oneToMany modo, cada sección de Markdown (basada en encabezados) se indexa como un documento de búsqueda independiente. Cuando el archivo se vuelve a indexar:

  • Sin eliminación automática: el indexador sobrescribe los documentos existentes con otros nuevos, pero no elimina los documentos que ya no corresponden a ningún contenido del archivo actualizado.
  • Potencial de duplicados: este problema se produce específicamente solo cuando se eliminan más secciones que las insertadas entre ejecuciones de indexación. En tales casos, los documentos restantes de la versión anterior permanecen en el índice, lo que conduce a entradas obsoletas que ya no reflejan el estado actual del archivo de origen.

Modo de análisis uno a uno

En oneToOne modo, todo el archivo Markdown se indexa como un único documento de búsqueda. Cuando el archivo se vuelve a indexar:

  • Comportamiento de sobrescritura: el documento existente se reemplaza completamente por la nueva versión.
  • Sin secciones obsoletas: cuando el archivo se vuelve a indexar, el documento existente se reemplaza por la versión actualizada y el contenido quitado ya no se incluye. La única excepción es si cambia la ruta de acceso del archivo o el URI de blob, lo que podría dar lugar a que se cree un nuevo documento junto con el anterior.

Opciones de solución alternativa

Para asegurarse de que el índice refleja el estado actual de los archivos Markdown, considere uno de los enfoques siguientes:

Opción 1. Eliminación suave con metadatos

Este método usa una eliminación temporal para eliminar documentos asociados a un blob específico. Para obtener más información, vea la detección de cambios y eliminación usando indexadores en Azure Storage para Búsqueda de Azure AI.

Pasos:

  1. Marque el blob como eliminado estableciendo un campo de metadatos.
  2. Deje que se ejecute el indexador. Elimina todos los documentos del índice asociado a ese blob.
  3. Quite el marcador de eliminación temporal y vuelva a indexar el archivo.

Opción 2. Uso de la API de eliminación

Antes de volver a indexar un archivo Markdown modificado, elimine explícitamente los documentos existentes asociados a ese archivo mediante la API delete. Puede hacer lo siguiente:

  • Identifique manualmente documentos obsoletos individuales mediante la identificación de duplicados en el índice que se va a eliminar. Esto puede ser factible para cambios pequeños y bien comprendidos, pero puede llevar mucho tiempo.
  • (Recomendado) Quite todos los documentos generados desde el mismo archivo primario antes de volver a indexar, lo que garantiza que se eviten incoherencias.

Pasos:

  1. Identifique el identificador de los documentos asociados al archivo. Use una consulta como el ejemplo siguiente para recuperar los identificadores de clave de documento (por ejemplo, id o chunk_id) para todos los documentos vinculados a un archivo específico. Reemplace por metadata_storage_path el campo adecuado del índice que se asigna a la ruta de acceso del archivo o al URI del blob. Este campo debe ser una clave.

    GET https://[service name].search.windows.net/indexes/[index name]/docs?api-version=2026-04-01
    Content-Type: application/json
    api-key: [admin key]
    
    
      {
          "filter": "metadata_storage_path eq 'https://<storage-account>.blob.core.windows.net/<container-name>/<file-name>.md'",
          "select": "id"
      }
    
  2. Emita una solicitud de eliminación para los documentos con las claves identificadas.

    POST https://[service name].search.windows.net/indexes/[index name]/docs/index?api-version=2026-04-01
    Content-Type: application/json
    api-key: [admin key]
    
    {
      "value": [
        {
          "@search.action": "delete",
          "id": "aHR0c...jI1"
        },
        {
          "@search.action": "delete",
          "id": "aHR0...MQ2"
        }
      ]
    }
    
  3. Vuelva a indexar el archivo actualizado.

Pasos siguientes