grevy Claude Opus 4.7 commited on
Commit
7e8db03
·
1 Parent(s): 15f4283

Add CodeAgent subagent with Qwen coder model + expose compute tool

Browse files

New architecture at manager level (4 subagents):
BasicAgent
├── web_research -> WebResearchAgent
├── file_analysis -> FileAnalysisAgent
├── media_analysis -> MediaAgent
├── compute -> CodeAgent (NEW)
└── AnswerNormalizer

CodeAgent wraps python_exec + calculator behind a specialist that
writes Python, runs it, and iterates on errors. Uses Qwen 2.5 Coder
32B by default via GROQ_CODE_MODEL env var (override to
openai/gpt-oss-120b or deepseek-r1-distill-llama-70b if Groq drops
the Qwen model).

tools.py: python_exec + calculator no longer in ALL_TOOLS; wrapped
by compute() which delegates to CodeAgent.

app.py: manager system prompt updated to describe 4 specialists.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ryPUj8AtsFopnufGRSc4L

Files changed (3) hide show
  1. agents.py +41 -0
  2. app.py +8 -8
  3. tools.py +18 -3
agents.py CHANGED
@@ -13,6 +13,16 @@ def _make_llm(model: str = "openai/gpt-oss-120b", temperature: float = 0.1) -> C
13
  )
14
 
15
 
 
 
 
 
 
 
 
 
 
 
16
  WEB_RESEARCH_PROMPT = """You are a web research specialist.
17
 
18
  For each question:
@@ -45,6 +55,22 @@ Workflow:
45
  verbatim when possible. Do not speculate."""
46
 
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  MEDIA_ANALYSIS_PROMPT = """You are a media analysis specialist (image, audio, video).
49
 
50
  You handle questions that reference a task_id, URL, or file path pointing to
@@ -144,6 +170,21 @@ class MediaAgent:
144
  return result["messages"][-1].content
145
 
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  class AnswerNormalizer:
148
  def __init__(self):
149
  self.llm = _make_llm(temperature=0.0)
 
13
  )
14
 
15
 
16
+ def _make_code_llm() -> ChatGroq:
17
+ """LLM for CodeAgent. Defaults to Qwen 2.5 Coder 32B on Groq.
18
+
19
+ Override with GROQ_CODE_MODEL env var if Groq drops it (e.g. set to
20
+ ``openai/gpt-oss-120b`` or ``deepseek-r1-distill-llama-70b``).
21
+ """
22
+ model = os.getenv("GROQ_CODE_MODEL", "qwen-2.5-coder-32b")
23
+ return _make_llm(model=model, temperature=0.1)
24
+
25
+
26
  WEB_RESEARCH_PROMPT = """You are a web research specialist.
27
 
28
  For each question:
 
55
  verbatim when possible. Do not speculate."""
56
 
57
 
58
+ CODE_AGENT_PROMPT = """You are a Python computation specialist.
59
+
60
+ You answer questions that need arithmetic, list/string manipulation, date math,
61
+ pandas transforms, unit conversions, or any calculation better *computed* than
62
+ reasoned about.
63
+
64
+ Workflow:
65
+ 1. Prefer `calculator` for a single closed-form math expression.
66
+ 2. Otherwise write a short Python snippet and run it via `python_exec`.
67
+ You MUST `print()` any value you want to see back — the tool returns stdout.
68
+ 3. If `python_exec` returns an error, read the traceback, fix the code, and
69
+ retry. Do not give up after one failure; iterate up to 3 times.
70
+ 4. Return ONLY the final computed value. No code in the final answer, no
71
+ explanation, no units unless asked."""
72
+
73
+
74
  MEDIA_ANALYSIS_PROMPT = """You are a media analysis specialist (image, audio, video).
75
 
76
  You handle questions that reference a task_id, URL, or file path pointing to
 
170
  return result["messages"][-1].content
171
 
172
 
173
+ class CodeAgent:
174
+ def __init__(self):
175
+ from tools import calculator, python_exec # lazy: avoids circular import
176
+
177
+ self.graph = create_agent(
178
+ _make_code_llm(),
179
+ tools=[python_exec, calculator],
180
+ system_prompt=CODE_AGENT_PROMPT,
181
+ )
182
+
183
+ def __call__(self, question: str) -> str:
184
+ result = self.graph.invoke({"messages": [("user", question)]})
185
+ return result["messages"][-1].content
186
+
187
+
188
  class AnswerNormalizer:
189
  def __init__(self):
190
  self.llm = _make_llm(temperature=0.0)
app.py CHANGED
@@ -17,22 +17,22 @@ from langgraph.prebuilt import ToolNode
17
 
18
  MANAGER_SYSTEM_PROMPT = """You are a QA agent for the GAIA benchmark.
19
 
20
- You have five tools:
21
- - web_research(question): factual/current world knowledge (people, dates, events).
 
22
  - file_analysis(question): question about an attached document
23
- (pdf/xlsx/csv/txt/json). Include the task_id or URL in your question.
24
  - media_analysis(question): question about an image, audio, or video (also
25
  YouTube URLs). Include the task_id or URL in your question.
26
- - python_exec(code): run Python for computation, list ops, date math,
27
- string parsing. You must print() the result.
28
- - calculator(expression): plain math expressions.
29
 
30
  Rules:
31
  1. When a task has an attached file (mentioned by task_id), route to
32
  file_analysis or media_analysis with the task_id embedded in the question.
33
  2. Ask each specialist ONE precise question at a time.
34
- 3. Chain tools when needed (e.g. web_research to find a number, then
35
- calculator to combine).
36
  4. Final answer: give ONLY the value the question asks for. No preamble,
37
  no explanation."""
38
 
 
17
 
18
  MANAGER_SYSTEM_PROMPT = """You are a QA agent for the GAIA benchmark.
19
 
20
+ You have four specialist tools:
21
+ - web_research(question): factual / current world knowledge (people, dates,
22
+ events, statistics).
23
  - file_analysis(question): question about an attached document
24
+ (pdf / xlsx / csv / txt / json). Include the task_id or URL in your question.
25
  - media_analysis(question): question about an image, audio, or video (also
26
  YouTube URLs). Include the task_id or URL in your question.
27
+ - compute(question): math, arithmetic, list ops, date math, string parsing,
28
+ unit conversions. State the computation in plain language with the inputs.
 
29
 
30
  Rules:
31
  1. When a task has an attached file (mentioned by task_id), route to
32
  file_analysis or media_analysis with the task_id embedded in the question.
33
  2. Ask each specialist ONE precise question at a time.
34
+ 3. Chain tools when needed (e.g. web_research to find numbers, then
35
+ compute to combine them).
36
  4. Final answer: give ONLY the value the question asks for. No preamble,
37
  no explanation."""
38
 
tools.py CHANGED
@@ -13,7 +13,7 @@ from langchain_core.tools import tool
13
  from langchain_groq import ChatGroq
14
  from tavily import TavilyClient
15
 
16
- from agents import FileAnalysisAgent, MediaAgent, WebResearchAgent
17
 
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
 
@@ -381,6 +381,7 @@ def youtube_transcript(url_or_id: str) -> str:
381
  _web_agent = WebResearchAgent()
382
  _file_agent = FileAnalysisAgent()
383
  _media_agent = MediaAgent()
 
384
 
385
 
386
  @tool
@@ -431,10 +432,24 @@ def media_analysis(question: str) -> str:
431
  return _media_agent(question)
432
 
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  ALL_TOOLS = [
435
  web_research,
436
  file_analysis,
437
  media_analysis,
438
- python_exec,
439
- calculator,
440
  ]
 
13
  from langchain_groq import ChatGroq
14
  from tavily import TavilyClient
15
 
16
+ from agents import CodeAgent, FileAnalysisAgent, MediaAgent, WebResearchAgent
17
 
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
 
 
381
  _web_agent = WebResearchAgent()
382
  _file_agent = FileAnalysisAgent()
383
  _media_agent = MediaAgent()
384
+ _code_agent = CodeAgent()
385
 
386
 
387
  @tool
 
432
  return _media_agent(question)
433
 
434
 
435
+ @tool
436
+ def compute(question: str) -> str:
437
+ """Delegate math, arithmetic, data manipulation, or string parsing to a code specialist.
438
+
439
+ The specialist writes Python, runs it, iterates on errors, and returns the
440
+ computed value. Use for anything better *computed* than reasoned about:
441
+ sums / averages / dates / list ops / unit conversions / regex extraction.
442
+
443
+ Args:
444
+ question: What to compute, plainly stated. Include any input data or
445
+ values needed to perform the computation.
446
+ """
447
+ return _code_agent(question)
448
+
449
+
450
  ALL_TOOLS = [
451
  web_research,
452
  file_analysis,
453
  media_analysis,
454
+ compute,
 
455
  ]