drAbreu commited on
Commit
9f47584
·
1 Parent(s): 1c0f5f2

Changed to mini models of openai to make it faster

Browse files
Files changed (2) hide show
  1. agents/llama_index_agent.py +51 -40
  2. app.py +48 -20
agents/llama_index_agent.py CHANGED
@@ -83,11 +83,14 @@ class GaiaAgent(ReActAgent):
83
  if system_prompt is None:
84
  system_prompt = self._get_default_system_prompt()
85
 
 
 
86
  can_handoff_to = [
87
  "writer_agent",
 
88
  ]
89
 
90
- # Initialize the parent ReActAgent
91
  super().__init__(
92
  name=name,
93
  description=description,
@@ -95,6 +98,7 @@ class GaiaAgent(ReActAgent):
95
  system_prompt=system_prompt,
96
  tools=tools,
97
  can_handoff_to=can_handoff_to,
 
98
  **kwargs
99
  )
100
 
@@ -114,7 +118,7 @@ class GaiaAgent(ReActAgent):
114
  return Anthropic(
115
  model=model_name,
116
  api_key=api_key or os.getenv("ANTHROPIC_API_KEY"),
117
- temperature=1.0 if "3-7" in model_name else 0.5,
118
  thinking_dict={"type": "enabled", "budget_tokens": 2048} if "3-7" in model_name else None,
119
  max_tokens=2048*4
120
  )
@@ -129,6 +133,14 @@ class GaiaAgent(ReActAgent):
129
  return """
130
  You are the lead coordinator for a team of specialized AI agents tackling the GAIA benchmark. Your job is to analyze questions and generate detailed analysis, which you'll pass to a specialized formatting agent for final answer preparation.
131
 
 
 
 
 
 
 
 
 
132
  ## QUESTION ANALYSIS PROCESS
133
  1. First, carefully read and parse the entire question
134
  2. Identify the EXACT output format required (single word, name, number, comma-separated list, etc.)
@@ -185,25 +197,17 @@ class GaiaAgent(ReActAgent):
185
  4. For data analysis tasks, ensure you've properly processed the CSV data and extracted the requested information
186
  5. When calculations or statistics are needed, perform them accurately and document your methodology
187
 
188
- ## DELEGATION TO WRITER AGENT
189
- After completing your analysis, ALWAYS delegate the final answer preparation to the writer_agent with:
190
- - query: The original question
191
- - research_notes: Your complete analysis, all relevant facts, and what you believe is the correct answer
192
- - answer_format: EXPLICIT instructions on exactly how the answer should be formatted (single word, comma-separated list, etc.)
193
-
194
- Example handoff to writer_agent:
195
- ```
196
- I'll delegate to writer_agent to format the final answer.
197
-
198
- query: What is the first name of the scientist who discovered penicillin?
199
- research_notes: After researching, I found that Sir Alexander Fleming discovered penicillin in 1928. The full answer is "Alexander Fleming" but the question only asks for the first name, which is "Alexander".
200
- ```
201
 
202
- IMPORTANT: NEVER provide the final answer directly to the user. ALWAYS hand off to the writer_agent for proper formatting.
 
 
203
 
204
- IMPORTANT: The final answer will be provided by the `review_agent`. Publish it as you receive it.
205
  """
206
 
 
207
  def create_writer_agent(model_config: Dict[str, Any]) -> ReActAgent:
208
  """
209
  Create a writer agent that formats final answers based on research notes.
@@ -241,46 +245,49 @@ def create_writer_agent(model_config: Dict[str, Any]) -> ReActAgent:
241
  else:
242
  raise ValueError(f"Unsupported model provider for writer agent: {model_provider}")
243
 
244
- # Create and return the writer agent
245
  return ReActAgent(
246
  name="writer_agent",
247
  description="Formats the final answer based on research notes for GAIA benchmark questions",
248
  system_prompt="""
249
  You are a specialized formatting agent for the GAIA benchmark. Your job is to take the research from the main agent and format the answer according to the benchmark requirements.
250
 
 
 
 
 
 
 
 
251
  ## YOUR ROLE
252
  You will receive:
253
  - query: The original question
254
  - research_notes: The main agent's complete analysis and reasoning
 
255
 
256
  ## FORMATTING RULES
257
- 1. Format the answer according to the instructions in the `query` received
258
  2. Your answers will be always as minimal as necessary to answer the question
259
- 2. Try to remove unnecessary characters, spaces, or wording
260
- 3. If asked for a name, provide **ONLY** the name
261
- 4. If asked for a number, provide the **ONLY** number
262
- 5. If asked for a list, format it exactly as specified
263
 
264
- ## DELEGATION TO REVIEW AGENT
265
- After formatting your answer, ALWAYS delegate to the review_agent with:
266
- - query: The original question
267
- - formatted_answer: Your formatted answer
268
 
269
- Example handoff to review_agent:
270
- ```
271
- I'll delegate to review_agent for final review.
272
-
273
- query: What is the first name of the scientist who discovered penicillin?
274
- formatted_answer: Alexander
275
- format_requirements: Return ONLY the first name, with no additional text.
276
- ```
277
 
278
- IMPORTANT: ALWAYS hand off to the "review_agent" for final verification and cleanup.
279
  """,
280
  llm=llm,
281
- can_handoff_to=["review_agent"]
 
282
  )
283
 
 
284
  def create_review_agent(model_config: Dict[str, Any]) -> ReActAgent:
285
  """
286
  Create a review agent that ensures the final answer follows exact formatting requirements.
@@ -329,6 +336,7 @@ def create_review_agent(model_config: Dict[str, Any]) -> ReActAgent:
329
  You will receive:
330
  - query: The original question
331
  - formatted_answer: The answer formatted by the writer agent
 
332
 
333
  ## CRITICAL RULES
334
  1. Your ENTIRE response must be ONLY the final answer - NOTHING ELSE
@@ -347,6 +355,9 @@ def create_review_agent(model_config: Dict[str, Any]) -> ReActAgent:
347
  - Case sensitivity (e.g., "PARIS" vs "Paris")
348
  - List formatting (e.g., comma-separated vs numbered)
349
 
 
 
 
350
  ## OUTPUT EXAMPLES
351
  - Input: "The answer is Alexander."
352
  Output: Alexander
@@ -361,10 +372,10 @@ def create_review_agent(model_config: Dict[str, Any]) -> ReActAgent:
361
  - Input: "She published studio albums "Album 1", "Album 2", "Album 3", so in total 3."
362
  Output: 3
363
  - Input: Misa Criolla (2000), Acústico (2002), Corazón Libre (2005), Cantora 1 (2009), and Cantora 2 (2009)
364
- Output 5
365
 
366
  REMEMBER: Your ENTIRE response should be just the bare answer with NOTHING else.
367
  """,
368
  llm=llm,
369
- can_handoff_to=["jefe"]
370
- )
 
83
  if system_prompt is None:
84
  system_prompt = self._get_default_system_prompt()
85
 
86
+ # CRITICAL: Explicitly define which agents this agent can hand off to
87
+ # This needs to be defined before calling super().__init__
88
  can_handoff_to = [
89
  "writer_agent",
90
+ "review_agent"
91
  ]
92
 
93
+ # Initialize the parent ReActAgent with explicit handoff configuration
94
  super().__init__(
95
  name=name,
96
  description=description,
 
98
  system_prompt=system_prompt,
99
  tools=tools,
100
  can_handoff_to=can_handoff_to,
101
+ verbose=True, # Enable verbose mode for better debugging
102
  **kwargs
103
  )
104
 
 
118
  return Anthropic(
119
  model=model_name,
120
  api_key=api_key or os.getenv("ANTHROPIC_API_KEY"),
121
+ temperature=0.7 if "3-7" in model_name else 0.5, # Slightly reduced temperature
122
  thinking_dict={"type": "enabled", "budget_tokens": 2048} if "3-7" in model_name else None,
123
  max_tokens=2048*4
124
  )
 
133
  return """
134
  You are the lead coordinator for a team of specialized AI agents tackling the GAIA benchmark. Your job is to analyze questions and generate detailed analysis, which you'll pass to a specialized formatting agent for final answer preparation.
135
 
136
+ ## CRITICAL WORKFLOW INSTRUCTIONS
137
+ YOU MUST FOLLOW THIS EXACT WORKFLOW:
138
+ 1. Analyze the question thoroughly
139
+ 2. Use tools if needed for research
140
+ 3. Formulate your answer
141
+ 4. ALWAYS use the handoff tool to delegate to writer_agent
142
+ 5. NEVER provide a direct answer with "Answer:" - this breaks the workflow
143
+
144
  ## QUESTION ANALYSIS PROCESS
145
  1. First, carefully read and parse the entire question
146
  2. Identify the EXACT output format required (single word, name, number, comma-separated list, etc.)
 
197
  4. For data analysis tasks, ensure you've properly processed the CSV data and extracted the requested information
198
  5. When calculations or statistics are needed, perform them accurately and document your methodology
199
 
200
+ ## REQUIRED HANDOFF TO WRITER AGENT
201
+ After completing your analysis, you MUST ALWAYS use the handoff tool with EXACTLY this format:
 
 
 
 
 
 
 
 
 
 
 
202
 
203
+ Thought: I have completed my analysis and need to delegate to the writer agent for proper formatting.
204
+ Action: handoff
205
+ Action Input: {"to_agent": "writer_agent", "reason": "Need to format the final answer according to requirements", "query": "<original question>", "research_notes": "<my complete analysis and what I believe is the correct answer>", "format_requirements": "<explicit formatting instructions>"}
206
 
207
+ CRITICAL: Even if the answer seems obvious or simple, you MUST use the handoff tool with the EXACT format above. NEVER respond with "Answer: ..." as this breaks the workflow.
208
  """
209
 
210
+
211
  def create_writer_agent(model_config: Dict[str, Any]) -> ReActAgent:
212
  """
213
  Create a writer agent that formats final answers based on research notes.
 
245
  else:
246
  raise ValueError(f"Unsupported model provider for writer agent: {model_provider}")
247
 
248
+ # Create and return the writer agent with updated system prompt
249
  return ReActAgent(
250
  name="writer_agent",
251
  description="Formats the final answer based on research notes for GAIA benchmark questions",
252
  system_prompt="""
253
  You are a specialized formatting agent for the GAIA benchmark. Your job is to take the research from the main agent and format the answer according to the benchmark requirements.
254
 
255
+ ## CRITICAL WORKFLOW INSTRUCTIONS
256
+ YOU MUST FOLLOW THIS EXACT WORKFLOW:
257
+ 1. Review the main agent's research and format requirements
258
+ 2. Format the answer according to specifications
259
+ 3. ALWAYS use the handoff tool to delegate to review_agent
260
+ 4. NEVER provide a direct answer with "Answer:" - this breaks the workflow
261
+
262
  ## YOUR ROLE
263
  You will receive:
264
  - query: The original question
265
  - research_notes: The main agent's complete analysis and reasoning
266
+ - format_requirements: How the answer should be formatted
267
 
268
  ## FORMATTING RULES
269
+ 1. Format the answer according to the instructions in the `query` and `format_requirements`
270
  2. Your answers will be always as minimal as necessary to answer the question
271
+ 3. Remove unnecessary characters, spaces, or wording
272
+ 4. If asked for a name, provide **ONLY** the name
273
+ 5. If asked for a number, provide the **ONLY** number
274
+ 6. If asked for a list, format it exactly as specified
275
 
276
+ ## REQUIRED HANDOFF TO REVIEW AGENT
277
+ After formatting your answer, you MUST ALWAYS use the handoff tool with EXACTLY this format:
 
 
278
 
279
+ Thought: I have formatted the answer and need to delegate to the review agent for final verification.
280
+ Action: handoff
281
+ Action Input: {"to_agent": "review_agent", "reason": "Need final verification and cleanup", "query": "<original question>", "formatted_answer": "<my formatted answer>", "format_requirements": "<explicit formatting requirements>"}
 
 
 
 
 
282
 
283
+ CRITICAL: Even if the answer seems perfectly formatted already, you MUST use the handoff tool with the EXACT format above. NEVER respond with "Answer: ..." as this breaks the workflow.
284
  """,
285
  llm=llm,
286
+ can_handoff_to=["review_agent"],
287
+ verbose=True # Enable verbose mode for better debugging
288
  )
289
 
290
+
291
  def create_review_agent(model_config: Dict[str, Any]) -> ReActAgent:
292
  """
293
  Create a review agent that ensures the final answer follows exact formatting requirements.
 
336
  You will receive:
337
  - query: The original question
338
  - formatted_answer: The answer formatted by the writer agent
339
+ - format_requirements: How the answer should be formatted
340
 
341
  ## CRITICAL RULES
342
  1. Your ENTIRE response must be ONLY the final answer - NOTHING ELSE
 
355
  - Case sensitivity (e.g., "PARIS" vs "Paris")
356
  - List formatting (e.g., comma-separated vs numbered)
357
 
358
+ ## OUTPUT FORMAT
359
+ Your entire response should be ONLY the final, formatted answer. Do not include any additional text, explanation, or reasoning.
360
+
361
  ## OUTPUT EXAMPLES
362
  - Input: "The answer is Alexander."
363
  Output: Alexander
 
372
  - Input: "She published studio albums "Album 1", "Album 2", "Album 3", so in total 3."
373
  Output: 3
374
  - Input: Misa Criolla (2000), Acústico (2002), Corazón Libre (2005), Cantora 1 (2009), and Cantora 2 (2009)
375
+ Output: 5
376
 
377
  REMEMBER: Your ENTIRE response should be just the bare answer with NOTHING else.
378
  """,
379
  llm=llm,
380
+ can_handoff_to=[] # Review agent is the final step, so it doesn't hand off to anyone
381
+ )
app.py CHANGED
@@ -32,8 +32,8 @@ OPENAI = {
32
  class BasicAgent:
33
  def __init__(
34
  self,
35
- model_provider="anthropic",
36
- model_name="claude-3-7-sonnet-latest",
37
  api_key=None,
38
  use_separate_writer_model=True,
39
  writer_model_provider="openai",
@@ -126,7 +126,7 @@ class BasicAgent:
126
 
127
  print(f"Agent received question (first 50 chars): {question_text[:50]}...")
128
 
129
- # Download audio file if present
130
  local_file_path = None
131
  if file_name and task_id:
132
  try:
@@ -144,30 +144,58 @@ class BasicAgent:
144
  "analysis_notes": "",
145
  "format_requirements": "",
146
  "next_agent": "",
147
- "final_answer": ""
 
 
148
  }
149
 
150
- # MODIFY THIS PART - Instead of just passing the question text,
151
- # create a more detailed input that includes the audio file path information
152
- enhanced_input = f"""Task ID: {task_id}
153
- Question: {question_text}
154
-
 
 
 
 
155
  """
156
- # Add audio file information if available
157
- if local_file_path:
158
- enhanced_input += f"Audio File Path: {local_file_path}\n\nPlease analyze this question. If it involves an audio file, use the transcribe_audio tool with the provided path."
159
 
160
- # Use the workflow to process the question with enhanced input
161
- workflow_response = await self.agent_workflow.run(
162
- enhanced_input,
163
- initial_state=initial_state
164
- )
165
- return workflow_response
166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  response = asyncio.run(agentic_main())
168
 
169
- # Extract the final answer from the writer agent's response
170
- final_answer = response.response.blocks[-1].text
 
 
 
171
  print(f"Agent returning final answer: {final_answer}")
172
  return final_answer
173
 
 
32
  class BasicAgent:
33
  def __init__(
34
  self,
35
+ model_provider="openai",
36
+ model_name="o4-mini",
37
  api_key=None,
38
  use_separate_writer_model=True,
39
  writer_model_provider="openai",
 
126
 
127
  print(f"Agent received question (first 50 chars): {question_text[:50]}...")
128
 
129
+ # Download file if present
130
  local_file_path = None
131
  if file_name and task_id:
132
  try:
 
144
  "analysis_notes": "",
145
  "format_requirements": "",
146
  "next_agent": "",
147
+ "final_answer": "",
148
+ "workflow_state": "initial_analysis", # Track workflow state
149
+ "require_handoff": True, # Flag that handoff is required
150
  }
151
 
152
+ # Create a more detailed input with workflow instructions
153
+ enhanced_input = f"""
154
+ WORKFLOW INSTRUCTIONS:
155
+ 1. You (jefe) MUST analyze this question and find the answer
156
+ 2. After analysis, you MUST use the handoff tool to delegate to writer_agent
157
+ 3. NEVER provide a direct answer - always delegate using the handoff tool
158
+
159
+ Task ID: {task_id}
160
+ Question: {question_text}
161
  """
 
 
 
162
 
163
+ # Add file information if available
164
+ if local_file_path:
165
+ enhanced_input += f"\nFile Path: {local_file_path}\n\nPlease analyze this question. If it involves an audio file, use the transcribe_audio tool with the provided path."
 
 
 
166
 
167
+ # Monitor the workflow execution
168
+ print("Starting workflow execution...")
169
+ try:
170
+ workflow_response = await self.agent_workflow.run(
171
+ enhanced_input,
172
+ initial_state=initial_state
173
+ )
174
+
175
+ # Extract the final answer from the last response
176
+ if hasattr(workflow_response.response, 'blocks') and workflow_response.response.blocks:
177
+ final_answer = workflow_response.response.blocks[-1].text
178
+ print(f"Workflow completed. Final answer extracted: {final_answer}")
179
+ return final_answer
180
+ else:
181
+ print("Warning: Could not extract final answer from workflow response blocks")
182
+ # Try to extract from the response content
183
+ final_answer = str(workflow_response.response)
184
+ return final_answer
185
+
186
+ except Exception as e:
187
+ print(f"Error in workflow execution: {e}")
188
+ import traceback
189
+ traceback.print_exc()
190
+ return f"Error: {str(e)}"
191
+
192
  response = asyncio.run(agentic_main())
193
 
194
+ # Extract the final answer and remove any "Answer:" prefix
195
+ final_answer = response.response.blocks[-1].text if hasattr(response, 'response') and hasattr(response.response, 'blocks') else str(response)
196
+ if isinstance(final_answer, str) and final_answer.startswith("Answer:"):
197
+ final_answer = final_answer.replace("Answer:", "").strip()
198
+
199
  print(f"Agent returning final answer: {final_answer}")
200
  return final_answer
201