Facelook commited on
Commit
ab8f825
·
1 Parent(s): 9469c9b

Added break down question via LLM.

Browse files
Files changed (3) hide show
  1. README.md +37 -1
  2. app.py +100 -11
  3. requirements.txt +2 -1
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Template Final Assignment
3
  emoji: 🕵🏻‍♂️
4
  colorFrom: indigo
5
  colorTo: indigo
@@ -12,4 +12,40 @@ hf_oauth: true
12
  hf_oauth_expiration_minutes: 480
13
  ---
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: LLM-Enhanced Internet Search Agent
3
  emoji: 🕵🏻‍♂️
4
  colorFrom: indigo
5
  colorTo: indigo
 
12
  hf_oauth_expiration_minutes: 480
13
  ---
14
 
15
+ # LLM-Enhanced Internet Search Agent
16
+
17
+ This agent uses a two-step approach to answer questions:
18
+
19
+ 1. **Question Breakdown**: The agent first uses an LLM (GPT-3.5) to break down complex questions into 2-3 key search queries
20
+ 2. **Targeted Search**: Each search query is sent to Wikipedia's API to retrieve relevant information
21
+ 3. **Answer Synthesis**: The agent then uses the LLM to synthesize a comprehensive answer based on all search results
22
+
23
+ ## Features
24
+
25
+ - **Smart Query Generation**: Transforms natural language questions into optimized search queries
26
+ - **Parallel Search Processing**: Searches for multiple key aspects of the question simultaneously
27
+ - **Knowledge Synthesis**: Combines information from multiple sources into a cohesive answer
28
+ - **Fallback Mechanisms**: Graceful handling of errors at each step of the process
29
+
30
+ ## Setup Requirements
31
+
32
+ 1. Clone this repository
33
+ 2. Install required packages: `pip install -r requirements.txt`
34
+ 3. Set your OpenAI API key as an environment variable: `OPENAI_API_KEY=your-api-key`
35
+
36
+ ## How It Works
37
+
38
+ 1. User submits a question
39
+ 2. LLM breaks down the question into key search terms
40
+ 3. Search terms are used to query Wikipedia API
41
+ 4. Results from multiple searches are collected
42
+ 5. LLM synthesizes the information into a comprehensive answer
43
+ 6. Answer is returned to the user
44
+
45
+ This approach is more effective than direct internet searches because:
46
+ - It identifies the most relevant aspects of complex questions
47
+ - It can break multi-part questions into their components
48
+ - It leverages the LLM's understanding of natural language
49
+ - It provides more targeted and accurate search results
50
+
51
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
 
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
@@ -13,6 +14,54 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
13
  class BasicAgent:
14
  def __init__(self):
15
  print("BasicAgent initialized.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  def search_internet(self, query: str) -> str:
18
  """
@@ -85,19 +134,59 @@ class BasicAgent:
85
  def __call__(self, question: str) -> str:
86
  print(f"Agent received question (first 50 chars): {question[:50]}...")
87
 
88
- # Use internet search to find answer
89
- search_results = self.search_internet(question)
90
 
91
- # Create a response based on search results
92
- if (search_results and search_results != "No relevant information found." and
93
- not search_results.startswith("Error")):
94
- answer = f"Based on my search, I found this information:\n\n{search_results}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  else:
96
- # Fallback to default answer if search fails
97
  answer = "I couldn't find specific information about that question."
98
-
99
- print(f"Agent returning answer based on internet search.")
100
- return answer
101
 
102
  def run_and_submit_all( profile: gr.OAuthProfile | None):
103
  """
@@ -222,7 +311,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
222
 
223
  # --- Build Gradio Interface using Blocks ---
224
  with gr.Blocks() as demo:
225
- gr.Markdown("# Basic Agent Evaluation Runner (Attempt #1)")
226
  gr.Markdown(
227
  """
228
  **Instructions:**
 
3
  import requests
4
  import inspect
5
  import pandas as pd
6
+ import openai # Import OpenAI library
7
 
8
  # (Keep Constants as is)
9
  # --- Constants ---
 
14
  class BasicAgent:
15
  def __init__(self):
16
  print("BasicAgent initialized.")
17
+ # Initialize OpenAI client - you'll need to set OPENAI_API_KEY in environment variables
18
+ self.openai_client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
19
+ if not os.getenv("OPENAI_API_KEY"):
20
+ print("Warning: OPENAI_API_KEY not found in environment variables.")
21
+
22
+ def break_down_question(self, question: str) -> list:
23
+ """
24
+ Use an LLM to break down a complex question into key search terms or sub-questions.
25
+
26
+ Args:
27
+ question (str): The original question
28
+
29
+ Returns:
30
+ list: A list of key search terms or sub-questions
31
+ """
32
+ try:
33
+ print(f"Breaking down question with LLM: {question[:50]}...")
34
+
35
+ # Create a prompt that asks the LLM to break down the question
36
+ prompt = f"""
37
+ Please break down this question into 2-3 key search queries that would help find information to answer it.
38
+ Return ONLY the search queries, one per line, with no additional text or explanations.
39
+
40
+ Question: {question}
41
+ """
42
+
43
+ # Call the OpenAI API to get the breakdown
44
+ response = self.openai_client.chat.completions.create(
45
+ model="gpt-3.5-turbo",
46
+ messages=[
47
+ {"role": "system", "content": "You are a helpful assistant that breaks down questions into key search terms."},
48
+ {"role": "user", "content": prompt}
49
+ ],
50
+ temperature=0.3,
51
+ max_tokens=150
52
+ )
53
+
54
+ # Extract the search terms from the response
55
+ search_terms = response.choices[0].message.content.strip().split('\n')
56
+ search_terms = [term.strip() for term in search_terms if term.strip()]
57
+
58
+ print(f"Question broken down into {len(search_terms)} search terms: {search_terms}")
59
+ return search_terms
60
+
61
+ except Exception as e:
62
+ print(f"Error breaking down question: {e}")
63
+ # If there's an error, return the original question as a fallback
64
+ return [question]
65
 
66
  def search_internet(self, query: str) -> str:
67
  """
 
134
  def __call__(self, question: str) -> str:
135
  print(f"Agent received question (first 50 chars): {question[:50]}...")
136
 
137
+ # Use LLM to break down the question into key search terms
138
+ search_terms = self.break_down_question(question)
139
 
140
+ # Search for information using each search term
141
+ all_results = []
142
+ for term in search_terms:
143
+ result = self.search_internet(term)
144
+ if result and result != "No relevant information found." and not result.startswith("Error"):
145
+ all_results.append(result)
146
+
147
+ # Create a response based on collected search results
148
+ if all_results:
149
+ # Join the results with clear separation
150
+ combined_results = "\n\n--- Next Search Result ---\n\n".join(all_results)
151
+
152
+ # Use LLM to synthesize a coherent answer from the search results
153
+ try:
154
+ synthesis_prompt = f"""
155
+ Based on the following search results, please provide a comprehensive answer to this question:
156
+
157
+ Question: {question}
158
+
159
+ Search Results:
160
+ {combined_results}
161
+
162
+ Answer:
163
+ """
164
+
165
+ response = self.openai_client.chat.completions.create(
166
+ model="gpt-3.5-turbo",
167
+ messages=[
168
+ {"role": "system", "content": "You are a helpful assistant that synthesizes information to answer questions accurately."},
169
+ {"role": "user", "content": synthesis_prompt}
170
+ ],
171
+ temperature=0.5,
172
+ max_tokens=500
173
+ )
174
+
175
+ answer = response.choices[0].message.content.strip()
176
+ print("Agent returning synthesized answer from search results.")
177
+ return answer
178
+
179
+ except Exception as e:
180
+ print(f"Error synthesizing answer: {e}")
181
+ # Fallback to returning the raw search results
182
+ answer = f"Based on my searches, I found this information:\n\n{combined_results}"
183
+ print("Agent returning raw search results due to synthesis error.")
184
+ return answer
185
  else:
186
+ # Fallback to default answer if all searches fail
187
  answer = "I couldn't find specific information about that question."
188
+ print("Agent returning default answer as searches found no useful information.")
189
+ return answer
 
190
 
191
  def run_and_submit_all( profile: gr.OAuthProfile | None):
192
  """
 
311
 
312
  # --- Build Gradio Interface using Blocks ---
313
  with gr.Blocks() as demo:
314
+ gr.Markdown("# Basic Agent Evaluation Runner (Attempt #2)")
315
  gr.Markdown(
316
  """
317
  **Instructions:**
requirements.txt CHANGED
@@ -1,2 +1,3 @@
1
  gradio
2
- requests
 
 
1
  gradio
2
+ requests
3
+ openai