Пример фигур и проекций в хранилище знаний

Note

Хранилища знаний — это дополнительное хранилище, которое существует в службе хранилища Azure и содержит выходные данные наборов навыков поиска ИИ Azure. Они отделены от источников знаний и баз знаний, которые используются в рабочих процессах агентного извлечения.

В этой статье приведен подробный пример, который дополняет высокоуровневые понятия и статьи на основе синтаксиса, проводя через этапы формирования и проецирования, необходимые, чтобы полностью выразить выходные данные богатого набора навыков в хранилище знаний в служба хранилища Azure.

Если требования к приложению требуют нескольких функций и проекций, этот пример может лучше показать, как взаимодействуют формы и проекции.

Настройка образцов данных

Примеры документов не включены в коллекцию проекций, но демонстрационные файлы данных обогащения ИИ содержат текст и изображения, которые работают с проекциями, описанными в этом примере. Если вы используете эти образцы данных, можно пропустить шаг, который присоединяет ресурс Microsoft Foundry, так как вы не превышаете ежедневный лимит индексатора для бесплатных обогащений.

Создайте контейнер объектов BLOB в службе хранилища Azure и отправьте все 14 элементов.

Находясь в службе хранилища Azure, скопируйте строку подключения.

Файл projections.rest можно использовать для выполнения примеров в этой статье.

Пример набора навыков

Чтобы понять зависимость между фигурами и проекциями, просмотрите следующий набор навыков, который создает обогащенное содержимое. Этот набор компетенций обрабатывает как исходные изображения, так и текст, производя выходные данные, на которые будут опираться формы и проекции.

Обратите внимание на выходные данные навыка (targetNames). Выходные данные, записанные в обогащенное дерево документов, используются в проекциях и формах (с помощью Shaper-навыков).

{
    "name": "projections-demo-ss",
    "description": "Skillset that enriches blob data found in the merged_content field. The enrichment granularity is a document.",
    "skills": [
        {
            "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
            "name": "#1",
            "description": null,
            "context": "/document/merged_content",
            "categories": [
                "Person",
                "Quantity",
                "Organization",
                "URL",
                "Email",
                "Location",
                "DateTime"
            ],
            "defaultLanguageCode": "en",
            "minimumPrecision": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "persons",
                    "targetName": "people"
                },
                {
                    "name": "organizations",
                    "targetName": "organizations"
                },
                {
                    "name": "locations",
                    "targetName": "locations"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
            "name": "#2",
            "description": null,
            "context": "/document/merged_content",
            "defaultLanguageCode": "en",
            "maxKeyPhraseCount": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "keyPhrases",
                    "targetName": "keyphrases"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
            "name": "#3",
            "description": null,
            "context": "/document",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                }
            ],
            "outputs": [
                {
                    "name": "languageCode",
                    "targetName": "language"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.MergeSkill",
            "name": "#4",
            "description": null,
            "context": "/document",
            "insertPreTag": " ",
            "insertPostTag": " ",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/content"
                },
                {
                    "name": "itemsToInsert",
                    "source": "/document/normalized_images/*/text"
                },
                {
                    "name": "offsets",
                    "source": "/document/normalized_images/*/contentOffset"
                }
            ],
            "outputs": [
                {
                    "name": "mergedText",
                    "targetName": "merged_content"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
            "name": "#5",
            "description": null,
            "context": "/document/normalized_images/*",
            "textExtractionAlgorithm": "printed",
            "lineEnding": "Space",
            "defaultLanguageCode": "en",
            "detectOrientation": true,
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                }
            ],
            "outputs": [
                {
                    "name": "text",
                    "targetName": "text"
                },
                {
                    "name": "layoutText",
                    "targetName": "layoutText"
                }
            ]
        }
    ],
    "cognitiveServices": {
        "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
        "description": "A Foundry resource in the same region as Search.",
        "key": "{{cognitive-services-key}}"
    },
    "knowledgeStore": null
}

Note

Индексатор может обрабатывать до 20 транзакций в день без платы. Пример данных для этого примера остается в пределах ограничения 20 транзакций, поэтому, если вы используете пример данных, можно опустить секцию cognitiveServices.

Пример навыка шейпера

Shaper skill — это утилита для работы с существующим обогащённым содержимым вместо создания нового обогащённого содержимого. Добавление компонента Shaper в набор навыков позволяет создать настраиваемую форму, которую можно размещать в таблицу или хранилище BLOB-объектов. Без пользовательской фигуры проекции ограничены ссылкой на один узел (по одной проекции на выход), что не подходит для таблиц. Создание пользовательской фигуры объединяет различные элементы в новое логическое единство, которое может быть спроецировано в виде одной таблицы или фрагментировано и распределено по коллекциям таблиц.

В этом примере произвольная форма сочетает метаданные BLOB и идентифицированные сущности с ключевыми фразами. Пользовательская фигура называется projectionShape, и ее родительский элемент — /document.

Одна из целей формирования — обеспечить представление всех узлов обогащения в корректном формате JSON, что необходимо для проецирования в хранилище знаний. Это особенно верно, если дерево обогащения содержит узлы, которые некорректно сформированы как JSON (например, если обогащение является родительским элементом для примитива, например, строки).

Обратите внимание на два последних узла: KeyPhrases и Entities. Они обёрнуты в допустимый объект JSON с помощью sourceContext. Это необходимо, так как keyphrases и entities являются обогащениями для примитивов и должны быть преобразованы в допустимые JSON, прежде чем их можно будет спроецировать.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForTables",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_content_type",
            "source": "/document/metadata_storage_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_path",
            "source": "/document/metadata_storage_path",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_content_type",
            "source": "/document/metadata_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "Entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        }
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "projectionShape"
        }
    ]
}

Добавить Shapers в набор умений

Пример набора навыков, представленный в начале этой статьи, не включал навык Шейпера, но навыки Шейпера принадлежат набору навыков и часто располагаются в конце.

В наборе навыков профилирующий навык может выглядеть следующим образом:

{
    "name": "projections-demo-ss",
    "skills": [
        {
            <Shaper skill goes here>
            }
        ],
    "cognitiveServices":  "A key goes here",
    "knowledgeStore": []
}  

Проецирование в таблицы

На основе приведенных выше примеров существует известное количество обогащений и фигур данных, на которые можно ссылаться в табличных проекциях. В проекции таблиц ниже три таблицы определяются путем задания свойств tableName, source и generatedKeyName.

Все три таблицы будут связаны через созданные ключи и общий родительский элемент /document/projectionShape.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "tblDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "tblKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases/*"
                },
                {
                    "tableName": "tblEntities",
                    "generatedKeyName": "Entityid",
                    "source": "/document/projectionShape/Entities/*"
                }
            ],
            "objects": [],
            "files": []
        }
    ]
}

Проверяйте свою работу

Вы можете проверить определения проекции, выполнив следующие действия.

  1. Установите свойство storageConnectionString хранилища знаний на допустимую строку подключения учетной записи общего назначения V2.

  2. Обновите набор навыков, отправив запрос PUT.

  3. После обновления набора навыков запустите индексатор.

Теперь у вас есть рабочая проекция с тремя таблицами. Импорт этих таблиц в Power BI должен привести к обнаружению связей Power BI .

Прежде чем перейти к следующему примеру, повторно рассмотрим аспекты проекции таблицы, чтобы понять механизм фрагментирования и создания отношений данных.

Фрагментирование таблицы на несколько дочерних таблиц

Фрагментирование — это метод разделения целой объединенной фигуры на составные части. В результате получаются отдельные, но связанные таблицы, с которыми можно работать по отдельности.

Например, projectionShape является объединенной фигурой (или узлом обогащения). В определении проекции projectionShape разделена на дополнительные таблицы, что позволяет выделять части фигуры, keyPhrases и Entities. В Power BI это полезно, так как несколько сущностей и ключевых фраз связаны с каждым документом, и вы получите дополнительные сведения, если можно увидеть сущности и ключевые фразы как классифицированные данные.

Фрагментирование неявным образом создает связь между родительской и дочерней таблицами с помощью generatedKeyName в родительской таблице для создания столбца с тем же именем в дочерней таблице.

Отношения именования

Свойства generatedKeyName и referenceKeyName используются, чтобы связать данные между таблицами или даже между типами проекций. Каждая строка дочерней таблицы имеет свойство, указывающее на родительский элемент. Имя столбца или свойства дочернего элемента — referenceKeyName из родительского элемента. referenceKeyName Если этот параметр не указан, служба по умолчанию устанавливает его на generatedKeyName родителя.

Power BI использует эти созданные ключи для обнаружения связей в таблицах. Если столбцу в дочерней таблице необходимо присвоить другое имя, установите свойство referenceKeyName в родительской таблице. Одним из примеров является установка generatedKeyName как идентификатора в таблице tblDocument и referenceKeyName в качестве DocumentID. Это приведет к тому, что столбец в таблицах tblEntities и tblKeyPhrases, содержащий идентификатор документа, получит имя DocumentID.

Отображение документов BLOB-объектов

Проекции объектов — это JSON-представления дерева обогащения, которые могут быть получены из любого узла. В сравнении с табличными проекциями проекции объектов проще определить и использовать при проецации целых документов. Проекции объектов ограничены одной проекцией в контейнере и не могут быть срезаны.

Чтобы определить проекцию объекта, используйте objects массив в свойстве проекций.

Источником является путь к узлу дерева обогащения, который является корнем проекции. Хотя это не обязательно, путь к узлу обычно является выходным результатом навыка Shaper. Это связано с тем, что большинство навыков не выводят допустимые объекты JSON самостоятельно, что означает, что требуется некоторая форма формирования. Во многих случаях для создания проекции объекта можно использовать тот же навык Формирователя,что создает табличные проекции. Кроме того, источник может быть установлен на узел с встроенной формой для предоставления структуры.

Назначение всегда является Blob-контейнером.

В следующем примере представляются отдельные документы отеля, по одному документу отеля для каждого большого двоичного объекта в контейнер, называемый hotels.

"knowledgeStore": {
  "storageConnectionString": "an Azure storage connection string",
  "projections" : [
    {
      "tables": [ ]
    },
    {
      "objects": [
        {
        "storageContainer": "hotels",
        "source": "/document/objectprojection",
        }
      ]
    },
    {
        "files": [ ]
    }
  ]
}

Это выходные данные, полученные из навыка Формировщика под названием "objectprojection". Каждый блоб будет иметь представление JSON для каждого поля ввода.

    {
      "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
      "name": "#3",
      "description": null,
      "context": "/document",
      "inputs": [
        {
          "name": "HotelId",
          "source": "/document/HotelId"
        },
        {
          "name": "HotelName",
          "source": "/document/HotelName"
        },
        {
          "name": "Category",
          "source": "/document/Category"
        },
        {
          "name": "keyPhrases",
          "source": "/document/HotelId/keyphrases/*"
        },
      ],
      "outputs": [
        {
          "name": "output",
          "targetName": "objectprojection"
        }
      ]
    }

Проецирование файла изображения

Проекции файлов всегда являются двоичными, нормализованными изображениями, где нормализация относится к потенциальному изменению размера и вращению для выполнения задач в наборе навыков. Проекции файлов, аналогичные проекциям объектов, создаются как BLOB-объекты в службе хранилищ Azure и содержат изображение.

Чтобы определить проекцию файла, используйте files массив в свойстве проекций.

Источник всегда /document/normalized_images/*. Проекции файлов действуют только в normalized_images коллекции. Ни индексаторы, ни набор навыков не будут проходить через исходный ненормализованный образ.

Назначение всегда является контейнером объектов BLOB с префиксом папки, закодированным в Base64 значении идентификатора документа. Проекции файлов не могут совместно использовать тот же контейнер, что и проекции объектов и должны быть проецированы в другой контейнер.

В следующем примере все нормализованные изображения, извлеченные из узла обогащенного документа, переносятся в контейнер с именем myImages.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [ ],
            "objects": [ ],
            "files": [
                {
                    "storageContainer": "myImages",
                    "source": "/document/normalized_images/*"
                }
            ]
        }
    ]
}

Проецирование на несколько типов

При более сложном сценарии может потребоваться спроецировать содержимое на различные типы проекций. Например, проецирование ключевых фраз и сущностей в таблицы, сохранение результатов распознавания текста и текста макета в виде объектов и последующее проецирование образов в виде файлов.

Шаги для нескольких типов проекций:

  1. Создание таблицы со строкой для каждого документа.
  2. Создание таблицы, связанной с таблицей документов, где каждая ключевая фраза идентифицируется как строка в этой таблице.
  3. Создание таблицы, связанной с таблицей документов, где каждая сущность идентифицируется как строка в этой таблице.
  4. Создайте проекцию объекта с текстом макета для каждого изображения.
  5. Создание проекции файла, проецирующей каждый извлеченный образ.
  6. Создание таблицы перекрестных ссылок, содержащей ссылки на таблицу документов, проекцию объекта с текстом макета и проекцию файла.

Данные формы для перекрестного проецирования

Чтобы получить фигуры, необходимые для этих проекций, начните с добавления нового навыка формирователя, который создает фигурный объект с именем crossProjection.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForCrossProjection",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        },
        {
            "name": "images",
            "source": null,
            "sourceContext": "/document/normalized_images/*",
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                },
                {
                    "name": "layoutText",
                    "source": "/document/normalized_images/*/layoutText"
                },
                {
                    "name": "ocrText",
                    "source": "/document/normalized_images/*/text"
                }
                ]
        }
 
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "crossProjection"
        }
    ]
}

Определение проекций таблицы, объекта и файла

Из консолидированного объекта crossProjection разделите объект на несколько таблиц, запишите выходные данные OCR как BLOB, а затем сохраните изображение в виде файлов (также в хранилище Blob).

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
            {
            "tables": [
                {
                    "tableName": "crossDocument",
                    "generatedKeyName": "Id",
                    "source": "/document/crossProjection"
                },
                {
                    "tableName": "crossEntities",
                    "generatedKeyName": "EntityId",
                    "source": "/document/crossProjection/entities/*"
                },
                {
                    "tableName": "crossKeyPhrases",
                    "generatedKeyName": "KeyPhraseId",
                    "source": "/document/crossProjection/keyPhrases/*"
                },
                {
                    "tableName": "crossReference",
                    "generatedKeyName": "CrossId",
                    "source": "/document/crossProjection/images/*"
                }
                    
            ],
            "objects": [
                {
                    "storageContainer": "crossobject",
                    "generatedKeyName": "crosslayout",
                    "source": null,
                    "sourceContext": "/document/crossProjection/images/*/layoutText",
                    "inputs": [
                        {
                            "name": "OcrLayoutText",
                            "source": "/document/crossProjection/images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": [
                {
                    "storageContainer": "crossimages",
                    "generatedKeyName": "crossimages",
                    "source": "/document/crossProjection/images/*/image"
                }
            ]
        }
    ]
}

Для каждой проекции объектов требуется имя контейнера. Проекции объектов и проекции файлов не могут совместно использовать контейнер.

Связи между проекциями таблицы, объекта и файла

В этом примере освещается другая функция проекций. Определив несколько типов проекций в одном объекте проекции, существует связь между различными типами (таблицами, объектами, файлами). Это позволяет начать со строки таблицы для документа и найти весь текст OCR для образов в этом документе в проекции объекта.

Если вы не хотите связывать данные, определите проекции в отдельных группах проекций. Например, следующий фрагмент приведет к тому, что таблицы будут связаны, но связь между таблицами и проекциями объекта (текстом OCR) будет отсутствовать.

Группы проекций полезны в тех случаях, когда необходимо спроецировать одни и те же данные в разные фигуры для различных нужд. Например, группа проекций для панели мониторинга Power BI и другая группа проекций для сбора данных, которые используются для обучения модели машинного обучения, интегрированной с пользовательским навыком.

При построении проекций разных типов сначала создаются проекции файла и объекта, а в таблицы добавляются пути.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "unrelatedDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "unrelatedKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases"
                }
            ],
            "objects": [
                
            ],
            "files": []
        }, 
        {
            "tables": [],
            "objects": [
                {
                    "storageContainer": "unrelatedocrtext",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/text",
                    "inputs": [
                        {
                            "name": "ocrText",
                            "source": "/document/normalized_images/*/text"
                        }
                    ]
                },
                {
                    "storageContainer": "unrelatedocrlayout",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/layoutText",
                    "inputs": [
                        {
                            "name": "ocrLayoutText",
                            "source": "/document/normalized_images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": []
        }
    ]
}

Дальнейшие шаги

В примере в этой статье показаны распространенные шаблоны создания проекций. Теперь, когда у вас есть хорошее понимание концепций, вы лучше оснащены для создания проекций для конкретного сценария.