Skip to content

Commit f76f27a

Browse files
authored
move workplace-search to chatbot-rag-app (elastic#116)
1 parent 78472ee commit f76f27a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+11864
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
frontend/build
2+
frontend/node_modules
3+
api/__pycache__
4+
api/.env
5+
.venv
6+
venv
7+
.DS_Store
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# app/Dockerfile
2+
3+
FROM node:16-alpine as build-step
4+
WORKDIR /app
5+
ENV PATH /node_modules/.bin:$PATH
6+
COPY frontend ./frontend
7+
RUN rm -rf /app/frontend/node_modules
8+
RUN cd frontend && yarn install
9+
RUN cd frontend && REACT_APP_API_HOST=/api yarn build
10+
11+
FROM python:3.9-slim
12+
13+
WORKDIR /app
14+
RUN mkdir -p ./frontend/build
15+
COPY --from=build-step ./app/frontend/build ./frontend/build
16+
RUN mkdir ./api
17+
18+
RUN apt-get update && apt-get install -y \
19+
build-essential \
20+
curl \
21+
software-properties-common \
22+
git \
23+
&& rm -rf /var/lib/apt/lists/*
24+
25+
26+
COPY api ./api
27+
COPY requirements.txt ./requirements.txt
28+
RUN pip3 install -r ./requirements.txt
29+
ENV FLASK_ENV production
30+
31+
EXPOSE 4000
32+
WORKDIR /app/api
33+
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--port=4000" ]
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Elastic Chatbot RAG App
2+
3+
This is a sample app that combines Elasticsearch, Langchain and a number of different LLMs to create a chatbot experience with ELSER with your own private data.
4+
5+
![Screenshot of the sample app](./app-demo.gif)
6+
7+
## 1. Download the Project
8+
9+
Download the project from Github and extract the `chatbot-rag-app` folder.
10+
11+
```bash
12+
curl https://codeload.github.com/elastic/elasticsearch-labs/tar.gz/main | \
13+
tar -xz --strip=2 elasticsearch-labs-main/example-apps/chatbot-rag-app
14+
```
15+
16+
## 2. Installing and connecting to Elasticsearch
17+
18+
### Install Elasticsearch
19+
20+
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.
21+
22+
### Connect to Elasticsearch
23+
24+
This app requires the following environment variables to be set to connect to Elasticsearch
25+
26+
```sh
27+
export ELASTIC_CLOUD_ID=...
28+
export ELASTIC_USERNAME=...
29+
export ELASTIC_PASSWORD=...
30+
```
31+
32+
### Change the Elasticsearch index and chat_history index
33+
34+
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:
35+
36+
```sh
37+
ES_INDEX=workplace-app-docs
38+
ES_INDEX_CHAT_HISTORY=workplace-app-docs-chat-history
39+
```
40+
41+
## 3. Connecting to LLM
42+
43+
We support three LLM providers: Azure, OpenAI and Bedrock.
44+
45+
To use one of them, you need to set the `LLM_TYPE` environment variable:
46+
47+
```sh
48+
export LLM_TYPE=azure
49+
```
50+
51+
### OpenAI
52+
53+
To use OpenAI LLM, you will need to provide the OpenAI key via `OPENAI_API_KEY` environment variable:
54+
55+
```sh
56+
export LLM_TYPE=openai
57+
export OPENAI_API_KEY=...
58+
```
59+
60+
You can get your OpenAI key from the [OpenAI dashboard](https://platform.openai.com/account/api-keys).
61+
62+
### Azure OpenAI
63+
64+
If you are using Azure LLM, you will need to set the following environment variables:
65+
66+
```sh
67+
export LLM_TYPE=azure
68+
export OPENAI_VERSION=... # e.g. 2023-05-15
69+
export OPENAI_BASE_URL=...
70+
export OPENAI_API_KEY=...
71+
export OPENAI_ENGINE=... # deployment name in Azure
72+
```
73+
74+
### Bedrock LLM
75+
76+
To use Bedrock LLM you need to set the following environment variables in order to AWS.
77+
78+
```sh
79+
export LLM_TYPE=bedrock
80+
export AWS_ACCESS_KEY=...
81+
export AWS_SECRET_KEY=...
82+
export AWS_REGION=... # e.g. us-east-1
83+
export AWS_MODEL_ID=... # Default is anthropic.claude-v2
84+
```
85+
86+
#### AWS Config
87+
88+
Optionally, you can connect to AWS via the config file in `~/.aws/config` described here:
89+
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials
90+
91+
```
92+
[default]
93+
aws_access_key_id=...
94+
aws_secret_access_key=...
95+
region=...
96+
```
97+
98+
### Vertex AI
99+
100+
To use Vertex AI you need to set the following environment variables. More infos [here](https://python.langchain.com/docs/integrations/llms/google_vertex_ai_palm).
101+
102+
```sh
103+
export LLM_TYPE=vertex
104+
export VERTEX_PROJECT_ID=<gcp-project-id>
105+
export VERTEX_REGION=<gcp-region> # Default is us-central1
106+
export GOOGLE_APPLICATION_CREDENTIALS=<path-json-service-account>
107+
```
108+
109+
## 3. Ingest Data
110+
111+
You can index the sample data from the provided .json files in the `data` folder:
112+
113+
```sh
114+
python data/index-data.py
115+
```
116+
117+
by default, this will index the data into the `workplace-app-docs` index. You can change this by setting the `ES_INDEX` environment variable.
118+
119+
### Indexing your own data
120+
121+
`index-data.py` 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+
123+
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)
124+
125+
Remember to keep the `ES_INDEX` environment variable set to the index you want to index into and to query from.
126+
127+
## Running the App
128+
129+
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.
130+
131+
### Through Docker
132+
133+
Build the Docker image and run it with the following environment variables.
134+
135+
```sh
136+
docker build -f Dockerfile -t chatbot-rag-app .
137+
```
138+
139+
Then run it with the following environment variables. In the example below, we are using OpenAI LLM.
140+
141+
If you're using one of the other LLMs, you will need to set the appropriate environment variables via `-e` flag.
142+
143+
```sh
144+
docker run -p 4000:4000 \
145+
-e "ELASTIC_CLOUD_ID=<cloud_id>" \
146+
-e "ELASTIC_USERNAME=elastic" \
147+
-e "ELASTIC_PASSWORD=<password>" \
148+
-e "LLM_TYPE=openai" \
149+
-e "OPENAI_API_KEY=<openai_key>" \
150+
-d chatbot-rag-app
151+
```
152+
153+
### Locally (for development)
154+
155+
With the environment variables set, you can run the following commands to start the server and frontend.
156+
157+
#### Pre-requisites
158+
159+
- Python 3.8+
160+
- Node 14+
161+
162+
#### Install the dependencies
163+
164+
For Python we recommend using a virtual environment.
165+
166+
_ℹ️ Here's a good [primer](https://realpython.com/python-virtual-environments-a-primer) on virtual environments from Real Python._
167+
168+
```sh
169+
# Create a virtual environment
170+
python -m venv .venv
171+
172+
# Activate the virtual environment
173+
source .venv/bin/activate
174+
```
175+
176+
```sh
177+
# Install Python dependencies
178+
pip install -r requirements.txt
179+
180+
# Install Node dependencies
181+
cd frontend && yarn
182+
```
183+
184+
#### Run API and frontend
185+
186+
```sh
187+
# Launch API app
188+
python api/app.py
189+
190+
# In a separate terminal launch frontend app
191+
cd frontend && yarn start
192+
```
193+
194+
You can now access the frontend at http://localhost:3000. Changes are automatically reloaded.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from flask import Flask, jsonify, request, Response
2+
from flask_cors import CORS
3+
from queue import Queue
4+
from uuid import uuid4
5+
from chat import chat, ask_question, parse_stream_message
6+
import threading
7+
8+
app = Flask(__name__, static_folder="../frontend/build", static_url_path="/")
9+
CORS(app)
10+
11+
12+
@app.route("/")
13+
def api_index():
14+
return app.send_static_file("index.html")
15+
16+
17+
@app.route("/api/chat", methods=["POST"])
18+
def api_chat():
19+
request_json = request.get_json()
20+
question = request_json.get("question")
21+
if question is None:
22+
return jsonify({"msg": "Missing question from request JSON"}), 400
23+
24+
stream_queue = Queue()
25+
session_id = request.args.get("session_id", str(uuid4()))
26+
27+
print("Chat session ID: ", session_id)
28+
29+
threading.Thread(
30+
target=ask_question, args=(question, stream_queue, session_id)
31+
).start()
32+
33+
return Response(
34+
parse_stream_message(session_id, stream_queue), mimetype="text/event-stream"
35+
)
36+
37+
38+
if __name__ == "__main__":
39+
app.run(port=3001, debug=True)

0 commit comments

Comments
 (0)