aelin commited on
Commit
f9bd7be
·
1 Parent(s): f791164

Refatora a inicialização do agente para usar agentes individuais em vez de funções, melhorando a organização e a clareza do código.

Browse files

Refactors to use individual agents for tool handling

Replaces function-based tool registration with dedicated agents for each tool, enhancing code organization and clarity. Simplifies agent initialization and improves maintainability by leveraging agent-based workflows.

Relates to improved code structure and readability.

Files changed (2) hide show
  1. _tools.py +83 -85
  2. app.py +30 -5
_tools.py CHANGED
@@ -1,16 +1,13 @@
1
 
2
  import re
3
  from markdownify import markdownify
4
-
5
-
6
  import requests
7
  import io
8
-
9
  import pandas as pd
10
  from PIL import Image
11
  from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec
12
- from llama_index.core.tools import FunctionTool
13
  from huggingface_hub import InferenceClient
 
14
 
15
  client = InferenceClient(
16
  provider="hf-inference",
@@ -20,70 +17,60 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
20
  search_tool_spec = DuckDuckGoSearchToolSpec()
21
 
22
  # Searching tools
23
- def _search_tool(query: str) -> str:
 
24
  """Browse the web using DuckDuckGo."""
25
  print(f"🔍 Executando busca no DuckDuckGo para: {query}")
26
-
27
  return search_tool_spec.duckduckgo_full_search(query=query)
28
-
29
- def _fetch_file_bytes(task_id: str) -> str | None:
30
  """
31
  Fetch a file from the given task ID.
32
  """
33
-
34
  try:
35
  response = requests.get(f"{DEFAULT_API_URL}/files/{task_id}", timeout=15)
36
  response.raise_for_status()
37
-
38
  print(f"File {task_id} fetched successfully.")
39
  return response.content
40
-
41
  except requests.exceptions.RequestException as e:
42
  print(f"Error fetching file {task_id}: {e}")
43
  return None
44
-
45
- # Parsing tools
46
- def _bytes_to_image(image_bytes: bytes) -> Image:
47
  """Convert bytes to image URL."""
48
-
49
  file = Image.open(io.BytesIO(image_bytes))
50
-
51
  file.save("temp_image.png")
52
-
53
  return file
54
 
55
- def _document_bytes_to_text(doc_bytes: bytes) -> str:
56
- """Convert document bytes to text."""
57
  return doc_bytes.decode("utf-8")
58
-
59
- def _xlsx_to_text(file_bytes: bytes) -> str:
60
  """Convert XLSX file bytes to text using pandas."""
61
  io_bytes = io.BytesIO(file_bytes)
62
  df = pd.read_excel(io_bytes, engine='openpyxl')
63
-
64
  return df.to_string(index=False)
65
 
66
- # Extracting text tools
67
- def _extract_text_from_image(image_url: bytes) -> str:
68
  """Extract text from an image using Tesseract."""
69
  return client.image_to_text(image_url=image_url, task="image-to-text", model="Salesforce/blip-image-captioning-base").generated_text
70
-
71
- def _extract_text_from_csv(file_bytes: bytes) -> str:
72
  """Extract text from a CSV file."""
73
  io_bytes = io.BytesIO(file_bytes)
74
  df = pd.read_csv(io_bytes)
75
-
76
  return df.to_string(index=False)
77
-
78
- def _extract_text_from_code_file(bytes: bytes) -> str:
79
  """Extract text from a code file."""
80
  return bytes.decode("utf-8")
81
-
82
- def _extract_text_from_audio_file(file_bytes: bytes) -> str:
83
  """Extract text from an audio file."""
84
  return client.automatic_speech_recognition(file_bytes, model="openai/whisper-large-v2").text
85
 
86
- def _webpage_to_markdown(url: str) -> str:
87
  """
88
  Access a web page and return its content as markdown.
89
  Limits output to 10,000 characters to avoid excessive responses.
@@ -103,76 +90,87 @@ def _webpage_to_markdown(url: str) -> str:
103
 
104
 
105
  # Initialize tools
106
- search_tool = FunctionTool.from_defaults(
107
- _search_tool,
108
- name="DuckDuckGo Search",
109
- description="Search the web using DuckDuckGo."
110
- )
111
 
112
- fetch_file_bytes_tool = FunctionTool.from_defaults(
113
- _fetch_file_bytes,
114
- name="Fetch File Bytes",
115
- description="Fetch a file from the given task ID."
 
 
116
  )
117
 
118
- bytes_to_image_tool = FunctionTool.from_defaults(
119
- _bytes_to_image,
120
- name="Bytes to Image",
121
- description="Convert bytes to image URL."
 
 
122
  )
123
 
124
- document_bytes_to_text_tool = FunctionTool.from_defaults(
125
- _document_bytes_to_text,
126
- name="Document Bytes to Text",
127
- description="Convert bytes to document text, i.e., .txt, .pdf, etc."
 
 
128
  )
129
 
130
- xlsx_to_text_tool = FunctionTool.from_defaults(
131
- _xlsx_to_text,
132
- name="XLSX to Text",
133
- description="Convert XLSX file bytes to text."
 
 
134
  )
135
 
136
- extract_text_from_image_tool = FunctionTool.from_defaults(
137
- _extract_text_from_image,
138
- name="Extract Text from Image",
139
- description="Extract text from an image using Tesseract."
 
 
140
  )
141
 
142
- extract_text_from_csv_tool = FunctionTool.from_defaults(
143
- _extract_text_from_csv,
144
- name="Extract Text from CSV",
145
- description="Extract text from a CSV file."
 
 
146
  )
147
 
148
- extract_text_from_code_file_tool = FunctionTool.from_defaults(
149
- _extract_text_from_code_file,
150
- name="Extract Text from Code File",
151
- description="Extract text from a code file, i.e., .py, .js, .java, etc."
 
 
152
  )
153
 
154
- extract_text_from_audio_file_tool = FunctionTool.from_defaults(
155
- _extract_text_from_audio_file,
156
- name="Extract Text from Audio File",
157
- description="Extract text from an audio file."
 
 
158
  )
159
 
160
- webpage_to_markdown_tool = FunctionTool.from_defaults(
161
- _webpage_to_markdown,
162
- name="Webpage to Markdown",
163
- description="Access a web page by URL and return the content as markdown. Use to read web pages."
 
 
164
  )
165
 
166
- tools = [
167
- search_tool,
168
- fetch_file_bytes_tool,
169
- bytes_to_image_tool,
170
- document_bytes_to_text_tool,
171
- extract_text_from_image_tool,
172
- extract_text_from_csv_tool,
173
- extract_text_from_code_file_tool,
174
- extract_text_from_audio_file_tool,
175
- xlsx_to_text_tool,
176
- webpage_to_markdown_tool,
177
- ]
178
 
 
1
 
2
  import re
3
  from markdownify import markdownify
 
 
4
  import requests
5
  import io
 
6
  import pandas as pd
7
  from PIL import Image
8
  from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec
 
9
  from huggingface_hub import InferenceClient
10
+ from llama_index.core.agent.workflow import ReActAgent
11
 
12
  client = InferenceClient(
13
  provider="hf-inference",
 
17
  search_tool_spec = DuckDuckGoSearchToolSpec()
18
 
19
  # Searching tools
20
+
21
+ def search_tool(query: str) -> str:
22
  """Browse the web using DuckDuckGo."""
23
  print(f"🔍 Executando busca no DuckDuckGo para: {query}")
 
24
  return search_tool_spec.duckduckgo_full_search(query=query)
25
+
26
+ def fetch_file_bytes(task_id: str) -> str | None:
27
  """
28
  Fetch a file from the given task ID.
29
  """
 
30
  try:
31
  response = requests.get(f"{DEFAULT_API_URL}/files/{task_id}", timeout=15)
32
  response.raise_for_status()
 
33
  print(f"File {task_id} fetched successfully.")
34
  return response.content
 
35
  except requests.exceptions.RequestException as e:
36
  print(f"Error fetching file {task_id}: {e}")
37
  return None
38
+
39
+ def bytes_to_image(image_bytes: bytes) -> Image:
 
40
  """Convert bytes to image URL."""
 
41
  file = Image.open(io.BytesIO(image_bytes))
 
42
  file.save("temp_image.png")
 
43
  return file
44
 
45
+ def document_bytes_to_text(doc_bytes: bytes) -> str:
46
+ """Convert document bytes to text."""
47
  return doc_bytes.decode("utf-8")
48
+
49
+ def xlsx_to_text(file_bytes: bytes) -> str:
50
  """Convert XLSX file bytes to text using pandas."""
51
  io_bytes = io.BytesIO(file_bytes)
52
  df = pd.read_excel(io_bytes, engine='openpyxl')
 
53
  return df.to_string(index=False)
54
 
55
+ def extract_text_from_image(image_url: bytes) -> str:
 
56
  """Extract text from an image using Tesseract."""
57
  return client.image_to_text(image_url=image_url, task="image-to-text", model="Salesforce/blip-image-captioning-base").generated_text
58
+
59
+ def extract_text_from_csv(file_bytes: bytes) -> str:
60
  """Extract text from a CSV file."""
61
  io_bytes = io.BytesIO(file_bytes)
62
  df = pd.read_csv(io_bytes)
 
63
  return df.to_string(index=False)
64
+
65
+ def extract_text_from_code_file(bytes: bytes) -> str:
66
  """Extract text from a code file."""
67
  return bytes.decode("utf-8")
68
+
69
+ def extract_text_from_audio_file(file_bytes: bytes) -> str:
70
  """Extract text from an audio file."""
71
  return client.automatic_speech_recognition(file_bytes, model="openai/whisper-large-v2").text
72
 
73
+ def webpage_to_markdown(url: str) -> str:
74
  """
75
  Access a web page and return its content as markdown.
76
  Limits output to 10,000 characters to avoid excessive responses.
 
90
 
91
 
92
  # Initialize tools
93
+ # --- ReActAgent and AgentWorkflow tool declaration ---
94
+
95
+ # Define agents for each tool (one agent per tool, with a clear description)
 
 
96
 
97
+ search_agent = ReActAgent(
98
+ name="search_agent",
99
+ description="Searches the web using DuckDuckGo.",
100
+ system_prompt="A helpful assistant that can search the web using DuckDuckGo.",
101
+ tools=[search_tool],
102
+ llm=None,
103
  )
104
 
105
+ fetch_file_agent = ReActAgent(
106
+ name="fetch_file_agent",
107
+ description="Fetches a file from a given task ID.",
108
+ system_prompt="A helpful assistant that can fetch files by task ID.",
109
+ tools=[fetch_file_bytes],
110
+ llm=None,
111
  )
112
 
113
+ bytes_to_image_agent = ReActAgent(
114
+ name="bytes_to_image_agent",
115
+ description="Converts bytes to an image.",
116
+ system_prompt="A helpful assistant that can convert bytes to an image.",
117
+ tools=[bytes_to_image],
118
+ llm=None,
119
  )
120
 
121
+ document_bytes_to_text_agent = ReActAgent(
122
+ name="document_bytes_to_text_agent",
123
+ description="Converts document bytes to text.",
124
+ system_prompt="A helpful assistant that can convert document bytes to text.",
125
+ tools=[document_bytes_to_text],
126
+ llm=None,
127
  )
128
 
129
+ xlsx_to_text_agent = ReActAgent(
130
+ name="xlsx_to_text_agent",
131
+ description="Converts XLSX file bytes to text.",
132
+ system_prompt="A helpful assistant that can convert XLSX file bytes to text.",
133
+ tools=[xlsx_to_text],
134
+ llm=None,
135
  )
136
 
137
+ extract_text_from_image_agent = ReActAgent(
138
+ name="extract_text_from_image_agent",
139
+ description="Extracts text from an image using Tesseract.",
140
+ system_prompt="A helpful assistant that can extract text from images.",
141
+ tools=[extract_text_from_image],
142
+ llm=None,
143
  )
144
 
145
+ extract_text_from_csv_agent = ReActAgent(
146
+ name="extract_text_from_csv_agent",
147
+ description="Extracts text from a CSV file.",
148
+ system_prompt="A helpful assistant that can extract text from CSV files.",
149
+ tools=[extract_text_from_csv],
150
+ llm=None,
151
  )
152
 
153
+ extract_text_from_code_file_agent = ReActAgent(
154
+ name="extract_text_from_code_file_agent",
155
+ description="Extracts text from a code file.",
156
+ system_prompt="A helpful assistant that can extract text from code files.",
157
+ tools=[extract_text_from_code_file],
158
+ llm=None,
159
  )
160
 
161
+ extract_text_from_audio_file_agent = ReActAgent(
162
+ name="extract_text_from_audio_file_agent",
163
+ description="Extracts text from an audio file.",
164
+ system_prompt="A helpful assistant that can extract text from audio files.",
165
+ tools=[extract_text_from_audio_file],
166
+ llm=None,
167
  )
168
 
169
+ webpage_to_markdown_agent = ReActAgent(
170
+ name="webpage_to_markdown_agent",
171
+ description="Accesses a web page by URL and returns the content as markdown.",
172
+ system_prompt="A helpful assistant that can access web pages and return markdown.",
173
+ tools=[webpage_to_markdown],
174
+ llm=None,
175
+ )
 
 
 
 
 
176
 
app.py CHANGED
@@ -7,7 +7,19 @@ from _types import Questions, Question, UserScore
7
  from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
8
  from llama_index.core.agent.workflow import AgentWorkflow
9
  from llama_index.core.workflow import Context
10
- from _tools import tools
 
 
 
 
 
 
 
 
 
 
 
 
11
  import asyncio
12
  from utils import cache_answers, update_cache_answer, get_cached_answer, load_cache
13
 
@@ -22,13 +34,26 @@ class BasicAgent:
22
  def __init__(self):
23
  print("BasicAgent initialized.")
24
 
 
25
  llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
26
 
27
- agent = AgentWorkflow.from_tools_or_functions(
28
- tools_or_functions=tools,
 
 
 
 
 
 
 
 
 
 
 
 
29
  llm=llm,
30
  verbose=True,
31
- system_prompt= """
32
  You are a general AI assistant. I will ask you a question. Think carefully and give your answer straight away as asked in the question or
33
  in the format below:
34
 
@@ -41,7 +66,7 @@ class BasicAgent:
41
  Don't use any other format than the one above and limit your attempts to answer the question to 3 times.
42
  """,
43
  )
44
-
45
  context = Context(agent)
46
  self.agent = agent
47
  self.context = context
 
7
  from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
8
  from llama_index.core.agent.workflow import AgentWorkflow
9
  from llama_index.core.workflow import Context
10
+ from _tools import (
11
+ search_agent,
12
+ fetch_file_agent,
13
+ bytes_to_image_agent,
14
+ document_bytes_to_text_agent,
15
+ xlsx_to_text_agent,
16
+ extract_text_from_image_agent,
17
+ extract_text_from_csv_agent,
18
+ extract_text_from_code_file_agent,
19
+ extract_text_from_audio_file_agent,
20
+ webpage_to_markdown_agent,
21
+ )
22
+ from llama_index.core.agent.workflow import AgentWorkflow
23
  import asyncio
24
  from utils import cache_answers, update_cache_answer, get_cached_answer, load_cache
25
 
 
34
  def __init__(self):
35
  print("BasicAgent initialized.")
36
 
37
+
38
  llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
39
 
40
+ agent = AgentWorkflow(
41
+ agents=[
42
+ search_agent,
43
+ fetch_file_agent,
44
+ bytes_to_image_agent,
45
+ document_bytes_to_text_agent,
46
+ xlsx_to_text_agent,
47
+ extract_text_from_image_agent,
48
+ extract_text_from_csv_agent,
49
+ extract_text_from_code_file_agent,
50
+ extract_text_from_audio_file_agent,
51
+ webpage_to_markdown_agent,
52
+ ],
53
+ root_agent="search_agent",
54
  llm=llm,
55
  verbose=True,
56
+ system_prompt="""
57
  You are a general AI assistant. I will ask you a question. Think carefully and give your answer straight away as asked in the question or
58
  in the format below:
59
 
 
66
  Don't use any other format than the one above and limit your attempts to answer the question to 3 times.
67
  """,
68
  )
69
+
70
  context = Context(agent)
71
  self.agent = agent
72
  self.context = context