|
1 |
| -# Flows |
2 | 1 |
|
3 |
| -In the ControlFlow framework, a `Flow` represents a container for an AI-enhanced workflow. It serves as the top-level object that encapsulates tasks, agents, tools, and context, providing a structured environment for AI-powered applications. |
| 2 | +Flows are the high-level containers that encapsulate and orchestrate AI-powered workflows in ControlFlow. They provide a structured and organized way to manage tasks, agents, tools, and context, enabling developers to build complex and dynamic applications with ease. |
4 | 3 |
|
5 |
| -## The Role of Flows |
| 4 | +## Creating Flows |
6 | 5 |
|
7 |
| -Flows play a crucial role in organizing and managing the execution of AI-powered workflows. They provide a high-level abstraction for defining the overall structure and dependencies of tasks, agents, and tools, allowing developers to focus on the desired outcomes rather than the low-level details of agent coordination and communication. |
| 6 | +Flows can be created using the `Flow` class or the `@flow` decorator. |
8 | 7 |
|
9 |
| -Key aspects of flows include: |
| 8 | +### Using the `Flow` Class |
10 | 9 |
|
11 |
| -- **Task Management**: Flows contain a collection of tasks that define the discrete objectives and goals of the workflow. Tasks can be added to a flow explicitly or implicitly through the use of the `@ai_task` decorator or the `Task` class. |
| 10 | +The `Flow` class allows you to explicitly define a flow and its properties. |
12 | 11 |
|
13 |
| -- **Agent Coordination**: Flows manage the assignment and orchestration of agents to tasks. By default, flows are initialized with a default agent, but custom agents can be specified to handle specific tasks or parts of the workflow. |
| 12 | +```python |
| 13 | +from controlflow import Flow |
14 | 14 |
|
15 |
| -- **Tool Management**: Flows provide a centralized place to define and manage tools that are available to agents throughout the workflow. Tools can be functions or callable objects that agents can use to perform specific actions or computations. |
| 15 | +flow = Flow( |
| 16 | + name="Data Processing Flow", |
| 17 | + description="A flow to process and analyze data", |
| 18 | + agents=[data_analyst, business_analyst], |
| 19 | + tools=[data_loader, data_cleaner], |
| 20 | +) |
| 21 | +``` |
16 | 22 |
|
17 |
| -- **Context Sharing**: Flows maintain a consistent context across tasks and agents, allowing for seamless sharing of information and state throughout the workflow. The flow's context can be accessed and modified by tasks and agents, enabling dynamic and adaptive behavior. |
| 23 | +By creating a `Flow` instance, you can specify the name, description, agents, tools, and other properties of the flow. This approach provides full control over the flow definition and is particularly useful when you need to customize the flow's behavior or configure advanced settings. |
18 | 24 |
|
19 |
| -## Creating a Flow |
| 25 | +### Using the `@flow` Decorator |
20 | 26 |
|
21 |
| -To create a flow, you can use the `@flow` decorator on a Python function. The decorated function becomes the entry point for the AI-powered workflow. |
| 27 | +The `@flow` decorator provides a convenient way to define a flow using a Python function. |
22 | 28 |
|
23 | 29 | ```python
|
24 | 30 | from controlflow import flow
|
25 | 31 |
|
26 | 32 | @flow
|
27 |
| -def my_flow(): |
28 |
| - # Define tasks, agents, and tools here |
29 |
| - ... |
| 33 | +def data_processing_flow(): |
| 34 | + data = load_data() |
| 35 | + cleaned_data = clean_data(data) |
| 36 | + insights = analyze_data(cleaned_data) |
| 37 | + return insights |
30 | 38 | ```
|
31 | 39 |
|
32 |
| -Alternatively, you can create a flow object directly using the `Flow` class: |
| 40 | +When using the `@flow` decorator, the decorated function becomes the entry point for the flow. The function can contain tasks, which are automatically executed when the flow is run. The `@flow` decorator also allows you to specify flow-level properties such as agents, tools, and context. |
| 41 | + |
| 42 | +## Flow Properties |
| 43 | + |
| 44 | +Flows have several key properties that define their behavior and configuration. |
| 45 | + |
| 46 | +### Name and Description |
| 47 | + |
| 48 | +The `name` and `description` properties allow you to provide a human-readable name and a brief description of the flow. These properties help in identifying and understanding the purpose of the flow. |
33 | 49 |
|
34 | 50 | ```python
|
35 |
| -from controlflow import Flow |
| 51 | +flow = Flow( |
| 52 | + name="Data Processing Flow", |
| 53 | + description="A flow to process and analyze data", |
| 54 | +) |
| 55 | +``` |
| 56 | + |
| 57 | +### Agents and Tools |
| 58 | + |
| 59 | +The `agents` and `tools` properties allow you to specify the AI agents and tools that are available throughout the flow. These agents and tools can be used by tasks within the flow to perform specific actions or computations. |
| 60 | + |
| 61 | +```python |
| 62 | +flow = Flow( |
| 63 | + agents=[data_analyst, business_analyst], |
| 64 | + tools=[data_loader, data_cleaner], |
| 65 | +) |
| 66 | +``` |
| 67 | + |
| 68 | +Agents and tools defined at the flow level are accessible to all tasks within the flow. However, tasks can also have their own specific agents and tools assigned to them. |
| 69 | + |
| 70 | +### Context |
36 | 71 |
|
37 |
| -flow = Flow() |
| 72 | +The `context` property allows you to define a shared context that is accessible to all tasks and agents within the flow. The context can contain any relevant information or data that is required throughout the flow. |
| 73 | + |
| 74 | +```python |
| 75 | +flow = Flow( |
| 76 | + context={ |
| 77 | + "data_source": "path/to/data.csv", |
| 78 | + "target_audience": "marketing_team", |
| 79 | + } |
| 80 | +) |
38 | 81 | ```
|
39 | 82 |
|
40 |
| -## Flow Properties |
| 83 | +The context can be accessed and modified by tasks and agents during the flow execution, enabling dynamic and adaptive behavior based on the flow's state. |
| 84 | + |
| 85 | +## Running Flows |
| 86 | + |
| 87 | +Flows can be run using the `run()` method, which executes all of the tasks that were defined within the flow. |
| 88 | +<CodeGroup> |
| 89 | + |
| 90 | +```python @flow decorator |
| 91 | +@flow |
| 92 | +def data_processing_flow(): |
| 93 | + data = load_data() |
| 94 | + cleaned_data = clean_data(data) |
| 95 | + insights = analyze_data(cleaned_data) |
| 96 | + return insights |
| 97 | + |
| 98 | +results = data_processing_flow() |
| 99 | +``` |
| 100 | +```python Flow class |
| 101 | +with Flow() as data_processing_flow: |
| 102 | + data = load_data() |
| 103 | + cleaned_data = clean_data(data) |
| 104 | + insights = analyze_data(cleaned_data) |
| 105 | + |
| 106 | +data_processing_flow.run() |
| 107 | +print(insights.result) |
| 108 | +``` |
| 109 | +</CodeGroup> |
41 | 110 |
|
42 |
| -Flows have several key properties that define their behavior and capabilities: |
| 111 | +When a flow is run, ControlFlow orchestrates the execution of tasks, resolving dependencies, and managing the flow of data between tasks. The flow ensures that tasks are executed in the correct order and that the necessary context and results are propagated throughout the flow. |
43 | 112 |
|
44 |
| -- `thread` (Thread): The thread associated with the flow, which stores the conversation history and context. |
45 |
| -- `tools` (list[ToolType]): A list of tools that are available to all agents in the flow. |
46 |
| -- `agents` (list[Agent]): The default agents for the flow, which are used for tasks that do not specify agents explicitly. |
47 |
| -- `context` (dict): Additional context or information that is shared across tasks and agents in the flow. |
| 113 | +## Flow Execution and Task Dependencies |
48 | 114 |
|
49 |
| -## Running a Flow |
| 115 | +Flows in ControlFlow follow a structured execution model based on task dependencies. When a flow is run, ControlFlow analyzes the dependencies between tasks and determines the execution order. |
50 | 116 |
|
51 |
| -To run a flow, you can simply call the decorated function: |
| 117 | +### Task Dependencies |
| 118 | + |
| 119 | +Tasks within a flow can have dependencies on other tasks. These dependencies define the order in which tasks should be executed and ensure that tasks have access to the necessary data or results from previous tasks. |
| 120 | + |
| 121 | +Dependencies can be specified using the `depends_on` property of the `Task` class or by passing tasks as arguments to other tasks. |
52 | 122 |
|
53 | 123 | ```python
|
54 | 124 | @flow
|
55 |
| -def my_flow(): |
56 |
| - # Define tasks, agents, and tools here |
57 |
| - ... |
| 125 | +def data_processing_flow(): |
| 126 | + raw_data = load_data() |
| 127 | + cleaned_data = clean_data(raw_data) |
| 128 | + insights = analyze_data(cleaned_data) |
| 129 | + report = generate_report(insights) |
| 130 | + return report |
| 131 | +``` |
| 132 | + |
| 133 | +In this example, the `clean_data` task depends on the `load_data` task, the `analyze_data` task depends on the `clean_data` task, and the `generate_report` task depends on the `analyze_data` task. ControlFlow ensures that the tasks are executed in the correct order based on these dependencies. |
58 | 134 |
|
59 |
| -my_flow() |
| 135 | +### Parallel Execution |
| 136 | + |
| 137 | +ControlFlow supports parallel execution of tasks that are independent of each other. When multiple tasks have no dependencies between them, they can be executed concurrently, improving the overall performance of the flow. |
| 138 | + |
| 139 | +```python |
| 140 | +@flow |
| 141 | +def parallel_flow(): |
| 142 | + task1 = process_data1() |
| 143 | + task2 = process_data2() |
| 144 | + task3 = process_data3() |
| 145 | + results = combine_results(task1, task2, task3) |
| 146 | + return results |
60 | 147 | ```
|
61 | 148 |
|
62 |
| -When a flow is run, it executes the defined tasks, assigning agents and tools as needed. The flow manages the context across agents. |
| 149 | +In this example, `task1`, `task2`, and `task3` have no dependencies on each other and can be executed in parallel. ControlFlow automatically manages the parallel execution and ensures that the results are properly combined in the `combine_results` task. |
| 150 | + |
| 151 | +## Error Handling and Flow Control |
| 152 | + |
| 153 | +ControlFlow provides mechanisms for error handling and flow control within flows. |
| 154 | + |
| 155 | +### Error Handling |
| 156 | + |
| 157 | +Errors that occur during task execution can be handled using exception handling. By wrapping tasks in try-except blocks, you can catch and handle specific exceptions, providing appropriate error messages or fallback behavior. |
| 158 | + |
| 159 | +```python |
| 160 | +@flow |
| 161 | +def error_handling_flow(): |
| 162 | + try: |
| 163 | + data = load_data() |
| 164 | + cleaned_data = clean_data(data) |
| 165 | + insights = analyze_data(cleaned_data) |
| 166 | + except DataLoadError: |
| 167 | + logger.error("Failed to load data") |
| 168 | + insights = None |
| 169 | + except DataCleaningError: |
| 170 | + logger.error("Failed to clean data") |
| 171 | + insights = None |
| 172 | + return insights |
| 173 | +``` |
| 174 | + |
| 175 | +In this example, if an error occurs during the `load_data` or `clean_data` tasks, the corresponding exception is caught, an error message is logged, and the `insights` variable is set to `None`. This allows the flow to gracefully handle errors and continue execution. |
| 176 | + |
| 177 | +### Flow Control |
| 178 | + |
| 179 | +ControlFlow provides flow control mechanisms to conditionally execute tasks or repeat tasks based on certain conditions. |
| 180 | + |
| 181 | +```python |
| 182 | +@flow |
| 183 | +def conditional_flow(condition): |
| 184 | + data = load_data() |
| 185 | + if condition: |
| 186 | + cleaned_data = clean_data(data) |
| 187 | + insights = analyze_data(cleaned_data) |
| 188 | + else: |
| 189 | + insights = analyze_raw_data(data) |
| 190 | + return insights |
| 191 | +``` |
| 192 | + |
| 193 | +In this example, the flow conditionally executes either the `clean_data` and `analyze_data` tasks or the `analyze_raw_data` task based on the value of the `condition` variable. This allows for dynamic flow execution based on runtime conditions. |
63 | 194 |
|
64 | 195 | ## Conclusion
|
65 | 196 |
|
66 |
| -Flows are a fundamental concept in the ControlFlow framework, providing a structured and flexible way to define, organize, and execute AI-powered workflows. By encapsulating tasks, agents, tools, and context within a flow, developers can create complex and dynamic applications that leverage the power of AI while maintaining a clear and maintainable structure. |
| 197 | +Flows in ControlFlow provide a powerful and flexible way to orchestrate AI-powered workflows. By defining flows using the `Flow` class or the `@flow` decorator, developers can create structured and organized workflows that manage tasks, agents, tools, and context. |
| 198 | + |
| 199 | +Flows enable the execution of tasks in a defined order, resolving dependencies and allowing for parallel execution when possible. They also provide mechanisms for error handling and flow control, allowing for robust and adaptive workflow execution. |
67 | 200 |
|
68 |
| -Flows abstract away the low-level details of agent coordination and communication, allowing developers to focus on defining the desired outcomes and objectives of their workflows. With the `@flow` decorator and the `Flow` class, creating and running AI-powered workflows becomes a straightforward and intuitive process. |
| 201 | +By leveraging flows in ControlFlow, developers can build complex and dynamic AI-powered applications that are maintainable, scalable, and aligned with business requirements. Flows provide a high-level abstraction for managing AI workflows, enabling developers to focus on the logic and objectives of their applications while ControlFlow handles the underlying orchestration and execution. |
0 commit comments