你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure AI 搜索中的结构感知分块和矢量化

注意

此功能目前处于公开预览状态。 此预览版没有附带服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

文本数据分块策略在优化 RAG 响应和性能方面具有关键作用。 通过使用当前处于预览版的新文档布局技能,可以根据段落或句子表示的语义上连贯的片段对内容进行分块。 然后,这些片段可以独立处理,并重新组合为语义表征,而不会丢失信息、解释或语义相关性。 文本的固有含义会用作分块过程的指导。

文档布局技能使用 Markdown 语法(标题和内容)来阐明搜索文档中的文档结构。 从源文档获取的可搜索内容为纯文本,但你可以添加集成矢量化为任何字段生成嵌入内容。

在本文中,将学习以下内容:

  • 使用文档布局技能检测节和输出 Markdown 内容
  • 使用文本拆分技能将区块大小限制到每个 Markdown 节
  • 为每个区块生成嵌入内容
  • 使用索引投影将嵌入内容映射到搜索索引中的字段

先决条件

准备数据文件

原始输入必须位于受支持的数据源中,并且文件必须是文档布局技能支持的格式。

  • 支持的文件格式包括:PDF、JPEG、JPG、PNG、BMP、TIFF、DOCX、XLSX、PPTX、HTML。

  • 支持的索引器可以是任何可处理受支持文件格式的索引器。 其中包括 Blob 索引器OneLake 索引器文件索引器

  • 此功能支持的区域包括:美国东部、美国西部 2、西欧、美国中北部。 请务必检查此列表,了解有关区域可用性的更新。

可以使用 Azure 门户、REST API 或 Azure SDK 包来创建数据源

提示

运行状况计划 PDF 示例文件上传到受支持的数据源,以在自己的搜索服务上试用文档布局技能和结构感知分块。 导入和矢量化数据向导是一种简单的无代码方法,可用于试用此技能。 请务必选择“默认分析模式”以使用结构感知分块。 否则,将改用 Markdown 分析模式

为一对多索引编制创建索引

下面是围绕区块设计的单个搜索文档的有效负载示例。 在此示例中,父字段是 text_parent_id。 子字段是 Markdown 节的矢量区块和非矢量区块。

可以使用 Azure 门户、REST API 或 Azure SDK 来创建索引

在创建技能组或运行索引器之前,搜索服务上必须存在索引。

{
  "name": "my_consolidated_index",
  "fields": [
    {
      "name": "chunk_id",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": true,
      "facetable": false,
      "key": true,
      "analyzer": "keyword"
    },
    {
      "name": "text_parent_id",
      "type": "Edm.String",
      "searchable": false,
      "filterable": true,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "chunk",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "title",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "header_1",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "header_2",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "header_3",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    },
    {
      "name": "text_vector",
      "type": "Collection(Edm.Single)",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false,
      "dimensions": 1536,
      "stored": false,
      "vectorSearchProfile": "profile"
    }
  ],
  "vectorSearch": {
    "profiles": [
      {
        "name": "profile",
        "algorithm": "algorithm"
      }
    ],
    "algorithms": [
      {
        "name": "algorithm",
        "kind": "hnsw"
      }
    ]
  }
}

为结构感知分块和矢量化定义技能组

由于文档布局技能组为预览版,因此必须在此步骤中使用创建技能组 2024-11-01-preview REST API。

下面是一个技能组定义有效负载示例,使用文档布局技能Azure OpenAI 嵌入技能将单个 Markdown 节块及其矢量输出投影为搜索索引中的文档

POST {endpoint}/skillsets?api-version=2024-11-01-preview

{
  "name": "my_skillset",
  "description": "A skillset for structure-aware chunking and vectorization with a index projection around markdown section",
  "skills": [
    {
      "@odata.type": "#Microsoft.Skills.Util.DocumentIntelligenceLayoutSkill",
      "name": "my_document_intelligence_layout_skill",
      "context": "/document",
      "outputMode": "oneToMany",
      "inputs": [
        {
          "name": "file_data",
          "source": "/document/file_data"
        }
      ],
      "outputs": [
        {
          "name": "markdown_document",
          "targetName": "markdownDocument"
        }
      ],
      "markdownHeaderDepth": "h3"
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.SplitSkill",
      "name": "my_markdown_section_split_skill",
      "description": "A skill that splits text into chunks",
      "context": "/document/markdownDocument/*",
      "inputs": [
        {
          "name": "text",
          "source": "/document/markdownDocument/*/content",
          "inputs": []
        }
      ],
      "outputs": [
        {
          "name": "textItems",
          "targetName": "pages"
        }
      ],
      "defaultLanguageCode": "en",
      "textSplitMode": "pages",
      "maximumPageLength": 2000,
      "pageOverlapLength": 500,
      "unit": "characters"
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
      "name": "my_azure_openai_embedding_skill",
      "context": "/document/markdownDocument/*/pages/*",
      "inputs": [
        {
          "name": "text",
          "source": "/document/markdownDocument/*/pages/*",
          "inputs": []
        }
      ],
      "outputs": [
        {
          "name": "embedding",
          "targetName": "text_vector"
        }
      ],
      "resourceUri": "https://<subdomain>.openai.azure.com",
      "deploymentId": "text-embedding-3-small",
      "apiKey": "<Azure OpenAI api key>",
      "modelName": "text-embedding-3-small"
    }
  ],
  "cognitiveServices": {
    "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
    "key": "<Cognitive Services api key>"
  },
  "indexProjections": {
    "selectors": [
      {
        "targetIndexName": "my_consolidated_index",
        "parentKeyFieldName": "text_parent_id",
        "sourceContext": "/document/markdownDocument/*/pages/*",
        "mappings": [
          {
            "name": "text_vector",
            "source": "/document/markdownDocument/*/pages/*/text_vector"
          },
          {
            "name": "chunk",
            "source": "/document/markdownDocument/*/pages/*"
          },
          {
            "name": "title",
            "source": "/document/title"
          },
          {
            "name": "header_1",
            "source": "/document/markdownDocument/*/sections/h1"
          },
          {
            "name": "header_2",
            "source": "/document/markdownDocument/*/sections/h2"
          },
          {
            "name": "header_3",
            "source": "/document/markdownDocument/*/sections/h3"
          }
        ]
      }
    ],
    "parameters": {
      "projectionMode": "skipIndexingParentDocuments"
    }
  }
}

运行索引器

创建数据源、索引和技能组后,即可创建并运行索引器。 此步骤将执行管道。

使用文档布局技能时,请确保在索引器定义上设置以下参数:

  • allowSkillsetToReadFileData 参数应设置为 true
  • parsingMode 参数应设置为 default

下面是一个有效负载示例

{
  "name": "my_indexer",
  "dataSourceName": "my_blob_datasource",
  "targetIndexName": "my_consolidated_index",
  "skillsetName": "my_skillset",
  "parameters": {
    "batchSize": 1,
    "configuration": {
        "dataToExtract": "contentAndMetadata",
        "parsingMode": "default",
        "allowSkillsetToReadFileData": true
    }
  },
  "fieldMappings": [
    {
      "sourceFieldName": "metadata_storage_path",
      "targetFieldName": "title"
    }
  ],
  "outputFieldMappings": []
}

验证结果

你可以在处理结束后查询你的搜索索引以测试你的解决方案。

若要检查结果,请针对索引运行查询。 使用搜索资源管理器作为搜索客户端或发送 HTTP 请求的任何工具。 以下查询选择的字段包含 Markdown 节非矢量内容及其矢量的输出。

对于搜索资源管理器,可以仅复制 JSON 并将其粘贴到 JSON 视图中以进行查询执行。

POST /indexes/[index name]/docs/search?api-version=[api-version]
{
    "search": "*",
    "select": "metadata_storage_path, markdown_section, vector"
}

另请参阅