Skip to content

Commit 09f1ba6

Browse files
feat: native async tool support
- add async support for tools - add async tool tests - improve tool decorator typing - fix _run backward compatibility - update docs and improve readability of docstrings
1 parent 2070474 commit 09f1ba6

File tree

7 files changed

+938
-33
lines changed

7 files changed

+938
-33
lines changed

docs/en/learn/create-custom-tools.mdx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,55 @@ def my_cache_strategy(arguments: dict, result: str) -> bool:
6666
cached_tool.cache_function = my_cache_strategy
6767
```
6868

69+
### Creating Async Tools
70+
71+
CrewAI supports async tools for non-blocking I/O operations. This is useful when your tool needs to make HTTP requests, database queries, or other I/O-bound operations.
72+
73+
#### Using the `@tool` Decorator with Async Functions
74+
75+
The simplest way to create an async tool is using the `@tool` decorator with an async function:
76+
77+
```python Code
78+
import aiohttp
79+
from crewai.tools import tool
80+
81+
@tool("Async Web Fetcher")
82+
async def fetch_webpage(url: str) -> str:
83+
"""Fetch content from a webpage asynchronously."""
84+
async with aiohttp.ClientSession() as session:
85+
async with session.get(url) as response:
86+
return await response.text()
87+
```
88+
89+
#### Subclassing `BaseTool` with Async Support
90+
91+
For more control, subclass `BaseTool` and implement both `_run` (sync) and `_arun` (async) methods:
92+
93+
```python Code
94+
import requests
95+
import aiohttp
96+
from crewai.tools import BaseTool
97+
from pydantic import BaseModel, Field
98+
99+
class WebFetcherInput(BaseModel):
100+
"""Input schema for WebFetcher."""
101+
url: str = Field(..., description="The URL to fetch")
102+
103+
class WebFetcherTool(BaseTool):
104+
name: str = "Web Fetcher"
105+
description: str = "Fetches content from a URL"
106+
args_schema: type[BaseModel] = WebFetcherInput
107+
108+
def _run(self, url: str) -> str:
109+
"""Synchronous implementation."""
110+
return requests.get(url).text
111+
112+
async def _arun(self, url: str) -> str:
113+
"""Asynchronous implementation for non-blocking I/O."""
114+
async with aiohttp.ClientSession() as session:
115+
async with session.get(url) as response:
116+
return await response.text()
117+
```
118+
69119
By adhering to these guidelines and incorporating new functionalities and collaboration tools into your tool creation and management processes,
70120
you can leverage the full capabilities of the CrewAI framework, enhancing both the development experience and the efficiency of your AI agents.

docs/ko/learn/create-custom-tools.mdx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,55 @@ def my_cache_strategy(arguments: dict, result: str) -> bool:
6363
cached_tool.cache_function = my_cache_strategy
6464
```
6565

66+
### 비동기 도구 생성하기
67+
68+
CrewAI는 논블로킹 I/O 작업을 위한 비동기 도구를 지원합니다. 이는 HTTP 요청, 데이터베이스 쿼리 또는 기타 I/O 바운드 작업이 필요한 경우에 유용합니다.
69+
70+
#### `@tool` 데코레이터와 비동기 함수 사용하기
71+
72+
비동기 도구를 만드는 가장 간단한 방법은 `@tool` 데코레이터와 async 함수를 사용하는 것입니다:
73+
74+
```python Code
75+
import aiohttp
76+
from crewai.tools import tool
77+
78+
@tool("Async Web Fetcher")
79+
async def fetch_webpage(url: str) -> str:
80+
"""Fetch content from a webpage asynchronously."""
81+
async with aiohttp.ClientSession() as session:
82+
async with session.get(url) as response:
83+
return await response.text()
84+
```
85+
86+
#### 비동기 지원으로 `BaseTool` 서브클래싱하기
87+
88+
더 많은 제어를 위해 `BaseTool`을 상속하고 `_run`(동기) 및 `_arun`(비동기) 메서드를 모두 구현할 수 있습니다:
89+
90+
```python Code
91+
import requests
92+
import aiohttp
93+
from crewai.tools import BaseTool
94+
from pydantic import BaseModel, Field
95+
96+
class WebFetcherInput(BaseModel):
97+
"""Input schema for WebFetcher."""
98+
url: str = Field(..., description="The URL to fetch")
99+
100+
class WebFetcherTool(BaseTool):
101+
name: str = "Web Fetcher"
102+
description: str = "Fetches content from a URL"
103+
args_schema: type[BaseModel] = WebFetcherInput
104+
105+
def _run(self, url: str) -> str:
106+
"""Synchronous implementation."""
107+
return requests.get(url).text
108+
109+
async def _arun(self, url: str) -> str:
110+
"""Asynchronous implementation for non-blocking I/O."""
111+
async with aiohttp.ClientSession() as session:
112+
async with session.get(url) as response:
113+
return await response.text()
114+
```
115+
66116
이 가이드라인을 준수하고 새로운 기능과 협업 도구를 도구 생성 및 관리 프로세스에 통합함으로써,
67-
CrewAI 프레임워크의 모든 기능을 활용할 수 있으며, AI agent의 개발 경험과 효율성을 모두 높일 수 있습니다.
117+
CrewAI 프레임워크의 모든 기능을 활용할 수 있으며, AI agent의 개발 경험과 효율성을 모두 높일 수 있습니다.

docs/pt-BR/learn/create-custom-tools.mdx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,55 @@ def my_cache_strategy(arguments: dict, result: str) -> bool:
6666
cached_tool.cache_function = my_cache_strategy
6767
```
6868

69+
### Criando Ferramentas Assíncronas
70+
71+
O CrewAI suporta ferramentas assíncronas para operações de I/O não bloqueantes. Isso é útil quando sua ferramenta precisa fazer requisições HTTP, consultas a banco de dados ou outras operações de I/O.
72+
73+
#### Usando o Decorador `@tool` com Funções Assíncronas
74+
75+
A maneira mais simples de criar uma ferramenta assíncrona é usando o decorador `@tool` com uma função async:
76+
77+
```python Code
78+
import aiohttp
79+
from crewai.tools import tool
80+
81+
@tool("Async Web Fetcher")
82+
async def fetch_webpage(url: str) -> str:
83+
"""Fetch content from a webpage asynchronously."""
84+
async with aiohttp.ClientSession() as session:
85+
async with session.get(url) as response:
86+
return await response.text()
87+
```
88+
89+
#### Subclassificando `BaseTool` com Suporte Assíncrono
90+
91+
Para maior controle, herde de `BaseTool` e implemente os métodos `_run` (síncrono) e `_arun` (assíncrono):
92+
93+
```python Code
94+
import requests
95+
import aiohttp
96+
from crewai.tools import BaseTool
97+
from pydantic import BaseModel, Field
98+
99+
class WebFetcherInput(BaseModel):
100+
"""Input schema for WebFetcher."""
101+
url: str = Field(..., description="The URL to fetch")
102+
103+
class WebFetcherTool(BaseTool):
104+
name: str = "Web Fetcher"
105+
description: str = "Fetches content from a URL"
106+
args_schema: type[BaseModel] = WebFetcherInput
107+
108+
def _run(self, url: str) -> str:
109+
"""Synchronous implementation."""
110+
return requests.get(url).text
111+
112+
async def _arun(self, url: str) -> str:
113+
"""Asynchronous implementation for non-blocking I/O."""
114+
async with aiohttp.ClientSession() as session:
115+
async with session.get(url) as response:
116+
return await response.text()
117+
```
118+
69119
Seguindo essas orientações e incorporando novas funcionalidades e ferramentas de colaboração nos seus processos de criação e gerenciamento de ferramentas,
70-
você pode aproveitar ao máximo as capacidades do framework CrewAI, aprimorando tanto a experiência de desenvolvimento quanto a eficiência dos seus agentes de IA.
120+
você pode aproveitar ao máximo as capacidades do framework CrewAI, aprimorando tanto a experiência de desenvolvimento quanto a eficiência dos seus agentes de IA.

0 commit comments

Comments
 (0)