Skip to content

Commit d05c158

Browse files
update second section
1 parent d39469c commit d05c158

File tree

1 file changed

+45
-23
lines changed

1 file changed

+45
-23
lines changed

jac/support/jac-lang.org/docs/learn/tutorial/2_building-a-rag-chatbot.md

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,42 @@
11
# Building a RAG Chatbot with Jac Cloud and Streamlit (Part 2/3)
22

3-
Now that we have a jac application served up, let's build a simple chatbot using Retrieval Augmented Generation (RAG) with Jac Cloud and Streamlit as our frontend interface.
3+
Now that we have a jac application served up, In this section, we'll build a simple chatbot using **Retrieval Augmented Generation (RAG)** with **Jac Cloud** for the backend and **Streamlit** for the frontend interface.
44

55
### Preparation / Installation
66

7-
There are a couple of additional dependenices we need here
7+
Before we start, let's install a few additional dependencies. Run the following command in your terminal:
88

99
```bash
1010
pip install mtllm==0.3.2 jac-streamlit==0.0.3 langchain==0.1.16 langchain_community==0.0.34 chromadb==0.5.0 pypdf==4.2.0
1111
```
1212

13+
- `mtllm`: A toolkit for multi-task learning with language models.
14+
- `jac-streamlit`: A plugin that integrates jaclang with Streamlit.
15+
- `langchain`, `langchain_community`: Essential tools for handling the language generation logic in your chatbot.
16+
- `chromadb`: A vector database to store and retrieve embeddings.
17+
- `pypdf`: A Python library to handle PDF documents.
18+
19+
1320
## Building a Streamlit Interface
1421

1522
Before we begin building out our chatbot, let's first build a simple GUI to interact with the chatbot. Streamlit offers several Chat elements, enabling you to build Graphical User Interfaces (GUIs) for conversational agents or chatbots. Leveraging session state along with these elements allows you to construct anything from a basic chatbot to a more advanced, ChatGPT-like experience using purely Python code.
1623

1724
Luckily for us, jaclang has a plugin for streamlit that allows us to build web applications with streamlit using jaclang. In this part of the tutorial, we will build a frontend for our conversational agent using streamlit. You can find more information about the `jac-streamlit` plugin [here](https://github.com/Jaseci-Labs/jaclang/blob/main/support/plugins/streamlit/README.md).
1825

19-
First, let's create a new file called `client.jac`. This file will contain the code for the frontend chat interface.
26+
Begin by creating a file named `client.jac`. This file will define the frontend logic for interacting with users and displaying responses from the chatbot.
2027

21-
We start by importing the necessary modules in Jac:
28+
First, import the necessary Python libraries that will handle the user interface (UI) and API communication:
2229

23-
- `streamlit` (for frontend UI components)
24-
- `requests` (for making API calls)
2530

2631
```jac
2732
import:py streamlit as st;
2833
import:py requests;
2934
```
3035

31-
- `streamlit` will handle the user interface (UI) of the chatbot.
32-
- `requests` will handle API calls to our backend.
36+
- `streamlit`: Handle the user interface (UI) of the chatbot.
37+
- `requests`: Handle API calls to our backend.
3338

34-
Now let's define a function bootstrap_frontend, which accepts a token for authentication and builds the chat interface.
39+
Now let's define a function `bootstrap_frontend`, which is the core of the user interface. It is responsible for rendering the welcome message, initializing the chat history, and interacting with the backend.
3540

3641
```jac
3742
can bootstrap_frontend (token: str) {
@@ -44,25 +49,35 @@ can bootstrap_frontend (token: str) {
4449
}
4550
```
4651

47-
- `st.write()` adds a welcome message to the app.
48-
- `st.session_state` is used to persist data across user interactions. Here, we're using it to store the chat history (`messages`).
52+
- `st.write("Welcome to your Demo Agent!")`: This displays a welcome message on the page.
53+
- `st.session_state`: Streamlit's `session_state` is used to persist the data (in this case, the chat history) across multiple interactions. Here, we initialize `st.session_state.messages` to store the messages between the user and the assistant.
4954

50-
Now, let's update the function such that when the page reloads or updates, the previous chat messages are reloaded from `st.session_state.messages`. Add the following to `bootstrap_frontend`
55+
Next, we need to ensure that the chat history is reloaded when the page is refreshed or updated. The following code snippet does that by iterating through the stored messages and rendering them on the interface:
5156

5257
```jac
58+
can bootstrap_frontend(token:str){
59+
//
60+
//
61+
5362
for message in st.session_state.messages {
5463
with st.chat_message(message["role"]) {
5564
st.markdown(message["content"]);
5665
}
5766
}
67+
}
5868
```
5969

60-
- This block loops through the stored messages in the session state.
61-
- For each message, we use `st.chat_message()` to display the message by its role (either `"user"` or `"assistant"`).
70+
- `for message in st.session_state.messages`: This loop goes through each message stored in `st.session_state.messages`.
71+
- `st.chat_message(message["role"])`: Displays each message by its role (either `"user"` or `"assistant"`)
72+
6273

6374
Next, let's capture user input using `st.chat_input()`. This is where users can type their message to the chatbot.
6475

6576
```jac
77+
can bootstrap_frontend(token:str){
78+
//
79+
//
80+
6681
if prompt := st.chat_input("What is up?") {
6782
# Add user message to chat history
6883
st.session_state.messages.append({"role": "user", "content": prompt});
@@ -72,16 +87,23 @@ Next, let's capture user input using `st.chat_input()`. This is where users can
7287
st.markdown(prompt);
7388
}
7489
}
90+
}
7591
```
7692

77-
- `st.chat_input()` waits for the user to type a message and submit it.
78-
- Once the user submits a message, it's appended to the session state's message history and immediately displayed on the screen.
93+
- `st.chat_input("What is up?")`: This waits for the user to type a message. The text typed by the user is stored in the variable `prompt`.
94+
- `st.session_state.messages.append(...)`: The user’s message is added to the session's chat history. Each message is stored as a dictionary with two keys: "role" (indicating whether the message is from the user or the assistant) and "content" (the actual text).
95+
- `with st.chat_message("user")`: The message is displayed in the chat box under the "user" role.
7996

80-
Now we handle the interaction with the backend server. After the user submits a message, the assistant responds. This involves sending the user's message to the backend, receiving a response from the backend and displaying it.
97+
Now we handle the interaction with the backend server. After capturing the user's input, it will send to the backend, retrieve the assistant's response, and display it,
8198

82-
Add the following to `bootstrap_frontend`.
99+
Modify the `bootstrap_frontend` as follows;
83100

84101
```jac
102+
103+
can bootstrap_frontend(token:str){
104+
//
105+
//
106+
85107
if prompt := st.chat_input("What is up?") {
86108
# Add user message to chat history
87109
st.session_state.messages.append({"role": "user", "content": prompt});
@@ -109,14 +131,14 @@ Add the following to `bootstrap_frontend`.
109131
}
110132
}
111133
}
134+
}
112135
```
113136

114-
- The user's input (`prompt`) is sent to the backend using a POST request to the `/walker/interact` endpoint.
115-
- The `interact` walker, as we created in the last chapter, just returns `Hello World!` for now. This will change as we build out our chatbot.
116-
- `message` and `session_id` are not yet utilized at this point. They will come into play later in this chapter.
137+
- `requests.post(...)`: This sends the user’s message (stored in `prompt`) to the backend using an HTTP POST request. The message is sent as JSON with a "message" key, and a "session_id" is also included, but `message` and `session_id` are not yet utilized at this point. They will come into play later in this chapter.
138+
- The backend is the `interact` walker, which we created in the last chapter, it just returns `Hello World!` for now. This will change as we build out our chatbot.
117139
- The response from the backend is then displayed using `st.write()`, and the assistant's message is stored in the session state.
118140

119-
Lastly, we'll define the entry point of `client.jac`. Think `main` function of a python program. We authenticates the user and retrieves the token needed for the `bootstrap_frontend` function.
141+
Lastly, we'll define the entry point of our program. Think about the `main` function of a python program. Here we authenticates the user and retrieves the token needed for the `bootstrap_frontend` function. Add the following code block to the `client.jac`
120142

121143
```jac
122144
with entry {
@@ -169,7 +191,7 @@ Now you can run the frontend using the following command:
169191
jac streamlit client.jac
170192
```
171193

172-
If your server is still running, you can chat with your assistant using the streamlit interface. The response will only be "Hello, world!" for now, but we will update it to be a fully working chatbot next.
194+
If your server is still running, you can chat with your assistant using the streamlit interface which is opening in your browser. The response will only be "Hello, world!" for now, but we will update it to be a fully working chatbot next.
173195

174196
Now let's move on to building the RAG module.
175197

0 commit comments

Comments
 (0)