You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+14-6
Original file line number
Diff line number
Diff line change
@@ -9,9 +9,9 @@ This project is designed for deployment to Azure using [the Azure Developer CLI]
9
9
10
10
*[Features](#features)
11
11
*[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)
15
15
*[Deployment](#deployment)
16
16
*[Local development](#local-development)
17
17
*[Costs](#costs)
@@ -27,7 +27,13 @@ This project provides the following features:
27
27
* OpenAI function calling to optionally convert user queries into query filter conditions, such as turning "Climbing gear cheaper than $30?" into "WHERE price < 30".
28
28
* Conversion of user queries into vectors using the OpenAI embedding API.
29
29
30
-

30
+

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.
Copy file name to clipboardExpand all lines: docs/deploy_existing.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,9 @@
1
-
# Deploying with existing Azure resources
1
+
# RAG on PostgreSQL: Deploying with existing Azure resources
2
2
3
3
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.
4
4
You should set these values before running `azd up`. Once you've set them, return to the [deployment steps](../README.md#deployment).
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.
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:
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.
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:
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