build-your-own-rag-chatbot
/
app_6.py
105 строк · 3.4 Кб
1import streamlit as st
2import os
3from langchain_openai import OpenAIEmbeddings
4from langchain_openai import ChatOpenAI
5from langchain_community.vectorstores import AstraDB
6from langchain.schema.runnable import RunnableMap
7from langchain.prompts import ChatPromptTemplate
8from langchain.callbacks.base import BaseCallbackHandler
9
10# Streaming call back handler for responses
11class StreamHandler(BaseCallbackHandler):
12def __init__(self, container, initial_text=""):
13self.container = container
14self.text = initial_text
15
16def on_llm_new_token(self, token: str, **kwargs):
17self.text += token
18self.container.markdown(self.text + "▌")
19
20# Cache prompt for future runs
21@st.cache_data()
22def load_prompt():
23template = """You're a helpful AI assistent tasked to answer the user's questions.
24You're friendly and you answer extensively with multiple sentences. You prefer to use bulletpoints to summarize.
25
26CONTEXT:
27{context}
28
29QUESTION:
30{question}
31
32YOUR ANSWER:"""
33return ChatPromptTemplate.from_messages([("system", template)])
34prompt = load_prompt()
35
36# Cache OpenAI Chat Model for future runs
37@st.cache_resource()
38def load_chat_model():
39return ChatOpenAI(
40temperature=0.3,
41model='gpt-3.5-turbo',
42streaming=True,
43verbose=True
44)
45chat_model = load_chat_model()
46
47# Cache the Astra DB Vector Store for future runs
48@st.cache_resource(show_spinner='Connecting to Astra')
49def load_retriever():
50# Connect to the Vector Store
51vector_store = AstraDB(
52embedding=OpenAIEmbeddings(),
53collection_name="my_store",
54api_endpoint=st.secrets['ASTRA_API_ENDPOINT'],
55token=st.secrets['ASTRA_TOKEN']
56)
57
58# Get the retriever for the Chat Model
59retriever = vector_store.as_retriever(
60search_kwargs={"k": 5}
61)
62return retriever
63retriever = load_retriever()
64
65# Start with empty messages, stored in session state
66if 'messages' not in st.session_state:
67st.session_state.messages = []
68
69# Draw a title and some markdown
70st.title("Your personal Efficiency Booster")
71st.markdown("""Generative AI is considered to bring the next Industrial Revolution.
72Why? Studies show a **37% efficiency boost** in day to day work activities!""")
73
74# Draw all messages, both user and bot so far (every time the app reruns)
75for message in st.session_state.messages:
76st.chat_message(message['role']).markdown(message['content'])
77
78# Draw the chat input box
79if question := st.chat_input("What's up?"):
80
81# Store the user's question in a session object for redrawing next time
82st.session_state.messages.append({"role": "human", "content": question})
83
84# Draw the user's question
85with st.chat_message('human'):
86st.markdown(question)
87
88# UI placeholder to start filling with agent response
89with st.chat_message('assistant'):
90response_placeholder = st.empty()
91
92# Generate the answer by calling OpenAI's Chat Model
93inputs = RunnableMap({
94'context': lambda x: retriever.get_relevant_documents(x['question']),
95'question': lambda x: x['question']
96})
97chain = inputs | prompt | chat_model
98response = chain.invoke({'question': question}, config={'callbacks': [StreamHandler(response_placeholder)]})
99answer = response.content
100
101# Store the bot's answer in a session object for redrawing next time
102st.session_state.messages.append({"role": "ai", "content": answer})
103
104# Write the final answer without the cursor
105response_placeholder.markdown(answer)