-
Notifications
You must be signed in to change notification settings - Fork 4.1k
[BUG]Type Error in Hierarchical Process Delegation #2606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
…2606) Co-Authored-By: Joe Moura <joao@crewai.com>
Hi @HaohanTsao, which large language model are you using because of which the validation issue is coming up? |
gpt-4o-mini |
Can you try a small experiment for me? can you replace this function def _generate_description(self):
print("Generating description...")
calling_class = self.__class__.__name__
print(f"Method called by: {calling_class}")
args_schema = {}
for name, field in self.args_schema.model_fields.items():
args_schema[name] = {
"description": field.description,
"type": BaseTool._get_arg_annotations(field.annotation),
"required": True # Assuming all parameters are required
}
print(args_schema)
usage_instructions = f"""Usage Instructions: To use this tool ({self.name}), you must provide the following parameters with their corresponding data types:\n"""
for name, info in args_schema.items():
usage_instructions += f"- {name}: {info['description']} (Type: {info['type']})\n"
example_args = {}
for name, info in args_schema.items():
if info["type"] == "str":
example_args[name] = f'"{name}_example"'
elif info["type"] == "int":
example_args[name] = "42"
elif info["type"] == "float":
example_args[name] = "3.14"
elif info["type"] == "bool":
example_args[name] = "True"
else:
example_args[name] = f'"{name}_example"'
correct_usage = f"\nExample Usage:\n{self.name}({', '.join([f'{name}={value}' for name, value in example_args.items()])})\n"
self.description = f"Tool Name: {self.name}\nTool Arguments: {args_schema}\nTool Description: {self.description}\n{usage_instructions}{correct_usage}"
print(self.description) here, crewAI/src/crewai/tools/base_tool.py Lines 147 to 156 in efe27bd
and check whether this validation error is still there. |
Ok, I just tried with gpt-3.5-turbo. It runs without error. |
With the above mentioned change or independently, it works? |
Independently. And I also tried your method on both 4o-mini and 3.5-turbo. Both work. Here is a part of printed output by 3.5-turbo.
|
@lucasgomide, what do you think on this? This validation issue is a problem which was faced before as well. The issue I see, is Tool Name: Delegate work to coworker
Tool Arguments: {'task': {'description': 'The task to delegate', 'type': 'str', 'required': True}, 'context': {'description': 'The context for the task', 'type': 'str', 'required': True}, 'coworker': {'description': 'The role/name of the coworker to delegate to', 'type': 'str', 'required': True}}
Tool Description: Delegate a specific task to one of the following coworkers: Research Specialist, Content Writer
The input to this tool should be the coworker, the task you want them to do, and ALL necessary context to execute the task, they know nothing about the task, so share absolutely everything you know, don't reference things but instead explain them. In the tool arguments, we give a description kind of field, because of which I believe llm are generating a nested dictionary. Tool Name: Delegate work to coworker
Tool Arguments: {'task': {'description': 'The task to delegate', 'type': 'str', 'required': True}, 'context': {'description': 'The context for the task', 'type': 'str', 'required': True}, 'coworker': {'description': 'The role/name of the coworker to delegate to', 'type': 'str', 'required': True}}
Tool Description: Delegate a specific task to one of the following coworkers: Research Specialist, Content Writer
The input to this tool should be the coworker, the task you want them to do, and ALL necessary context to execute the task, they know nothing about the task, so share absolutely everything you know, don't reference things but instead explain them.
Usage Instructions: To use this tool (Delegate work to coworker), you must provide the following parameters with their corresponding data types:
- task: The task to delegate (Type: str)
- context: The context for the task (Type: str)
- coworker: The role/name of the coworker to delegate to (Type: str)
Example Usage:
Delegate work to coworker(task="task_example", context="context_example", coworker="coworker_example") There is no way to tell, whether this prompting would work or not?. Just to add and check whether users are facing these validation issue or not. |
Thanks for digging into this. I see your point about it being a prompt engineering issue. What about keeping both solutions? We could improve the tool descriptions as you suggested AND keep the flexible type handling as a safety net. This way we're covered regardless of which LLM is being used or how it interprets the instructions. What do you think? |
so the validation fix can not be applied globally, If we relax the validation which is happening in this particular case, then it might resolve the issue currently, but this issue will persists, if any other user uses any other tool. Also, another consideration is if tomorrow, llm by itself, decides to make the nested dictionary, with some other parameter, then also this tool will fail. That's why I am trying to create a global solution, which will apply on all the tools. |
This topic is relatively new to me, so I’ll need some time to digest it, though. At the first view, i totally agreed with @HaohanTsao (including its PR) but as i said, I need a bit more time to fully understand what’s happening I really appreciate your though @Vidit-Ostwal .. very clear. I'm going to dive deeper into it tomorrow |
Let me know if you need any help on this one!? |
I'm wondering what if we just embrace what LLMs do best - generating plain text? For parameters like "task" and "context" that are essentially just descriptions, what if we explicitly instruct LLMs to provide simple text respectively without any JSON or nested structures? This would be a bigger change to the tool description system than my PR fix and cost more, but might solve a whole class of similar issues across different models. Do you think this approach would work with CrewAI's design philosophy, or would it require too much refactoring? |
I am a bit biased to use pydantic classes as a type check to ensure only relevant fields are passed! |
here's my 🪙
|
Thank you for your explanation and insights! I appreciate you taking the time to share your perspective on addressing this issue. I understand your approach now - focusing on improving the prompts/instructions rather than adapting the code to handle various output formats. That makes sense from a design philosophy standpoint. Should I close my PR ? Since it doesn't align with the preferred direction. I'm looking forward to seeing how the prompt engineering solution develops, and would be happy to help test or contribute to that approach if needed. Thanks again for the thoughtful discussion around this issue! |
Agreed in this, the entire change if we need to do will happen in the |
Yeah you can close (: Thank your for bringing this theme up and your patience 😆 |
Description
When using CrewAI's hierarchical process with delegation, the manager agent fails to delegate tasks due to type validation errors in the DelegateWorkToolSchema. The manager attempts to pass dictionary objects for task and context parameters, but the schema expects string values.
Steps to Reproduce
Expected behavior
The manager agent should be able to successfully delegate tasks to appropriate worker agents.
Screenshots/Code snippets
Operating System
macOS Sonoma
Python Version
3.12
crewAI Version
0.114.0
crewAI Tools Version
0.40.1
Virtual Environment
Conda
Evidence
The tool execution fails with validation errors. The manager is attempting to pass dictionary objects when the schema expects strings:
Possible Solution
Analysis of the CrewAI Delegation Error and Proposed Solution
After analyzing the CrewAI codebase thoroughly, I can identify the exact cause of the delegation error and suggest an appropriate fix that the repository owners would likely appreciate.
Root Cause Analysis
The issue occurs in the hierarchical process when the manager agent attempts to delegate tasks. Here's what's happening:
The
DelegateWorkToolSchema
(indelegate_work_tool.py
) is defined with string fields:However, when the manager agent tries to delegate, it's passing Task objects or dictionaries with a format like:
The validation fails because the schema expects strings, not dictionaries.
Most Likely Solution
The best solution would be to modify the
DelegateWorkToolSchema
class to accept both string and dictionary inputs, ensuring backward compatibility while fixing the issue:Then, modify the
DelegateWorkTool._run
method to handle both formats:Why This Solution Works
Backward Compatibility: This solution maintains compatibility with existing code that passes strings.
Enhanced Flexibility: It allows for both string and dictionary inputs, making the API more flexible.
Minimal Changes: The fix is localized to just the delegation tool schema and its implementation.
Matches Workflow Intent: It maintains the original intent of the delegation workflow while fixing the type mismatch.
This approach is also aligned with how CrewAI handles other tool validations in the codebase, as seen in the
tool_usage.py
file where there are several input validation and conversion mechanisms.Alternative Solution (If Type Changes Are Undesirable)
If changing the schema types is problematic, an alternative would be to add pre-processing in the
Agent.get_delegation_tools
method to ensure tasks are converted to strings before being passed to the delegation tool:Additional context
None
The text was updated successfully, but these errors were encountered: