Skip to content

Commit 7b538f1

Browse files
Updates chatbot-rag-app and simplifies instructions (#362)
* Updates chatbot-rag-app and simplifies instructions This updates chatbot-rag-app to the latest libraries and simplifies instructions by delegating details of configuration to the .env file. This also works around problems we found in DEBUG mode, by using production mode regardless of task. Doing so notably will allow tracing to work in the future. Efforts here were thanks to many, despite me raising it, notably @joemcelroy @ezimuel @xrmx and @anuraaga Signed-off-by: Adrian Cole <[email protected]> * precommit Signed-off-by: Adrian Cole <[email protected]> * feedback Signed-off-by: Adrian Cole <[email protected]> * addresses feedback and cleans up azure Signed-off-by: Adrian Cole <[email protected]> * RIP rip Signed-off-by: Adrian Cole <[email protected]> --------- Signed-off-by: Adrian Cole <[email protected]>
1 parent cacb13a commit 7b538f1

15 files changed

+4814
-4011
lines changed

Diff for: example-apps/chatbot-rag-app/.flaskenv

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
FLASK_APP=api/app.py
2-
FLASK_RUN_PORT=3001
3-
FLASK_DEBUG=1
2+
FLASK_RUN_PORT=4000
3+
# Production mode ensures we don't run into problems.
4+
FLASK_ENV=production

Diff for: example-apps/chatbot-rag-app/Dockerfile

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
# app/Dockerfile
2-
3-
FROM node:16-alpine as build-step
1+
FROM node:20-alpine AS build-step
42
WORKDIR /app
5-
ENV PATH /node_modules/.bin:$PATH
3+
ENV PATH=/node_modules/.bin:$PATH
64
COPY frontend ./frontend
75
RUN rm -rf /app/frontend/node_modules
86
RUN cd frontend && yarn install
97
RUN cd frontend && REACT_APP_API_HOST=/api yarn build
108

11-
FROM python:3.9-slim
9+
FROM python:3.12-slim
1210

1311
WORKDIR /app
1412
RUN mkdir -p ./frontend/build
15-
COPY --from=build-step ./app/frontend/build ./frontend/build
13+
COPY --from=build-step ./app/frontend/build ./frontend/build
1614
RUN mkdir ./api
1715
RUN mkdir ./data
1816

@@ -24,12 +22,13 @@ RUN apt-get update && apt-get install -y \
2422
&& rm -rf /var/lib/apt/lists/*
2523

2624

27-
COPY api ./api
28-
COPY data ./data
2925
COPY requirements.txt ./requirements.txt
3026
RUN pip3 install -r ./requirements.txt
31-
ENV FLASK_ENV production
27+
COPY api ./api
28+
COPY data ./data
3229

3330
EXPOSE 4000
34-
WORKDIR /app/api
35-
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--port=4000" ]
31+
# The only thing different from running local is that in docker we need to
32+
# listen on all IPs, not just localhost.
33+
ENV FLASK_RUN_HOST=0.0.0.0
34+
CMD [ "flask", "run"]

Diff for: example-apps/chatbot-rag-app/README.md

+82-170
Original file line numberDiff line numberDiff line change
@@ -15,216 +15,128 @@ curl https://codeload.github.com/elastic/elasticsearch-labs/tar.gz/main | \
1515
tar -xz --strip=2 elasticsearch-labs-main/example-apps/chatbot-rag-app
1616
```
1717

18-
## Installing and connecting to Elasticsearch
19-
20-
### Install Elasticsearch
21-
22-
There are a number of ways to install Elasticsearch. Cloud is best for most use-cases. Visit the [Install Elasticsearch](https://www.elastic.co/search-labs/tutorials/install-elasticsearch) for more information.
23-
24-
### Connect to Elasticsearch
25-
26-
This app requires the following environment variables to be set to connect to Elasticsearch hosted on Elastic Cloud:
27-
28-
```sh
29-
export ELASTIC_CLOUD_ID=...
30-
export ELASTIC_API_KEY=...
31-
```
32-
33-
You can add these to a `.env` file for convenience. See the `env.example` file for a .env file template.
18+
## Make your .env file
3419

35-
#### Self-Hosted Elasticsearch
20+
Copy [env.example](env.example) to `.env` and fill in values noted inside.
3621

37-
You can also connect to a self-hosted Elasticsearch instance. To do so, you will need to set the following environment variables:
22+
## Installing and connecting to Elasticsearch
3823

39-
```sh
40-
export ELASTICSEARCH_URL=...
41-
```
24+
There are a number of ways to install Elasticsearch. Cloud is best for most
25+
use-cases. Visit the [Install Elasticsearch](https://www.elastic.co/search-labs/tutorials/install-elasticsearch) for more information.
4226

43-
### Change the Elasticsearch index and chat_history index
27+
Once you decided your approach, edit your `.env` file accordingly.
4428

45-
By default, the app will use the `workplace-app-docs` index and the chat history index will be `workplace-app-docs-chat-history`. If you want to change these, you can set the following environment variables:
29+
### Elasticsearch index and chat_history index
4630

47-
```sh
48-
ES_INDEX=workplace-app-docs
49-
ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
50-
```
31+
By default, the app will use the `workplace-app-docs` index and the chat
32+
history index will be `workplace-app-docs-chat-history`. If you want to change
33+
these, edit `ES_INDEX` and `ES_INDEX_CHAT_HISTORY` entries in your `.env` file.
5134

5235
## Connecting to LLM
5336

54-
We support several LLM providers. To use one of them, you need to set the `LLM_TYPE` environment variable. For example:
55-
56-
```sh
57-
export LLM_TYPE=azure
58-
```
59-
60-
The following sub-sections define the configuration requirements of each supported LLM.
61-
62-
### OpenAI
63-
64-
To use OpenAI LLM, you will need to provide the OpenAI key via `OPENAI_API_KEY` environment variable:
65-
66-
```sh
67-
export LLM_TYPE=openai
68-
export OPENAI_API_KEY=...
69-
```
70-
71-
You can get your OpenAI key from the [OpenAI dashboard](https://platform.openai.com/account/api-keys).
72-
73-
### Azure OpenAI
74-
75-
If you want to use Azure LLM, you will need to set the following environment variables:
76-
77-
```sh
78-
export LLM_TYPE=azure
79-
export OPENAI_VERSION=... # e.g. 2023-05-15
80-
export OPENAI_BASE_URL=...
81-
export OPENAI_API_KEY=...
82-
export OPENAI_ENGINE=... # deployment name in Azure
83-
```
84-
85-
### Bedrock LLM
86-
87-
To use Bedrock LLM you need to set the following environment variables in order to authenticate to AWS.
88-
89-
```sh
90-
export LLM_TYPE=bedrock
91-
export AWS_ACCESS_KEY=...
92-
export AWS_SECRET_KEY=...
93-
export AWS_REGION=... # e.g. us-east-1
94-
export AWS_MODEL_ID=... # Default is anthropic.claude-v2
95-
```
96-
97-
#### AWS Config
98-
99-
Optionally, you can connect to AWS via the config file in `~/.aws/config` described here:
100-
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials
101-
102-
```
103-
[default]
104-
aws_access_key_id=...
105-
aws_secret_access_key=...
106-
region=...
107-
```
108-
109-
### Vertex AI
110-
111-
To use Vertex AI you need to set the following environment variables. More information [here](https://python.langchain.com/docs/integrations/llms/google_vertex_ai_palm).
112-
113-
```sh
114-
export LLM_TYPE=vertex
115-
export VERTEX_PROJECT_ID=<gcp-project-id>
116-
export VERTEX_REGION=<gcp-region> # Default is us-central1
117-
export GOOGLE_APPLICATION_CREDENTIALS=<path-json-service-account>
118-
```
119-
120-
### Mistral AI
121-
122-
To use Mistral AI you need to set the following environment variables. The app has been tested with Mistral Large Model deployed through Microsoft Azure. More information [here](https://learn.microsoft.com/en-us/azure/ai-studio/how-to/deploy-models-mistral).
123-
124-
```
125-
export LLM_TYPE=mistral
126-
export MISTRAL_API_KEY=...
127-
export MISTRAL_API_ENDPOINT=... # should be of the form https://<endpoint>.<region>.inference.ai.azure.com
128-
export MISTRAL_MODEL=... # optional
129-
```
130-
131-
### Cohere
37+
We support several LLM providers, but only one is used at runtime, and selected
38+
by the `LLM_TYPE` entry in your `.env` file. Edit that file to choose an LLM,
39+
and configure its templated connection settings:
13240

133-
To use Cohere you need to set the following environment variables:
134-
135-
```
136-
export LLM_TYPE=cohere
137-
export COHERE_API_KEY=...
138-
export COHERE_MODEL=... # optional
139-
```
41+
* azure: [Azure OpenAI Service](https://learn.microsoft.com/en-us/azure/ai-services/openai/)
42+
* bedrock: [Amazon Bedrock](https://docs.aws.amazon.com/bedrock/)
43+
* openai: [OpenAI Platform](https://platform.openai.com/docs/overview) and
44+
services compatible with its API.
45+
* vertex: [Google Vertex AI](https://cloud.google.com/vertex-ai/docs)
46+
* mistral: [Mistral AI](https://docs.mistral.ai/)
47+
* cohere: [Cohere](https://docs.cohere.com/)
14048

14149
## Running the App
14250

143-
Once you have indexed data into the Elasticsearch index, there are two ways to run the app: via Docker or locally. Docker is advised for testing & production use. Locally is advised for development.
144-
145-
### Through Docker
146-
147-
Build the Docker image and run it with the following environment variables.
148-
149-
```sh
150-
docker build -f Dockerfile -t chatbot-rag-app .
151-
```
152-
153-
#### Ingest data
154-
155-
Make sure you have a `.env` file with all your variables, then run:
156-
157-
```sh
158-
docker run --rm --env-file .env chatbot-rag-app flask create-index
159-
```
51+
There are two ways to run the app: via Docker or locally. Docker is advised for
52+
ease while locally is advised if you are making changes to the application.
16053

161-
See "Ingest data" section under Running Locally for more details about the `flask create-index` command.
54+
### Run with docker
16255

163-
#### Run API and frontend
56+
Docker compose is the easiest way, as you get one-step to:
57+
* build the [frontend](frontend)
58+
* ingest data into elasticsearch
59+
* run the app, which listens on http://localhost:4000
16460

165-
You will need to set the appropriate environment variables in your `.env` file. See the `env.example` file for instructions.
61+
**Double-check you have a `.env` file with all your variables set first!**
16662

167-
```sh
168-
docker run --rm -p 4000:4000 --env-file .env -d chatbot-rag-app
63+
```bash
64+
docker compose up --build --force-recreate
16965
```
17066

171-
Note that if you are using an LLM that requires an external credentials file (such as Vertex AI), you will need to make this file accessible to the container in the `run` command above. For this you can use a bind mount, or you can also edit the Dockerfile to copy the credentials file to the container image at build time.
67+
*Note*: First time creating the index can fail on timeout. Wait a few minutes
68+
and retry.
17269

173-
### Locally (for development)
70+
### Run locally
17471

175-
With the environment variables set, you can run the following commands to start the server and frontend.
72+
If you want to run this example with Python and Node.js, you need to do a few
73+
things listed in the [Dockerfile](Dockerfile). The below uses the same
74+
production mode as used in Docker to avoid problems in debug mode.
17675

177-
#### Pre-requisites
76+
**Double-check you have a `.env` file with all your variables set first!**
17877

179-
- Python 3.8+
180-
- Node 14+
78+
#### Build the frontend
18179

182-
#### Install the dependencies
80+
The web assets are in the [frontend](frontend) directory, and built with yarn.
18381

184-
For Python we recommend using a virtual environment.
82+
```bash
83+
# Install and use a recent node, if you don't have one.
84+
nvm install --lts
85+
nvm use --lts
86+
# Build the frontend web assets
87+
(cd frontend; yarn install; REACT_APP_API_HOST=/api yarn build)
88+
```
18589

186-
_ℹ️ Here's a good [primer](https://realpython.com/python-virtual-environments-a-primer) on virtual environments from Real Python._
90+
#### Configure your python environment
18791

188-
```sh
189-
# Create a virtual environment
190-
python -m venv .venv
92+
Before we can run the app, we need a working Python environment with the
93+
correct packages installed:
19194

192-
# Activate the virtual environment
95+
```bash
96+
python3 -m venv .venv
19397
source .venv/bin/activate
194-
195-
# Install Python dependencies
98+
# install dev requirements for pip-compile and dotenv
99+
pip install pip-tools "python-dotenv[cli]"
100+
pip-compile
196101
pip install -r requirements.txt
197-
198-
# Install Node dependencies
199-
cd frontend && yarn && cd ..
200102
```
201103

202-
#### Ingest data
203-
204-
You can index the sample data from the provided .json files in the `data` folder:
104+
#### Run the ingest command
205105

206-
```sh
207-
flask create-index
106+
First, ingest the data into elasticsearch:
107+
```bash
108+
$ dotenv run -- flask create-index
109+
".elser_model_2" model not available, downloading it now
110+
Model downloaded, starting deployment
111+
Loading data from ./data/data.json
112+
Loaded 15 documents
113+
Split 15 documents into 26 chunks
114+
Creating Elasticsearch sparse vector store in http://localhost:9200
208115
```
209116

210-
By default, this will index the data into the `workplace-app-docs` index. You can change this by setting the `ES_INDEX` environment variable.
117+
*Note*: First time creating the index can fail on timeout. Wait a few minutes
118+
and retry.
211119

212-
##### Indexing your own data
120+
#### Run the app
213121

214-
The ingesting logic is stored in `data/index-data.py`. This is a simple script that uses Langchain to index data into Elasticsearch, using the `JSONLoader` and `CharacterTextSplitter` to split the large documents into passages. Modify this script to index your own data.
122+
Now, run the app, which listens on http://localhost:4000
123+
```bash
124+
$ dotenv run -- flask run
125+
* Serving Flask app 'api/app.py'
126+
* Debug mode: off
127+
```
215128

216-
Langchain offers many different ways to index data, if you cant just load it via JSONLoader. See the [Langchain documentation](https://python.langchain.com/docs/modules/data_connection/document_loaders)
129+
## Customizing the app
217130

218-
Remember to keep the `ES_INDEX` environment variable set to the index you want to index into and to query from.
131+
### Indexing your own data
219132

220-
#### Run API and frontend
133+
The ingesting logic is stored in [data/index_data.py](data/index_data.py). This
134+
is a simple script that uses Langchain to index data into Elasticsearch, using
135+
`RecursiveCharacterTextSplitter` to split the large JSON documents into
136+
passages. Modify this script to index your own data.
221137

222-
```sh
223-
# Launch API app
224-
flask run
138+
See [Langchain documentation][loader-docs] for more ways to load documents.
225139

226-
# In a separate terminal launch frontend app
227-
cd frontend && yarn start
228-
```
229140

230-
You can now access the frontend at http://localhost:3000. Changes are automatically reloaded.
141+
---
142+
[loader-docs]: https://python.langchain.com/docs/how_to/#document-loaders

Diff for: example-apps/chatbot-rag-app/api/app.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ def create_index():
3636
index_data.main()
3737

3838

39+
# Unless we run through flask, we can miss critical settings or telemetry signals.
3940
if __name__ == "__main__":
40-
app.run(port=3001, debug=True)
41+
raise RuntimeError("Run via the parent directory: 'flask run'")

0 commit comments

Comments
 (0)