Как заполнить поле поиска Azure AI специальным навыком?

Я пытаюсь заполнить поле ParsedDate в индексе поиска Azure, чтобы позже создать профиль оценки для улучшения результатов поиска (с помощью свежести).

Я определил индекс, набор навыков и индексатор в соответствии с документацией, но когда я запускаю индексатор, поле всегда имеет значение NULL.

Вот как я определил навык в своем наборе навыков:


  {
      "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
      "name": "#0",
      "description": "A custom skill that parses dates from file names",
      "uri": "https://az-function.azurewebsites.net/api/custom-skill-date-extraction?code=ABC",
      "httpMethod": "POST",
      "timeout": "PT30S",
      "batchSize": 1,
      "context": "/document",
      "inputs": [
        {
          "name": "fileName",
          "source": "/document/metadata_storage_path" 
        }
      ],
      "outputs": [
        {
          "name": "parsedDate",
          "targetName": "parsedDate"
        }
      ]
    }

Вот как я определил индекс:

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    # Environment Variables
    endpoint = os.environ["AZURE_SEARCH_SERVICE_ENDPOINT"]
    endpoint_openai = os.environ["AZURE_OPENAI_ENDPOINT"]
    deployment_id = os.environ["AZURE_OPENAI_EMBEDDING_DEPLOYMENT_ID"]
    credential_search = AzureKeyCredential(os.environ["AZURE_SEARCH_ADMIN_KEY"]) if os.environ["AZURE_SEARCH_ADMIN_KEY"] else DefaultAzureCredential()
    credential = DefaultAzureCredential()
    customer = readRequestBody(req)
    _ , datasource_name = utils.getStorageAccountInfo(customer, credential)
    index_name = utils.get_index_name( datasource_name)

    # Logic for creating a search index
    try:
        index_client = SearchIndexClient(endpoint=endpoint, credential=credential_search)
        fields = [
            SearchField(name = "parent_id", type=SearchFieldDataType.String, sortable=True, filterable=True, facetable=True),
            SearchField(name = "parsedDate", type=SearchFieldDataType.DateTimeOffset, sortable=True, filterable=True, facetable=True),
            SearchField(name = "title", type=SearchFieldDataType.String),
            SearchField(name = "chunk_id", type=SearchFieldDataType.String, key=True, sortable=True, filterable=True, facetable=True, analyzer_name = "keyword"),
            SearchField(name = "chunk", type=SearchFieldDataType.String, sortable=False, filterable=False, facetable=False),
            SearchField(name = "vector", type=SearchFieldDataType.Collection(SearchFieldDataType.Single), vector_search_dimensions=1536, vector_search_profile_name = "myHnswProfile"),
        ]

        vector_search = VectorSearch(  
    algorithms=[  
        HnswAlgorithmConfiguration(  
            name = "myHnsw",  
            parameters=HnswParameters(  
                m=4,  
                ef_construction=400,  
                ef_search=500,  
                metric=VectorSearchAlgorithmMetric.COSINE,  
            ),  
        ),  
        ExhaustiveKnnAlgorithmConfiguration(  
            name = "myExhaustiveKnn",  
            parameters=ExhaustiveKnnParameters(  
                metric=VectorSearchAlgorithmMetric.COSINE,  
            ),  
        ),  
    ],  
    profiles=[  
        VectorSearchProfile(  
            name = "myHnswProfile",  
            algorithm_configuration_name = "myHnsw",  
            vectorizer = "myOpenAI",  
        ),  
        VectorSearchProfile(  
            name = "myExhaustiveKnnProfile",  
            algorithm_configuration_name = "myExhaustiveKnn",  
            vectorizer = "myOpenAI",  
        ),  
    ],  
    vectorizers=[  
        AzureOpenAIVectorizer(  
            name = "myOpenAI",  
            kind = "azureOpenAI",  
            azure_open_ai_parameters=AzureOpenAIParameters(  
                resource_uri=endpoint_openai,  
                deployment_id=deployment_id,  
                api_key=credential_search,  
            ),  
        ),  
    ],  
)  
        semantic_search = SemanticSearch(configurations=[SemanticConfiguration(
            name = "my-semantic-config",
            prioritized_fields=SemanticPrioritizedFields(content_fields=[SemanticField(field_name = "chunk"),SemanticField(field_name = "title")] )
        )])

        index = SearchIndex(name=index_name, fields=fields, vector_search=vector_search, semantic_search=semantic_search)
        result = index_client.create_or_update_index(index)
        return func.HttpResponse(f"{result.name} created", status_code=200)
    except Exception as e:
        return func.HttpResponse(f"Failed to create or update the index. Error: {str(e)}", status_code=500)

И наконец, как я настроил индексатор:

Питон

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    
    # Environment Variables
    endpoint = os.environ["AZURE_SEARCH_SERVICE_ENDPOINT"]
    credential_search = AzureKeyCredential(os.environ["AZURE_SEARCH_ADMIN_KEY"])
    customer = readRequestBody(req)
    credential = DefaultAzureCredential()
    _, data_source_name= utils.getStorageAccountInfo(customer, credential)
    index_name = utils.get_index_name(data_source_name)
    skillset_name = utils.get_skillset_name(data_source_name)

    
    # Indexer creation logic
    try:
        indexer_name = f"{data_source_name}-indexer"
        indexer = SearchIndexer(
            name=indexer_name,
            description = "Indexer to index documents and generate embeddings",
            skillset_name=skillset_name,
            target_index_name=index_name,
            data_source_name=data_source_name,
            field_mappings=[FieldMapping(source_field_name = "metadata_storage_name", target_field_name = "title"),
                            FieldMapping(source_field_name = "parsedDate", target_field_name = "parsedDate")],
            parameters=IndexingParameters(
                configuration = {
                    "dataToExtract": "contentAndMetadata",
                    "imageAction": "generateNormalizedImages"
                }
            )
        )
        
        indexer_client = SearchIndexerClient(endpoint, credential_search)
        indexer_result = indexer_client.create_or_update_indexer(indexer)
        
        # Run the indexer
        indexer_client.run_indexer(indexer_name)
        message = f'{indexer_name} is created and running. If queries return no results, please wait a bit and try again.'
        logging.info(message)
        return func.HttpResponse(message, status_code=200)
    except Exception as e:
        error_message = f"Failed to create or run the indexer. Error: {str(e)}"
        logging.error(error_message)
        return func.HttpResponse(error_message, status_code=500)

Я также пробовал использовать out_field_mappings в индексаторе, но безуспешно.

Любое предложение было бы здорово.

Поиск Azure с использованием искусственного интеллекта

каков результат вашего пользовательского навыка веб-API. он должен вернуть дату, соответствующую типу данных DateTimeOffset, и необходимо добавить сопоставления в out_field_mappings

JayashankarGS 22.04.2024 08:40
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
1
191
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы получите значения null по следующим причинам:

  1. Неправильный outputFieldMappings в индексаторе, например несоответствие имени в выходных данных набора навыков targetName или sourceFieldName в определении индексатора.
  2. Пусто outputFieldMappings.
  3. Несоответствие между выходным именем в наборе навыков и значением данных из пользовательского веб-API.

Пример: Если в поле вывода parsedDate указано name и вы возвращаете данные, как в примере ниже, вы получите нулевое значение. Поле должно соответствовать выходному имени в наборе навыков.

{
  "values": [
    {
      "recordId": "0",
      "data": {
        "parsedate": "2015-01-01T00:00:00.000Z"
      }
    }
  ]
}

Затем используйте следующий код в своей функции Azure при возврате значений:

    req_body = req.get_json()
    values = req_body.get('values')
    res = []
    for i in values:
        tmp = i
        tmp['data'] = {'parsedDte': "parsed_date_from_path"}  # example: 2015-01-01T00:00:00.000Z
        res.append(tmp)
    if res:
        return func.HttpResponse(json.dumps({"values": res}), mimetype = "application/json")

Настройте outputFieldMappings:

"outputs": [
        {
          "name": "parsedDate",
          "targetName": "parsedDate"
        }]

Для приведенного выше вывода в наборе навыков вам необходимо указать outputFieldMappings следующим образом:

"outputFieldMappings": [
    {
      "sourceFieldName": "/document/parsedDate", # output of skillset
      "targetFieldName": "parsedDate" # Target index field name
    }
  ]

Или в коде:

indexer_name = f"vs-code-2-indexer"
indexer = SearchIndexer(
    name=indexer_name,
    description = "Indexer to index documents and generate embeddings",
    skillset_name = "skillset1712921532571",
    target_index_name = "vs-code-2",
    data_source_name = "hotels-sample",
    output_field_mappings=[FieldMapping(source_field_name = "/document/parsedDate", target_field_name = "parsedDate")]
)

Если приведенное выше решение не работает, удалите текущий индекс и создайте новый индекс с тем же определением. Затем перезагрузите и запустите индексатор, как указано выше outputFieldMappings.

Indexer Configuration

Другие вопросы по теме

Похожие вопросы

SSL-сертификат NGINX + Cloudflare недействителен
Мониторинг неактивных пользователей AzureAD
Получение списка планов Планировщика через Microsoft Graph — в сообщении об исключении говорится, что требуется недокументированный фильтр
Создайте субъект-службу Azure с помощью пакета SDK Python
Действия GitHub построены успешно, но веб-сайт не отражает изменения кода (проблема с развертыванием)
Как использовать управляемое удостоверение для подключения учетной записи хранения BLOB-объектов Azure и управления ACL контейнера с помощью пакета SDK Azure для Java
Зарегистрируйте фрейм данных Pandas в машинном обучении Azure: NOT_SUPPORTED_API_USE_ATTEMPT
Попытка получить ответ API от настройки ollama на виртуальной машине Azure (ubuntu)
Базовое тестовое приложение .NET 8 не работает в службе приложений
Политика доступа Azure Key Vault, разрешающая приложение логики (стандартно): «ресурс не найден»