benjipeng commited on
Commit
b5adc16
·
verified ·
1 Parent(s): c36ad5a

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +87 -43
agent.py CHANGED
@@ -1,57 +1,101 @@
1
  import os
 
2
  import google.generativeai as genai
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  class GeminiAgent:
5
- """
6
- An agent that uses the Gemini-1.5-Pro model to answer questions.
7
- """
8
  def __init__(self):
9
- """
10
- Initializes the agent, configures the Gemini API key, and sets up the model.
11
- Raises a ValueError if the GEMINI_API_KEY is not found in the environment secrets.
12
- """
13
- print("Initializing GeminiAgent...")
14
-
15
- # 1. Get API Key from Hugging Face Secrets
16
  api_key = os.getenv("GEMINI_API_KEY")
17
  if not api_key:
18
  raise ValueError("GEMINI_API_KEY secret not found! Please set it in your Space's settings.")
19
-
20
- # 2. Configure the Generative AI client
21
  genai.configure(api_key=api_key)
22
-
23
- # 3. Initialize the Gemini 1.5 Pro model
24
- self.model = genai.GenerativeModel('gemini-1.5-pro-latest')
25
- print("GeminiAgent initialized successfully.")
 
 
 
26
 
27
- def __call__(self, question: str) -> str:
28
- """
29
- Processes a question by sending it to the Gemini model and returns the stripped text answer.
30
-
31
- The prompt is engineered to request a direct, exact-match answer as required by the competition.
32
- """
33
- print(f"Agent received question (first 80 chars): {question[:80]}...")
34
 
35
- # Prompt engineered for the "EXACT MATCH" requirement.
36
- # It instructs the model to provide only the answer and nothing else.
37
- prompt = f"""You are an expert problem-solving agent. Your goal is to answer the following question as accurately as possible.
38
- The evaluation system requires an EXACT MATCH. Therefore, you must provide only the final answer and nothing else.
39
- Do not include any introductory text, explanations, or the phrase "FINAL ANSWER".
40
- For example, if the question asks for a specific year, your response should be just "2023". If it's a name, just "John Doe". If it is a number, just "42".
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- Question: {question}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- Final Answer:"""
 
45
 
46
- try:
47
- # 4. Call the model
48
- response = self.model.generate_content(prompt)
49
-
50
- # 5. Extract and clean the answer
51
- final_answer = response.text.strip()
52
- print(f"Agent returning answer: {final_answer}")
53
- return final_answer
54
-
55
- except Exception as e:
56
- print(f"An error occurred while calling the Gemini API: {e}")
57
- return f"Error processing question: {e}"
 
1
  import os
2
+ import re
3
  import google.generativeai as genai
4
+ from tools import web_search, read_file_from_api, python_interpreter
5
+
6
+ # --- NEW, MORE ADVANCED REACT PROMPT ---
7
+ REACT_PROMPT = """
8
+ You are a state-of-the-art, helpful AI agent designed to solve complex, multi-step problems.
9
+
10
+ **Your Task:**
11
+ Your goal is to answer the user's question with 100% accuracy. To do this, you will operate in a loop of Thought, Action, and Observation. You must break down the problem into a series of smaller steps.
12
+
13
+ **Your Tools:**
14
+ You have access to the following tools. Choose ONE tool per turn.
15
+ 1. `web_search[query]`: Use this to find current information, facts, or to research topics.
16
+ 2. `read_file_from_api[task_id]`: Use this ONLY when the question or an agent note explicitly mentions an attached file. It reads the raw content of that file.
17
+ 3. `python_interpreter[code]`: Use this for all calculations, data processing, and complex logic.
18
+ - **This tool is powerful.** It has the `pandas` and `openpyxl` libraries installed.
19
+ - You can use it to analyze data from files. For example, after using `read_file_from_api`, you can pass the raw content into a Python script for processing.
20
+ - For Excel files, it's often better to use `pandas.read_excel(file_url)` directly within the python tool, where `file_url` can be constructed from the task_id.
21
+
22
+ **Reasoning Process:**
23
+ 1. **Thought:** Carefully analyze the question. Identify the required information and devise a step-by-step plan.
24
+ 2. **Action:** Choose the appropriate tool and input to execute the current step of your plan. Your action MUST be in the format `Action: tool_name[input]`.
25
+ 3. **Observation:** You will receive the result of your action.
26
+ 4. **Repeat:** Analyze the observation and continue with the next step in your plan until you have the final answer.
27
+
28
+ **CRITICAL SUBMISSION RULE:**
29
+ When you have the final, definitive answer, you MUST format your response as:
30
+ `Final Answer: [The single, exact answer]`
31
+ The system will automatically extract only the text after this prefix for submission. Do not add any other text or explanation.
32
+
33
+ ---
34
+ Here is the problem:
35
+ Question: {question}
36
+ """
37
 
38
  class GeminiAgent:
 
 
 
39
  def __init__(self):
40
+ print("Initializing GeminiAgent (Advanced ReAct)...")
41
+ # ... (init logic remains the same: api_key, model, tools)
 
 
 
 
 
42
  api_key = os.getenv("GEMINI_API_KEY")
43
  if not api_key:
44
  raise ValueError("GEMINI_API_KEY secret not found! Please set it in your Space's settings.")
 
 
45
  genai.configure(api_key=api_key)
46
+ self.model = genai.GenerativeModel('gemini-2.5-pro')
47
+ self.tools = {
48
+ "web_search": web_search,
49
+ "read_file_from_api": read_file_from_api,
50
+ "python_interpreter": python_interpreter
51
+ }
52
+ print("GeminiAgent initialized successfully with model 'gemini-2.5-pro'.")
53
 
54
+
55
+ # MODIFIED to accept task_id
56
+ def __call__(self, question: str, task_id: str) -> str:
57
+ prompt = REACT_PROMPT.format(question=question)
 
 
 
58
 
59
+ # ReAct loop
60
+ for turn in range(10): # Max 10 turns
61
+ print(f"\n--- Turn {turn + 1} for Task ID: {task_id} ---\n")
62
+
63
+ response = self.model.generate_content(prompt)
64
+ if not response.parts:
65
+ print("Warning: Model returned an empty response.")
66
+ prompt += "\nObservation: The model returned an empty response. Please try again."
67
+ continue
68
+
69
+ response_text = response.text
70
+ print(f"LLM Response:\n{response_text}\n")
71
+
72
+ # Check for Final Answer
73
+ final_answer_match = re.search(r"Final Answer: (.*)", response_text, re.DOTALL)
74
+ if final_answer_match:
75
+ answer = final_answer_match.group(1).strip()
76
+ print(f"Final Answer extracted: '{answer}'")
77
+ return answer
78
 
79
+ # Look for an Action
80
+ action_match = re.search(r"Action: (\w+)\[(.*)\]", response_text, re.DOTALL)
81
+ if not action_match:
82
+ observation = "No valid 'Action:' or 'Final Answer:' found. Please think step-by-step and select a tool or provide the final answer."
83
+ else:
84
+ tool_name = action_match.group(1).strip()
85
+ tool_input = action_match.group(2).strip()
86
+
87
+ if tool_name not in self.tools:
88
+ observation = f"Error: Unknown tool '{tool_name}'."
89
+ else:
90
+ try:
91
+ # Pass the task_id to the tool function, which can then use it if needed
92
+ observation = self.tools[tool_name](tool_input if tool_name != 'read_file_from_api' else task_id)
93
+ except Exception as e:
94
+ observation = f"Error executing tool {tool_name}: {e}"
95
+
96
+ print(f"Observation:\n{observation}\n")
97
 
98
+ # Append the full turn to the prompt
99
+ prompt += f"{response_text}\nObservation: {observation}\n"
100
 
101
+ return "Agent failed to find an answer within 10 turns."