Spaces:
Running
on
Zero
Running
on
Zero
jedick
commited on
Commit
·
6a3fed7
1
Parent(s):
100d2c7
Adjust prompts
Browse files- app.py +2 -2
- graph.py +11 -7
- prompts.py +13 -9
app.py
CHANGED
|
@@ -327,7 +327,7 @@ with gr.Blocks(
|
|
| 327 |
info_text = f"""
|
| 328 |
**Database:** {len(sources)} emails from {start} to {end}.
|
| 329 |
**Features:** RAG, today's date, hybrid search (dense+sparse), query analysis,
|
| 330 |
-
multiple
|
| 331 |
**Tech:** LangChain + Hugging Face + Gradio; ChromaDB and [BM25S](https://github.com/xhluca/bm25s)-based retrievers.<br>
|
| 332 |
"""
|
| 333 |
return info_text
|
|
@@ -385,7 +385,7 @@ with gr.Blocks(
|
|
| 385 |
gr.Examples(
|
| 386 |
examples=[[q] for q in multi_tool_questions],
|
| 387 |
inputs=[chat_interface.textbox],
|
| 388 |
-
label="
|
| 389 |
elem_id="example-questions",
|
| 390 |
)
|
| 391 |
multi_turn_questions = [
|
|
|
|
| 327 |
info_text = f"""
|
| 328 |
**Database:** {len(sources)} emails from {start} to {end}.
|
| 329 |
**Features:** RAG, today's date, hybrid search (dense+sparse), query analysis,
|
| 330 |
+
multiple retrievals per turn (cloud mode), answer with citations (cloud mode), chat memory.
|
| 331 |
**Tech:** LangChain + Hugging Face + Gradio; ChromaDB and [BM25S](https://github.com/xhluca/bm25s)-based retrievers.<br>
|
| 332 |
"""
|
| 333 |
return info_text
|
|
|
|
| 385 |
gr.Examples(
|
| 386 |
examples=[[q] for q in multi_tool_questions],
|
| 387 |
inputs=[chat_interface.textbox],
|
| 388 |
+
label="Multiple retrievals (cloud mode)",
|
| 389 |
elem_id="example-questions",
|
| 390 |
)
|
| 391 |
multi_turn_questions = [
|
graph.py
CHANGED
|
@@ -174,7 +174,10 @@ def BuildGraph(
|
|
| 174 |
)
|
| 175 |
# For now, just add the months to the search query
|
| 176 |
if months:
|
| 177 |
-
search_query =
|
|
|
|
|
|
|
|
|
|
| 178 |
retrieved_docs = retriever.invoke(search_query)
|
| 179 |
serialized = "\n\n--- --- --- --- Next Email --- --- --- ---".join(
|
| 180 |
# source key has file names (e.g. R-help/2024-December.txt), useful for retrieval and reporting
|
|
@@ -206,9 +209,10 @@ def BuildGraph(
|
|
| 206 |
query_model = ToolifyHF(
|
| 207 |
chat_model, retrieve_prompt(compute_mode), "", think_retrieve
|
| 208 |
).bind_tools([retrieve_emails])
|
|
|
|
| 209 |
generate_model = ToolifyHF(
|
| 210 |
-
chat_model, answer_prompt(), "", think_generate
|
| 211 |
-
)
|
| 212 |
else:
|
| 213 |
# For cloud model (OpenAI API)
|
| 214 |
query_model = chat_model.bind_tools([retrieve_emails])
|
|
@@ -222,9 +226,9 @@ def BuildGraph(
|
|
| 222 |
if is_edge:
|
| 223 |
# Don't include the system message here because it's defined in ToolCallingLLM
|
| 224 |
messages = state["messages"]
|
| 225 |
-
print_messages_summary(messages, "--- query: before normalization ---")
|
| 226 |
messages = normalize_messages(messages)
|
| 227 |
-
print_messages_summary(messages, "--- query: after normalization ---")
|
| 228 |
else:
|
| 229 |
messages = [SystemMessage(retrieve_prompt(compute_mode))] + state[
|
| 230 |
"messages"
|
|
@@ -237,9 +241,9 @@ def BuildGraph(
|
|
| 237 |
"""Generates an answer with the chat model"""
|
| 238 |
if is_edge:
|
| 239 |
messages = state["messages"]
|
| 240 |
-
print_messages_summary(messages, "--- generate: before normalization ---")
|
| 241 |
messages = normalize_messages(messages)
|
| 242 |
-
print_messages_summary(messages, "--- generate: after normalization ---")
|
| 243 |
else:
|
| 244 |
messages = [SystemMessage(answer_prompt())] + state["messages"]
|
| 245 |
response = generate_model.invoke(messages)
|
|
|
|
| 174 |
)
|
| 175 |
# For now, just add the months to the search query
|
| 176 |
if months:
|
| 177 |
+
search_query = " ".join([search_query, months])
|
| 178 |
+
# If the search query is empty, use the years
|
| 179 |
+
if not search_query:
|
| 180 |
+
search_query = " ".join([search_query, start_year, end_year])
|
| 181 |
retrieved_docs = retriever.invoke(search_query)
|
| 182 |
serialized = "\n\n--- --- --- --- Next Email --- --- --- ---".join(
|
| 183 |
# source key has file names (e.g. R-help/2024-December.txt), useful for retrieval and reporting
|
|
|
|
| 209 |
query_model = ToolifyHF(
|
| 210 |
chat_model, retrieve_prompt(compute_mode), "", think_retrieve
|
| 211 |
).bind_tools([retrieve_emails])
|
| 212 |
+
# Don't use answer_with_citations tool here because responses with Gemma are sometimes unparseable
|
| 213 |
generate_model = ToolifyHF(
|
| 214 |
+
chat_model, answer_prompt(with_tools=False), "", think_generate
|
| 215 |
+
)
|
| 216 |
else:
|
| 217 |
# For cloud model (OpenAI API)
|
| 218 |
query_model = chat_model.bind_tools([retrieve_emails])
|
|
|
|
| 226 |
if is_edge:
|
| 227 |
# Don't include the system message here because it's defined in ToolCallingLLM
|
| 228 |
messages = state["messages"]
|
| 229 |
+
# print_messages_summary(messages, "--- query: before normalization ---")
|
| 230 |
messages = normalize_messages(messages)
|
| 231 |
+
# print_messages_summary(messages, "--- query: after normalization ---")
|
| 232 |
else:
|
| 233 |
messages = [SystemMessage(retrieve_prompt(compute_mode))] + state[
|
| 234 |
"messages"
|
|
|
|
| 241 |
"""Generates an answer with the chat model"""
|
| 242 |
if is_edge:
|
| 243 |
messages = state["messages"]
|
| 244 |
+
# print_messages_summary(messages, "--- generate: before normalization ---")
|
| 245 |
messages = normalize_messages(messages)
|
| 246 |
+
# print_messages_summary(messages, "--- generate: after normalization ---")
|
| 247 |
else:
|
| 248 |
messages = [SystemMessage(answer_prompt())] + state["messages"]
|
| 249 |
response = generate_model.invoke(messages)
|
prompts.py
CHANGED
|
@@ -14,17 +14,18 @@ def retrieve_prompt(compute_mode):
|
|
| 14 |
start, end = get_start_end_months(get_sources())
|
| 15 |
|
| 16 |
retrieve_prompt = (
|
| 17 |
-
f"
|
| 18 |
"You are a helpful RAG chatbot designed to answer questions about R programming based on the R-help mailing list. "
|
| 19 |
"Do not ask the user for more information, but retrieve emails from the R-help mailing list archives. "
|
| 20 |
f"The emails available for retrieval are from {start} to {end}. "
|
| 21 |
-
"Write a search query based on the user'
|
| 22 |
"For questions about differences or comparison between X and Y, retrieve emails about X and Y. "
|
| 23 |
"Use the 'months' argument to search for months. "
|
| 24 |
# This confuses gpt-4o-mini (empty search_query - token problem?)
|
| 25 |
# "Use 3-letter month abbreviations (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec). "
|
| 26 |
-
"
|
| 27 |
-
"
|
|
|
|
| 28 |
"If you decide not to retrieve emails, tell the user why and suggest how to improve their question to chat with the R-help mailing list. "
|
| 29 |
)
|
| 30 |
# A sanity check that we don't have unassigned variables
|
|
@@ -35,22 +36,25 @@ def retrieve_prompt(compute_mode):
|
|
| 35 |
return retrieve_prompt
|
| 36 |
|
| 37 |
|
| 38 |
-
def answer_prompt():
|
| 39 |
"""Return system prompt for generate step"""
|
| 40 |
answer_prompt = (
|
| 41 |
-
f"
|
| 42 |
"You are a helpful RAG chatbot designed to answer questions about R programming based on the R-help mailing list. "
|
| 43 |
"Summarize the retrieved emails from the R-help mailing list archives to answer the user's question or query. "
|
| 44 |
-
"
|
| 45 |
"Tell the user if there are no retrieved emails or if you are unable to answer the question based on the information in the emails. "
|
| 46 |
"Do not give an answer based on your own knowledge or memory, and do not include examples that aren't based on the retrieved emails. "
|
| 47 |
"Example: For a question about writing formulas for lm(), make your answer about formulas for lm() from the retrieved emails. "
|
| 48 |
"Do not respond with packages that are only listed under sessionInfo, session info, or other attached packages. "
|
| 49 |
"Include inline citations (email senders and dates) in your response. "
|
| 50 |
-
"Use answer_with_citations to provide the answer and all citations used. "
|
| 51 |
-
"Respond with 300 words maximum and 30 lines of code maximum and include any relevant URLs from the retrieved emails. "
|
| 52 |
"Only answer general questions about R if the answer is given in the retrieved emails. "
|
|
|
|
| 53 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
matches = re.findall(r"\{.*?\}", "".join(answer_prompt))
|
| 55 |
if matches:
|
| 56 |
raise ValueError(f"Unassigned variables in prompt: {' '.join(matches)}")
|
|
|
|
| 14 |
start, end = get_start_end_months(get_sources())
|
| 15 |
|
| 16 |
retrieve_prompt = (
|
| 17 |
+
f"Today Date: {date.today()}. "
|
| 18 |
"You are a helpful RAG chatbot designed to answer questions about R programming based on the R-help mailing list. "
|
| 19 |
"Do not ask the user for more information, but retrieve emails from the R-help mailing list archives. "
|
| 20 |
f"The emails available for retrieval are from {start} to {end}. "
|
| 21 |
+
"Write a search query based on the user'r question, but do not answer the question just yet. "
|
| 22 |
"For questions about differences or comparison between X and Y, retrieve emails about X and Y. "
|
| 23 |
"Use the 'months' argument to search for months. "
|
| 24 |
# This confuses gpt-4o-mini (empty search_query - token problem?)
|
| 25 |
# "Use 3-letter month abbreviations (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec). "
|
| 26 |
+
"Example: retrieve emails about R in <month> using retrieve_emails(search_query='R', months=<month>). "
|
| 27 |
+
"Try to infer years from the user's question (last month or this month is this year). "
|
| 28 |
+
"If you can infer years, use retrieve_emails(search_query=, start_year=, end_year=), otherwise retrieve_emails(search_query=). "
|
| 29 |
"If you decide not to retrieve emails, tell the user why and suggest how to improve their question to chat with the R-help mailing list. "
|
| 30 |
)
|
| 31 |
# A sanity check that we don't have unassigned variables
|
|
|
|
| 36 |
return retrieve_prompt
|
| 37 |
|
| 38 |
|
| 39 |
+
def answer_prompt(with_tools=True):
|
| 40 |
"""Return system prompt for generate step"""
|
| 41 |
answer_prompt = (
|
| 42 |
+
f"Today Date: {date.today()}. "
|
| 43 |
"You are a helpful RAG chatbot designed to answer questions about R programming based on the R-help mailing list. "
|
| 44 |
"Summarize the retrieved emails from the R-help mailing list archives to answer the user's question or query. "
|
| 45 |
+
"If any of the retrieved emails are irrelevant (e.g. wrong dates), then do not use them. "
|
| 46 |
"Tell the user if there are no retrieved emails or if you are unable to answer the question based on the information in the emails. "
|
| 47 |
"Do not give an answer based on your own knowledge or memory, and do not include examples that aren't based on the retrieved emails. "
|
| 48 |
"Example: For a question about writing formulas for lm(), make your answer about formulas for lm() from the retrieved emails. "
|
| 49 |
"Do not respond with packages that are only listed under sessionInfo, session info, or other attached packages. "
|
| 50 |
"Include inline citations (email senders and dates) in your response. "
|
|
|
|
|
|
|
| 51 |
"Only answer general questions about R if the answer is given in the retrieved emails. "
|
| 52 |
+
"Respond with 300 words maximum and 30 lines of code maximum and include any relevant URLs from the retrieved emails. "
|
| 53 |
)
|
| 54 |
+
if with_tools:
|
| 55 |
+
answer_prompt += (
|
| 56 |
+
"Use answer_with_citations to provide the answer and all citations used. "
|
| 57 |
+
)
|
| 58 |
matches = re.findall(r"\{.*?\}", "".join(answer_prompt))
|
| 59 |
if matches:
|
| 60 |
raise ValueError(f"Unassigned variables in prompt: {' '.join(matches)}")
|