-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathapp.py
More file actions
249 lines (213 loc) · 8.13 KB
/
Copy pathapp.py
File metadata and controls
249 lines (213 loc) · 8.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
from smolagents import CodeAgent, ManagedAgent
from src.rag import (
init_rag_agent,
init_qdrant_vector_store,
load_pdf,
load_dataset,
)
from src.web_search import init_web_search_agent
import streamlit as st
from src.common import load_model
@st.cache_resource
def st_init_vector_store():
# Load the vector store
vector_store, splitter = init_qdrant_vector_store()
return vector_store, splitter
@st.cache_resource
def init_agentic_rag(provider=None, model_id=None, api_key=None, api_base=None):
# Load the model
model = load_model(
provider=provider,
model_id=model_id,
api_key=api_key,
api_base=api_base,
)
# Initialize retriever Agent
rag_agent = init_rag_agent(model)
return rag_agent
@st.cache_resource
def init_multiagent_rag(provider=None, model_id=None, api_key=None, api_base=None):
# Load the model
model = load_model(
provider=provider,
model_id=model_id,
api_key=api_key,
api_base=api_base,
)
# Initialize retriever Agent
rag_agent = init_rag_agent(model)
rag_agent = ManagedAgent(
rag_agent,
name="retriever_agent",
description="""Uses a retriever tool to retrieve information from a vector database of related documents
using semantic search.
""",
additional_prompting="Use the retriever tool to find the information you need.",
)
# Initialize web search Agent
web_search_agent = init_web_search_agent(model)
web_search_agent = ManagedAgent(
web_search_agent,
name="web_search_agent",
description="""Runs web searches only to append, verify, or fill in missing information from
a generated response from the retriever_agent. Only run the whole input query to this agent if the
retriever_agent does not return the desired information.
""",
)
# Create the manager agent
manager_agent = CodeAgent(
tools=[],
model=model,
managed_agents=[rag_agent, web_search_agent],
max_steps=5,
verbose=False,
)
return manager_agent
def reset_conversation():
st.session_state.messages = []
def main():
# Start streamlit app
st.title("Agentic RAG Demo")
# Initialize the vector store
vector_store, splitter = st_init_vector_store()
# Initialize the Agentic-RAG agent
st.sidebar.header("RAG Configuration")
provider = st.sidebar.selectbox(
"Select model provider",
["ollama", "huggingface", "openai"],
index=1,
help="Choose the model provider you want to use. HuggingFace uses the HuggingFace API, while ollama uses local models through Ollama",
)
if provider == "ollama":
model_id = st.sidebar.text_input(
"Enter model ID",
"qwen2.5-coder:7b",
help="The model name listed in ollama. Run 'ollama list' to see available models.",
)
api_base = st.sidebar.text_input(
"Enter API base",
"http://localhost:11434",
help="The base URL of the ollama API.",
)
api_key = None
elif provider == "huggingface":
model_id = st.sidebar.text_input(
"Enter model ID",
"Qwen/Qwen2.5-Coder-32B-Instruct",
help="The model ID from HuggingFace.",
)
api_base = None
api_key = st.sidebar.text_input(
"Enter token", None, help="Your HuggingFace token."
)
elif provider == "openai":
model_id = st.sidebar.text_input(
"Enter model ID", "gpt-4", help="The model to use from OpenAI."
)
api_base = "https://api.openai.com/v1"
api_key = st.sidebar.text_input(
"Enter API key", "", help="Your OpenAI API key."
)
# Single Agent or Multi Agent RAG
rag_type = st.sidebar.selectbox(
"Select RAG type",
["single-agent", "multi-agent"],
index=0,
help="""Choose the RAG type you want to use. Single-agent uses a single agent system,
while multi-agent utilizes a RAG agent and a WebSearch agent.""",
)
if rag_type == "single-agent":
agentic_rag = init_agentic_rag(provider, model_id, api_key, api_base)
elif rag_type == "multi-agent":
agentic_rag = init_multiagent_rag(provider, model_id, api_key, api_base)
else:
raise ValueError(f"Invalid RAG type: {rag_type}")
st.sidebar.divider()
# Documents here
st.sidebar.header("Documents")
doc_type = st.sidebar.selectbox(
"Select type of documents to upload:",
["dataset", "pdf"],
index=0,
help="""Choose the type of documents you want to upload. Dataset uses a huggingface dataset,
while pdf uploads PDF files.""",
)
if doc_type == "dataset":
# Load huggingface dataset as Documents
dataset = st.sidebar.text_input(
"Enter dataset name",
"jamesnatulan/small_wiki_medical_terms",
help="THe repo ID of the huggingface dataset you want to use.",
)
content_field = st.sidebar.text_input(
"Enter content field",
"page_text",
help="The field in the dataset that contains the text.",
)
if st.sidebar.button("Load dataset"):
docs = load_dataset(dataset, splitter, content_field)
progress_text = """Loading dataset into vector store... This might take a while so
feel free to grab a cup of coffee. 🤗"""
progress_bar = st.sidebar.progress(0, text=progress_text)
for i, doc in enumerate(docs):
vector_store.add_documents([doc])
progress_bar.progress(i / len(docs), text=progress_text)
progress_bar.empty()
st.sidebar.success("Dataset loaded successfully.")
elif doc_type == "pdf":
# Load PDF files as Documents
uploaded_files = st.sidebar.file_uploader(
"Upload PDF", type=["pdf"], accept_multiple_files=True
)
if len(uploaded_files) > 0:
docs = load_pdf(uploaded_files, splitter)
progress_text = """Loading PDF into vector store... This might take a while so
feel free to grab a cup of coffee. 🤗"""
progress_bar = st.sidebar.progress(0, text=progress_text)
for i, doc in enumerate(docs):
vector_store.add_documents([doc])
progress_bar.progress(i / len(docs))
progress_bar.empty()
st.sidebar.success("PDFs loaded successfully.")
else:
raise ValueError(f"Invalid document type: {doc_type}")
st.sidebar.divider()
# Chat
st.sidebar.header("Chat")
st.sidebar.button('Reset Chat', on_click=reset_conversation)
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Accept user input
prompt = st.chat_input("Enter query: ")
if prompt:
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Display assistant response in chat message container
with st.chat_message("assistant"):
# Run the agent with the user input
prompt_template = """
Chat history:
{history}
User input:
{query}
"""
with st.spinner("Thinking..."):
response = agentic_rag.run(
prompt_template.format(
history=st.session_state.messages, query=prompt
),
stream=False,
)
st.write(response)
# Add assistant response to chat history
st.session_state.messages.append({"role": "assistant", "content": response})
if __name__ == "__main__":
main()