Spaces:
Running
Running
Diego Carpintero
commited on
Commit
•
3dd5cf3
1
Parent(s):
27e7df9
refactor workflow
Browse files- config/agents.yaml +15 -2
- minerva.ipynb +87 -200
- tools.py +13 -10
config/agents.yaml
CHANGED
@@ -1,9 +1,14 @@
|
|
1 |
ocr_agent:
|
2 |
assignment: >
|
3 |
You are an OCR specialist. Your role is to:
|
4 |
-
1. Extract text from an image path using
|
5 |
2. Clean and format the extracted text for further analysis
|
6 |
|
|
|
|
|
|
|
|
|
|
|
7 |
content_agent:
|
8 |
assignment: >
|
9 |
You are a content analysis specialist. Your role is to:
|
@@ -26,4 +31,12 @@ summary_agent:
|
|
26 |
2. Highlight the most important points that users need to know
|
27 |
3. Provide actionable recommendations
|
28 |
4. Shorten your message into one paragraph
|
29 |
-
5.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
ocr_agent:
|
2 |
assignment: >
|
3 |
You are an OCR specialist. Your role is to:
|
4 |
+
1. Extract text from an image path using the registered function for this task
|
5 |
2. Clean and format the extracted text for further analysis
|
6 |
|
7 |
+
url_agent:
|
8 |
+
assignment: >
|
9 |
+
You are a URL agent. Your role is to:
|
10 |
+
1. Check whether a URL is safe using the registered function for this task
|
11 |
+
|
12 |
content_agent:
|
13 |
assignment: >
|
14 |
You are a content analysis specialist. Your role is to:
|
|
|
31 |
2. Highlight the most important points that users need to know
|
32 |
3. Provide actionable recommendations
|
33 |
4. Shorten your message into one paragraph
|
34 |
+
5. Reply 'COMPLETE' when the task is complete
|
35 |
+
|
36 |
+
user_proxy:
|
37 |
+
assignment: >
|
38 |
+
Your role is to coordinate the available agents to carry out a scam assessment process. These are the steps to follow:
|
39 |
+
1. Extract text from an image
|
40 |
+
2. Analyze the text content for scam patterns
|
41 |
+
3. Synthesize the analyses and make final determination
|
42 |
+
4. Generate a summary of the final determination
|
minerva.ipynb
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
},
|
29 |
{
|
30 |
"cell_type": "code",
|
31 |
-
"execution_count":
|
32 |
"metadata": {},
|
33 |
"outputs": [
|
34 |
{
|
@@ -45,7 +45,7 @@
|
|
45 |
},
|
46 |
{
|
47 |
"cell_type": "code",
|
48 |
-
"execution_count":
|
49 |
"metadata": {},
|
50 |
"outputs": [
|
51 |
{
|
@@ -65,7 +65,7 @@
|
|
65 |
},
|
66 |
{
|
67 |
"cell_type": "code",
|
68 |
-
"execution_count":
|
69 |
"metadata": {},
|
70 |
"outputs": [],
|
71 |
"source": [
|
@@ -89,7 +89,7 @@
|
|
89 |
},
|
90 |
{
|
91 |
"cell_type": "code",
|
92 |
-
"execution_count":
|
93 |
"metadata": {},
|
94 |
"outputs": [],
|
95 |
"source": [
|
@@ -108,7 +108,7 @@
|
|
108 |
},
|
109 |
{
|
110 |
"cell_type": "code",
|
111 |
-
"execution_count":
|
112 |
"metadata": {},
|
113 |
"outputs": [],
|
114 |
"source": [
|
@@ -119,38 +119,43 @@
|
|
119 |
"\n",
|
120 |
" ocr_agent = autogen.AssistantAgent(\n",
|
121 |
" name=\"OCR_Specialist\",\n",
|
|
|
122 |
" system_message=config['ocr_agent']['assignment'],\n",
|
123 |
" llm_config=llm_config\n",
|
124 |
" )\n",
|
125 |
"\n",
|
126 |
-
"
|
127 |
-
" name=\"
|
128 |
-
"
|
|
|
129 |
" llm_config=llm_config\n",
|
130 |
" )\n",
|
131 |
" \n",
|
132 |
" content_agent = autogen.AssistantAgent(\n",
|
133 |
" name=\"Content_Analyst\",\n",
|
|
|
134 |
" system_message=config['content_agent']['assignment'],\n",
|
135 |
" llm_config=llm_config\n",
|
136 |
" )\n",
|
137 |
"\n",
|
138 |
" decision_agent = autogen.AssistantAgent(\n",
|
139 |
" name=\"Decision_Maker\",\n",
|
|
|
140 |
" system_message=config['decision_agent']['assignment'],\n",
|
141 |
" llm_config=llm_config\n",
|
142 |
" )\n",
|
143 |
"\n",
|
144 |
" summary_agent = autogen.AssistantAgent(\n",
|
145 |
" name=\"Summary_Agent\",\n",
|
146 |
-
" description=\"
|
147 |
" system_message=config['summary_agent']['assignment'],\n",
|
148 |
" llm_config=llm_config\n",
|
149 |
" )\n",
|
150 |
"\n",
|
151 |
" user_proxy = autogen.UserProxyAgent(\n",
|
152 |
" name=\"user_proxy\",\n",
|
153 |
-
" is_termination_msg=lambda
|
|
|
154 |
" human_input_mode=\"NEVER\",\n",
|
155 |
" max_consecutive_auto_reply=10,\n",
|
156 |
" )\n",
|
@@ -161,12 +166,13 @@
|
|
161 |
" return tools.ocr(image_path)\n",
|
162 |
" \n",
|
163 |
" @user_proxy.register_for_execution()\n",
|
164 |
-
" @
|
165 |
-
" def
|
166 |
" return tools.is_url_safe(url)\n",
|
167 |
"\n",
|
168 |
"\n",
|
169 |
-
" return ocr_agent,
|
|
|
170 |
]
|
171 |
},
|
172 |
{
|
@@ -178,33 +184,40 @@
|
|
178 |
},
|
179 |
{
|
180 |
"cell_type": "code",
|
181 |
-
"execution_count":
|
182 |
"metadata": {},
|
183 |
"outputs": [],
|
184 |
"source": [
|
185 |
"class ScamDetectionWorkflow:\n",
|
186 |
" def __init__(self):\n",
|
187 |
-
" self.ocr_agent, self.
|
|
|
188 |
" \n",
|
189 |
" def analyze(self, image_path):\n",
|
190 |
" \"\"\"Coordinate the multi-agent analysis.\n",
|
191 |
" \"\"\"\n",
|
192 |
" \n",
|
193 |
" groupchat = autogen.GroupChat(\n",
|
194 |
-
" agents=[self.ocr_agent, self.
|
|
|
195 |
" messages=[],\n",
|
196 |
" max_round=15,\n",
|
|
|
197 |
" )\n",
|
198 |
-
" manager = autogen.GroupChatManager(groupchat=groupchat)\n",
|
199 |
"\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
" messages = self.user_proxy.initiate_chat(\n",
|
201 |
" manager,\n",
|
202 |
-
" message=f\"\"\"\n",
|
203 |
-
" 1. OCR Agent: Extract text from this image: {image_path}\n",
|
204 |
-
" 2. Extract any URL from the text and check if it is safe\n",
|
205 |
-
" 2. Content Agent: Evaluate the messaging and claims\n",
|
206 |
-
" 3. Decision Maker: Synthesize all analyses and make final determination\n",
|
207 |
-
" 4. Summarize the findings\"\"\",\n",
|
208 |
" )\n",
|
209 |
"\n",
|
210 |
" return messages"
|
@@ -212,7 +225,7 @@
|
|
212 |
},
|
213 |
{
|
214 |
"cell_type": "code",
|
215 |
-
"execution_count":
|
216 |
"metadata": {},
|
217 |
"outputs": [
|
218 |
{
|
@@ -238,7 +251,7 @@
|
|
238 |
},
|
239 |
{
|
240 |
"cell_type": "code",
|
241 |
-
"execution_count":
|
242 |
"metadata": {},
|
243 |
"outputs": [
|
244 |
{
|
@@ -247,20 +260,21 @@
|
|
247 |
"text": [
|
248 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
249 |
"\n",
|
|
|
250 |
"\n",
|
251 |
-
"
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
"\u001b[32m\n",
|
259 |
"Next speaker: OCR_Specialist\n",
|
260 |
"\u001b[0m\n",
|
261 |
"\u001b[33mOCR_Specialist\u001b[0m (to chat_manager):\n",
|
262 |
"\n",
|
263 |
-
"\u001b[32m***** Suggested tool call (
|
264 |
"Arguments: \n",
|
265 |
"{\"image_path\":\"./samples/02.giftcard.message.scam.png\"}\n",
|
266 |
"\u001b[32m********************************************************************\u001b[0m\n",
|
@@ -270,18 +284,12 @@
|
|
270 |
"Next speaker: user_proxy\n",
|
271 |
"\u001b[0m\n",
|
272 |
"\u001b[35m\n",
|
273 |
-
">>>>>>>> EXECUTING FUNCTION ocr...\u001b[0m\n"
|
274 |
-
]
|
275 |
-
},
|
276 |
-
{
|
277 |
-
"name": "stdout",
|
278 |
-
"output_type": "stream",
|
279 |
-
"text": [
|
280 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
281 |
"\n",
|
282 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
283 |
"\n",
|
284 |
-
"\u001b[32m***** Response from calling tool (
|
285 |
"Congratulations!\n",
|
286 |
"You've won a $1,000\n",
|
287 |
"Walmart gift card. Go\n",
|
@@ -293,68 +301,17 @@
|
|
293 |
"\n",
|
294 |
"--------------------------------------------------------------------------------\n",
|
295 |
"\u001b[32m\n",
|
296 |
-
"Next speaker:
|
297 |
"\u001b[0m\n",
|
298 |
-
"\u001b[
|
299 |
"\n",
|
300 |
-
"\u001b[32m***** Suggested tool call (
|
301 |
"Arguments: \n",
|
302 |
"{\"url\": \"http://bit.ly/123456\"}\n",
|
303 |
-
"\u001b[32m
|
304 |
-
"\u001b[32m***** Suggested tool call (
|
305 |
-
"Arguments: \n",
|
306 |
-
"{\"text\": \"Congratulations! You've won a $1,000 Walmart gift card. Go http://bit.ly/123456 tp claim now.\"}\n",
|
307 |
-
"\u001b[32m***********************************************************************************\u001b[0m\n",
|
308 |
-
"\n",
|
309 |
-
"--------------------------------------------------------------------------------\n",
|
310 |
-
"\u001b[32m\n",
|
311 |
-
"Next speaker: user_proxy\n",
|
312 |
-
"\u001b[0m\n",
|
313 |
-
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
314 |
-
"\n",
|
315 |
-
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
316 |
-
"\n",
|
317 |
-
"\u001b[32m***** Response from calling tool (call_38Y8iIQ4rrgZCLEHmHziBXZa) *****\u001b[0m\n",
|
318 |
-
"Error: Function check_url_safety not found.\n",
|
319 |
-
"\u001b[32m**********************************************************************\u001b[0m\n",
|
320 |
-
"\n",
|
321 |
-
"--------------------------------------------------------------------------------\n",
|
322 |
-
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
323 |
-
"\n",
|
324 |
-
"\u001b[32m***** Response from calling tool (call_RpsQS2ep2q9ahungdLSb5Xp2) *****\u001b[0m\n",
|
325 |
-
"Error: Function evaluate_messaging not found.\n",
|
326 |
-
"\u001b[32m**********************************************************************\u001b[0m\n",
|
327 |
-
"\n",
|
328 |
-
"--------------------------------------------------------------------------------\n",
|
329 |
-
"\u001b[32m\n",
|
330 |
-
"Next speaker: OCR_Specialist\n",
|
331 |
-
"\u001b[0m\n",
|
332 |
-
"\u001b[33mOCR_Specialist\u001b[0m (to chat_manager):\n",
|
333 |
-
"\n",
|
334 |
-
"It seems that there was an error attempting to check the URL for safety and evaluate the messaging. However, I can summarize the findings based on the extracted text.\n",
|
335 |
-
"\n",
|
336 |
-
"### Extracted Text:\n",
|
337 |
-
"- **Message**: \"Congratulations! You've won a $1,000 Walmart gift card. Go to http://bit.ly/123456 to claim now.\"\n",
|
338 |
-
"\n",
|
339 |
-
"### Findings:\n",
|
340 |
-
"1. **Claim Analysis**: The message makes a claim of winning a significant prize ($1,000 Walmart gift card), which is a common tactic used in scams to lure individuals into providing personal information or engaging in fraudulent activities.\n",
|
341 |
-
" \n",
|
342 |
-
"2. **URL Safety**: The URL provided is a shortened link (bit.ly), which can often be used to mask the true destination. Shortened URLs can lead to unsafe sites, making it essential to check the link before clicking.\n",
|
343 |
-
"\n",
|
344 |
-
"### Conclusion:\n",
|
345 |
-
"Based on the extracted text and the nature of the claims, the messaging appears to be a scam, typical of phishing attempts. The claim of winning a large gift card is insincere and aims to deceive recipients. \n",
|
346 |
-
"\n",
|
347 |
-
"If you need to proceed with URL safety checks or further evaluations, please inform me!\n",
|
348 |
-
"\n",
|
349 |
-
"--------------------------------------------------------------------------------\n",
|
350 |
-
"\u001b[32m\n",
|
351 |
-
"Next speaker: URL_Checker\n",
|
352 |
-
"\u001b[0m\n",
|
353 |
-
"\u001b[33mURL_Checker\u001b[0m (to chat_manager):\n",
|
354 |
-
"\n",
|
355 |
-
"\u001b[32m***** Suggested tool call (call_tA5lFFHPQVNLNdYtB0Ugvunr): is_url_safe *****\u001b[0m\n",
|
356 |
"Arguments: \n",
|
357 |
-
"{\"url\"
|
358 |
"\u001b[32m****************************************************************************\u001b[0m\n",
|
359 |
"\n",
|
360 |
"--------------------------------------------------------------------------------\n",
|
@@ -362,78 +319,25 @@
|
|
362 |
"Next speaker: user_proxy\n",
|
363 |
"\u001b[0m\n",
|
364 |
"\u001b[35m\n",
|
365 |
-
">>>>>>>> EXECUTING FUNCTION
|
|
|
|
|
|
|
|
|
366 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
367 |
"\n",
|
368 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
369 |
"\n",
|
370 |
-
"\u001b[32m***** Response from calling tool (
|
371 |
-
"
|
372 |
"\u001b[32m**********************************************************************\u001b[0m\n",
|
373 |
"\n",
|
374 |
"--------------------------------------------------------------------------------\n",
|
375 |
-
"\u001b[
|
376 |
-
"Next speaker: OCR_Specialist\n",
|
377 |
-
"\u001b[0m\n",
|
378 |
-
"\u001b[33mOCR_Specialist\u001b[0m (to chat_manager):\n",
|
379 |
-
"\n",
|
380 |
-
"It seems there was an issue while attempting to verify the safety of the URL provided (http://bit.ly/123456). \n",
|
381 |
-
"\n",
|
382 |
-
"### Summary of Findings:\n",
|
383 |
-
"1. **Message Content**:\n",
|
384 |
-
" - The extracted message suggests that the recipient has won a $1,000 Walmart gift card, which is a likely scam intended to lure individuals into divulging personal information or clicking on potentially harmful links.\n",
|
385 |
-
"\n",
|
386 |
-
"2. **URL Safety**:\n",
|
387 |
-
" - The URL is a shortened link which hides the actual destination, a common tactic used in scams. Without confirming its safety through a reliable service, caution should be exercised.\n",
|
388 |
-
"\n",
|
389 |
-
"### Conclusion:\n",
|
390 |
-
"The messaging appears to be fraudulent, designed to deceive individuals into believing they have won a prize. Any engagement with such messages, including clicking on links, is not advisable. \n",
|
391 |
-
"\n",
|
392 |
-
"If you need additional assistance or have other questions, feel free to ask!\n",
|
393 |
-
"\n",
|
394 |
-
"--------------------------------------------------------------------------------\n",
|
395 |
-
"\u001b[32m\n",
|
396 |
-
"Next speaker: URL_Checker\n",
|
397 |
-
"\u001b[0m\n",
|
398 |
-
"\u001b[33mURL_Checker\u001b[0m (to chat_manager):\n",
|
399 |
-
"\n",
|
400 |
-
"### Summary of Findings:\n",
|
401 |
-
"\n",
|
402 |
-
"1. **Message Content**:\n",
|
403 |
-
" - The extracted message states: \"Congratulations! You've won a $1,000 Walmart gift card. Go to http://bit.ly/123456 to claim now.\"\n",
|
404 |
-
" - This message is a classic scam tactic aiming to entice recipients by claiming they have won a significant prize. Such claims are often associated with phishing attempts designed to acquire personal information.\n",
|
405 |
-
"\n",
|
406 |
-
"2. **URL Safety**:\n",
|
407 |
-
" - The provided URL is a shortened link (bit.ly), which can mask the actual destination. This makes it hard to assess the link’s safety without further checks. Shortened URLs are often used in scams, and clicking on them can lead to unsafe websites.\n",
|
408 |
-
"\n",
|
409 |
-
"### Conclusion:\n",
|
410 |
-
"The messaging appears to be fraudulent and aimed at deceiving individuals. It is highly recommended not to engage with such messages or click on any links provided.\n",
|
411 |
-
"\n",
|
412 |
-
"If you require further analysis or have other inquiries, please let me know!\n",
|
413 |
-
"\n",
|
414 |
-
"--------------------------------------------------------------------------------\n",
|
415 |
-
"\u001b[32m\n",
|
416 |
-
"Next speaker: Content_Analyst\n",
|
417 |
-
"\u001b[0m\n",
|
418 |
-
"\u001b[33mContent_Analyst\u001b[0m (to chat_manager):\n",
|
419 |
-
"\n",
|
420 |
-
"### Final Summary of Findings:\n",
|
421 |
-
"\n",
|
422 |
-
"1. **Message Content**:\n",
|
423 |
-
" - The message claims, \"Congratulations! You've won a $1,000 Walmart gift card. Go to http://bit.ly/123456 to claim now.\"\n",
|
424 |
-
" - This is a common scam tactic that tempts recipients with the lure of a significant prize, often leading to phishing attempts aimed at stealing personal information.\n",
|
425 |
-
"\n",
|
426 |
-
"2. **URL Safety**:\n",
|
427 |
-
" - The URL is a shortened link (bit.ly), which conceals its true destination. It is important to approach such links with caution, as they are frequently utilized in scams and can direct users to potentially harmful sites.\n",
|
428 |
-
"\n",
|
429 |
-
"3. **Urgency and Pressure Tactics**:\n",
|
430 |
-
" - The phrase \"claim now\" creates a sense of urgency, a typical pressure tactic used in scams to prompt immediate action without thoughtful consideration.\n",
|
431 |
-
"\n",
|
432 |
-
"4. **Inconsistencies**:\n",
|
433 |
-
" - Legitimate communications from companies like Walmart typically do not deliver prizes via unsolicited messages. There’s no prior contact or context provided indicating that the recipient has entered any contests with Walmart.\n",
|
434 |
"\n",
|
435 |
-
"
|
436 |
-
"
|
|
|
437 |
"\n",
|
438 |
"--------------------------------------------------------------------------------\n",
|
439 |
"\u001b[32m\n",
|
@@ -441,28 +345,19 @@
|
|
441 |
"\u001b[0m\n",
|
442 |
"\u001b[33mDecision_Maker\u001b[0m (to chat_manager):\n",
|
443 |
"\n",
|
444 |
-
"
|
445 |
-
"\n",
|
446 |
-
"### Detailed Explanation of the Decision:\n",
|
447 |
"\n",
|
448 |
-
"
|
449 |
-
" - The message employs common elements of scams, such as congratulatory language for a large prize that the recipient has not entered to win. Scams frequently use similar tactics to generate excitement and encourage immediate action.\n",
|
450 |
-
" \n",
|
451 |
-
"2. **Use of Shortened URLs**:\n",
|
452 |
-
" - The presence of a shortened URL (http://bit.ly/123456) is particularly concerning, as such links can obscure the destination website. Many scams utilize shortened URLs because they can lead to phishing websites without showing the actual link, making it harder for recipients to evaluate the safety of the link before clicking.\n",
|
453 |
"\n",
|
454 |
-
"
|
455 |
-
" - The phrasing \"claim now\" creates a sense of urgency and pressures recipients to act quickly, a common tactic employed by scammers to bypass critical thinking, prompting them to take immediate action without verifying the legitimacy of the offer.\n",
|
456 |
"\n",
|
457 |
-
"
|
458 |
-
" - There is no prior context that suggests the recipient would have any connection to the reward being offered. Legitimate promotional offers typically have a clear and contextually relevant background, often requiring prior engagement with the company.\n",
|
459 |
"\n",
|
460 |
-
"
|
461 |
-
" - Major retailers like Walmart do not conduct their promotions through unsolicited messages promising prizes without prior engagement. This adds to the legitimacy concerns surrounding the communication.\n",
|
462 |
"\n",
|
463 |
-
"
|
464 |
"\n",
|
465 |
-
"
|
466 |
"\n",
|
467 |
"--------------------------------------------------------------------------------\n",
|
468 |
"\u001b[32m\n",
|
@@ -470,9 +365,9 @@
|
|
470 |
"\u001b[0m\n",
|
471 |
"\u001b[33mSummary_Agent\u001b[0m (to chat_manager):\n",
|
472 |
"\n",
|
473 |
-
"
|
474 |
"\n",
|
475 |
-
"
|
476 |
"\n",
|
477 |
"--------------------------------------------------------------------------------\n",
|
478 |
"\u001b[32m\n",
|
@@ -488,26 +383,25 @@
|
|
488 |
},
|
489 |
{
|
490 |
"cell_type": "code",
|
491 |
-
"execution_count":
|
492 |
"metadata": {},
|
493 |
"outputs": [
|
494 |
{
|
495 |
"name": "stdout",
|
496 |
"output_type": "stream",
|
497 |
"text": [
|
498 |
-
"{'content': '
|
499 |
-
" '
|
500 |
-
" '
|
501 |
-
" '
|
502 |
-
" '(
|
503 |
-
" '
|
504 |
-
" '
|
505 |
-
" '
|
506 |
-
" '
|
507 |
-
" 'messages. Remain cautious and report any suspicious '\n",
|
508 |
" 'communications. \\n'\n",
|
509 |
" '\\n'\n",
|
510 |
-
" '
|
511 |
" 'name': 'Summary_Agent',\n",
|
512 |
" 'role': 'user'}\n"
|
513 |
]
|
@@ -521,7 +415,7 @@
|
|
521 |
},
|
522 |
{
|
523 |
"cell_type": "code",
|
524 |
-
"execution_count":
|
525 |
"metadata": {},
|
526 |
"outputs": [],
|
527 |
"source": [
|
@@ -551,13 +445,6 @@
|
|
551 |
"source": [
|
552 |
"results.summary"
|
553 |
]
|
554 |
-
},
|
555 |
-
{
|
556 |
-
"cell_type": "code",
|
557 |
-
"execution_count": null,
|
558 |
-
"metadata": {},
|
559 |
-
"outputs": [],
|
560 |
-
"source": []
|
561 |
}
|
562 |
],
|
563 |
"metadata": {
|
|
|
28 |
},
|
29 |
{
|
30 |
"cell_type": "code",
|
31 |
+
"execution_count": 1,
|
32 |
"metadata": {},
|
33 |
"outputs": [
|
34 |
{
|
|
|
45 |
},
|
46 |
{
|
47 |
"cell_type": "code",
|
48 |
+
"execution_count": 2,
|
49 |
"metadata": {},
|
50 |
"outputs": [
|
51 |
{
|
|
|
65 |
},
|
66 |
{
|
67 |
"cell_type": "code",
|
68 |
+
"execution_count": 17,
|
69 |
"metadata": {},
|
70 |
"outputs": [],
|
71 |
"source": [
|
|
|
89 |
},
|
90 |
{
|
91 |
"cell_type": "code",
|
92 |
+
"execution_count": 18,
|
93 |
"metadata": {},
|
94 |
"outputs": [],
|
95 |
"source": [
|
|
|
108 |
},
|
109 |
{
|
110 |
"cell_type": "code",
|
111 |
+
"execution_count": 19,
|
112 |
"metadata": {},
|
113 |
"outputs": [],
|
114 |
"source": [
|
|
|
119 |
"\n",
|
120 |
" ocr_agent = autogen.AssistantAgent(\n",
|
121 |
" name=\"OCR_Specialist\",\n",
|
122 |
+
" description=\"Extracts text from an image\",\n",
|
123 |
" system_message=config['ocr_agent']['assignment'],\n",
|
124 |
" llm_config=llm_config\n",
|
125 |
" )\n",
|
126 |
"\n",
|
127 |
+
" url_agent = autogen.AssistantAgent(\n",
|
128 |
+
" name=\"URL_Agent\",\n",
|
129 |
+
" description=\"Checks if a URL is safe\",\n",
|
130 |
+
" system_message=config['url_agent']['assignment'],\n",
|
131 |
" llm_config=llm_config\n",
|
132 |
" )\n",
|
133 |
" \n",
|
134 |
" content_agent = autogen.AssistantAgent(\n",
|
135 |
" name=\"Content_Analyst\",\n",
|
136 |
+
" description=\"Analyzes the text for scam patterns\",\n",
|
137 |
" system_message=config['content_agent']['assignment'],\n",
|
138 |
" llm_config=llm_config\n",
|
139 |
" )\n",
|
140 |
"\n",
|
141 |
" decision_agent = autogen.AssistantAgent(\n",
|
142 |
" name=\"Decision_Maker\",\n",
|
143 |
+
" description=\"Synthesizes the analyses and make final determination\",\n",
|
144 |
" system_message=config['decision_agent']['assignment'],\n",
|
145 |
" llm_config=llm_config\n",
|
146 |
" )\n",
|
147 |
"\n",
|
148 |
" summary_agent = autogen.AssistantAgent(\n",
|
149 |
" name=\"Summary_Agent\",\n",
|
150 |
+
" description=\"Generate a summary of the final determination\",\n",
|
151 |
" system_message=config['summary_agent']['assignment'],\n",
|
152 |
" llm_config=llm_config\n",
|
153 |
" )\n",
|
154 |
"\n",
|
155 |
" user_proxy = autogen.UserProxyAgent(\n",
|
156 |
" name=\"user_proxy\",\n",
|
157 |
+
" is_termination_msg=lambda x: \"COMPLETE\" in x.get(\"content\", \"\"),\n",
|
158 |
+
" #is_termination_msg=lambda x: x.get(\"content\", \"\") and x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n",
|
159 |
" human_input_mode=\"NEVER\",\n",
|
160 |
" max_consecutive_auto_reply=10,\n",
|
161 |
" )\n",
|
|
|
166 |
" return tools.ocr(image_path)\n",
|
167 |
" \n",
|
168 |
" @user_proxy.register_for_execution()\n",
|
169 |
+
" @content_agent.register_for_llm(description=\"Checks if a URL is safe\")\n",
|
170 |
+
" def url_checker (url: str) -> str:\n",
|
171 |
" return tools.is_url_safe(url)\n",
|
172 |
"\n",
|
173 |
"\n",
|
174 |
+
" #return ocr_agent, url_agent, content_agent, decision_agent, summary_agent, user_proxy\n",
|
175 |
+
" return ocr_agent, content_agent, decision_agent, summary_agent, user_proxy"
|
176 |
]
|
177 |
},
|
178 |
{
|
|
|
184 |
},
|
185 |
{
|
186 |
"cell_type": "code",
|
187 |
+
"execution_count": 21,
|
188 |
"metadata": {},
|
189 |
"outputs": [],
|
190 |
"source": [
|
191 |
"class ScamDetectionWorkflow:\n",
|
192 |
" def __init__(self):\n",
|
193 |
+
" #self.ocr_agent, self.url_agent, self.content_agent, self.decision_agent, self.summary_agent, self.user_proxy = create_agents()\n",
|
194 |
+
" self.ocr_agent, self.content_agent, self.decision_agent, self.summary_agent, self.user_proxy = create_agents()\n",
|
195 |
" \n",
|
196 |
" def analyze(self, image_path):\n",
|
197 |
" \"\"\"Coordinate the multi-agent analysis.\n",
|
198 |
" \"\"\"\n",
|
199 |
" \n",
|
200 |
" groupchat = autogen.GroupChat(\n",
|
201 |
+
" #agents=[self.ocr_agent, self.url_agent, self.content_agent, self.decision_agent, self.summary_agent, self.user_proxy],\n",
|
202 |
+
" agents=[self.ocr_agent, self.content_agent, self.decision_agent, self.summary_agent, self.user_proxy],\n",
|
203 |
" messages=[],\n",
|
204 |
" max_round=15,\n",
|
205 |
+
" #speaker_selection_method=\"round_robin\",\n",
|
206 |
" )\n",
|
207 |
+
" manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)\n",
|
208 |
"\n",
|
209 |
+
" # 2. URL Agent: Check if a URL is safe\n",
|
210 |
+
" #messages = self.user_proxy.initiate_chat(\n",
|
211 |
+
" # manager,\n",
|
212 |
+
" # message=f\"\"\"\n",
|
213 |
+
" # 1. OCR Agent: Extract text from this image: {image_path}\n",
|
214 |
+
" # 2. Content Agent: Evaluate the messaging and claims\n",
|
215 |
+
" # 3. Decision Maker: Synthesize all analyses and make final determination\n",
|
216 |
+
" # 4. Summarize the findings\"\"\",\n",
|
217 |
+
" #)\n",
|
218 |
" messages = self.user_proxy.initiate_chat(\n",
|
219 |
" manager,\n",
|
220 |
+
" message=f\"\"\"does the content of the image in {image_path} represent a scam?\"\"\",\n",
|
|
|
|
|
|
|
|
|
|
|
221 |
" )\n",
|
222 |
"\n",
|
223 |
" return messages"
|
|
|
225 |
},
|
226 |
{
|
227 |
"cell_type": "code",
|
228 |
+
"execution_count": 22,
|
229 |
"metadata": {},
|
230 |
"outputs": [
|
231 |
{
|
|
|
251 |
},
|
252 |
{
|
253 |
"cell_type": "code",
|
254 |
+
"execution_count": 23,
|
255 |
"metadata": {},
|
256 |
"outputs": [
|
257 |
{
|
|
|
260 |
"text": [
|
261 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
262 |
"\n",
|
263 |
+
"does the content of the image in ./samples/02.giftcard.message.scam.png represent a scam?\n",
|
264 |
"\n",
|
265 |
+
"--------------------------------------------------------------------------------\n"
|
266 |
+
]
|
267 |
+
},
|
268 |
+
{
|
269 |
+
"name": "stdout",
|
270 |
+
"output_type": "stream",
|
271 |
+
"text": [
|
272 |
"\u001b[32m\n",
|
273 |
"Next speaker: OCR_Specialist\n",
|
274 |
"\u001b[0m\n",
|
275 |
"\u001b[33mOCR_Specialist\u001b[0m (to chat_manager):\n",
|
276 |
"\n",
|
277 |
+
"\u001b[32m***** Suggested tool call (call_CRjjATgsjHAUQECgDKBauJNe): ocr *****\u001b[0m\n",
|
278 |
"Arguments: \n",
|
279 |
"{\"image_path\":\"./samples/02.giftcard.message.scam.png\"}\n",
|
280 |
"\u001b[32m********************************************************************\u001b[0m\n",
|
|
|
284 |
"Next speaker: user_proxy\n",
|
285 |
"\u001b[0m\n",
|
286 |
"\u001b[35m\n",
|
287 |
+
">>>>>>>> EXECUTING FUNCTION ocr...\u001b[0m\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
289 |
"\n",
|
290 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
291 |
"\n",
|
292 |
+
"\u001b[32m***** Response from calling tool (call_CRjjATgsjHAUQECgDKBauJNe) *****\u001b[0m\n",
|
293 |
"Congratulations!\n",
|
294 |
"You've won a $1,000\n",
|
295 |
"Walmart gift card. Go\n",
|
|
|
301 |
"\n",
|
302 |
"--------------------------------------------------------------------------------\n",
|
303 |
"\u001b[32m\n",
|
304 |
+
"Next speaker: Content_Analyst\n",
|
305 |
"\u001b[0m\n",
|
306 |
+
"\u001b[33mContent_Analyst\u001b[0m (to chat_manager):\n",
|
307 |
"\n",
|
308 |
+
"\u001b[32m***** Suggested tool call (call_68tUF9q6PDAu3QtPpPFp0dBr): url_checker *****\u001b[0m\n",
|
309 |
"Arguments: \n",
|
310 |
"{\"url\": \"http://bit.ly/123456\"}\n",
|
311 |
+
"\u001b[32m****************************************************************************\u001b[0m\n",
|
312 |
+
"\u001b[32m***** Suggested tool call (call_grNDKKmo9xObrUQ3kUTdlqsK): url_checker *****\u001b[0m\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
"Arguments: \n",
|
314 |
+
"{\"url\": \"http://bit.ly/123456\"}\n",
|
315 |
"\u001b[32m****************************************************************************\u001b[0m\n",
|
316 |
"\n",
|
317 |
"--------------------------------------------------------------------------------\n",
|
|
|
319 |
"Next speaker: user_proxy\n",
|
320 |
"\u001b[0m\n",
|
321 |
"\u001b[35m\n",
|
322 |
+
">>>>>>>> EXECUTING FUNCTION url_checker...\u001b[0m\n",
|
323 |
+
"request_body: {'client': {'clientId': 'minerva', 'clientVersion': '0.1.0'}, 'threatInfo': {'threatTypes': ['MALWARE', 'SOCIAL_ENGINEERING', 'UNWANTED_SOFTWARE', 'POTENTIALLY_HARMFUL_APPLICATION'], 'platformTypes': ['ANY_PLATFORM'], 'threatEntryTypes': ['URL'], 'threatEntries': [{'url': 'http://bit.ly/123456'}]}}\n",
|
324 |
+
"\u001b[35m\n",
|
325 |
+
">>>>>>>> EXECUTING FUNCTION url_checker...\u001b[0m\n",
|
326 |
+
"request_body: {'client': {'clientId': 'minerva', 'clientVersion': '0.1.0'}, 'threatInfo': {'threatTypes': ['MALWARE', 'SOCIAL_ENGINEERING', 'UNWANTED_SOFTWARE', 'POTENTIALLY_HARMFUL_APPLICATION'], 'platformTypes': ['ANY_PLATFORM'], 'threatEntryTypes': ['URL'], 'threatEntries': [{'url': 'http://bit.ly/123456'}]}}\n",
|
327 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
328 |
"\n",
|
329 |
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
330 |
"\n",
|
331 |
+
"\u001b[32m***** Response from calling tool (call_68tUF9q6PDAu3QtPpPFp0dBr) *****\u001b[0m\n",
|
332 |
+
"[true, []]\n",
|
333 |
"\u001b[32m**********************************************************************\u001b[0m\n",
|
334 |
"\n",
|
335 |
"--------------------------------------------------------------------------------\n",
|
336 |
+
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
337 |
"\n",
|
338 |
+
"\u001b[32m***** Response from calling tool (call_grNDKKmo9xObrUQ3kUTdlqsK) *****\u001b[0m\n",
|
339 |
+
"[true, []]\n",
|
340 |
+
"\u001b[32m**********************************************************************\u001b[0m\n",
|
341 |
"\n",
|
342 |
"--------------------------------------------------------------------------------\n",
|
343 |
"\u001b[32m\n",
|
|
|
345 |
"\u001b[0m\n",
|
346 |
"\u001b[33mDecision_Maker\u001b[0m (to chat_manager):\n",
|
347 |
"\n",
|
348 |
+
"Based on the analysis of the content in the image, the probability of it being a scam is very high.\n",
|
|
|
|
|
349 |
"\n",
|
350 |
+
"### Explanation:\n",
|
|
|
|
|
|
|
|
|
351 |
"\n",
|
352 |
+
"1. **Content of the Message**: The message claims that the recipient has \"won a $1,000 Walmart gift card.\" Such claims are typical of scam messages. Scammers often use phrases that suggest the receiver has won something unexpectedly, aiming to entice the recipient to click on a link.\n",
|
|
|
353 |
"\n",
|
354 |
+
"2. **Link Included**: The presence of a shortened URL (http://bit.ly/123456) raises red flags. Scammers often use URL shorteners to obscure the true destination of the link, making it harder for recipients to determine if the link leads to a legitimate site or a malicious one.\n",
|
|
|
355 |
"\n",
|
356 |
+
"3. **Verification of URL**: While the URL seems to be valid, the use of bit.ly doesn't guarantee it's a safe destination. Shortened URLs can lead to phishing platforms or websites designed to steal personal information.\n",
|
|
|
357 |
"\n",
|
358 |
+
"4. **Common Scam Patterns**: The elements of the message align with known scam tactics—such as the promise of free money, urgency in claiming the prize, and the use of official brand names to lure victims.\n",
|
359 |
"\n",
|
360 |
+
"In conclusion, considering the suspicious offer of a gift card, the use of a shortened link, and the overall context typical of scams, it is highly likely that the content of the image represents a scam.\n",
|
361 |
"\n",
|
362 |
"--------------------------------------------------------------------------------\n",
|
363 |
"\u001b[32m\n",
|
|
|
365 |
"\u001b[0m\n",
|
366 |
"\u001b[33mSummary_Agent\u001b[0m (to chat_manager):\n",
|
367 |
"\n",
|
368 |
+
"The analysis of the message claiming a $1,000 Walmart gift card indicates a high probability that it's a scam. Key warning signs include the unsolicited nature of the \"win,\" a shortened URL that conceals the link's real destination, and common scam tactics that use enticing offers to trick victims. To protect yourself, do not click on any links in such messages, avoid sharing personal information, and report suspicious content to relevant authorities. Stay vigilant and skeptical of unsolicited offers claiming you've won something. \n",
|
369 |
"\n",
|
370 |
+
"COMPLETE\n",
|
371 |
"\n",
|
372 |
"--------------------------------------------------------------------------------\n",
|
373 |
"\u001b[32m\n",
|
|
|
383 |
},
|
384 |
{
|
385 |
"cell_type": "code",
|
386 |
+
"execution_count": 10,
|
387 |
"metadata": {},
|
388 |
"outputs": [
|
389 |
{
|
390 |
"name": "stdout",
|
391 |
"output_type": "stream",
|
392 |
"text": [
|
393 |
+
"{'content': 'The message claiming \"You\\'ve won a $1,000 Walmart gift card\" '\n",
|
394 |
+
" 'raises several red flags indicating a high probability of being a '\n",
|
395 |
+
" 'scam. It notifies the recipient about an unsolicited prize, '\n",
|
396 |
+
" 'creates urgency by urging immediate action, and includes a '\n",
|
397 |
+
" 'shortened link (bit.ly) that obscures its real destination and '\n",
|
398 |
+
" 'often indicates a potential threat. Users should avoid clicking '\n",
|
399 |
+
" 'on such links and be skeptical of unsolicited prize '\n",
|
400 |
+
" 'notifications. **Actionable recommendation:** Do not engage with '\n",
|
401 |
+
" 'or follow links in unsolicited messages and report suspicious '\n",
|
|
|
402 |
" 'communications. \\n'\n",
|
403 |
" '\\n'\n",
|
404 |
+
" 'COMPLETE',\n",
|
405 |
" 'name': 'Summary_Agent',\n",
|
406 |
" 'role': 'user'}\n"
|
407 |
]
|
|
|
415 |
},
|
416 |
{
|
417 |
"cell_type": "code",
|
418 |
+
"execution_count": 11,
|
419 |
"metadata": {},
|
420 |
"outputs": [],
|
421 |
"source": [
|
|
|
445 |
"source": [
|
446 |
"results.summary"
|
447 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
}
|
449 |
],
|
450 |
"metadata": {
|
tools.py
CHANGED
@@ -12,7 +12,7 @@ class Tools:
|
|
12 |
load_dotenv(find_dotenv())
|
13 |
|
14 |
self.safebrowsing_key = os.getenv("SAFEBROWSING_API_KEY")
|
15 |
-
self.
|
16 |
self.client_id = "minerva"
|
17 |
self.client_version = "0.1.0"
|
18 |
self.threat_types = [
|
@@ -41,15 +41,15 @@ class Tools:
|
|
41 |
except requests.exceptions.RequestException as e:
|
42 |
return url # Return original URL if expansion fails
|
43 |
|
44 |
-
def is_url_safe(self,
|
45 |
"""Check if URL is safe using Google Safe Browsing API
|
46 |
"""
|
47 |
if not self.safebrowsing_key:
|
48 |
raise ValueError("SAFEBROWSING_API_KEY is missing.")
|
49 |
|
50 |
-
|
51 |
-
expanded_url = self.expand_url(
|
52 |
-
|
53 |
request_body = {
|
54 |
"client": {
|
55 |
"clientId": self.client_id,
|
@@ -60,14 +60,18 @@ class Tools:
|
|
60 |
"platformTypes": ["ANY_PLATFORM"],
|
61 |
"threatEntryTypes": ["URL"],
|
62 |
"threatEntries": [
|
63 |
-
{"url":
|
64 |
-
{"url": expanded_url} if expanded_url != url else {}
|
65 |
]
|
66 |
}
|
67 |
}
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
try:
|
70 |
-
response = requests.post(
|
71 |
response.raise_for_status()
|
72 |
|
73 |
result = response.json()
|
@@ -80,8 +84,7 @@ class Tools:
|
|
80 |
for match in result["matches"]:
|
81 |
threats.append({
|
82 |
"threat_type": match.get("threatType"),
|
83 |
-
"
|
84 |
-
"threat_entry_type": match.get("threatEntryType")
|
85 |
})
|
86 |
|
87 |
return False, threats
|
|
|
12 |
load_dotenv(find_dotenv())
|
13 |
|
14 |
self.safebrowsing_key = os.getenv("SAFEBROWSING_API_KEY")
|
15 |
+
self.base_url = "https://safebrowsing.googleapis.com/v4"
|
16 |
self.client_id = "minerva"
|
17 |
self.client_version = "0.1.0"
|
18 |
self.threat_types = [
|
|
|
41 |
except requests.exceptions.RequestException as e:
|
42 |
return url # Return original URL if expansion fails
|
43 |
|
44 |
+
def is_url_safe(self, target_url: str) -> Tuple[bool, List[Dict[str, str]]]:
|
45 |
"""Check if URL is safe using Google Safe Browsing API
|
46 |
"""
|
47 |
if not self.safebrowsing_key:
|
48 |
raise ValueError("SAFEBROWSING_API_KEY is missing.")
|
49 |
|
50 |
+
safe_endpoint = f"{self.base_url}/threatMatches:find?key={self.safebrowsing_key}"
|
51 |
+
expanded_url = self.expand_url(target_url)
|
52 |
+
|
53 |
request_body = {
|
54 |
"client": {
|
55 |
"clientId": self.client_id,
|
|
|
60 |
"platformTypes": ["ANY_PLATFORM"],
|
61 |
"threatEntryTypes": ["URL"],
|
62 |
"threatEntries": [
|
63 |
+
{"url": target_url}
|
|
|
64 |
]
|
65 |
}
|
66 |
}
|
67 |
+
|
68 |
+
if expanded_url != target_url:
|
69 |
+
request_body["threatInfo"]["threatEntries"].append({"url": expanded_url})
|
70 |
+
|
71 |
+
print(f"request_body: {request_body}")
|
72 |
|
73 |
try:
|
74 |
+
response = requests.post(safe_endpoint, json=request_body)
|
75 |
response.raise_for_status()
|
76 |
|
77 |
result = response.json()
|
|
|
84 |
for match in result["matches"]:
|
85 |
threats.append({
|
86 |
"threat_type": match.get("threatType"),
|
87 |
+
"threat_url": match.get("threat", {}).get("url"),
|
|
|
88 |
})
|
89 |
|
90 |
return False, threats
|