chore: add deprecation notices to Task.max_retries (#3379)
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled

This commit is contained in:
Lucas Gomide
2025-08-26 18:24:58 -03:00
committed by GitHub
parent 7addda9398
commit 88d2968fd5
6 changed files with 36 additions and 15 deletions

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Output Pydantic** _(optional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | A Pydantic model for task output. | | **Output Pydantic** _(optional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | A Pydantic model for task output. |
| **Callback** _(optional)_ | `callback` | `Optional[Any]` | Function/object to be executed after task completion. | | **Callback** _(optional)_ | `callback` | `Optional[Any]` | Function/object to be executed after task completion. |
| **Guardrail** _(optional)_ | `guardrail` | `Optional[Callable]` | Function to validate task output before proceeding to next task. | | **Guardrail** _(optional)_ | `guardrail` | `Optional[Callable]` | Function to validate task output before proceeding to next task. |
| **Guardrail Max Retries** _(optional)_ | `guardrail_max_retries` | `Optional[int]` | Maximum number of retries when guardrail validation fails. Defaults to 3. |
## Creating Tasks ## Creating Tasks
@@ -452,7 +453,7 @@ task = Task(
expected_output="A valid JSON object", expected_output="A valid JSON object",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limit retry attempts guardrail_max_retries=3 # Limit retry attempts
) )
``` ```

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Pydantic 출력** _(선택 사항)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | 태스크 출력용 Pydantic 모델입니다. | | **Pydantic 출력** _(선택 사항)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | 태스크 출력용 Pydantic 모델입니다. |
| **콜백** _(선택 사항)_ | `callback` | `Optional[Any]` | 태스크 완료 후 실행할 함수/객체입니다. | | **콜백** _(선택 사항)_ | `callback` | `Optional[Any]` | 태스크 완료 후 실행할 함수/객체입니다. |
| **가드레일** _(선택 사항)_ | `guardrail` | `Optional[Callable]` | 다음 태스크로 진행하기 전에 태스크 출력을 검증하는 함수입니다. | | **가드레일** _(선택 사항)_ | `guardrail` | `Optional[Callable]` | 다음 태스크로 진행하기 전에 태스크 출력을 검증하는 함수입니다. |
| **가드레일 최대 재시도** _(선택 사항)_ | `guardrail_max_retries` | `Optional[int]` | 가드레일 검증 실패 시 최대 재시도 횟수입니다. 기본값은 3입니다. |
## 작업 생성하기 ## 작업 생성하기
@@ -448,7 +449,7 @@ task = Task(
expected_output="A valid JSON object", expected_output="A valid JSON object",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limit retry attempts guardrail_max_retries=3 # 재시도 횟수 제한
) )
``` ```
@@ -899,4 +900,4 @@ except RuntimeError as e:
작업(task)은 CrewAI 에이전트의 행동을 이끄는 원동력입니다. 작업(task)은 CrewAI 에이전트의 행동을 이끄는 원동력입니다.
작업과 그 결과를 적절하게 정의함으로써, 에이전트가 독립적으로 또는 협업 단위로 효과적으로 작동할 수 있는 기반을 마련할 수 있습니다. 작업과 그 결과를 적절하게 정의함으로써, 에이전트가 독립적으로 또는 협업 단위로 효과적으로 작동할 수 있는 기반을 마련할 수 있습니다.
작업에 적합한 도구를 장착하고, 실행 과정을 이해하며, 견고한 검증 절차를 따르는 것은 CrewAI의 잠재력을 극대화하는 데 필수적입니다. 작업에 적합한 도구를 장착하고, 실행 과정을 이해하며, 견고한 검증 절차를 따르는 것은 CrewAI의 잠재력을 극대화하는 데 필수적입니다.
이를 통해 에이전트가 할당된 작업에 효과적으로 준비되고, 작업이 의도대로 수행될 수 있습니다. 이를 통해 에이전트가 할당된 작업에 효과적으로 준비되고, 작업이 의도대로 수행될 수 있습니다.

View File

@@ -59,6 +59,7 @@ crew = Crew(
| **Output Pydantic** _(opcional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | Um modelo Pydantic para a saída da tarefa. | | **Output Pydantic** _(opcional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | Um modelo Pydantic para a saída da tarefa. |
| **Callback** _(opcional)_ | `callback` | `Optional[Any]` | Função/objeto a ser executado após a conclusão da tarefa. | | **Callback** _(opcional)_ | `callback` | `Optional[Any]` | Função/objeto a ser executado após a conclusão da tarefa. |
| **Guardrail** _(opcional)_ | `guardrail` | `Optional[Callable]` | Função para validar a saída da tarefa antes de prosseguir para a próxima tarefa. | | **Guardrail** _(opcional)_ | `guardrail` | `Optional[Callable]` | Função para validar a saída da tarefa antes de prosseguir para a próxima tarefa. |
| **Max Tentativas Guardrail** _(opcional)_ | `guardrail_max_retries` | `Optional[int]` | Número máximo de tentativas quando a validação do guardrail falha. Padrão é 3. |
## Criando Tarefas ## Criando Tarefas
@@ -450,7 +451,7 @@ task = Task(
expected_output="Um objeto JSON válido", expected_output="Um objeto JSON válido",
agent=analyst, agent=analyst,
guardrail=validate_json_output, guardrail=validate_json_output,
max_retries=3 # Limite de tentativas guardrail_max_retries=3 # Limite de tentativas
) )
``` ```
@@ -935,7 +936,7 @@ task = Task(
description="Gerar dados", description="Gerar dados",
expected_output="Dados válidos", expected_output="Dados válidos",
guardrail=validate_data, guardrail=validate_data,
max_retries=5 # Sobrescreve o limite padrão de tentativas guardrail_max_retries=5 # Sobrescreve o limite padrão de tentativas
) )
``` ```

View File

@@ -4,6 +4,7 @@ import json
import logging import logging
import threading import threading
import uuid import uuid
import warnings
from concurrent.futures import Future from concurrent.futures import Future
from copy import copy from copy import copy
from hashlib import md5 from hashlib import md5
@@ -157,8 +158,13 @@ class Task(BaseModel):
default=None, default=None,
description="Function or string description of a guardrail to validate task output before proceeding to next task", description="Function or string description of a guardrail to validate task output before proceeding to next task",
) )
max_retries: int = Field( max_retries: Optional[int] = Field(
default=3, description="Maximum number of retries when guardrail fails" default=None,
description="[DEPRECATED] Maximum number of retries when guardrail fails. Use guardrail_max_retries instead. Will be removed in v1.0.0"
)
guardrail_max_retries: int = Field(
default=3,
description="Maximum number of retries when guardrail fails"
) )
retry_count: int = Field(default=0, description="Current number of retries") retry_count: int = Field(default=0, description="Current number of retries")
start_time: Optional[datetime.datetime] = Field( start_time: Optional[datetime.datetime] = Field(
@@ -354,6 +360,18 @@ class Task(BaseModel):
) )
return self return self
@model_validator(mode="after")
def handle_max_retries_deprecation(self):
if self.max_retries is not None:
warnings.warn(
"The 'max_retries' parameter is deprecated and will be removed in CrewAI v1.0.0. "
"Please use 'guardrail_max_retries' instead.",
DeprecationWarning,
stacklevel=2
)
self.guardrail_max_retries = self.max_retries
return self
def execute_sync( def execute_sync(
self, self,
agent: Optional[BaseAgent] = None, agent: Optional[BaseAgent] = None,
@@ -450,9 +468,9 @@ class Task(BaseModel):
retry_count=self.retry_count, retry_count=self.retry_count,
) )
if not guardrail_result.success: if not guardrail_result.success:
if self.retry_count >= self.max_retries: if self.retry_count >= self.guardrail_max_retries:
raise Exception( raise Exception(
f"Task failed guardrail validation after {self.max_retries} retries. " f"Task failed guardrail validation after {self.guardrail_max_retries} retries. "
f"Last error: {guardrail_result.error}" f"Last error: {guardrail_result.error}"
) )

View File

@@ -4150,7 +4150,7 @@ def test_crew_with_failing_task_guardrails():
expected_output="A properly formatted report", expected_output="A properly formatted report",
agent=researcher, agent=researcher,
guardrail=strict_format_guardrail, guardrail=strict_format_guardrail,
max_retries=3, guardrail_max_retries=3,
) )
crew = Crew( crew = Crew(
@@ -4196,7 +4196,7 @@ def test_crew_guardrail_feedback_in_context():
expected_output="A response containing the keyword 'IMPORTANT'", expected_output="A response containing the keyword 'IMPORTANT'",
agent=researcher, agent=researcher,
guardrail=format_guardrail, guardrail=format_guardrail,
max_retries=2, guardrail_max_retries=2,
) )
crew = Crew(agents=[researcher], tasks=[task]) crew = Crew(agents=[researcher], tasks=[task])

View File

@@ -61,7 +61,7 @@ def test_task_with_failing_guardrail():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=1, guardrail_max_retries=1,
) )
# First execution fails guardrail, second succeeds # First execution fails guardrail, second succeeds
@@ -88,7 +88,7 @@ def test_task_with_guardrail_retries():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=2, guardrail_max_retries=2,
) )
with pytest.raises(Exception) as exc_info: with pytest.raises(Exception) as exc_info:
@@ -113,7 +113,7 @@ def test_guardrail_error_in_context():
description="Test task", description="Test task",
expected_output="Output", expected_output="Output",
guardrail=guardrail, guardrail=guardrail,
max_retries=1, guardrail_max_retries=1,
) )
# Mock execute_task to succeed on second attempt # Mock execute_task to succeed on second attempt
@@ -265,7 +265,7 @@ def test_guardrail_when_an_error_occurs(sample_agent, task_output):
agent=sample_agent, agent=sample_agent,
expected_output="A list of available books on the First World War", expected_output="A list of available books on the First World War",
guardrail="Ensure the authors are from Italy", guardrail="Ensure the authors are from Italy",
max_retries=0, guardrail_max_retries=0,
) )
task.execute_sync(agent=sample_agent) task.execute_sync(agent=sample_agent)