Break complex or open-ended tasks into smaller, manageable steps.

In complex AI workflows, breaking down large tasks into smaller, manageable steps can significantly improve the quality and reliability of the results. ControlFlow’s subtask feature provides a powerful mechanism for structuring these hierarchical task relationships, allowing you to guide AI agents through a series of logical steps to achieve a larger goal.

Subtasks in ControlFlow are child tasks that must be completed before their parent task can be considered finished. This hierarchical structure enables you to create detailed, step-by-step workflows that an AI agent can follow, ensuring thorough and accurate task completion.

When you run a parent task, all of its subtasks are automatically executed because they become dependencies of the parent. You don’t need to also explicitly run the subtasks or return them from the flow.

Creating Subtasks with Context Managers

One way to create subtasks is by using a context manager. This approach allows you to dynamically generate and execute subtasks within the scope of a parent task.

import controlflow as cf

@cf.flow
def counting_flow():
    with cf.Task("Count to three", result_type=None) as count_task:
        cf.Task("Say one")
        cf.Task("Say two")
        cf.Task("Say three")

    return count_task

result = counting_flow()

In this example, the AI agent must complete all three subtasks (“Say one”, “Say two”, “Say three”) before the parent task “Count to three” can be considered complete.

Creating Subtasks Imperatively

You can also create subtasks imperatively by passing the parent task as an argument when creating a new task.

import controlflow as cf

@cf.flow
def greeting_flow():
    parent_task = cf.Task("Create a greeting", result_type=str)
    
    cf.Task("Choose a greeting word", parent=parent_task)
    cf.Task("Add a friendly adjective", parent=parent_task)
    cf.Task("Construct the final greeting", parent=parent_task)

    return parent_task

result = greeting_flow()

This approach provides more flexibility in creating and organizing subtasks, especially when the parent-child relationships are determined dynamically during runtime.

Generating Subtasks Automatically

For more complex scenarios where you need to automatically generate subtasks based on the parent task’s objective, ControlFlow provides a generate_subtasks() method. This powerful feature allows for dynamic task planning and is especially useful for breaking down complex tasks into more manageable steps.

For more information on how to use generate_subtasks(), please refer to the Task Planning pattern.