Compartilhar via


Guia Rápido: Pesquisa Generativa (RAG) usando dados de base do Azure AI Search

Neste início rápido, você envia consultas para um modelo de conclusão de chat para uma experiência de pesquisa de conversa sobre seu conteúdo indexado na Pesquisa de IA do Azure. Depois de configurar os recursos do Azure OpenAI e do Azure AI Search no portal do Azure, você executa o código para chamar as APIs.

Pré-requisitos

Fazer download do arquivo

No GitHub, baixe um notebook do Jupyter para enviar as solicitações nesse início rápido. Para obter mais informações, consulte Baixando arquivos do GitHub.

Você também pode iniciar um novo arquivo em seu sistema local e criar solicitações manualmente usando as instruções nesse artigo.

Configurar o acesso

As solicitações para o ponto de extremidade de pesquisa precisam ser autenticadas e autorizadas. Você pode usar funções ou chaves de API para essa tarefa. É mais fácil usar as chaves para começar, mas as funções são mais seguras. Este início rápido assume funções.

Você está configurando dois clientes, portanto, precisa de permissões em ambos os recursos.

A Pesquisa de IA do Azure está recebendo a solicitação de consulta do sistema local. Atribua a si mesmo a atribuição de função Leitor de Dados do Índice de Pesquisa se o índice de exemplo de hotéis já existir. Se ele não existir, atribua a si mesmo as funções Colaborador do Serviço Pesquisa e Colaborador de Dados do Índice de Pesquisa para que você possa criar e consultar o índice.

O OpenAI do Azure está recebendo a consulta e os resultados da pesquisa do sistema local. Atribua a si mesmo a função de Usuário do OpenAI de Serviços Cognitivos no OpenAI do Azure.

  1. Entre no portal do Azure.

  2. Configurar a Pesquisa de IA do Azure para acesso baseado em função:

    1. No portal do Azure, localize o serviço de Pesquisa de IA do Azure.

    2. No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.

  3. Atribuir funções:

    1. No menu à esquerda, selecione Controle de acesso (IAM).

    2. Na Pesquisa de IA do Azure, selecione essas funções para criar, carregar e consultar um índice de pesquisa e, em seguida, atribuí-las à sua identidade de usuário do Microsoft Entra ID:

      • Colaborador de dados de índice de pesquisa
      • Colaborador do Serviço de Pesquisa
    3. No OpenAI do Azure, selecione IAM (controle de acesso) para atribuir essa função a si mesmo no OpenAI do Azure:

      • Usuário do OpenAI de Serviços Cognitivos

Pode demorar vários minutos para que as alterações entrem em vigor.

Crie um índice

Um índice de pesquisa fornece dados de base para o modelo de chat. Recomendamos o hotels-sample-index, que pode ser criado em minutos e é executado em qualquer camada de serviço de pesquisa. Esse índice é criado usando dados de exemplo internos.

  1. No portal do Azure, encontre seu serviço de pesquisa.

  2. Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.

  3. Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.

  4. Escolha o hotels-sample.

  5. Selecione Avançar nas páginas restantes, aceitando os valores padrão.

  6. Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.

  7. Selecione Editar JSON.

  8. Role até o final do índice, onde você pode encontrar espaços reservados para constructos que podem ser adicionados a um índice.

    "analyzers": [],
    "tokenizers": [],
    "tokenFilters": [],
    "charFilters": [],
    "normalizers": [],
    
  9. Em uma nova linha após "normalizadores", cole a seguinte configuração semântica. Este exemplo especifica um "defaultConfiguration", que é importante para a execução deste início rápido.

    "semantic":{
       "defaultConfiguration":"semantic-config",
       "configurations":[
          {
             "name":"semantic-config",
             "prioritizedFields":{
                "titleField":{
                   "fieldName":"HotelName"
                },
                "prioritizedContentFields":[
                   {
                      "fieldName":"Description"
                   }
                ],
                "prioritizedKeywordsFields":[
                   {
                      "fieldName":"Category"
                   },
                   {
                      "fieldName":"Tags"
                   }
                ]
             }
          }
       ]
    },
    
  10. Salve suas alterações.

  11. Execute a seguinte consulta no Gerenciador de Pesquisa para testar o seu índice: complimentary breakfast.

    A saída deve ser semelhante ao exemplo a seguir. Os resultados retornados diretamente do mecanismo de pesquisa consistem em campos e seus valores verbais, juntamente com metadados como uma pontuação de pesquisa e uma classificação semântica e legenda se você usar o classificador semântico. Usamos uma instrução select para retornar apenas os campos HotelName, Descrição e Rótulos.

    {
    "@odata.count": 18,
    "@search.answers": [],
    "value": [
       {
          "@search.score": 2.2896252,
          "@search.rerankerScore": 2.506816864013672,
          "@search.captions": [
          {
             "text": "Head Wind Resort. Suite. coffee in lobby\r\nfree wifi\r\nview. The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a **complimentary continental breakfast** in the lobby, and free Wi-Fi throughout the hotel..",
             "highlights": ""
          }
          ],
          "HotelName": "Head Wind Resort",
          "Description": "The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a complimentary continental breakfast in the lobby, and free Wi-Fi throughout the hotel.",
          "Tags": [
          "coffee in lobby",
          "free wifi",
          "view"
          ]
       },
       {
          "@search.score": 2.2158256,
          "@search.rerankerScore": 2.288334846496582,
          "@search.captions": [
          {
             "text": "Swan Bird Lake Inn. Budget. continental breakfast\r\nfree wifi\r\n24-hour front desk service. We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins..",
             "highlights": ""
          }
          ],
          "HotelName": "Swan Bird Lake Inn",
          "Description": "We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins.",
          "Tags": [
          "continental breakfast",
          "free wifi",
          "24-hour front desk service"
          ]
       },
       {
          "@search.score": 0.92481667,
          "@search.rerankerScore": 2.221315860748291,
          "@search.captions": [
          {
             "text": "White Mountain Lodge & Suites. Resort and Spa. continental breakfast\r\npool\r\nrestaurant. Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings..",
             "highlights": ""
          }
          ],
          "HotelName": "White Mountain Lodge & Suites",
          "Description": "Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings.",
          "Tags": [
          "continental breakfast",
          "pool",
          "restaurant"
          ]
       },
       . . .
    ]}
    

Obter pontos de extremidade de serviço

Nas seções restantes, você configurará chamadas de API para o OpenAI do Azure e para a Pesquisa de IA do Azure. Obtenha os pontos de extremidade de serviço para que você possa fornecê-los como variáveis em seu código.

  1. Entre no portal do Azure.

  2. Encontre o seu serviço de pesquisa.

  3. Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.search.windows.net.

  4. Localize o serviço OpenAI do Azure.

  5. Na página inicial Visão geral, selecione o link para exibir os pontos de extremidade. Copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.openai.azure.com/.

Criar um ambiente virtual

Nesta etapa, volte para seu sistema local e para o Visual Studio Code. Recomendamos que você crie um ambiente virtual para que possa instalar as dependências isoladamente.

  1. No Visual Studio Code, abra a pasta que contém Quickstart-RAG.ipynb.

  2. Pressione Ctrl-shift-P para abrir a paleta de comandos, pesquise "Python: Criar Ambiente" e selecione Venv para criar um ambiente virtual no workspace atual.

  3. Selecione Quickstart-RAG\requirements.txt para as dependências.

A criação do ambiente leva alguns minutos. Quando o ambiente estiver pronto, continue para a próxima etapa.

Entrar no Azure

Você está usando o Microsoft Entra ID e as atribuições de função para a conexão. Verifique se você está conectado ao mesmo locatário e assinatura da Pesquisa de IA do Azure e do OpenAI do Azure. Você pode usar a CLI do Azure na linha de comando para mostrar as propriedades atuais, alterar propriedades e entrar. Para obter mais informações, confira Conectar-se sem chaves.

Execute cada um dos comandos a seguir na sequência.

az account show

az account set --subscription <PUT YOUR SUBSCRIPTION ID HERE>

az login --tenant <PUT YOUR TENANT ID HERE>

Agora você deve estar conectado ao Azure em seu dispositivo local.

Configurar o thread de chat e a consulta

Esta seção usa o Visual Studio Code e o Python para chamar as APIs de conclusão de chat no OpenAI do Azure.

  1. Inicie o Visual Studio Code e abra o arquivo .ipynb ou crie um novo arquivo Python.

  2. Instale os seguintes pacotes do Python.

    ! pip install azure-search-documents==11.6.0b5 --quiet
    ! pip install azure-identity==1.16.1 --quiet
    ! pip install openai --quiet
    ! pip install aiohttp --quiet
    ! pip install ipykernel --quiet
    
  3. Defina as variáveis a seguir, substituindo espaços reservados pelos pontos de extremidade coletados na etapa anterior.

     AZURE_SEARCH_SERVICE: str = "PUT YOUR SEARCH SERVICE ENDPOINT HERE"
     AZURE_OPENAI_ACCOUNT: str = "PUT YOUR AZURE OPENAI ENDPOINT HERE"
     AZURE_DEPLOYMENT_MODEL: str = "gpt-4o"
    
  4. Configure clientes, o prompt, a consulta e a resposta.

    Ao usar a nuvem Azure Government, modifique o ponto de extremidade da API no provedor de token para "https://cognitiveservices.azure.us/.default".

    # Set up the query for generating responses
     from azure.identity import DefaultAzureCredential
     from azure.identity import get_bearer_token_provider
     from azure.search.documents import SearchClient
     from openai import AzureOpenAI
    
     credential = DefaultAzureCredential()
     token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
     openai_client = AzureOpenAI(
         api_version="2024-06-01",
         azure_endpoint=AZURE_OPENAI_ACCOUNT,
         azure_ad_token_provider=token_provider
     )
    
     search_client = SearchClient(
         endpoint=AZURE_SEARCH_SERVICE,
         index_name="hotels-sample-index",
         credential=credential
     )
    
     # This prompt provides instructions to the model
     GROUNDED_PROMPT="""
     You are a friendly assistant that recommends hotels based on activities and amenities.
     Answer the query using only the sources provided below in a friendly and concise bulleted manner.
     Answer ONLY with the facts listed in the list of sources below.
     If there isn't enough information below, say you don't know.
     Do not generate answers that don't use the sources below.
     Query: {query}
     Sources:\n{sources}
     """
    
     # Query is the question being asked. It's sent to the search engine and the chat model
     query="Can you recommend a few hotels with complimentary breakfast?"
    
     # Search results are created by the search client
     # Search results are composed of the top 5 results and the fields selected from the search index
     # Search results include the top 5 matches to your query
     search_results = search_client.search(
         search_text=query,
         top=5,
         select="Description,HotelName,Tags"
     )
     sources_formatted = "\n".join([f'{document["HotelName"]}:{document["Description"]}:{document["Tags"]}' for document in search_results])
    
     # Send the search results and the query to the LLM to generate a response based on the prompt.
     response = openai_client.chat.completions.create(
         messages=[
             {
                 "role": "user",
                 "content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
             }
         ],
         model=AZURE_DEPLOYMENT_MODEL
     )
    
     # Here is the response from the chat model.
     print(response.choices[0].message.content)
    

    A saída é do Azure OpenAI e consiste em recomendações para vários hotéis. Aqui está um exemplo de como a saída pode ser:

    Sure! Here are a few hotels that offer complimentary breakfast:
    
    - **Head Wind Resort**
    - Complimentary continental breakfast in the lobby
    - Free Wi-Fi throughout the hotel
    
    - **Double Sanctuary Resort**
    - Continental breakfast included
    
    - **White Mountain Lodge & Suites**
    - Continental breakfast available
    
    - **Swan Bird Lake Inn**
    - Continental-style breakfast each morning with a variety of food and drinks 
     such as caramel cinnamon rolls, coffee, orange juice, milk, cereal, 
     instant oatmeal, bagels, and muffins
    

    Se você receber uma mensagem de erro Proibido, verifique a configuração da Pesquisa de IA do Azure para verificar se o acesso baseado em função está habilitado.

    Se você receber uma mensagem de erro de Falha na autorização, aguarde alguns minutos e tente novamente. Pode levar vários minutos para que as atribuições de função se tornem operacionais.

    Se você receber uma mensagem de erro Recurso não encontrado, verifique os URIs do recurso e verifique se a versão da API no modelo de chat é válida.

    Caso contrário, para experimentar mais, altere a consulta e execute novamente a última etapa para entender melhor como o modelo funciona com os dados de fundamentação.

    Você também pode modificar o prompt para alterar o tom ou a estrutura da saída.

    Você também pode tentar a consulta sem classificação semântica definindo use_semantic_reranker=False na etapa de parâmetros de consulta. A classificação semântica pode melhorar a relevância dos resultados da consulta e a capacidade da LLM de retornar informações úteis. A experimentação pode ajudar você a decidir se isso faz diferença para o conteúdo.

Enviar uma consulta RAG complexa

A Pesquisa de IA do Azure dá suporte a tipos complexos para estruturas JSON aninhadas. No índice de amostra de hotéis, Address é um exemplo de um tipo complexo, consistindo em Address.StreetAddress, Address.City, Address.StateProvince, Address.PostalCode e Address.Country. O índice também tem uma coleção complexa de Rooms para cada hotel.

Se o seu índice tiver tipos complexos, sua consulta poderá fornecer esses campos se você primeiro converter a saída dos resultados da pesquisa para JSON e, em seguida, passar o JSON para o modelo de chat. O exemplo a seguir adiciona tipos complexos à solicitação. As instruções de formatação incluem uma especificação JSON.

import json

# Query is the question being asked. It's sent to the search engine and the LLM.
query="Can you recommend a few hotels that offer complimentary breakfast? 
Tell me their description, address, tags, and the rate for one room that sleeps 4 people."

# Set up the search results and the chat thread.
# Retrieve the selected fields from the search index related to the question.
selected_fields = ["HotelName","Description","Address","Rooms","Tags"]
search_results = search_client.search(
    search_text=query,
    top=5,
    select=selected_fields,
    query_type="semantic"
)
sources_filtered = [{field: result[field] for field in selected_fields} for result in search_results]
sources_formatted = "\n".join([json.dumps(source) for source in sources_filtered])

response = openai_client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
        }
    ],
    model=AZURE_DEPLOYMENT_MODEL
)

print(response.choices[0].message.content)

A saída é do OpenAI do Azure e adiciona conteúdo de tipos complexos.

Here are a few hotels that offer complimentary breakfast and have rooms that sleep 4 people:

1. **Head Wind Resort**
   - **Description:** The best of old town hospitality combined with views of the river and 
   cool breezes off the prairie. Enjoy a complimentary continental breakfast in the lobby, 
   and free Wi-Fi throughout the hotel.
   - **Address:** 7633 E 63rd Pl, Tulsa, OK 74133, USA
   - **Tags:** Coffee in lobby, free Wi-Fi, view
   - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99

2. **Double Sanctuary Resort**
   - **Description:** 5-star Luxury Hotel - Biggest Rooms in the city. #1 Hotel in the area 
   listed by Traveler magazine. Free WiFi, Flexible check in/out, Fitness Center & espresso 
   in room. Offers continental breakfast.
   - **Address:** 2211 Elliott Ave, Seattle, WA 98121, USA
   - **Tags:** View, pool, restaurant, bar, continental breakfast
   - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99

3. **Swan Bird Lake Inn**
   - **Description:** Continental-style breakfast featuring a variety of food and drinks. 
   Locally made caramel cinnamon rolls are a favorite.
   - **Address:** 1 Memorial Dr, Cambridge, MA 02142, USA
   - **Tags:** Continental breakfast, free Wi-Fi, 24-hour front desk service
   - **Room for 4:** Budget Room, 2 Queen Beds (City View) - $85.99

4. **Gastronomic Landscape Hotel**
   - **Description:** Known for its culinary excellence under the management of William Dough, 
   offers continental breakfast.
   - **Address:** 3393 Peachtree Rd, Atlanta, GA 30326, USA
   - **Tags:** Restaurant, bar, continental breakfast
   - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $66.99
...
   - **Tags:** Pool, continental breakfast, free parking
   - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $60.99

Enjoy your stay! Let me know if you need any more information.

Solução de problemas

Para depurar erros de autenticação, insira o código a seguir antes da etapa que chama o mecanismo de pesquisa e o LLM.

import sys
import logging # Set the logging level for all azure-storage-* libraries
logger = logging.getLogger('azure.identity') 
logger.setLevel(logging.DEBUG)

handler = logging.StreamHandler(stream=sys.stdout)
formatter = logging.Formatter('[%(levelname)s %(name)s] %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

Execute novamente o script de consulta. Agora você deve obter instruções INFO e DEBUG na saída que fornecem mais detalhes sobre o problema.

Se você vir mensagens de saída relacionadas a falhas de aquisição de token e ManagedIdentityCredential, pode ser que você tenha vários locatários e sua entrada no Azure esteja usando um locatário que não tenha seu serviço de pesquisa. Para obter sua ID de locatário, pesquise “propriedades de locatário” no portal do Azure. ou execute az login tenant list.

Assim que você tiver a sua ID de locatário, execute az login --tenant <YOUR-TENANT-ID> em um prompt de comando e execute novamente o script.

Limpar

Quando você está trabalhando em sua própria assinatura, é uma boa ideia identificar, no final de um projeto, se você ainda precisa dos recursos criados. Recursos deixados em execução podem custar dinheiro. É possível excluir os recursos individualmente ou excluir o grupo de recursos para excluir todo o conjunto de recursos.

Você pode encontrar e gerenciar recursos no portal do Azure usando o link Todos os recursos ou Grupos de recursos no painel de navegação à esquerda.

Pré-requisitos

Configurar o acesso

As solicitações para o ponto de extremidade de pesquisa precisam ser autenticadas e autorizadas. Você pode usar funções ou chaves de API para essa tarefa. É mais fácil usar as chaves para começar, mas as funções são mais seguras. Este início rápido assume funções.

Você está configurando dois clientes, portanto, precisa de permissões em ambos os recursos.

A Pesquisa de IA do Azure está recebendo a solicitação de consulta do sistema local. Atribua a si mesmo a atribuição de função Leitor de Dados do Índice de Pesquisa se o índice de exemplo de hotéis já existir. Se ele não existir, atribua a si mesmo as funções Colaborador do Serviço Pesquisa e Colaborador de Dados do Índice de Pesquisa para que você possa criar e consultar o índice.

O OpenAI do Azure está recebendo a consulta e os resultados da pesquisa do sistema local. Atribua a si mesmo a função de Usuário do OpenAI de Serviços Cognitivos no OpenAI do Azure.

  1. Entre no portal do Azure.

  2. Configurar a Pesquisa de IA do Azure para acesso baseado em função:

    1. No portal do Azure, localize o serviço de Pesquisa de IA do Azure.

    2. No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.

  3. Atribuir funções:

    1. No menu à esquerda, selecione Controle de acesso (IAM).

    2. Na Pesquisa de IA do Azure, selecione essas funções para criar, carregar e consultar um índice de pesquisa e, em seguida, atribuí-las à sua identidade de usuário do Microsoft Entra ID:

      • Colaborador de dados de índice de pesquisa
      • Colaborador do Serviço de Pesquisa
    3. No OpenAI do Azure, selecione IAM (controle de acesso) para atribuir essa função a si mesmo no OpenAI do Azure:

      • Usuário do OpenAI de Serviços Cognitivos

Pode demorar vários minutos para que as alterações entrem em vigor.

Crie um índice

Um índice de pesquisa fornece dados de base para o modelo de chat. Recomendamos o hotels-sample-index, que pode ser criado em minutos e é executado em qualquer camada de serviço de pesquisa. Esse índice é criado usando dados de exemplo internos.

  1. No portal do Azure, encontre seu serviço de pesquisa.

  2. Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.

  3. Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.

  4. Escolha o hotels-sample.

  5. Selecione Avançar nas páginas restantes, aceitando os valores padrão.

  6. Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.

  7. Selecione Editar JSON.

  8. Role até o final do índice, onde você pode encontrar espaços reservados para constructos que podem ser adicionados a um índice.

    "analyzers": [],
    "tokenizers": [],
    "tokenFilters": [],
    "charFilters": [],
    "normalizers": [],
    
  9. Em uma nova linha após "normalizadores", cole a seguinte configuração semântica. Este exemplo especifica um "defaultConfiguration", que é importante para a execução deste início rápido.

    "semantic":{
       "defaultConfiguration":"semantic-config",
       "configurations":[
          {
             "name":"semantic-config",
             "prioritizedFields":{
                "titleField":{
                   "fieldName":"HotelName"
                },
                "prioritizedContentFields":[
                   {
                      "fieldName":"Description"
                   }
                ],
                "prioritizedKeywordsFields":[
                   {
                      "fieldName":"Category"
                   },
                   {
                      "fieldName":"Tags"
                   }
                ]
             }
          }
       ]
    },
    
  10. Salve suas alterações.

  11. Execute a seguinte consulta no Gerenciador de Pesquisa para testar o seu índice: complimentary breakfast.

    A saída deve ser semelhante ao exemplo a seguir. Os resultados retornados diretamente do mecanismo de pesquisa consistem em campos e seus valores verbais, juntamente com metadados como uma pontuação de pesquisa e uma classificação semântica e legenda se você usar o classificador semântico. Usamos uma instrução select para retornar apenas os campos HotelName, Descrição e Rótulos.

    {
    "@odata.count": 18,
    "@search.answers": [],
    "value": [
       {
          "@search.score": 2.2896252,
          "@search.rerankerScore": 2.506816864013672,
          "@search.captions": [
          {
             "text": "Head Wind Resort. Suite. coffee in lobby\r\nfree wifi\r\nview. The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a **complimentary continental breakfast** in the lobby, and free Wi-Fi throughout the hotel..",
             "highlights": ""
          }
          ],
          "HotelName": "Head Wind Resort",
          "Description": "The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a complimentary continental breakfast in the lobby, and free Wi-Fi throughout the hotel.",
          "Tags": [
          "coffee in lobby",
          "free wifi",
          "view"
          ]
       },
       {
          "@search.score": 2.2158256,
          "@search.rerankerScore": 2.288334846496582,
          "@search.captions": [
          {
             "text": "Swan Bird Lake Inn. Budget. continental breakfast\r\nfree wifi\r\n24-hour front desk service. We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins..",
             "highlights": ""
          }
          ],
          "HotelName": "Swan Bird Lake Inn",
          "Description": "We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins.",
          "Tags": [
          "continental breakfast",
          "free wifi",
          "24-hour front desk service"
          ]
       },
       {
          "@search.score": 0.92481667,
          "@search.rerankerScore": 2.221315860748291,
          "@search.captions": [
          {
             "text": "White Mountain Lodge & Suites. Resort and Spa. continental breakfast\r\npool\r\nrestaurant. Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings..",
             "highlights": ""
          }
          ],
          "HotelName": "White Mountain Lodge & Suites",
          "Description": "Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings.",
          "Tags": [
          "continental breakfast",
          "pool",
          "restaurant"
          ]
       },
       . . .
    ]}
    

Obter pontos de extremidade de serviço

Nas seções restantes, você configurará chamadas de API para o OpenAI do Azure e para a Pesquisa de IA do Azure. Obtenha os pontos de extremidade de serviço para que você possa fornecê-los como variáveis em seu código.

  1. Entre no portal do Azure.

  2. Encontre o seu serviço de pesquisa.

  3. Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.search.windows.net.

  4. Localize o serviço OpenAI do Azure.

  5. Na página inicial Visão geral, selecione o link para exibir os pontos de extremidade. Copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.openai.azure.com/.

Configurar variáveis de ambiente para desenvolvimento local

  1. Crie um .env ficheiro.

  2. Adicione as seguintes variáveis de ambiente ao arquivo .env, substituindo os valores por seus próprios pontos de extremidade de serviço e chaves.

    AZURE_SEARCH_ENDPOINT=<YOUR AZURE AI SEARCH ENDPOINT>
    AZURE_SEARCH_INDEX_NAME=hotels-sample-index
    
    AZURE_OPENAI_ENDPOINT=<YOUR AZURE OPENAI ENDPOINT>
    AZURE_OPENAI_VERSION=<YOUR AZURE OPENAI API VERSION>
    AZURE_DEPLOYMENT_MODEL=<YOUR DEPLOYMENT NAME>
    

Configurar o projeto de Node.JS

Configure o projeto com o Visual Studio Code e o TypeScript.

  1. Inicie o Visual Studio Code em um novo diretório.

    mkdir rag-quickstart && cd rag-quickstart
    code .
    
  2. Crie um novo pacote para módulos ESM no diretório do projeto.

    npm init -y
    npm pkg set type=module
    

    Isso cria um package.json arquivo com valores padrão.

  3. Instale os seguintes pacotes npm.

    npm install @azure/identity @azure/search-documents openai dotenv @types/node
    
  4. Crie um src diretório no diretório do projeto.

    mkdir src
    
  5. Crie um tsconfig.json arquivo no diretório do projeto para ESM com o conteúdo a seguir.

    {
      "compilerOptions": {
        "target": "esnext",
        "module": "NodeNext",
        "moduleResolution": "nodenext",
        "rootDir": "./src",
        "outDir": "./dist/",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true,
        "declaration": true,
        "sourceMap": true,
        "resolveJsonModule": true,
        "moduleDetection": "force", // Add this for ESM
        "allowSyntheticDefaultImports": true // Helpful for ESM interop
      },
      "include": [
        "src/**/*.ts"
      ]
    }
    

Entrar no Azure

Você está usando o Microsoft Entra ID e as atribuições de função para a conexão. Verifique se você está conectado ao mesmo locatário e assinatura da Pesquisa de IA do Azure e do OpenAI do Azure. Você pode usar a CLI do Azure na linha de comando para mostrar as propriedades atuais, alterar propriedades e entrar. Para obter mais informações, confira Conectar-se sem chaves.

Execute cada um dos comandos a seguir na sequência.

az account show

az account set --subscription <PUT YOUR SUBSCRIPTION ID HERE>

az login --tenant <PUT YOUR TENANT ID HERE>

Agora você deve estar conectado ao Azure em seu dispositivo local.

Configurar a consulta e o thread de chat

Crie um script de consulta que use o índice do Azure AI Search e o modelo de conversação para gerar respostas com base nos dados de referência. As etapas a seguir orientam você na configuração do script de consulta.

  1. Crie um query.ts arquivo no src diretório com o código a seguir.

    // This is a RAG (Retrieval Augmented Generation) implementation that:
    // 1. Takes a user query about hotels
    // 2. Searches a hotel database using Azure AI Search
    // 3. Formats the search results for the LLM
    // 4. Sends the query and formatted results to Azure OpenAI
    // 5. Returns a grounded response based only on the retrieved information
    
    import { SearchClient, AzureKeyCredential, SearchDocumentsResult } from "@azure/search-documents";
    import { AzureOpenAI } from "openai";
    import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
    
    function getClients(): { openaiClient: AzureOpenAI, searchClient: SearchClient<{ HotelName: string; Description: string; Tags: string[] | string }>, modelName: string }  {
    
        const credential = new DefaultAzureCredential();
    
        // Search
        const azureSearchEndpoint = process.env.AZURE_SEARCH_ENDPOINT!;
        const azureSearchIndexName = process.env.AZURE_SEARCH_INDEX_NAME!;
    
        const searchClient = new SearchClient<{ HotelName: string; Description: string; Tags: string[] | string }>(
            azureSearchEndpoint,
            azureSearchIndexName,
            credential
        );
    
    
        // OpenAI
        const azureOpenAiEndpoint = process.env.AZURE_OPENAI_ENDPOINT!;
        const azureOpenAiApiVersion = process.env.AZURE_OPENAI_VERSION!;
        const azureOpenAiDeploymentName = process.env.AZURE_DEPLOYMENT_MODEL!;
    
        const scope = "https://cognitiveservices.azure.com/.default";
        const azureADTokenProvider = getBearerTokenProvider(credential, scope);
        const options = { azureADTokenProvider, deployment: azureOpenAiDeploymentName, apiVersion: azureOpenAiApiVersion, endpoint: azureOpenAiEndpoint }
        const openaiClient = new AzureOpenAI(options);
    
        return { openaiClient, searchClient, modelName: azureOpenAiDeploymentName };
    }
    
    async function queryAISearchForSources(searchClient: SearchClient<{ HotelName: string; Description: string; Tags: string[] | string }>, query: string): Promise<string> {
        console.log(`Searching for: "${query}"\n`);
        const searchResults: SearchDocumentsResult<{ HotelName: string; Description: string; Tags: string[] | string }> = await searchClient.search(query, {
            top: 5,
            select: ["Description", "HotelName", "Tags"]
        });
    
        const sources: string[] = [];
        for await (const result of searchResults.results) {
            const doc = result.document;
            sources.push(
                `Hotel: ${doc.HotelName}\n` +
                `Description: ${doc.Description}\n` +
                `Tags: ${Array.isArray(doc.Tags) ? doc.Tags.join(', ') : doc.Tags}\n`
            );
        }
        const sourcesFormatted = sources.join("\n---\n");
        return sourcesFormatted;
    }
    async function queryOpenAIForResponse(
        openaiClient: AzureOpenAI, 
        query: string, 
        sourcesFormatted: string, 
        modelName: string
    ): Promise<{ choices: { message: { content: string | null } }[] }> {
    
        const GROUNDED_PROMPT = `
     You are a friendly assistant that recommends hotels based on activities and amenities.
     Answer the query using only the sources provided below in a friendly and concise bulleted manner.
     Answer ONLY with the facts listed in the list of sources below.
     If there isn't enough information below, say you don't know.
     Do not generate answers that don't use the sources below.
    
    Query: {query}
    Sources: {sources}
    `;
    
        return openaiClient.chat.completions.create({
            model: modelName,
            messages: [
                {
                    role: "user",
                    content: GROUNDED_PROMPT.replace("{query}", query).replace("{sources}", sourcesFormatted),
                }
            ],
            temperature: 0.7,
            max_tokens: 800,
        });
    }
    
    async function main():Promise<void> {
    
        const { openaiClient, searchClient, modelName } = getClients();
    
        const query = "Can you recommend a few hotels with complimentary breakfast?";
    
        const sources = await queryAISearchForSources(searchClient, query);
        const response = await queryOpenAIForResponse(openaiClient, query, sources, modelName);
    
        // Print the response from the chat model
        const content = response.choices[0].message.content;
        if (content) {
            console.log(content);
        } else {
            console.log("No content available in the response.");
        }
    }
    
    main().catch((error) => {
        console.error("An error occurred:", error);
        process.exit(1);
    });
    

    O código anterior faz o seguinte:

    • Importa as bibliotecas necessárias para o Azure AI Search e o Azure OpenAI.
    • Usa variáveis de ambiente para configurar os clientes do Azure AI Search e do Azure OpenAI.
    • Define uma função para obter os clientes do Azure AI Search e do Azure OpenAI, usando variáveis de ambiente para configuração.
    • Define uma função para consultar fontes do Azure AI Search com base na consulta de usuário.
    • Define uma função para consultar o Azure OpenAI para obter uma resposta com base na consulta de usuário e nas fontes recuperadas do Azure AI Search.
    • A main função orquestra o fluxo chamando as funções de pesquisa e OpenAI e, em seguida, imprime a resposta.
  2. Compile o código TypeScript para JavaScript.

    tsc
    

    Esse comando compila o código TypeScript no src diretório e gera os arquivos JavaScript no dist diretório.

  3. Execute o seguinte comando em um terminal para executar o script de consulta:

    node -r dotenv/config dist/query.js
    

    O .env é passado para o runtime usando o -r dotenv/config.

  4. Exibir a saída consiste em recomendações para vários hotéis. Aqui está um exemplo de como a saída pode ser:

    Sure! Here are a few hotels that offer complimentary breakfast:
    
    - **Head Wind Resort**
    - Complimentary continental breakfast in the lobby
    - Free Wi-Fi throughout the hotel
    
    - **Double Sanctuary Resort**
    - Continental breakfast included
    
    - **White Mountain Lodge & Suites**
    - Continental breakfast available
    
    - **Swan Bird Lake Inn**
    - Continental-style breakfast each morning with a variety of food and drinks 
        such as caramel cinnamon rolls, coffee, orange juice, milk, cereal, 
        instant oatmeal, bagels, and muffins
    

Resolução de problemas

Se você receber uma mensagem de erro Proibido, verifique a configuração da Pesquisa de IA do Azure para verificar se o acesso baseado em função está habilitado.

Se você receber uma mensagem de erro de Falha na autorização, aguarde alguns minutos e tente novamente. Pode levar vários minutos para que as atribuições de função se tornem operacionais.

Se você receber uma mensagem de erro Recurso não encontrado, verifique os URIs do recurso e verifique se a versão da API no modelo de chat é válida.

Caso contrário, para experimentar mais, altere a consulta e execute novamente a última etapa para entender melhor como o modelo funciona com os dados de fundamentação.

Você também pode modificar o prompt para alterar o tom ou a estrutura da saída.

Você também pode tentar a consulta sem classificação semântica definindo use_semantic_reranker=False na etapa de parâmetros de consulta. A classificação semântica pode melhorar a relevância dos resultados da consulta e a capacidade da LLM de retornar informações úteis. A experimentação pode ajudar você a decidir se isso faz diferença para o conteúdo.

Enviar uma consulta RAG complexa

A Pesquisa de IA do Azure dá suporte a tipos complexos para estruturas JSON aninhadas. No índice de amostra de hotéis, Address é um exemplo de um tipo complexo, consistindo em Address.StreetAddress, Address.City, Address.StateProvince, Address.PostalCode e Address.Country. O índice também tem uma coleção complexa de Rooms para cada hotel.

Se o índice tiver tipos complexos, altere o prompt para incluir instruções de formatação:

Can you recommend a few hotels that offer complimentary breakfast? 
Tell me their description, address, tags, and the rate for one room that sleeps 4 people.
  1. Crie um novo arquivo queryComplex.ts no src diretório.

  2. Copie o seguinte código para o arquivo:

    // This is a RAG (Retrieval Augmented Generation) implementation that:
    // 1. Takes a user query about hotels
    // 2. Searches a hotel database using Azure AI Search
    // 3. Formats the search results for the LLM
    // 4. Sends the query and formatted results to Azure OpenAI
    // 5. Returns a grounded response based only on the retrieved information
    
    import { SearchClient, SearchDocumentsResult } from "@azure/search-documents";
    import { AzureOpenAI } from "openai";
    import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
    
    function getClients(): { openaiClient: AzureOpenAI; searchClient: SearchClient<{ HotelName: string; Description: string; Tags: string[] | string; Address: string; Rooms: string }>; modelName: string }  {
    
        const credential = new DefaultAzureCredential();
    
        // Search
        const azureSearchEndpoint = process.env.AZURE_SEARCH_ENDPOINT!;
        const azureSearchIndexName = process.env.AZURE_SEARCH_INDEX_NAME!;
        const searchClient = new SearchClient<{ HotelName: string; Description: string; Tags: string[] | string; Address: string; Rooms: string }>(
            azureSearchEndpoint,
            azureSearchIndexName,
            credential
        );
    
        // OpenAI
        const azureOpenAiEndpoint = process.env.AZURE_OPENAI_ENDPOINT!;
        const azureOpenAiApiVersion = process.env.AZURE_OPENAI_VERSION!;
        const azureOpenAiDeploymentName = process.env.AZURE_DEPLOYMENT_MODEL!;
    
        const scope = "https://cognitiveservices.azure.com/.default";
        const azureADTokenProvider = getBearerTokenProvider(credential, scope);
        const options = { azureADTokenProvider, deployment: azureOpenAiDeploymentName, apiVersion: azureOpenAiApiVersion, endpoint: azureOpenAiEndpoint }
        const openaiClient = new AzureOpenAI(options);
    
        return { openaiClient, searchClient, modelName: azureOpenAiDeploymentName };
    }
    
    
    async function queryAISearchForSources(
        searchClient: SearchClient<{ HotelName: string; Description: string; Tags: string[] | string; Address: string; Rooms: string }>,
        query: string
    ): Promise<SearchDocumentsResult<{ HotelName: string; Description: string; Tags: string[] | string; Address: string; Rooms: string }>> {
        console.log(`Searching for: "${query}"\n`);
    
        const selectedFields: readonly ["HotelName", "Description", "Address", "Rooms", "Tags"] = ["HotelName", "Description", "Address", "Rooms", "Tags"];
        const searchResults = await searchClient.search(query, {
            top: 5,
            select: selectedFields,
            queryType: "semantic",
            semanticSearchOptions: {},
        });
    
        return searchResults;
    }
    async function queryOpenAIForResponse(
        openaiClient: AzureOpenAI, 
        query: string, 
        sourcesFormatted: string, 
        modelName: string
    ): Promise<{ choices: { message: { content: string | null } }[] }> {
    
        const GROUNDED_PROMPT = `
     You are a friendly assistant that recommends hotels based on activities and amenities.
     Answer the query using only the sources provided below in a friendly and concise bulleted manner.
     Answer ONLY with the facts listed in the list of sources below.
     If there isn't enough information below, say you don't know.
     Do not generate answers that don't use the sources below.
    
    Query: {query}
    Sources: {sources}
    `;
    
        return openaiClient.chat.completions.create({
            model: modelName,
            messages: [
                {
                    role: "user",
                    content: GROUNDED_PROMPT.replace("{query}", query).replace("{sources}", sourcesFormatted),
                }
            ],
            temperature: 0.7,
            max_tokens: 800,
        });
    }
    
    async function main(): Promise<void> {
    
        const { openaiClient, searchClient, modelName } = getClients();
    
        const query = `
        Can you recommend a few hotels that offer complimentary breakfast? 
        Tell me their description, address, tags, and the rate for one room that sleeps 4 people.
        `;
    
        const sourcesResult = await queryAISearchForSources(searchClient, query);
        let sourcesFormatted = "";
    
        for await (const result of sourcesResult.results) {
            // Explicitly typing result to ensure compatibility
            sourcesFormatted += JSON.stringify(result.document) + "\n";
        }
    
        const response = await queryOpenAIForResponse(openaiClient, query, sourcesFormatted.trim(), modelName);
    
        // Print the response from the chat model
        const content = response.choices[0].message.content;
        if (content) {
            console.log(content);
        } else {
            console.log("No content available in the response.");
        }
    }
    
    main().catch((error) => {
        console.error("An error occurred:", error);
        process.exit(1);
    });
    
  3. Compile o código TypeScript para JavaScript.

    tsc
    

    Esse comando compila o código TypeScript no src diretório e gera os arquivos JavaScript no dist diretório.

  4. Execute o seguinte comando em um terminal para executar o script de consulta:

    node -r dotenv/config dist/queryComplex.js
    

    O .env é passado para o runtime usando o -r dotenv/config.

  5. Exiba a saída do OpenAI do Azure, e conteúdo de tipos complexos é adicionado.

Here are a few hotels that offer complimentary breakfast and have rooms that sleep 4 people:

1. **Head Wind Resort**
   - **Description:** The best of old town hospitality combined with views of the river and 
   cool breezes off the prairie. Enjoy a complimentary continental breakfast in the lobby, 
   and free Wi-Fi throughout the hotel.
   - **Address:** 7633 E 63rd Pl, Tulsa, OK 74133, USA
   - **Tags:** Coffee in lobby, free Wi-Fi, view
   - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99

2. **Double Sanctuary Resort**
   - **Description:** 5-star Luxury Hotel - Biggest Rooms in the city. #1 Hotel in the area 
   listed by Traveler magazine. Free WiFi, Flexible check in/out, Fitness Center & espresso 
   in room. Offers continental breakfast.
   - **Address:** 2211 Elliott Ave, Seattle, WA 98121, USA
   - **Tags:** View, pool, restaurant, bar, continental breakfast
   - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99

3. **Swan Bird Lake Inn**
   - **Description:** Continental-style breakfast featuring a variety of food and drinks. 
   Locally made caramel cinnamon rolls are a favorite.
   - **Address:** 1 Memorial Dr, Cambridge, MA 02142, USA
   - **Tags:** Continental breakfast, free Wi-Fi, 24-hour front desk service
   - **Room for 4:** Budget Room, 2 Queen Beds (City View) - $85.99

4. **Gastronomic Landscape Hotel**
   - **Description:** Known for its culinary excellence under the management of William Dough, 
   offers continental breakfast.
   - **Address:** 3393 Peachtree Rd, Atlanta, GA 30326, USA
   - **Tags:** Restaurant, bar, continental breakfast
   - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $66.99
...
   - **Tags:** Pool, continental breakfast, free parking
   - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $60.99

Enjoy your stay! Let me know if you need any more information.

Solução de problemas

Para depurar erros do SDK do Azure, defina a variável AZURE_LOG_LEVEL de ambiente como uma das seguintes: verbose, , info, warning. error Isso habilitará o registro em log detalhado para o SDK do Azure, o que pode ajudar a identificar problemas com autenticação, conectividade de rede ou outros problemas.

Execute novamente o script de consulta. Agora você deve obter instruções informativas dos SDKs na saída que fornecem mais detalhes sobre quaisquer problemas.

Se você vir mensagens de saída relacionadas a falhas de aquisição de token e ManagedIdentityCredential, pode ser que você tenha vários locatários e sua entrada no Azure esteja usando um locatário que não tenha seu serviço de pesquisa. Para obter sua ID de locatário, pesquise “propriedades de locatário” no portal do Azure. ou execute az login tenant list.

Assim que você tiver a sua ID de locatário, execute az login --tenant <YOUR-TENANT-ID> em um prompt de comando e execute novamente o script.

Limpar

Quando você está trabalhando em sua própria assinatura, é uma boa ideia identificar, no final de um projeto, se você ainda precisa dos recursos criados. Recursos deixados em execução podem custar dinheiro. É possível excluir os recursos individualmente ou excluir o grupo de recursos para excluir todo o conjunto de recursos.

Você pode encontrar e gerenciar recursos no portal do Azure usando o link Todos os recursos ou Grupos de recursos no painel de navegação à esquerda.

Pré-requisitos

Configurar o acesso

As solicitações para o ponto de extremidade de pesquisa precisam ser autenticadas e autorizadas. Você pode usar funções ou chaves de API para essa tarefa. É mais fácil usar as chaves para começar, mas as funções são mais seguras. Este início rápido assume funções.

Você está configurando dois clientes, portanto, precisa de permissões em ambos os recursos.

A Pesquisa de IA do Azure está recebendo a solicitação de consulta do sistema local. Atribua a si mesmo a atribuição de função Leitor de Dados do Índice de Pesquisa se o índice de exemplo de hotéis já existir. Se ele não existir, atribua a si mesmo as funções Colaborador do Serviço Pesquisa e Colaborador de Dados do Índice de Pesquisa para que você possa criar e consultar o índice.

O OpenAI do Azure está recebendo a consulta e os resultados da pesquisa do sistema local. Atribua a si mesmo a função de Usuário do OpenAI de Serviços Cognitivos no OpenAI do Azure.

  1. Entre no portal do Azure.

  2. Configurar a Pesquisa de IA do Azure para acesso baseado em função:

    1. No portal do Azure, localize o serviço de Pesquisa de IA do Azure.

    2. No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.

  3. Atribuir funções:

    1. No menu à esquerda, selecione Controle de acesso (IAM).

    2. Na Pesquisa de IA do Azure, selecione essas funções para criar, carregar e consultar um índice de pesquisa e, em seguida, atribuí-las à sua identidade de usuário do Microsoft Entra ID:

      • Colaborador de dados de índice de pesquisa
      • Colaborador do Serviço de Pesquisa
    3. No OpenAI do Azure, selecione IAM (controle de acesso) para atribuir essa função a si mesmo no OpenAI do Azure:

      • Usuário do OpenAI de Serviços Cognitivos

Pode demorar vários minutos para que as alterações entrem em vigor.

Crie um índice

Um índice de pesquisa fornece dados de base para o modelo de chat. Recomendamos o hotels-sample-index, que pode ser criado em minutos e é executado em qualquer camada de serviço de pesquisa. Esse índice é criado usando dados de exemplo internos.

  1. No portal do Azure, encontre seu serviço de pesquisa.

  2. Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.

  3. Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.

  4. Escolha o hotels-sample.

  5. Selecione Avançar nas páginas restantes, aceitando os valores padrão.

  6. Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.

  7. Selecione Editar JSON.

  8. Role até o final do índice, onde você pode encontrar espaços reservados para constructos que podem ser adicionados a um índice.

    "analyzers": [],
    "tokenizers": [],
    "tokenFilters": [],
    "charFilters": [],
    "normalizers": [],
    
  9. Em uma nova linha após "normalizadores", cole a seguinte configuração semântica. Este exemplo especifica um "defaultConfiguration", que é importante para a execução deste início rápido.

    "semantic":{
       "defaultConfiguration":"semantic-config",
       "configurations":[
          {
             "name":"semantic-config",
             "prioritizedFields":{
                "titleField":{
                   "fieldName":"HotelName"
                },
                "prioritizedContentFields":[
                   {
                      "fieldName":"Description"
                   }
                ],
                "prioritizedKeywordsFields":[
                   {
                      "fieldName":"Category"
                   },
                   {
                      "fieldName":"Tags"
                   }
                ]
             }
          }
       ]
    },
    
  10. Salve suas alterações.

  11. Execute a seguinte consulta no Gerenciador de Pesquisa para testar o seu índice: complimentary breakfast.

    A saída deve ser semelhante ao exemplo a seguir. Os resultados retornados diretamente do mecanismo de pesquisa consistem em campos e seus valores verbais, juntamente com metadados como uma pontuação de pesquisa e uma classificação semântica e legenda se você usar o classificador semântico. Usamos uma instrução select para retornar apenas os campos HotelName, Descrição e Rótulos.

    {
    "@odata.count": 18,
    "@search.answers": [],
    "value": [
       {
          "@search.score": 2.2896252,
          "@search.rerankerScore": 2.506816864013672,
          "@search.captions": [
          {
             "text": "Head Wind Resort. Suite. coffee in lobby\r\nfree wifi\r\nview. The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a **complimentary continental breakfast** in the lobby, and free Wi-Fi throughout the hotel..",
             "highlights": ""
          }
          ],
          "HotelName": "Head Wind Resort",
          "Description": "The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a complimentary continental breakfast in the lobby, and free Wi-Fi throughout the hotel.",
          "Tags": [
          "coffee in lobby",
          "free wifi",
          "view"
          ]
       },
       {
          "@search.score": 2.2158256,
          "@search.rerankerScore": 2.288334846496582,
          "@search.captions": [
          {
             "text": "Swan Bird Lake Inn. Budget. continental breakfast\r\nfree wifi\r\n24-hour front desk service. We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins..",
             "highlights": ""
          }
          ],
          "HotelName": "Swan Bird Lake Inn",
          "Description": "We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins.",
          "Tags": [
          "continental breakfast",
          "free wifi",
          "24-hour front desk service"
          ]
       },
       {
          "@search.score": 0.92481667,
          "@search.rerankerScore": 2.221315860748291,
          "@search.captions": [
          {
             "text": "White Mountain Lodge & Suites. Resort and Spa. continental breakfast\r\npool\r\nrestaurant. Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings..",
             "highlights": ""
          }
          ],
          "HotelName": "White Mountain Lodge & Suites",
          "Description": "Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings.",
          "Tags": [
          "continental breakfast",
          "pool",
          "restaurant"
          ]
       },
       . . .
    ]}
    

Obter pontos de extremidade de serviço

Nas seções restantes, você configurará chamadas de API para o OpenAI do Azure e para a Pesquisa de IA do Azure. Obtenha os pontos de extremidade de serviço para que você possa fornecê-los como variáveis em seu código.

  1. Entre no portal do Azure.

  2. Encontre o seu serviço de pesquisa.

  3. Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.search.windows.net.

  4. Localize o serviço OpenAI do Azure.

  5. Na página inicial Visão geral, selecione o link para exibir os pontos de extremidade. Copie a URL. Um ponto de extremidade de exemplo pode parecer com https://example.openai.azure.com/.

Configurar variáveis de ambiente para desenvolvimento local

  1. Crie um .env ficheiro.

  2. Adicione as seguintes variáveis de ambiente ao arquivo .env, substituindo os valores por seus próprios endereços de serviço e chaves.

    AZURE_SEARCH_ENDPOINT=<YOUR AZURE AI SEARCH ENDPOINT>
    AZURE_SEARCH_INDEX_NAME=hotels-sample-index
    
    AZURE_OPENAI_ENDPOINT=<YOUR AZURE OPENAI ENDPOINT>
    AZURE_OPENAI_VERSION=<YOUR AZURE OPENAI API VERSION>
    AZURE_DEPLOYMENT_MODEL=<YOUR DEPLOYMENT NAME>
    

Configurar o projeto de Node.JS

Configure o projeto com o Visual Studio Code e o TypeScript.

  1. Inicie o Visual Studio Code em um novo diretório.

    mkdir rag-quickstart && cd rag-quickstart
    code .
    
  2. Crie um novo pacote para módulos ESM no diretório do projeto.

    npm init -y
    npm pkg set type=module
    

    Isso cria um package.json arquivo com valores padrão.

  3. Instale os seguintes pacotes npm.

    npm install @azure/identity @azure/search-documents openai dotenv 
    
  4. Crie um src diretório no diretório do projeto.

    mkdir src
    

Entrar no Azure

Você está usando o Microsoft Entra ID e as atribuições de função para a conexão. Verifique se você está conectado ao mesmo locatário e assinatura da Pesquisa de IA do Azure e do OpenAI do Azure. Você pode usar a CLI do Azure na linha de comando para mostrar as propriedades atuais, alterar propriedades e entrar. Para obter mais informações, confira Conectar-se sem chaves.

Execute cada um dos comandos a seguir na sequência.

az account show

az account set --subscription <PUT YOUR SUBSCRIPTION ID HERE>

az login --tenant <PUT YOUR TENANT ID HERE>

Agora você deve estar conectado ao Azure em seu dispositivo local.

Configurar a consulta e o thread de chat

Crie um script de consulta que use o índice do Azure AI Search e o modelo de chat para gerar respostas com base nos dados de base. As etapas a seguir orientam você na configuração do script de consulta.

  1. Crie um query.js arquivo no src diretório com o código a seguir.

    // This is a RAG (Retrieval Augmented Generation) implementation that:
    // 1. Takes a user query about hotels
    // 2. Searches a hotel database using Azure AI Search
    // 3. Formats the search results for the LLM
    // 4. Sends the query and formatted results to Azure OpenAI
    // 5. Returns a grounded response based only on the retrieved information
    
    import { SearchClient } from "@azure/search-documents";
    import { AzureOpenAI } from "openai";
    import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
    
    function getClients() {
    
        const credential = new DefaultAzureCredential();
    
        // Search
        const azureSearchEndpoint = process.env.AZURE_SEARCH_ENDPOINT;
        const azureSearchIndexName = process.env.AZURE_SEARCH_INDEX_NAME;
    
        const searchClient = new SearchClient(
            azureSearchEndpoint,
            azureSearchIndexName,
            credential
        );
    
    
        // OpenAI
        const azureOpenAiEndpoint = process.env.AZURE_OPENAI_ENDPOINT;
        const azureOpenAiApiVersion = process.env.AZURE_OPENAI_VERSION;
        const azureOpenAiDeploymentName = process.env.AZURE_DEPLOYMENT_MODEL;
    
        const scope = "https://cognitiveservices.azure.com/.default";
        const azureADTokenProvider = getBearerTokenProvider(credential, scope);
        const options = { azureADTokenProvider, deployment: azureOpenAiDeploymentName, apiVersion: azureOpenAiApiVersion, endpoint: azureOpenAiEndpoint }
        const openaiClient = new AzureOpenAI(options);
    
        return { openaiClient, searchClient, modelName: azureOpenAiDeploymentName };
    }
    
    async function queryAISearchForSources(searchClient, query) {
        console.log(`Searching for: "${query}"\n`);
        const searchResults = await searchClient.search(query, {
            top: 5,
            select: ["Description", "HotelName", "Tags"]
        });
    
        const sources = [];
        for await (const result of searchResults.results) {
            const doc = result.document;
            sources.push(
                `Hotel: ${doc.HotelName}\n` +
                `Description: ${doc.Description}\n` +
                `Tags: ${Array.isArray(doc.Tags) ? doc.Tags.join(', ') : doc.Tags}\n`
            );
        }
        const sourcesFormatted = sources.join("\n---\n");
        return sourcesFormatted;
    }
    async function queryOpenAIForResponse(openaiClient, query, sourcesFormatted, modelName) {
    
        const GROUNDED_PROMPT = `
     You are a friendly assistant that recommends hotels based on activities and amenities.
     Answer the query using only the sources provided below in a friendly and concise bulleted manner.
     Answer ONLY with the facts listed in the list of sources below.
     If there isn't enough information below, say you don't know.
     Do not generate answers that don't use the sources below.
    
    Query: {query}
    Sources: {sources}
    `;
    
        return openaiClient.chat.completions.create({
            model: modelName,
            messages: [
                {
                    role: "user",
                    content: GROUNDED_PROMPT.replace("{query}", query).replace("{sources}", sourcesFormatted),
                }
            ],
            temperature: 0.7,
            max_tokens: 800,
        });
    }
    
    async function main() {
    
        const { openaiClient, searchClient, modelName } = getClients();
    
        const query = "Can you recommend a few hotels with complimentary breakfast?";
    
        const sources = await queryAISearchForSources(searchClient, query);
        const response = await queryOpenAIForResponse(openaiClient, query, sources, modelName);
    
        // Print the response from the chat model
        const content = response.choices[0].message.content;
        if (content) {
            console.log(content);
        } else {
            console.log("No content available in the response.");
        }
    }
    
    main().catch((error) => {
        console.error("An error occurred:", error);
        process.exit(1);
    });
    

    O código anterior faz o seguinte:

    • Importa as bibliotecas necessárias para o Azure AI Search e o Azure OpenAI.
    • Usa variáveis de ambiente para configurar os clientes do Azure AI Search e do Azure OpenAI.
    • Define uma função para obter os clientes do Azure AI Search e do Azure OpenAI, usando variáveis de ambiente para configuração.
    • Define uma função para consultar fontes do Azure AI Search com base na consulta de usuário.
    • Define uma função para consultar o Azure OpenAI para obter uma resposta com base na consulta de usuário e nas fontes recuperadas do Azure AI Search.
    • A main função orquestra o fluxo chamando as funções de pesquisa e OpenAI e, em seguida, imprime a resposta.
  2. Execute o seguinte comando em um terminal para executar o script de consulta:

    node -r dotenv/config query.js
    

    O .env é passado para o runtime usando o -r dotenv/config.

  3. Exiba a saída, que consiste em recomendações para vários hotéis. Aqui está um exemplo de como a saída pode ser:

    Sure! Here are a few hotels that offer complimentary breakfast:
    
    - **Head Wind Resort**
    - Complimentary continental breakfast in the lobby
    - Free Wi-Fi throughout the hotel
    
    - **Double Sanctuary Resort**
    - Continental breakfast included
    
    - **White Mountain Lodge & Suites**
    - Continental breakfast available
    
    - **Swan Bird Lake Inn**
    - Continental-style breakfast each morning with a variety of food and drinks 
        such as caramel cinnamon rolls, coffee, orange juice, milk, cereal, 
        instant oatmeal, bagels, and muffins
    

Resolução de problemas

Se você receber uma mensagem de erro Proibido, verifique a configuração da Pesquisa de IA do Azure para verificar se o acesso baseado em função está habilitado.

Se você receber uma mensagem de erro de Falha na autorização, aguarde alguns minutos e tente novamente. Pode levar vários minutos para que as atribuições de função se tornem operacionais.

Se você receber uma mensagem de erro Recurso não encontrado, verifique os URIs do recurso e verifique se a versão da API no modelo de chat é válida.

Caso contrário, para experimentar mais, altere a consulta e execute novamente a última etapa para entender melhor como o modelo funciona com os dados de fundamentação.

Você também pode modificar o prompt para alterar o tom ou a estrutura da saída.

Você também pode tentar a consulta sem classificação semântica definindo use_semantic_reranker=False na etapa de parâmetros de consulta. A classificação semântica pode melhorar a relevância dos resultados da consulta e a capacidade da LLM de retornar informações úteis. A experimentação pode ajudar você a decidir se isso faz diferença para o conteúdo.

Enviar uma consulta RAG complexa

A Pesquisa de IA do Azure dá suporte a tipos complexos para estruturas JSON aninhadas. No índice de amostra de hotéis, Address é um exemplo de um tipo complexo, consistindo em Address.StreetAddress, Address.City, Address.StateProvince, Address.PostalCode e Address.Country. O índice também tem uma coleção complexa de Rooms para cada hotel.

Se o índice tiver tipos complexos, altere o prompt para incluir instruções de formatação:

Can you recommend a few hotels that offer complimentary breakfast? 
Tell me their description, address, tags, and the rate for one room that sleeps 4 people.
  1. Criar um novo arquivo queryComplex.js.

  2. Copie o seguinte código para o arquivo:

    // This is a RAG (Retrieval Augmented Generation) implementation that:
    // 1. Takes a user query about hotels
    // 2. Searches a hotel database using Azure AI Search
    // 3. Formats the search results for the LLM
    // 4. Sends the query and formatted results to Azure OpenAI
    // 5. Returns a grounded response based only on the retrieved information
    
    import { SearchClient } from "@azure/search-documents";
    import { AzureOpenAI } from "openai";
    import { DefaultAzureCredential, getBearerTokenProvider } from "@azure/identity";
    
    function getClients() {
    
        const credential = new DefaultAzureCredential();
    
        // Search
        const azureSearchEndpoint = process.env.AZURE_SEARCH_ENDPOINT;
        const azureSearchIndexName = process.env.AZURE_SEARCH_INDEX_NAME;
    
        const searchClient = new SearchClient(
            azureSearchEndpoint,
            azureSearchIndexName,
            credential
        );
    
    
        // OpenAI
        const azureOpenAiEndpoint = process.env.AZURE_OPENAI_ENDPOINT;
        const azureOpenAiApiVersion = process.env.AZURE_OPENAI_VERSION;
        const azureOpenAiDeploymentName = process.env.AZURE_DEPLOYMENT_MODEL;
    
        const scope = "https://cognitiveservices.azure.com/.default";
        const azureADTokenProvider = getBearerTokenProvider(credential, scope);
        const options = { azureADTokenProvider, deployment: azureOpenAiDeploymentName, apiVersion: azureOpenAiApiVersion, endpoint: azureOpenAiEndpoint }
        const openaiClient = new AzureOpenAI(options);
    
        return { openaiClient, searchClient, modelName: azureOpenAiDeploymentName };
    }
    
    async function queryAISearchForSources(
        searchClient,
        query
    ) {
        console.log(`Searching for: "${query}"\n`);
    
        const selectedFields = ["HotelName", "Description", "Address", "Rooms", "Tags"];
        const searchResults = await searchClient.search(query, {
            top: 5,
            select: selectedFields,
            queryType: "semantic",
            semanticSearchOptions: {},
        });
    
        return searchResults;
    }
    async function queryOpenAIForResponse(
        openaiClient, 
        query, 
        sourcesFormatted, 
        modelName
    ){
    
        const GROUNDED_PROMPT = `
     You are a friendly assistant that recommends hotels based on activities and amenities.
     Answer the query using only the sources provided below in a friendly and concise bulleted manner.
     Answer ONLY with the facts listed in the list of sources below.
     If there isn't enough information below, say you don't know.
     Do not generate answers that don't use the sources below.
    
    Query: {query}
    Sources: {sources}
    `;
    
        return openaiClient.chat.completions.create({
            model: modelName,
            messages: [
                {
                    role: "user",
                    content: GROUNDED_PROMPT.replace("{query}", query).replace("{sources}", sourcesFormatted),
                }
            ],
            temperature: 0.7,
            max_tokens: 800,
        });
    }
    
    async function main() {
    
        const { openaiClient, searchClient, modelName } = getClients();
    
        const query = `
        Can you recommend a few hotels that offer complimentary breakfast? 
        Tell me their description, address, tags, and the rate for one room that sleeps 4 people.
        `;
    
        const sourcesResult = await queryAISearchForSources(searchClient, query);
        let sourcesFormatted = "";
    
        for await (const result of sourcesResult.results) {
            // Explicitly typing result to ensure compatibility
            sourcesFormatted += JSON.stringify(result.document) + "\n";
        }
    
        const response = await queryOpenAIForResponse(openaiClient, query, sourcesFormatted.trim(), modelName);
    
        // Print the response from the chat model
        const content = response.choices[0].message.content;
        if (content) {
            console.log(content);
        } else {
            console.log("No content available in the response.");
        }
    }
    
    main().catch((error) => {
        console.error("An error occurred:", error);
        process.exit(1);
    });
    
  3. Execute o seguinte comando em um terminal para executar o script de consulta:

    node -r dotenv/config queryComplex.js
    

    O .env é passado para o runtime usando o -r dotenv/config.

  4. Exiba a saída do OpenAI do Azure, e conteúdo de tipos complexos é adicionado.

    Here are a few hotels that offer complimentary breakfast and have rooms that sleep 4 people:
    
    1. **Head Wind Resort**
       - **Description:** The best of old town hospitality combined with views of the river and 
       cool breezes off the prairie. Enjoy a complimentary continental breakfast in the lobby, 
       and free Wi-Fi throughout the hotel.
       - **Address:** 7633 E 63rd Pl, Tulsa, OK 74133, USA
       - **Tags:** Coffee in lobby, free Wi-Fi, view
       - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99
    
    2. **Double Sanctuary Resort**
       - **Description:** 5-star Luxury Hotel - Biggest Rooms in the city. #1 Hotel in the area 
       listed by Traveler magazine. Free WiFi, Flexible check in/out, Fitness Center & espresso 
       in room. Offers continental breakfast.
       - **Address:** 2211 Elliott Ave, Seattle, WA 98121, USA
       - **Tags:** View, pool, restaurant, bar, continental breakfast
       - **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99
    
    3. **Swan Bird Lake Inn**
       - **Description:** Continental-style breakfast featuring a variety of food and drinks. 
       Locally made caramel cinnamon rolls are a favorite.
       - **Address:** 1 Memorial Dr, Cambridge, MA 02142, USA
       - **Tags:** Continental breakfast, free Wi-Fi, 24-hour front desk service
       - **Room for 4:** Budget Room, 2 Queen Beds (City View) - $85.99
    
    4. **Gastronomic Landscape Hotel**
       - **Description:** Known for its culinary excellence under the management of William Dough, 
       offers continental breakfast.
       - **Address:** 3393 Peachtree Rd, Atlanta, GA 30326, USA
       - **Tags:** Restaurant, bar, continental breakfast
       - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $66.99
    ...
       - **Tags:** Pool, continental breakfast, free parking
       - **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $60.99
    
    Enjoy your stay! Let me know if you need any more information.
    

Solução de problemas

Para depurar erros do SDK do Azure, defina a variável AZURE_LOG_LEVEL de ambiente como uma das seguintes: verbose, , info, warning. error Isso habilitará o registro em log detalhado para o SDK do Azure, o que pode ajudar a identificar problemas com autenticação, conectividade de rede ou outros problemas.

Execute novamente o script de consulta. Agora você deve obter declarações informativas dos SDKs na saída que fornecem mais detalhes em relação a quaisquer problemas.

Se você vir mensagens de saída relacionadas a falhas de aquisição de token e ManagedIdentityCredential, pode ser que você tenha vários locatários e sua entrada no Azure esteja usando um locatário que não tenha seu serviço de pesquisa. Para obter sua ID de locatário, pesquise “propriedades de locatário” no portal do Azure. ou execute az login tenant list.

Assim que você tiver a sua ID de locatário, execute az login --tenant <YOUR-TENANT-ID> em um prompt de comando e execute novamente o script.

Limpar

Quando você está trabalhando em sua própria assinatura, é uma boa ideia identificar, no final de um projeto, se você ainda precisa dos recursos criados. Recursos deixados em execução podem custar dinheiro. É possível excluir os recursos individualmente ou excluir o grupo de recursos para excluir todo o conjunto de recursos.

Você pode encontrar e gerenciar recursos no portal do Azure usando o link Todos os recursos ou Grupos de recursos no painel de navegação à esquerda.