First_agent_template / tools /web_search.py
Ark4u's picture
Deploy OmniAssistant smolagent (Hugging Face Agents Course Unit 1)
3fcf7a5 verified
Raw History Blame Contribute Delete
2.43 kB
from typing import Any, Optional
from smolagents.tools import Tool
import ddgs
import time
class DuckDuckGoSearchTool(Tool):
"""Web search tool that performs searches using the DuckDuckGo search engine.
Args:
max_results (`int`, default `10`): Maximum number of search results to return.
rate_limit (`float`, default `1.0`): Maximum queries per second. Set to `None` to disable rate limiting.
**kwargs: Additional keyword arguments for the `DDGS` client.
Examples:
```python
>>> from smolagents import DuckDuckGoSearchTool
>>> web_search_tool = DuckDuckGoSearchTool(max_results=5, rate_limit=2.0)
>>> results = web_search_tool("Hugging Face")
>>> print(results)
```
"""
name = "web_search"
description = "Performs a duckduckgo web search based on your query (think a Google search) then returns the top search results."
inputs = {'query': {'type': 'string', 'description': 'The search query to perform.'}}
output_type = "string"
def __init__(self, max_results: int = 10, rate_limit: float | None = 1.0, **kwargs):
super().__init__()
self.max_results = max_results
self.rate_limit = rate_limit
self._min_interval = 1.0 / rate_limit if rate_limit else 0.0
self._last_request_time = 0.0
try:
from ddgs import DDGS
except ImportError as e:
raise ImportError(
"You must install package `ddgs` to run this tool: for instance run `pip install ddgs`."
) from e
self.ddgs = DDGS(**kwargs)
def forward(self, query: str) -> str:
self._enforce_rate_limit()
results = self.ddgs.text(query, max_results=self.max_results)
if len(results) == 0:
raise Exception("No results found! Try a less restrictive/shorter query.")
postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
def _enforce_rate_limit(self) -> None:
import time
# No rate limit enforced
if not self.rate_limit:
return
now = time.time()
elapsed = now - self._last_request_time
if elapsed < self._min_interval:
time.sleep(self._min_interval - elapsed)
self._last_request_time = time.time()