Skip to content

Commit 05f2d38

Browse files
committed
Update docs
1 parent d1e9d16 commit 05f2d38

13 files changed

+81
-12
lines changed

README.md

+14-6
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ This project is designed for deployment to Azure using [the Azure Developer CLI]
99

1010
* [Features](#features)
1111
* [Getting started](#getting-started)
12-
* [GitHub Codespaces](#github-codespaces)
13-
* [VS Code Dev Containers](#vs-code-dev-containers)
14-
* [Local environment](#local-environment)
12+
* [GitHub Codespaces](#github-codespaces)
13+
* [VS Code Dev Containers](#vs-code-dev-containers)
14+
* [Local environment](#local-environment)
1515
* [Deployment](#deployment)
1616
* [Local development](#local-development)
1717
* [Costs](#costs)
@@ -27,7 +27,13 @@ This project provides the following features:
2727
* OpenAI function calling to optionally convert user queries into query filter conditions, such as turning "Climbing gear cheaper than $30?" into "WHERE price < 30".
2828
* Conversion of user queries into vectors using the OpenAI embedding API.
2929

30-
![Screenshot of chat app with question about climbing gear](docs/screenshot_chat.png)
30+
![Screenshot of chat app with question about climbing gear](docs/images/screenshot_chat.png)
31+
32+
## Architecture diagram
33+
34+
The deployed app uses a user-assigned managed identity to authenticate to Azure services, and stores logs in Log Analytics.
35+
36+
![Architecture diagram: Azure Container Apps, Azure Container Registry, Managed Identity, Azure OpenAI, Azure Database for PostgreSQL](docs/images/architecture.png)
3137

3238
## Getting started
3339

@@ -98,7 +104,7 @@ Once you've opened the project in [Codespaces](#github-codespaces), [Dev Contain
98104
For GitHub Codespaces users, if the previous command fails, try:
99105
100106
```shell
101-
azd auth login --use-device-code
107+
azd auth login --use-device-code
102108
```
103109
104110
2. Create a new azd environment:
@@ -111,7 +117,7 @@ Once you've opened the project in [Codespaces](#github-codespaces), [Dev Contain
111117
112118
3. (Optional) If you would like to customize the deployment to [use existing Azure resources](docs/deploy_existing.md), you can set the values now.
113119
114-
3. Provision the resources and deploy the code:
120+
4. Provision the resources and deploy the code:
115121
116122
```shell
117123
azd up
@@ -195,6 +201,7 @@ Additionally, we have added a [GitHub Action](https://github.com/microsoft/secur
195201
196202
Further documentation is available in the `docs/` folder:
197203
204+
* [Understanding the RAG flow](docs/rag_flow.md)
198205
* [Customizing the data](docs/customize_data.md)
199206
* [Deploying with existing resources](docs/deploy_existing.md)
200207
* [Monitoring with Azure Monitor](docs/monitoring.md)
@@ -204,5 +211,6 @@ Please post in the issue tracker with any questions or issues.
204211
205212
## Resources
206213
214+
* [RAGHack livestream: Building RAG with PostgreSQL](https://www.youtube.com/watch?v=Dk65oQjYAfo)
207215
* [RAG chat with Azure AI Search + Python](https://github.com/Azure-Samples/azure-search-openai-demo/)
208216
* [Develop Python apps that use Azure AI services](https://learn.microsoft.com/azure/developer/python/azure-ai-for-python-developers)

docs/customize_data.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Customizing the data
1+
# RAG on PostgreSQL: Customizing the data
22

33
This guide shows you how to bring in a table with a different schema than the sample table.
44

@@ -30,6 +30,7 @@ If you don't yet have any embeddings in `seed_data.json`:
3030
3131
## Add the seed data to the database
3232
33+
Now that you have the new table schema and `seed_data.json` populated with embeddings, you can add the seed data to the database:
3334
3435
```shell
3536
python src/backend/fastapi_app/setup_postgres_seeddata.py

docs/deploy_existing.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Deploying with existing Azure resources
1+
# RAG on PostgreSQL: Deploying with existing Azure resources
22

33
If you already have existing Azure resources, or if you want to specify the exact name of new Azure Resource, you can do so by setting `azd` environment values.
44
You should set these values before running `azd up`. Once you've set them, return to the [deployment steps](../README.md#deployment).
55

6-
### Openai.com OpenAI account
6+
## Openai.com OpenAI account
77

88
1. Run `azd env set DEPLOY_AZURE_OPENAI false`
99
1. Run `azd env set OPENAI_CHAT_HOST openaicom`

docs/images/advanced_hybrid_flow.png

112 KB
Loading

docs/images/azure_architecture.png

75.5 KB
Loading
62.7 KB
Loading
227 KB
Loading
File renamed without changes.

docs/images/simple_hybrid_flow.png

96.4 KB
Loading

docs/images/simple_rag_thoughts.png

271 KB
Loading

docs/loadtesting.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Load testing
1+
# RAG on PostgreSQL: Load testing
22

33
We recommend running a loadtest for your expected number of users.
44
You can use the [locust tool](https://docs.locust.io/) with the `locustfile.py` in this sample

docs/monitoring.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
# Monitoring with Azure Monitor
1+
# RAG on PostgreSQL: Monitoring with Azure Monitor
32

43
By default, deployed apps use Application Insights for the tracing of each request, along with the logging of errors.
54

docs/rag_flow.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# RAG on PostgreSQL: Understanding the RAG flow
2+
3+
This RAG application uses an LLM to answer questions based off matching rows in a PostgreSQL database. It supports two different RAG flows:
4+
5+
* [Simple RAG flow](#simple-rag-flow): First searches the database for a matching row, then uses the LLM to generate an answer.
6+
* [Advanced RAG flow](#advanced-rag-flow): Adds a query rewriting step before searching the database.
7+
8+
## Simple RAG flow
9+
10+
The simple flow is only used if you de-select the "Advanced flow" option in the Developer Settings dialog. We do not recommend this flow for production use, as it is less sophisticated, but it may be helpful for development and comparison.
11+
12+
This diagram shows the simple RAG flow:
13+
14+
![Simple RAG flow diagram](images/simple_hybrid_flow.png)
15+
16+
1. The user asks a question.
17+
2. The app uses an embedding model to generate a vector embedding for the question.
18+
3. The app searches the target table in the PostgreSQL database using a hybrid search (full-text search plus vector search) to find the most relevant rows.
19+
4. The app sends the original user question and the retrieved rows to the LLM to generate an answer.
20+
21+
When using the app, click the lightbulb on an answer to see the steps:
22+
23+
![Simple RAG flow example](images/simple_rag_thoughts.png)
24+
25+
For the full code, see [/src/backend/fastapi_app/rag_simple.py](/src/backend/fastapi_app/rag_simple.py).
26+
27+
## Advanced RAG flow
28+
29+
The advanced flow is used if you select the "Advanced flow" option in the Developer Settings dialog, and is the default flow for the RAG application.
30+
31+
This diagram shows the advanced RAG flow:
32+
33+
![Advanced RAG flow diagram](images/advanced_hybrid_flow.png)
34+
35+
The difference between the simple and advanced flows is an additional query rewriting step before the database search, which can improve the relevance of the search results. All the steps:
36+
37+
1. The user asks a question.
38+
2. The app uses an LLM to rewrite the question into a text query that can be used to search the database.
39+
3. The app uses an embedding model to generate a vector embedding for the rewritten text query.
40+
4. The app searches the target table in the PostgreSQL database using a hybrid search (full-text search plus vector search) to find the most relevant rows.
41+
5. The app sends the original user question and the retrieved rows to the LLM to generate an answer.
42+
43+
When using the app, click the lightbulb on an answer to see the query rewriting step call and its results.
44+
45+
![Query rewriting example](images/query_rewriting_thoughts.png)
46+
47+
For the full code, see [/src/backend/fastapi_app/rag_advanced.py](/src/backend/fastapi_app/rag_advanced.py).
48+
49+
### Query rewriting with function calling
50+
51+
Let's dive even deeper into the query rewriting step.
52+
53+
The query rewriting step uses [OpenAI function calling](https://platform.openai.com/docs/guides/function-calling) to generate the rewritten query. That function may also optionally specify column filters, which are then applied to the SQL query for the search step. For the sample data, the filters are for the "brand" and "price" columns, but you could change those to match your own [custom data schema](customize_data.md).
54+
55+
This diagram illustrates the function calling process for a sample question:
56+
57+
![Function calling diagram](images/function_calling_diagram.png)
58+
59+
The `search_database` function definition is in [query_rewriter.py](/src/backend/fastapi_app/query_rewriter.py), and the few shot examples are in [query_fewshots.json](/src/backend/fastapi_app/prompts/query_fewshots.json). The function calling response is parsed in [query_rewriter.py](/src/backend/fastapi_app/query_rewriter.py) to extract the suggested SQL query and column filters, and those are passed to [postgres_searcher.py](/src/backend/fastapi_app/postgres_searcher.py) to search the database.
60+
61+
To be able to use function calling, the app must use a model that has support for it. The OpenAI GPT models do support function calling, but other models may not. If you're developing locally with Ollama, we recommend llama3.1 as it has been tested to work with function calling.

0 commit comments

Comments
 (0)