mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-11 00:58:30 +00:00
Adding support for expected output
This commit is contained in:
@@ -6,12 +6,14 @@ from pydantic_core import PydanticCustomError
|
|||||||
|
|
||||||
from crewai.agent import Agent
|
from crewai.agent import Agent
|
||||||
from crewai.tasks.task_output import TaskOutput
|
from crewai.tasks.task_output import TaskOutput
|
||||||
|
from crewai.utilities import I18N
|
||||||
|
|
||||||
|
|
||||||
class Task(BaseModel):
|
class Task(BaseModel):
|
||||||
"""Class that represent a task to be executed."""
|
"""Class that represent a task to be executed."""
|
||||||
|
|
||||||
__hash__ = object.__hash__
|
__hash__ = object.__hash__
|
||||||
|
i18n: I18N = I18N()
|
||||||
description: str = Field(description="Description of the actual task.")
|
description: str = Field(description="Description of the actual task.")
|
||||||
agent: Optional[Agent] = Field(
|
agent: Optional[Agent] = Field(
|
||||||
description="Agent responsible for the task.", default=None
|
description="Agent responsible for the task.", default=None
|
||||||
@@ -20,6 +22,10 @@ class Task(BaseModel):
|
|||||||
default_factory=list,
|
default_factory=list,
|
||||||
description="Tools the agent are limited to use for this task.",
|
description="Tools the agent are limited to use for this task.",
|
||||||
)
|
)
|
||||||
|
expected_output: str = Field(
|
||||||
|
description="Clear definition of expected output for the task.",
|
||||||
|
default=None,
|
||||||
|
)
|
||||||
output: Optional[TaskOutput] = Field(
|
output: Optional[TaskOutput] = Field(
|
||||||
description="Task output, it's final result.", default=None
|
description="Task output, it's final result.", default=None
|
||||||
)
|
)
|
||||||
@@ -54,9 +60,25 @@ class Task(BaseModel):
|
|||||||
raise Exception(
|
raise Exception(
|
||||||
f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Crew using a specific process that support that, either consensual or hierarchical."
|
f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Crew using a specific process that support that, either consensual or hierarchical."
|
||||||
)
|
)
|
||||||
|
|
||||||
result = self.agent.execute_task(
|
result = self.agent.execute_task(
|
||||||
task=self.description, context=context, tools=self.tools
|
task=self._prompt(), context=context, tools=self.tools
|
||||||
)
|
)
|
||||||
|
|
||||||
self.output = TaskOutput(description=self.description, result=result)
|
self.output = TaskOutput(description=self.description, result=result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _prompt(self) -> str:
|
||||||
|
"""Prompt the task.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Prompt of the task.
|
||||||
|
"""
|
||||||
|
tasks_slices = [self.description]
|
||||||
|
|
||||||
|
if self.expected_output:
|
||||||
|
output = self.i18n.slice("expected_output").format(
|
||||||
|
expected_output=self.expected_output
|
||||||
|
)
|
||||||
|
tasks_slices = [self.description, output]
|
||||||
|
return "\n".join(tasks_slices)
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
"memory": "Αυτή είναι η περίληψη της μέχρι τώρα δουλειάς σας:\n{chat_history}",
|
"memory": "Αυτή είναι η περίληψη της μέχρι τώρα δουλειάς σας:\n{chat_history}",
|
||||||
"role_playing": "Είσαι {role}.\n{backstory}\n\nΟ προσωπικός σας στόχος είναι: {goal}",
|
"role_playing": "Είσαι {role}.\n{backstory}\n\nΟ προσωπικός σας στόχος είναι: {goal}",
|
||||||
"tools": "ΕΡΓΑΛΕΙΑ:\n------\nΈχετε πρόσβαση μόνο στα ακόλουθα εργαλεία:\n\n{tools}\n\nΓια να χρησιμοποιήσετε ένα εργαλείο, χρησιμοποιήστε την ακόλουθη ακριβώς μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Ναί\nΔράση: η ενέργεια που πρέπει να γίνει, πρέπει να είναι μία από τις[{tool_names}], μόνο το όνομα.\nΕνέργεια προς εισαγωγή: η είσοδος στη δράση\nΠαρατήρηση: το αποτέλεσμα της δράσης\n```\n\nΌταν έχετε μια απάντηση για την εργασία σας ή εάν δεν χρειάζεται να χρησιμοποιήσετε ένα εργαλείο, ΠΡΕΠΕΙ να χρησιμοποιήσετε τη μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Οχι\nΤελική απάντηση: [η απάντησή σας εδώ]",
|
"tools": "ΕΡΓΑΛΕΙΑ:\n------\nΈχετε πρόσβαση μόνο στα ακόλουθα εργαλεία:\n\n{tools}\n\nΓια να χρησιμοποιήσετε ένα εργαλείο, χρησιμοποιήστε την ακόλουθη ακριβώς μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Ναί\nΔράση: η ενέργεια που πρέπει να γίνει, πρέπει να είναι μία από τις[{tool_names}], μόνο το όνομα.\nΕνέργεια προς εισαγωγή: η είσοδος στη δράση\nΠαρατήρηση: το αποτέλεσμα της δράσης\n```\n\nΌταν έχετε μια απάντηση για την εργασία σας ή εάν δεν χρειάζεται να χρησιμοποιήσετε ένα εργαλείο, ΠΡΕΠΕΙ να χρησιμοποιήσετε τη μορφή:\n\n```\nΣκέψη: Χρειάζεται να χρησιμοποιήσω κάποιο εργαλείο; Οχι\nΤελική απάντηση: [η απάντησή σας εδώ]",
|
||||||
"task_with_context": "{task}\nΑυτό είναι το πλαίσιο με το οποίο εργάζεστε:\n{context}"
|
"task_with_context": "{task}\nΑυτό είναι το πλαίσιο με το οποίο εργάζεστε:\n{context}",
|
||||||
|
"expected_output": "Η τελική σας απάντηση πρέπει να είναι: {expected_output}"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"used_too_many_tools": "Έχω χρησιμοποιήσει πάρα πολλά εργαλεία για αυτήν την εργασία. Θα σας δώσω την απόλυτη ΚΑΛΥΤΕΡΗ τελική μου απάντηση τώρα και δεν θα χρησιμοποιήσω άλλα εργαλεία.",
|
"used_too_many_tools": "Έχω χρησιμοποιήσει πάρα πολλά εργαλεία για αυτήν την εργασία. Θα σας δώσω την απόλυτη ΚΑΛΥΤΕΡΗ τελική μου απάντηση τώρα και δεν θα χρησιμοποιήσω άλλα εργαλεία.",
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
"memory": "This is the summary of your work so far:\n{chat_history}",
|
"memory": "This is the summary of your work so far:\n{chat_history}",
|
||||||
"role_playing": "You are {role}.\n{backstory}\n\nYour personal goal is: {goal}",
|
"role_playing": "You are {role}.\n{backstory}\n\nYour personal goal is: {goal}",
|
||||||
"tools": "TOOLS:\n------\nYou have access to only the following tools:\n\n{tools}\n\nTo use a tool, please use the exact following format:\n\n```\nThought: Do I need to use a tool? Yes\nAction: the action to take, should be one of [{tool_names}], just the name.\nAction Input: the input to the action\nObservation: the result of the action\n```\n\nWhen you have a response for your task, or if you do not need to use a tool, you MUST use the format:\n\n```\nThought: Do I need to use a tool? No\nFinal Answer: [your response here]",
|
"tools": "TOOLS:\n------\nYou have access to only the following tools:\n\n{tools}\n\nTo use a tool, please use the exact following format:\n\n```\nThought: Do I need to use a tool? Yes\nAction: the action to take, should be one of [{tool_names}], just the name.\nAction Input: the input to the action\nObservation: the result of the action\n```\n\nWhen you have a response for your task, or if you do not need to use a tool, you MUST use the format:\n\n```\nThought: Do I need to use a tool? No\nFinal Answer: [your response here]",
|
||||||
"task_with_context": "{task}\nThis is the context you're working with:\n{context}"
|
"task_with_context": "{task}\nThis is the context you're working with:\n{context}",
|
||||||
|
"expected_output": "Your final answer must be: {expected_output}"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"used_too_many_tools": "I've used too many tools for this task. I'm going to give you my absolute BEST Final answer now and not use any more tools.",
|
"used_too_many_tools": "I've used too many tools for this task. I'm going to give you my absolute BEST Final answer now and not use any more tools.",
|
||||||
|
|||||||
@@ -55,3 +55,26 @@ def test_task_tool_takes_precedence_ove_agent_tools():
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert task.tools == [fake_task_tool]
|
assert task.tools == [fake_task_tool]
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_prompt_includes_expected_output():
|
||||||
|
researcher = Agent(
|
||||||
|
role="Researcher",
|
||||||
|
goal="Make the best research and analysis on content about AI and AI agents",
|
||||||
|
backstory="You're an expert researcher, specialized in technology, software engineering, AI and startups. You work as a freelancer and is now working on doing research and analysis for a new customer.",
|
||||||
|
allow_delegation=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
task = Task(
|
||||||
|
description="Give me a list of 5 interesting ideas to explore for na article, what makes them unique and interesting.",
|
||||||
|
expected_output="Bullet point list of 5 interesting ideas.",
|
||||||
|
agent=researcher,
|
||||||
|
allow_delegation=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
with patch.object(Agent, "execute_task") as execute:
|
||||||
|
execute.return_value = "ok"
|
||||||
|
task.execute()
|
||||||
|
execute.assert_called_once_with(task=task._prompt(), context=None, tools=[])
|
||||||
|
|||||||
Reference in New Issue
Block a user