Update app.py
Browse files
app.py
CHANGED
|
@@ -27,6 +27,50 @@ def duckduckgo_search(query):
|
|
| 27 |
results = ddgs.text(query, max_results=10)
|
| 28 |
return results
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
def create_web_search_vectors(search_results):
|
| 31 |
embed = get_embeddings()
|
| 32 |
documents = []
|
|
@@ -36,7 +80,7 @@ def create_web_search_vectors(search_results):
|
|
| 36 |
documents.append(Document(page_content=content, metadata={"source": result['href']}))
|
| 37 |
return FAISS.from_documents(documents, embed)
|
| 38 |
|
| 39 |
-
async def get_response_with_search(query, model, use_embeddings,
|
| 40 |
search_results = duckduckgo_search(query)
|
| 41 |
|
| 42 |
if not search_results:
|
|
@@ -51,20 +95,14 @@ async def get_response_with_search(query, model, use_embeddings, conversation_hi
|
|
| 51 |
else:
|
| 52 |
context = "\n".join([f"{result['title']}\n{result['body']}\nSource: {result['href']}" for result in search_results])
|
| 53 |
|
| 54 |
-
system_message = """You are a world-class AI system, capable of complex reasoning and reflection.
|
| 55 |
Reason through the query inside <thinking> tags, and then provide your final response inside <output> tags.
|
| 56 |
Providing comprehensive and accurate information based on web search results is essential.
|
| 57 |
Your goal is to synthesize the given context into a coherent and detailed response that directly addresses the user's query.
|
| 58 |
Please ensure that your response is well-structured, factual, and cites sources where appropriate.
|
| 59 |
-
If you detect that you made a mistake in your reasoning at any point, correct yourself inside <reflection> tags.
|
| 60 |
-
Consider the conversation history when formulating your response to maintain context and coherence."""
|
| 61 |
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
user_message = f"""Conversation history:
|
| 65 |
-
{conversation_context}
|
| 66 |
-
|
| 67 |
-
Using the following context from web search results:
|
| 68 |
{context}
|
| 69 |
|
| 70 |
Write a detailed and complete research document that fulfills the following user request: '{query}'
|
|
@@ -110,11 +148,14 @@ async def respond(message, history, model, temperature, num_calls, use_embedding
|
|
| 110 |
logging.info(f"Number of API Calls: {num_calls}")
|
| 111 |
logging.info(f"Use Embeddings: {use_embeddings}")
|
| 112 |
|
| 113 |
-
# Convert Gradio history to a list of dictionaries
|
| 114 |
-
conversation_history = [{"human": h, "ai": a} for h, a in history]
|
| 115 |
-
|
| 116 |
try:
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
response = f"{main_content}\n\n{sources}"
|
| 119 |
yield response
|
| 120 |
except asyncio.CancelledError:
|
|
@@ -147,8 +188,8 @@ def create_gradio_interface():
|
|
| 147 |
gr.Slider(minimum=1, maximum=5, value=1, step=1, label="Number of API Calls"),
|
| 148 |
gr.Checkbox(label="Use Embeddings", value=False),
|
| 149 |
],
|
| 150 |
-
title="AI-powered
|
| 151 |
-
description="Use web search to answer questions or generate summaries.
|
| 152 |
theme=gr.Theme.from_hub("allenai/gradio-theme"),
|
| 153 |
css=css,
|
| 154 |
examples=[
|
|
@@ -177,7 +218,6 @@ def create_gradio_interface():
|
|
| 177 |
5. Check or uncheck the "Use Embeddings" box to toggle between using embeddings or direct text summarization.
|
| 178 |
6. Press Enter or click the submit button to get your answer.
|
| 179 |
7. Use the provided examples or ask your own questions.
|
| 180 |
-
8. The assistant will remember previous interactions and maintain context throughout the conversation.
|
| 181 |
""")
|
| 182 |
|
| 183 |
return demo
|
|
|
|
| 27 |
results = ddgs.text(query, max_results=10)
|
| 28 |
return results
|
| 29 |
|
| 30 |
+
async def rephrase_query(query, history, model):
|
| 31 |
+
system_message = """You are an AI assistant tasked with analyzing and rephrasing user queries. Your goal is to determine if a query is unique or related to the previous conversation, and then rephrase it appropriately for web search. Keep the rephrased query succinct and in a web search query format.
|
| 32 |
+
|
| 33 |
+
If the query is unique, rephrase it to be more specific and searchable.
|
| 34 |
+
If the query is related to the previous conversation, incorporate relevant context from the previous response.
|
| 35 |
+
|
| 36 |
+
Provide your analysis in the following format:
|
| 37 |
+
<analysis>Your reasoning about whether the query is unique or related</analysis>
|
| 38 |
+
<rephrased_query>The rephrased query</rephrased_query>"""
|
| 39 |
+
|
| 40 |
+
user_message = f"""Current query: {query}
|
| 41 |
+
|
| 42 |
+
Previous conversation history:
|
| 43 |
+
{history}
|
| 44 |
+
|
| 45 |
+
Analyze the query and provide a rephrased version suitable for web search."""
|
| 46 |
+
|
| 47 |
+
client = InferenceClient(model, token=huggingface_token)
|
| 48 |
+
|
| 49 |
+
try:
|
| 50 |
+
response = await asyncio.to_thread(
|
| 51 |
+
client.text_generation,
|
| 52 |
+
prompt=f"{system_message}\n\n{user_message}",
|
| 53 |
+
max_new_tokens=150,
|
| 54 |
+
temperature=0.2,
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
# Extract the rephrased query from the response
|
| 58 |
+
analysis_start = response.find("<analysis>")
|
| 59 |
+
analysis_end = response.find("</analysis>")
|
| 60 |
+
rephrased_start = response.find("<rephrased_query>")
|
| 61 |
+
rephrased_end = response.find("</rephrased_query>")
|
| 62 |
+
|
| 63 |
+
if analysis_start != -1 and analysis_end != -1 and rephrased_start != -1 and rephrased_end != -1:
|
| 64 |
+
analysis = response[analysis_start + 10:analysis_end].strip()
|
| 65 |
+
rephrased_query = response[rephrased_start + 17:rephrased_end].strip()
|
| 66 |
+
return analysis, rephrased_query
|
| 67 |
+
else:
|
| 68 |
+
logging.error("Failed to parse the rephrase response")
|
| 69 |
+
return None, query
|
| 70 |
+
except Exception as e:
|
| 71 |
+
logging.error(f"Error in rephrase_query: {str(e)}")
|
| 72 |
+
return None, query
|
| 73 |
+
|
| 74 |
def create_web_search_vectors(search_results):
|
| 75 |
embed = get_embeddings()
|
| 76 |
documents = []
|
|
|
|
| 80 |
documents.append(Document(page_content=content, metadata={"source": result['href']}))
|
| 81 |
return FAISS.from_documents(documents, embed)
|
| 82 |
|
| 83 |
+
async def get_response_with_search(query, model, use_embeddings, num_calls=3, temperature=0.2):
|
| 84 |
search_results = duckduckgo_search(query)
|
| 85 |
|
| 86 |
if not search_results:
|
|
|
|
| 95 |
else:
|
| 96 |
context = "\n".join([f"{result['title']}\n{result['body']}\nSource: {result['href']}" for result in search_results])
|
| 97 |
|
| 98 |
+
system_message = """ You are a world-class AI system, capable of complex reasoning and reflection.
|
| 99 |
Reason through the query inside <thinking> tags, and then provide your final response inside <output> tags.
|
| 100 |
Providing comprehensive and accurate information based on web search results is essential.
|
| 101 |
Your goal is to synthesize the given context into a coherent and detailed response that directly addresses the user's query.
|
| 102 |
Please ensure that your response is well-structured, factual, and cites sources where appropriate.
|
| 103 |
+
If you detect that you made a mistake in your reasoning at any point, correct yourself inside <reflection> tags."""
|
|
|
|
| 104 |
|
| 105 |
+
user_message = f"""Using the following context from web search results:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
{context}
|
| 107 |
|
| 108 |
Write a detailed and complete research document that fulfills the following user request: '{query}'
|
|
|
|
| 148 |
logging.info(f"Number of API Calls: {num_calls}")
|
| 149 |
logging.info(f"Use Embeddings: {use_embeddings}")
|
| 150 |
|
|
|
|
|
|
|
|
|
|
| 151 |
try:
|
| 152 |
+
# Rephrase the query
|
| 153 |
+
analysis, rephrased_query = await rephrase_query(message, history, model)
|
| 154 |
+
|
| 155 |
+
if analysis:
|
| 156 |
+
yield f"Query Analysis: {analysis}\n\nRephrased Query: {rephrased_query}\n\nSearching the web...\n\n"
|
| 157 |
+
|
| 158 |
+
async for main_content, sources in get_response_with_search(rephrased_query, model, use_embeddings, num_calls=num_calls, temperature=temperature):
|
| 159 |
response = f"{main_content}\n\n{sources}"
|
| 160 |
yield response
|
| 161 |
except asyncio.CancelledError:
|
|
|
|
| 188 |
gr.Slider(minimum=1, maximum=5, value=1, step=1, label="Number of API Calls"),
|
| 189 |
gr.Checkbox(label="Use Embeddings", value=False),
|
| 190 |
],
|
| 191 |
+
title="AI-powered Web Search Assistant",
|
| 192 |
+
description="Use web search to answer questions or generate summaries.",
|
| 193 |
theme=gr.Theme.from_hub("allenai/gradio-theme"),
|
| 194 |
css=css,
|
| 195 |
examples=[
|
|
|
|
| 218 |
5. Check or uncheck the "Use Embeddings" box to toggle between using embeddings or direct text summarization.
|
| 219 |
6. Press Enter or click the submit button to get your answer.
|
| 220 |
7. Use the provided examples or ask your own questions.
|
|
|
|
| 221 |
""")
|
| 222 |
|
| 223 |
return demo
|