ABVM commited on
Commit
e689a4f
·
verified ·
1 Parent(s): 9ea57d7

Upload multi_agent.py

Browse files
Files changed (1) hide show
  1. multi_agent.py +168 -0
multi_agent.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import (
2
+ CodeAgent,
3
+ InferenceClientModel,
4
+ VisitWebpageTool,
5
+ WebSearchTool,
6
+ WikipediaSearchTool,
7
+ PythonInterpreterTool,
8
+ FinalAnswerTool,
9
+ tool,
10
+ )
11
+ from groq import Groq
12
+ from typing import Dict, Any
13
+ import os
14
+ import time
15
+
16
+
17
+ # ---- TOOLS ----
18
+ @tool
19
+ def image_process(image_file: str) -> Dict[str, str]:
20
+ """
21
+ Extract text from an image file using OCR and return OCR text and base64 encoding.
22
+
23
+ Args:
24
+ image_file: Path to the image file
25
+
26
+ Returns:
27
+ Dict with keys 'ocr_text' and 'base64_image'
28
+ """
29
+ try:
30
+ import pytesseract
31
+ from PIL import Image
32
+ from smolagents.utils import encode_image_base64
33
+
34
+ image = Image.open(image_file)
35
+ base64_img = encode_image_base64(image)
36
+ text = pytesseract.image_to_string(image)
37
+ return {"ocr_text": text, "base64_image": base64_img}
38
+ except Exception as e:
39
+ return {"ocr_text": "", "base64_image": "", "error": str(e)}
40
+
41
+
42
+ # ---- GROQ MODEL WRAPPER ----
43
+ class LLMResponse:
44
+ def __init__(self, content: str, token_usage: int | None = None):
45
+ self.content = content
46
+ self.token_usage = token_usage
47
+
48
+
49
+ class GroqModel:
50
+ def __init__(self, model_name=""):
51
+ self.model_name = model_name
52
+ self.client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
53
+
54
+ def __call__(self, prompt, max_tokens=8096):
55
+ if isinstance(prompt, str):
56
+ messages = [{"role": "user", "content": prompt}]
57
+ else:
58
+ messages = prompt
59
+
60
+ response = None
61
+ for attempt in range(3):
62
+ try:
63
+ response = self.client.chat.completions.create(
64
+ messages=messages,
65
+ model=self.model_name,
66
+ stream=False,
67
+ max_tokens=max_tokens,
68
+ )
69
+ break
70
+ except Exception as e:
71
+ msg = str(e).lower()
72
+ if "rate limit" in msg and attempt < 2:
73
+ wait = 10 * (attempt + 1)
74
+ time.sleep(wait)
75
+ continue
76
+ raise
77
+
78
+ if response is None:
79
+ response = self.client.chat.completions.create(
80
+ messages=messages,
81
+ model=self.model_name,
82
+ stream=False,
83
+ max_tokens=max_tokens,
84
+ )
85
+
86
+ content = response.choices[0].message.content
87
+ token_usage = None
88
+ if hasattr(response, "usage") and response.usage is not None:
89
+ token_usage = response.usage.total_tokens
90
+
91
+ return LLMResponse(content, token_usage)
92
+
93
+ def generate(self, prompt, max_tokens=8096, **kwargs):
94
+ # For compatibility with agent frameworks
95
+ return self.__call__(prompt, max_tokens=max_tokens)
96
+
97
+
98
+ # ---- MULTI-AGENT SYSTEM ----
99
+ class MultyAgentSystem:
100
+ def __init__(self):
101
+ deepseek_model = GroqModel("deepseek-r1-distill-llama-70b")
102
+ qwen_model = GroqModel("qwen-qwq-32b")
103
+
104
+ # --- Web agent definition ---
105
+ self.web_agent = CodeAgent(
106
+ model=qwen_model,
107
+ tools=[WebSearchTool(), VisitWebpageTool(), WikipediaSearchTool()],
108
+ name="web_agent",
109
+ description=(
110
+ "You are a web browsing agent. Whenever the given {task} involves browsing "
111
+ "the web or a specific website such as Wikipedia or YouTube, you will use "
112
+ "the provided tools. For web-based factual and retrieval tasks, be as precise and source-reliable as possible."
113
+ ),
114
+ additional_authorized_imports=[
115
+ "markdownify",
116
+ "json",
117
+ "requests",
118
+ "urllib.request",
119
+ "urllib.parse",
120
+ "wikipedia-api",
121
+ ],
122
+ verbosity_level=0,
123
+ max_steps=10,
124
+ )
125
+
126
+ # --- Info agent definition ---
127
+ self.info_agent = CodeAgent(
128
+ model=qwen_model,
129
+ tools=[PythonInterpreterTool(), image_process],
130
+ name="info_agent",
131
+ description=(
132
+ "You are an agent tasked with cleaning, parsing, calculating information, and performing OCR if images are provided in the {task}. "
133
+ "You handle all math, code, and data manipulation. Use numpy, math, and available libraries. For image or chess tasks, use pytesseract, PIL, or chess as required."
134
+ ),
135
+ additional_authorized_imports=[
136
+ "numpy",
137
+ "math",
138
+ "pytesseract",
139
+ "PIL",
140
+ "chess",
141
+ ],
142
+ )
143
+
144
+ # --- Manager agent definition ---
145
+ self.manager_agent = CodeAgent(
146
+ model=deepseek_model,
147
+ tools=[FinalAnswerTool()],
148
+ managed_agents=[self.web_agent, self.info_agent],
149
+ name="manager_agent",
150
+ description=(
151
+ "You are the manager. Given a {task}, plan which agent to use: "
152
+ "If web data is needed, delegate to web_agent. If math, parsing, or code is needed, use info_agent. "
153
+ "After collecting outputs, optionally cross-validate and check correctness, then finalize and submit the best answer using FinalAnswerTool. "
154
+ "For each task, explicitly explain your planning steps and reasons for choosing which agent, and always prefer the most accurate and complete answer possible."
155
+ ),
156
+ additional_authorized_imports=[
157
+ "json",
158
+ "pandas",
159
+ "numpy",
160
+ ],
161
+ planning_interval=5,
162
+ verbosity_level=2,
163
+ max_steps=20,
164
+ )
165
+
166
+ def __call__(self, question, **kwargs):
167
+
168
+ return self.manager_agent(question, **kwargs)