Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
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
Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
-
- Escolha uma região que dê suporte ao modelo de conclusão de chat que você deseja usar (gpt-4o, gpt-4o-mini ou um modelo equivalente).
- Implante o modelo de conclusão de chat na Fábrica de IA do Azure ou use outra abordagem.
Um recurso do Azure AI Search.
- É recomendável usar a camada Básica ou superior.
- Habilite a classificação semântica.
Visual Studio Code com a extensão do Python e o pacote do Jupyter. Para mais informações, Python no Visual Studio Code.
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.
Entre no portal do Azure.
Configurar a Pesquisa de IA do Azure para acesso baseado em função:
No portal do Azure, localize o serviço de Pesquisa de IA do Azure.
No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.
Atribuir funções:
No menu à esquerda, selecione Controle de acesso (IAM).
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
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.
No portal do Azure, encontre seu serviço de pesquisa.
Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.
Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.
Escolha o hotels-sample.
Selecione Avançar nas páginas restantes, aceitando os valores padrão.
Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.
Selecione Editar JSON.
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": [],
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" } ] } } ] },
Salve suas alterações.
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.
Entre no portal do Azure.
Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com
https://example.search.windows.net
.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.
No Visual Studio Code, abra a pasta que contém Quickstart-RAG.ipynb.
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.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.
Inicie o Visual Studio Code e abra o arquivo .ipynb ou crie um novo arquivo Python.
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
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"
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
Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
-
- Escolha uma região que dê suporte ao modelo de conclusão de chat que você deseja usar (gpt-4o, gpt-4o-mini ou um modelo equivalente).
- Implante o modelo de conclusão de chat na Fábrica de IA do Azure ou use outra abordagem.
Um recurso do Azure AI Search.
- É recomendável usar a camada Básica ou superior.
- Habilite a classificação semântica.
TypeScript. Você pode instalar o TypeScript globalmente usando o npm:
npm install -g typescript
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.
Entre no portal do Azure.
Configurar a Pesquisa de IA do Azure para acesso baseado em função:
No portal do Azure, localize o serviço de Pesquisa de IA do Azure.
No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.
Atribuir funções:
No menu à esquerda, selecione Controle de acesso (IAM).
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
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.
No portal do Azure, encontre seu serviço de pesquisa.
Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.
Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.
Escolha o hotels-sample.
Selecione Avançar nas páginas restantes, aceitando os valores padrão.
Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.
Selecione Editar JSON.
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": [],
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" } ] } } ] },
Salve suas alterações.
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.
Entre no portal do Azure.
Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com
https://example.search.windows.net
.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
Crie um
.env
ficheiro.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.
Inicie o Visual Studio Code em um novo diretório.
mkdir rag-quickstart && cd rag-quickstart code .
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.Instale os seguintes pacotes npm.
npm install @azure/identity @azure/search-documents openai dotenv @types/node
Crie um
src
diretório no diretório do projeto.mkdir src
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.
Crie um
query.ts
arquivo nosrc
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.
Compile o código TypeScript para JavaScript.
tsc
Esse comando compila o código TypeScript no
src
diretório e gera os arquivos JavaScript nodist
diretório.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
.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.
Crie um novo arquivo
queryComplex.ts
nosrc
diretório.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); });
Compile o código TypeScript para JavaScript.
tsc
Esse comando compila o código TypeScript no
src
diretório e gera os arquivos JavaScript nodist
diretório.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
.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
Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
-
- Escolha uma região que dê suporte ao modelo de conclusão de chat que você deseja usar (gpt-4o, gpt-4o-mini ou um modelo equivalente).
- Implante o modelo de conclusão de chat na Fábrica de IA do Azure ou use outra abordagem.
Um recurso do Azure AI Search.
- É recomendável usar a camada Básica ou superior.
- Habilite a classificação semântica.
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.
Entre no portal do Azure.
Configurar a Pesquisa de IA do Azure para acesso baseado em função:
No portal do Azure, localize o serviço de Pesquisa de IA do Azure.
No menu à esquerda, selecione Configurações>Chaves e selecione Controle de acesso baseado em função ou Ambos.
Atribuir funções:
No menu à esquerda, selecione Controle de acesso (IAM).
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
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.
No portal do Azure, encontre seu serviço de pesquisa.
Na página inicial Visão geral, selecione Importar dados para iniciar o assistente.
Na página Conectar aos seus dados, selecione Exemplos na lista suspensa.
Escolha o hotels-sample.
Selecione Avançar nas páginas restantes, aceitando os valores padrão.
Depois que o índice for criado, selecione Gerenciamento de Pesquisa>Índices no menu à esquerda para abrir o índice.
Selecione Editar JSON.
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": [],
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" } ] } } ] },
Salve suas alterações.
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.
Entre no portal do Azure.
Na página inicial Visão Geral, copie a URL. Um ponto de extremidade de exemplo pode parecer com
https://example.search.windows.net
.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
Crie um
.env
ficheiro.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.
Inicie o Visual Studio Code em um novo diretório.
mkdir rag-quickstart && cd rag-quickstart code .
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.Instale os seguintes pacotes npm.
npm install @azure/identity @azure/search-documents openai dotenv
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.
Crie um
query.js
arquivo nosrc
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.
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
.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.
Criar um novo arquivo
queryComplex.js
.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); });
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
.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.