name | description | languages | products | page_type | urlFragment | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ChatGPT + Enterprise data |
Chat with your data using OpenAI and Cognitive Search. |
|
|
sample |
azure-search-openai-demo |
- Features
- Azure account requirements
- Azure deployment
- Sharing environments
- Enabling optional features
- Using the app
- Running locally
- Productionizing
- Resources
This sample demonstrates a few approaches for creating ChatGPT-like experiences over your own data using the Retrieval Augmented Generation pattern. It uses Azure OpenAI Service to access the ChatGPT model (gpt-35-turbo), and Azure Cognitive Search for data indexing and retrieval.
The repo includes sample data so it's ready to try end to end. In this sample application we use a fictitious company called Contoso Electronics, and the experience allows its employees to ask questions about the benefits, internal policies, as well as job descriptions and roles.
- Chat and Q&A interfaces
- Explores various options to help users evaluate the trustworthiness of responses with citations, tracking of source content, etc.
- Shows possible approaches for data preparation, prompt construction, and orchestration of interaction between model (ChatGPT) and retriever (Cognitive Search)
- Settings directly in the UX to tweak the behavior and experiment with options
- Optional performance tracing and monitoring with Application Insights
IMPORTANT: In order to deploy and run this example, you'll need:
- Azure account. If you're new to Azure, get an Azure account for free and you'll get some free Azure credits to get started.
- Azure subscription with access enabled for the Azure OpenAI service. You can request access with this form. If your access request to Azure OpenAI service doesn't match the acceptance criteria, you can use OpenAI public API instead. Learn how to switch to an OpenAI instance.
- Azure account permissions:
- Your Azure account must have
Microsoft.Authorization/roleAssignments/write
permissions, such as Role Based Access Control Administrator, User Access Administrator, or Owner. If you don't have subscription-level permissions, you must be granted RBAC for an existing resource group and deploy to that existing group. - Your Azure account also needs
Microsoft.Resources/deployments/write
permissions on the subscription level.
- Your Azure account must have
Pricing varies per region and usage, so it isn't possible to predict exact costs for your usage. However, you can try the Azure pricing calculator for the resources below.
- Azure App Service: Basic Tier with 1 CPU core, 1.75 GB RAM. Pricing per hour. Pricing
- Azure OpenAI: Standard tier, ChatGPT and Ada models. Pricing per 1K tokens used, and at least 1K tokens are used per question. Pricing
- Form Recognizer: SO (Standard) tier using pre-built layout. Pricing per document page, sample documents have 261 pages total. Pricing
- Azure Cognitive Search: Standard tier, 1 replica, free level of semantic search. Pricing per hour.Pricing
- Azure Blob Storage: Standard tier with ZRS (Zone-redundant storage). Pricing per storage and read operations. Pricing
- Azure Monitor: Pay-as-you-go tier. Costs based on data ingested. Pricing
To reduce costs, you can switch to free SKUs for Azure App Service and Form Recognizer by changing the parameters file under the infra
folder. There are some limits to consider; for example, the free Form Recognizer resource only analyzes the first 2 pages of each document. You can also reduce costs associated with the Form Recognizer by reducing the number of documents in the data
folder, or by removing the postprovision hook in azure.yaml
that runs the prepdocs.py
script.
azd down
.
You have a few options for setting up this project. The easiest way to get started is GitHub Codespaces, since it will setup all the tools for you, but you can also set it up locally if desired.
You can run this repo virtually by using GitHub Codespaces, which will open a web-based VS Code in your browser:
A related option is VS Code Dev Containers, which will open the project in your local VS Code using the Dev Containers extension:
- Start Docker Desktop (install it if not already installed)
- Open the project:
- In the VS Code window that opens, once the project files show up (this may take several minutes), open a terminal window
- Run
azd auth login
- Now you can follow the instructions in Deploying from scratch below
First install the required tools:
- Azure Developer CLI
- Python 3.9, 3.10, or 3.11
- Important: Python and the pip package manager must be in the path in Windows for the setup scripts to work.
- Important: Ensure you can run
python --version
from console. On Ubuntu, you might need to runsudo apt install python-is-python3
to linkpython
topython3
.
- Node.js 14+
- Git
- Powershell 7+ (pwsh) - For Windows users only.
- Important: Ensure you can run
pwsh.exe
from a PowerShell terminal. If this fails, you likely need to upgrade PowerShell.
- Important: Ensure you can run
Then bring down the project code:
- Create a new folder and switch to it in the terminal
- Run
azd auth login
- Run
azd init -t azure-search-openai-demo
- note that this command will initialize a git repository and you do not need to clone this repository
Execute the following command, if you don't have any pre-existing Azure services and want to start from a fresh deployment.
- Run
azd up
- This will provision Azure resources and deploy this sample to those resources, including building the search index based on the files found in the./data
folder.- Important: Beware that the resources created by this command will incur immediate costs, primarily from the Cognitive Search resource. These resources may accrue costs even if you interrupt the command before it is fully executed. You can run
azd down
or delete the resources manually to avoid unnecessary spending. - You will be prompted to select two locations, one for the majority of resources and one for the OpenAI resource, which is currently a short list. That location list is based on the OpenAI model availability table and may become outdated as availability changes.
- Important: Beware that the resources created by this command will incur immediate costs, primarily from the Cognitive Search resource. These resources may accrue costs even if you interrupt the command before it is fully executed. You can run
- After the application has been successfully deployed you will see a URL printed to the console. Click that URL to interact with the application in your browser. It will look like the following:
NOTE: It may take 5-10 minutes for the application to be fully deployed. If you see a "Python Developer" welcome screen or an error page, then wait a bit and refresh the page.
If you already have existing Azure resources, you can re-use those by setting azd
environment values.
- Run
azd env set AZURE_RESOURCE_GROUP {Name of existing resource group}
- Run
azd env set AZURE_LOCATION {Location of existing resource group}
- Run
azd env set AZURE_OPENAI_SERVICE {Name of existing OpenAI service}
- Run
azd env set AZURE_OPENAI_RESOURCE_GROUP {Name of existing resource group that OpenAI service is provisioned to}
- Run
azd env set AZURE_OPENAI_CHATGPT_DEPLOYMENT {Name of existing ChatGPT deployment}
. Only needed if your ChatGPT deployment is not the default 'chat'. - Run
azd env set AZURE_OPENAI_EMB_DEPLOYMENT {Name of existing GPT embedding deployment}
. Only needed if your embeddings deployment is not the default 'embedding'.
When you run azd up
after and are prompted to select a value for openAiResourceGroupLocation
, make sure to select the same location as the existing OpenAI resource group.
- Run
azd env set OPENAI_HOST openai
- Run
azd env set OPENAI_ORGANIZATION {Your OpenAI organization}
- Run
azd env set OPENAI_API_KEY {Your OpenAI API key}
- Run
azd up
You can retrieve your OpenAI key by checking your user page and your organization by navigating to your organization page. Learn more about creating an OpenAI free trial at this link. Do not check your key into source control.
When you run azd up
after and are prompted to select a value for openAiResourceGroupLocation
, you can select any location as it will not be used.
- Run
azd env set AZURE_SEARCH_SERVICE {Name of existing Azure Cognitive Search service}
- Run
azd env set AZURE_SEARCH_SERVICE_RESOURCE_GROUP {Name of existing resource group with ACS service}
- If that resource group is in a different location than the one you'll pick for the
azd up
step, then runazd env set AZURE_SEARCH_SERVICE_LOCATION {Location of existing service}
- If the search service's SKU is not standard, then run
azd env set AZURE_SEARCH_SERVICE_SKU {Name of SKU}
. The free tier won't work as it doesn't support managed identity. (See other possible values) - If you have an existing index that is set up with all the expected fields, then run
azd env set AZURE_SEARCH_INDEX {Name of existing index}
. Otherwise, theazd up
command will create a new index.
You can also customize the search service (new or existing) for non-English searches:
- To configure the language of the search query to a value other than "en-us", run
azd env set AZURE_SEARCH_QUERY_LANGUAGE {Name of query language}
. (See other possible values) - To turn off the spell checker, run
azd env set AZURE_SEARCH_QUERY_SPELLER none
. (See other possible values) - To configure the name of the analyzer to use for a searchable text field to a value other than "en.microsoft", run
azd env set AZURE_SEARCH_ANALYZER_NAME {Name of analyzer name}
. (See other possible values)
You can also use existing Form Recognizer and Storage Accounts. See ./infra/main.parameters.json
for list of environment variables to pass to azd env set
to configure those existing resources.
Now you can run azd up
, following the steps in Deploying from scratch above.
That will both provision resources and deploy the code.
If you've only changed the backend/frontend code in the app
folder, then you don't need to re-provision the Azure resources. You can just run:
azd deploy
If you've changed the infrastructure files (infra
folder or azure.yaml
), then you'll need to re-provision the Azure resources. You can do that by running:
azd up
To give someone else access to a completely deployed and existing environment, either you or they can follow these steps:
- Install the Azure CLI
- Run
azd init -t azure-search-openai-demo
or clone this repository. - Run
azd env refresh -e {environment name}
They will need the azd environment name, subscription ID, and location to run this command. You can find those values in your.azure/{env name}/.env
file. This will populate their azd environment's.env
file with all the settings needed to run the app locally. - Set the environment variable
AZURE_PRINCIPAL_ID
either in that.env
file or in the active shell to their Azure ID, which they can get withaz ad signed-in-user show
. - Run
./scripts/roles.ps1
or.scripts/roles.sh
to assign all of the necessary roles to the user. If they do not have the necessary permission to create roles in the subscription, then you may need to run this script for them. Once the script runs, they should be able to run the app locally.
To enable Application Insights and the tracing of each request, along with the logging of errors, set the AZURE_USE_APPLICATION_INSIGHTS
variable to true before running azd up
- Run
azd env set AZURE_USE_APPLICATION_INSIGHTS true
- Run
azd up
To see the performance data, go to the Application Insights resource in your resource group, click on the "Investigate -> Performance" blade and navigate to any HTTP request to see the timing data. To inspect the performance of chat requests, use the "Drill into Samples" button to see end-to-end traces of all the API calls made for any chat request:
To see any exceptions and server errors, navigate to the "Investigate -> Failures" blade and use the filtering tools to locate a specific exception. You can see Python stack traces on the right-hand side.
By default, the deployed Azure web app will have no authentication or access restrictions enabled, meaning anyone with routable network access to the web app can chat with your indexed data. You can require authentication to your Azure Active Directory by following the Add app authentication tutorial and set it up against the deployed web app.
To then limit access to a specific set of users or groups, you can follow the steps from Restrict your Azure AD app to a set of users by changing "Assignment Required?" option under the Enterprise Application, and then assigning users/groups access. Users not granted explicit access will receive the error message -AADSTS50105: Your administrator has configured the application <app_name> to block users unless they are specifically granted ('assigned') access to the application.-
By default, the deployed Azure web app allows users to chat with all your indexed data. You can enable an optional login system using Azure Active Directory to restrict access to indexed data based on the logged in user. Enable the optional login and document level access control system by following this guide.
By default, the deployed Azure web app will only allow requests from the same origin. To enable CORS for a frontend hosted on a different origin, run:
- Run
azd env set ALLOWED_ORIGIN https://<your-domain.com>
- Run
azd up
For the frontend code, change BACKEND_URI
in api.ts
to point at the deployed backend URL, so that all fetch requests will be sent to the deployed backend.
For an alternate frontend that's written in Web Components and deployed to Static Web Apps, check out azure-search-openai-javascript and its guide on using a different backend.
You can only run locally after having successfully run the azd up
command. If you haven't yet, follow the steps in Azure deployment above.
- Run
azd auth login
- Change dir to
app
- Run
./start.ps1
or./start.sh
or run the "VS Code Task: Start App" to start the project locally.
- In Azure: navigate to the Azure WebApp deployed by azd. The URL is printed out when azd completes (as "Endpoint"), or you can find it in the Azure portal.
- Running locally: navigate to 127.0.0.1:50505
Once in the web app:
- Try different topics in chat or Q&A context. For chat, try follow up questions, clarifications, ask to simplify or elaborate on answer, etc.
- Explore citations and sources
- Click on "settings" to try different options, tweak prompts, etc.
Once you successfully deploy the app, you can start customizing it for your needs: changing the text, tweaking the prompts, and replacing the data. Consult the app customization guide as well as the data ingestion guide for more details.
This sample is designed to be a starting point for your own production application, but you should do a thorough review of the security and performance before deploying to production. Read through our productionizing guide for more details.
- Revolutionize your Enterprise Data with ChatGPT: Next-gen Apps w/ Azure OpenAI and Cognitive Search
- Azure Cognitive Search
- Azure OpenAI Service
- Comparing Azure OpenAI and OpenAI
To clean up all the resources created by this sample:
- Run
azd down
- When asked if you are sure you want to continue, enter
y
- When asked if you want to permanently delete the resources, enter
y
The resource group and all the resources will be deleted.
Note: The PDF documents used in this demo contain information generated using a language model (Azure OpenAI Service). The information contained in these documents is only for demonstration purposes and does not reflect the opinions or beliefs of Microsoft. Microsoft makes no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the information contained in this document. All rights reserved to Microsoft.
How does this sample compare to other Chat with Your Data samples?
Another popular repository for this use case is here: https://github.com/Microsoft/sample-app-aoai-chatGPT/
That repository is designed for use by customers using Azure OpenAI studio and Azure Portal for setup. It also includes azd
support for folks who want to deploy it completely from scratch.
The primary differences:
- This repository includes multiple RAG (retrieval-augmented generation) approaches that chain the results of multiple API calls (to Azure OpenAI and ACS) together in different ways. The other repository uses only the built-in data sources option for the ChatCompletions API, which uses a RAG approach on the specified ACS index. That should work for most uses, but if you needed more flexibility, this sample may be a better option.
- This repository is also a bit more experimental in other ways, since it's not tied to the Azure OpenAI Studio like the other repository.
Feature comparison:
Feature | azure-search-openai-demo | sample-app-aoai-chatGPT |
---|---|---|
RAG approach | Multiple approaches | Only via ChatCompletion API data_sources |
Vector support | ✅ Yes | ✅ Yes |
Data ingestion | ✅ Yes (PDF) | ✅ Yes (PDF, TXT, MD, HTML) |
Persistent chat history | ❌ No (browser tab only) | ✅ Yes, in CosmosDB |
Technology comparison:
Tech | azure-search-openai-demo | sample-app-aoai-chatGPT |
---|---|---|
Frontend | React | React |
Backend | Python (Quart) | Python (Flask) |
Vector DB | Azure Cognitive Search | Azure Cognitive Search |
Deployment | Azure Developer CLI (azd) | Azure Portal, az, azd |
How do you use GPT-4 with this sample?
In infra/main.bicep
, change chatGptModelName
to 'gpt-4' instead of 'gpt-35-turbo'. You may also need to adjust the capacity above that line depending on how much TPM your account is allowed.
What does the `azd up` command do?
The azd up
command comes from the Azure Developer CLI, and takes care of both provisioning the Azure resources and deploying code to the selected Azure hosts.
The azd up
command uses the azure.yaml
file combined with the infrastructure-as-code .bicep
files in the infra/
folder. The azure.yaml
file for this project declares several "hooks" for the prepackage step and postprovision steps. The up
command first runs the prepackage
hook which installs Node dependencies and builds the React.JS-based JavaScript files. It then packages all the code (both frontend and backend) into a zip file which it will deploy later.
Next, it provisions the resources based on main.bicep
and main.parameters.json
. At that point, since there is no default value for the OpenAI resource location, it asks you to pick a location from a short list of available regions. Then it will send requests to Azure to provision all the required resources. With everything provisioned, it runs the postprovision
hook to process the local data and add it to an Azure Cognitive Search index.
Finally, it looks at azure.yaml
to determine the Azure host (appservice, in this case) and uploads the zip to Azure App Service. The azd up
command is now complete, but it may take another 5-10 minutes for the App Service app to be fully available and working, especially for the initial deploy.
Related commands are azd provision
for just provisioning (if infra files change) and azd deploy
for just deploying updated app code.
How can we view logs from the App Service app?
You can view production logs in the Portal using either the Log stream or by downloading the default_docker.log file from Advanced tools.
The following line of code in app/backend/app.py
configures the logging level:
logging.basicConfig(level=os.getenv("APP_LOG_LEVEL", default_level))
To change the default level, either change default_level
or set the APP_LOG_LEVEL
environment variable
to one of the allowed log levels:
DEBUG
, INFO
, WARNING
, ERROR
, CRITICAL
.
If you need to log in a route handler, use the the global variable current_app
's logger:
async def chat():
current_app.logger.info("Received /chat request")
Otherwise, use the logging
module's root logger:
logging.info("System message: %s", system_message)
If you're having troubles finding the logs in App Service, see this blog post on tips for debugging App Service app deployments or watch this video about viewing App Service logs.
Here are the most common failure scenarios and solutions:
-
The subscription (
AZURE_SUBSCRIPTION_ID
) doesn't have access to the Azure OpenAI service. Please ensureAZURE_SUBSCRIPTION_ID
matches the ID specified in the OpenAI access request process. -
You're attempting to create resources in regions not enabled for Azure OpenAI (e.g. East US 2 instead of East US), or where the model you're trying to use isn't enabled. See this matrix of model availability.
-
You've exceeded a quota, most often number of resources per region. See this article on quotas and limits.
-
You're getting "same resource name not allowed" conflicts. That's likely because you've run the sample multiple times and deleted the resources you've been creating each time, but are forgetting to purge them. Azure keeps resources for 48 hours unless you purge from soft delete. See this article on purging resources.
-
You see
CERTIFICATE_VERIFY_FAILED
when theprepdocs.py
script runs. That's typically due to incorrect SSL certificates setup on your machine. Try the suggestions in this StackOverflow answer. -
After running
azd up
and visiting the website, you see a '404 Not Found' in the browser. Wait 10 minutes and try again, as it might be still starting up. Then try runningazd deploy
and wait again. If you still encounter errors with the deployed app, consult these tips for debugging App Service app deployments or watch this video about downloading App Service logs. Please file an issue if the logs don't help you resolve the error.