ControlFlow
ControlFlow copied to clipboard
Creating specialized agents section of Quickstart fails
Description
I am following the quickstart and running the code myself. The first agent writes a reply to the email successfully. The second agent intended to mark emails as spam fails reliably.
It classifies the first email successfully then fails for the subsequent emails as it has already marked the task as completed. The output follows:
╭─ Agent: Email Classifier ────────────────────────────────────────────────────────────────────────╮
│ │
│ ✅ Tool call: "mark_task_9101424a_successful" │
│ │
│ Tool args: {'task_result': 0} │
│ │
│ Tool result: Task #9101424a ("Classify the emails") marked successful. │
│ ❌ Tool call: "mark_task_9101424a_successful" │
│ │
│ Tool args: {'task_result': 1} │
│ │
│ Tool result: Error calling function "mark_task_9101424a_successful": Task #9101424a │
│ ("Classify the emails") is already marked successful. │
│ ❌ Tool call: "mark_task_9101424a_successful" │
│ │
│ Tool args: {'task_result': 0} │
│ │
│ Tool result: Error calling function "mark_task_9101424a_successful": Task #9101424a │
│ ("Classify the emails") is already marked successful. │
│ │
╰──────────────────────────────────────────────────────────────────────────────────── 10:23:29 AM ─╯
10:23:29.726 | ERROR | Task run 'Tool call: mark_task_9101424a_successful' - Task run failed with exception: ValueError('Task #9101424a ("Classify the emails") is already marked successful.') - Retries are exhausted
Traceback (most recent call last):
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 805, in run_context
yield self
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 1387, in run_task_sync
engine.call_task_fn(txn)
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 828, in call_task_fn
result = call_with_parameters(self.task.fn, parameters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/utilities/callables.py", line 208, in call_with_parameters
return fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/controlflow/tools/tools.py", line 61, in run
result = self.fn(**input)
^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/controlflow/tasks/task.py", line 675, in succeed
raise ValueError(
ValueError: Task #9101424a ("Classify the emails") is already marked successful.
10:23:29.731 | ERROR | Task run 'Tool call: mark_task_9101424a_successful' - Finished in state Failed('Task run encountered an exception ValueError: Task #9101424a ("Classify the emails") is already marked successful.')
10:23:29.761 | ERROR | Task run 'Tool call: mark_task_9101424a_successful' - Task run failed with exception: ValueError('Task #9101424a ("Classify the emails") is already marked successful.') - Retries are exhausted
Traceback (most recent call last):
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 805, in run_context
yield self
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 1387, in run_task_sync
engine.call_task_fn(txn)
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/task_engine.py", line 828, in call_task_fn
result = call_with_parameters(self.task.fn, parameters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/prefect/utilities/callables.py", line 208, in call_with_parameters
return fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/controlflow/tools/tools.py", line 61, in run
result = self.fn(**input)
^^^^^^^^^^^^^^^^
File "/home/matthew/.cache/pypoetry/virtualenvs/ask-anything-d4NqA-em-py3.12/lib/python3.12/site-packages/controlflow/tasks/task.py", line 675, in succeed
raise ValueError(
ValueError: Task #9101424a ("Classify the emails") is already marked successful.
10:23:29.765 | ERROR | Task run 'Tool call: mark_task_9101424a_successful' - Finished in state Failed('Task run encountered an exception ValueError: Task #9101424a ("Classify the emails") is already marked successful.')
important
Example Code
import controlflow as cf
emails = [
"Hello, I need an update on the project status.",
"Subject: Exclusive offer just for you!",
"Urgent: Project deadline moved up by one week.",
]
# Create a specialized agent
classifier = cf.Agent(
name="Email Classifier",
model="openai/gpt-4o-mini",
instructions="You are an expert at quickly classifying emails.",
)
# Set up a ControlFlow task to classify emails
classifications = cf.run(
'Classify the emails',
result_type=['important', 'spam'],
agents=[classifier],
context=dict(emails=emails),
)
print(classifications)
Version Information
ControlFlow version: 0.11.4
Prefect version: 3.1.13
LangChain Core version: 0.3.30
Python version: 3.12.7
Platform: Linux-6.8.0-51-generic-x86_64-with-glibc2.39
Additional Context
No response
For reference this code works:
import controlflow as cf
from pydantic import BaseModel
class EmailClassification(BaseModel):
content: str
is_spam: bool
emails = [
"Hello, I need an update on the project status.",
"Subject: Exclusive offer just for you!",
"Urgent: Project deadline moved up by one week.",
]
# Create a specialized agent
classifier = cf.Agent(
name="Email Classifier",
model="openai/gpt-4o-mini",
instructions="You are an expert at quickly classifying emails.",
)
# Set up a ControlFlow task to classify emails
classifications = cf.run(
'Classify the emails',
result_type=list[EmailClassification],
agents=[classifier],
context={"emails": emails},
)
print(classifications)
It produces:
╭─ Agent: Email Classifier ────────────────────────────────────────────────────────────────────────╮
│ │
│ ✅ Tool call: "mark_task_88b66e6e_successful" │
│ │
│ Tool args: {'task_result': [{'content': 'Hello, I need an update on the project status.', │
│ 'is_spam': False}, {'content': 'Subject: Exclusive offer just for you!', 'is_spam': True}, │
│ {'content': 'Urgent: Project deadline moved up by one week.', 'is_spam': False}]} │
│ │
│ Tool result: Task #88b66e6e ("Classify the emails") marked successful. │
│ │
╰──────────────────────────────────────────────────────────────────────────────────── 10:30:04 AM ─╯
[EmailClassification(content='Hello, I need an update on the project status.', is_spam=False), EmailClassification(content='Subject: Exclusive offer just for you!', is_spam=True), EmailClassification(content='Urgent: Project deadline moved up by one week.', is_spam=False)]