|
| 1 | +<p align="center" class="flex items-center gap-1 justify-center flex-wrap"> |
| 2 | + <img src="../../../assets/gcp-logo.svg?raw=true" alt="GCP Logo" height="20" width="20"> |
| 3 | + <a href="https://pathway.com/developers/user-guide/deployment/gcp-deploy">Deploy with GCP</a> | |
| 4 | + <img src="../../../assets/aws-fargate-logo.svg?raw=true" alt="AWS Logo" height="20" width="20"> |
| 5 | + <a href="https://pathway.com/developers/user-guide/deployment/aws-fargate-deploy">Deploy with AWS</a> | |
| 6 | + <img src="../../../assets/azure-logo.svg?raw=true" alt="Azure Logo" height="20" width="20"> |
| 7 | + <a href="https://pathway.com/developers/user-guide/deployment/azure-aci-deploy">Deploy with Azure</a> | |
| 8 | + <img src="../../../assets/render.png?raw=true" alt="Render Logo" height="20" width="20"> |
| 9 | + <a href="https://pathway.com/developers/user-guide/deployment/render-deploy"> Deploy with Render </a> |
| 10 | +</p> |
| 11 | + |
| 12 | + |
| 13 | +# End to end Adaptive RAG with Pathway |
| 14 | + |
| 15 | +This is the accompanying code for deploying the `adaptive RAG` technique with Pathway. To understand the technique and learn how it can save tokens without sacrificing accuracy, read [our showcase](https://pathway.com/developers/templates/rag/adaptive-rag). |
| 16 | + |
| 17 | +To learn more about building & deploying RAG applications with Pathway, including containerization, refer to [demo question answering](../question_answering_rag/README.md). |
| 18 | + |
| 19 | +## Introduction |
| 20 | +This app relies on modules provided under `pathway.xpacks.llm`. |
| 21 | + |
| 22 | +BaseRAGQuestionAnswerer is the base class to build RAG applications with Pathway vector store and Pathway xpack components. |
| 23 | +It is meant to get you started with your RAG application right away. |
| 24 | + |
| 25 | +Here, we extend the `BaseRAGQuestionAnswerer` to implement the adaptive retrieval and reply to requests in the endpoint `/v2/answer`. |
| 26 | +Since we are interested in changing the behavior and logic of the RAG, we only modify `answer` function that handles all this logic, and then replies to the post request. |
| 27 | + |
| 28 | +`answer` function takes the `pw_ai_queries` table as the input, this table contains the prompt, and other arguments coming from the post request, see the `BaseRAGQuestionAnswerer` class and defined schemas to learn more about getting inputs with post requests. |
| 29 | +We use the data in this table to call our adaptive retrieval logic. |
| 30 | + |
| 31 | +To do that, we use `answer_with_geometric_rag_strategy_from_index` implementation provided under the `pathway.xpacks.llm.question_answering`. |
| 32 | +This function takes an index, LLM, prompt and adaptive parameters such as the starting number of documents. Then, iteratively asks the question to the LLM with an increasing number of context documents retrieved from the index. |
| 33 | + |
| 34 | +We encourage you to check the implementation of `answer_with_geometric_rag_strategy_from_index`. |
| 35 | + |
| 36 | +## Customizing the pipeline |
| 37 | + |
| 38 | +The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml). |
| 39 | + |
| 40 | +In the `app.yaml` file we define: |
| 41 | +- input connectors |
| 42 | +- LLM |
| 43 | +- embedder |
| 44 | +- index |
| 45 | +and any of these can be replaced or, if no longer needed, removed. For components that can be used check |
| 46 | +Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own. |
| 47 | + |
| 48 | +You can also check our other templates - [Question Answering RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag), |
| 49 | +[Multimodal RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/multimodal_rag) or |
| 50 | +[Private RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/private_rag). As all of these only differ |
| 51 | +in the YAML configuration file, you can also use them as an inspiration for your custom pipeline. |
| 52 | + |
| 53 | +Here some examples of what can be modified. |
| 54 | + |
| 55 | +### LLM Model |
| 56 | + |
| 57 | +You can choose any of the GPT-3.5 Turbo, GPT-4, or GPT-4 Turbo models proposed by Open AI. |
| 58 | +You can find the whole list on their [models page](https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo). |
| 59 | + |
| 60 | +You simply need to change the `model` to the one you want to use: |
| 61 | +```yaml |
| 62 | +$llm: !pw.xpacks.llm.llms.OpenAIChat |
| 63 | + model: "gpt-3.5-turbo" |
| 64 | + retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy |
| 65 | + max_retries: 6 |
| 66 | + cache_strategy: !pw.udfs.DiskCache |
| 67 | + temperature: 0.05 |
| 68 | + capacity: 8 |
| 69 | +``` |
| 70 | +
|
| 71 | +The default model is `gpt-3.5-turbo` |
| 72 | + |
| 73 | +You can also use different provider, by using different class from [Pathway LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), |
| 74 | +e.g. here is configuration for locally run Mistral model. |
| 75 | + |
| 76 | +```yaml |
| 77 | +$llm: !pw.xpacks.llm.llms.LiteLLMChat |
| 78 | + model: "ollama/mistral" |
| 79 | + retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy |
| 80 | + max_retries: 6 |
| 81 | + cache_strategy: !pw.udfs.DiskCache |
| 82 | + temperature: 0 |
| 83 | + top_p: 1 |
| 84 | + api_base: "http://localhost:11434" |
| 85 | +``` |
| 86 | + |
| 87 | +### Webserver |
| 88 | + |
| 89 | +You can configure the host and the port of the webserver. |
| 90 | +Here is the default configuration: |
| 91 | +```yaml |
| 92 | +host: "0.0.0.0" |
| 93 | +port: 8000 |
| 94 | +``` |
| 95 | + |
| 96 | +### Cache |
| 97 | + |
| 98 | +You can configure whether you want to enable cache, to avoid repeated API accesses, and where the cache is stored. |
| 99 | +Default values: |
| 100 | +```yaml |
| 101 | +with_cache: True |
| 102 | +cache_backend: !pw.persistence.Backend.filesystem |
| 103 | + path: ".Cache" |
| 104 | +``` |
| 105 | + |
| 106 | +### Data sources |
| 107 | + |
| 108 | +You can configure the data sources by changing `$sources` in `app.yaml`. |
| 109 | +You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders. |
| 110 | +The sections below describe how to configure local, Google Drive and Sharepoint source, but you can use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package. |
| 111 | + |
| 112 | +By default, the app uses a local data source to read documents from the `data` folder. |
| 113 | + |
| 114 | +#### Local Data Source |
| 115 | + |
| 116 | +The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed. |
| 117 | + |
| 118 | +#### Google Drive Data Source |
| 119 | + |
| 120 | +The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters: |
| 121 | +- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. Consequently, the last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`, hence this is the `object_id` you would need to specify. |
| 122 | +- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive). |
| 123 | + |
| 124 | +Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds. |
| 125 | + |
| 126 | +For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read). |
| 127 | + |
| 128 | +#### SharePoint Data Source |
| 129 | + |
| 130 | +This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license). |
| 131 | + |
| 132 | +To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read). |
| 133 | + |
| 134 | +## Running the app |
| 135 | +To run the app, depending on the configuration, you may need to set up environmntal variables with LLM provider keys. By default, this template uses OpenAI API, so to run it you need to set `OPENAI_API_KEY` environmental key or create an `.env` file in this directory with your key: `OPENAI_API_KEY=sk-...`. If you modify the code to use another LLM provider, you may need to set a relevant API key. |
| 136 | + |
| 137 | +### With Docker |
| 138 | +In order to let the pipeline get updated with each change in local files, you need to mount the folder onto the docker. The following commands show how to do that. |
| 139 | + |
| 140 | +```bash |
| 141 | +# Build the image in this folder |
| 142 | +docker build -t adaptiverag . |
| 143 | +
|
| 144 | +# Run the image, mount the `data` folder into image |
| 145 | +# -e is used to pass value of OPENAI_API_KEY environmental variable |
| 146 | +docker run -v ./data:/app/data -e OPENAI_API_KEY -p 8000:8000 adaptiverag |
| 147 | +``` |
| 148 | + |
| 149 | +### Locally |
| 150 | +To run locally you need to install the Pathway app with LLM dependencies using: |
| 151 | +```bash |
| 152 | +pip install pathway[all] |
| 153 | +``` |
| 154 | + |
| 155 | +Then change your directory in the terminal to this folder and run the app: |
| 156 | +```bash |
| 157 | +python app.py |
| 158 | +``` |
| 159 | + |
| 160 | +## Using the app |
| 161 | + |
| 162 | +Finally, query the application with; |
| 163 | + |
| 164 | +```bash |
| 165 | +curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{ |
| 166 | + "prompt": "What is the start date of the contract?" |
| 167 | +}' |
| 168 | +``` |
| 169 | +> `{"response": "December 21, 2015 [6]"}` |
0 commit comments