-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from jlowin/docs
Add docs
- Loading branch information
Showing
15 changed files
with
897 additions
and
56 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Agents | ||
|
||
In the ControlFlow framework, an `Agent` represents an AI entity capable of performing tasks and interacting with other agents to achieve desired outcomes. Agents are powered by specialized AI models that excel at specific tasks, such as text generation, decision-making based on unstructured data, or engaging in interactive conversations. | ||
|
||
## The Role of Agents in ControlFlow | ||
|
||
Agents play a crucial role in the execution of tasks within the ControlFlow framework. When a task is defined and added to a workflow, it is assigned to one or more agents responsible for completing the task based on the provided objectives, instructions, and context. | ||
|
||
ControlFlow treats agents as autonomous entities with their own knowledge, capabilities, and tools. By assigning tasks to agents and allowing them to collaborate and communicate with each other, ControlFlow enables the creation of complex AI-powered workflows that can adapt to different scenarios and requirements. | ||
|
||
## Defining Agents | ||
|
||
To create an agent in ControlFlow, you can use the `Agent` class, which provides a flexible way to define an agent's properties and capabilities. | ||
|
||
```python | ||
from controlflow import Agent | ||
|
||
writer_agent = Agent( | ||
name="WriterAgent", | ||
description="An AI agent specializing in creative writing tasks.", | ||
tools=[generate_text, summarize_text], | ||
user_access=False | ||
) | ||
``` | ||
|
||
In this example, we define an agent named "WriterAgent" with a description of its specialization. We also specify the tools available to the agent, which are functions or callable objects that the agent can use to perform specific actions or computations. The `user_access` parameter indicates whether the agent is allowed to interact directly with human users. | ||
|
||
## Agent Properties | ||
|
||
Agents have several key properties that define their characteristics and capabilities: | ||
|
||
- `name` (str): The name of the agent, used for identification and communication purposes. | ||
- `description` (str, optional): A brief description of the agent's specialization or role. | ||
- `tools` (list[AssistantTool | Callable], optional): A list of tools or functions available to the agent for performing tasks. | ||
- `user_access` (bool, optional): Indicates whether the agent is allowed to interact directly with human users. | ||
|
||
## Assigning Tasks to Agents | ||
|
||
When defining a task using the `Task` class or the `@ai_task` decorator, you can specify the agents responsible for completing the task by setting the `agents` parameter. | ||
|
||
```python | ||
from controlflow import Task | ||
|
||
write_story_task = Task( | ||
objective="Write a short story about a mysterious artifact.", | ||
result_type=str, | ||
agents=[writer_agent, editor_agent] | ||
) | ||
``` | ||
|
||
In this example, we assign the "write_story_task" to two agents: "writer_agent" and "editor_agent". These agents will collaborate to complete the task based on their individual capabilities and tools. | ||
|
||
## Agent Execution and Communication | ||
|
||
During the execution of a workflow, agents assigned to tasks take turns performing actions and communicating with each other to progress towards completing the tasks. The `run()` method of a task automatically handles the selection and iteration of agents until the task is complete. | ||
|
||
Agents can communicate with each other by posting messages within the context of a task. These messages are visible to all agents involved in the task and can be used to share information, provide updates, or request assistance. | ||
|
||
```python | ||
from controlflow import Flow | ||
|
||
with Flow(): | ||
story_task = Task( | ||
objective="Write a short story and provide feedback.", | ||
result_type=str, | ||
agents=[writer_agent, editor_agent] | ||
) | ||
result = story_task.run() | ||
``` | ||
|
||
In this example, the "writer_agent" and "editor_agent" will take turns working on the "story_task". They can communicate with each other by posting messages within the task's context, allowing them to collaborate and provide feedback until the task is complete. | ||
|
||
## Agent Tools and User Access | ||
|
||
Agents can be equipped with tools, which are functions or callable objects that provide additional capabilities or actions that the agent can perform. These tools can be used by the agent during task execution to perform specific computations, access external resources, or interact with other systems. | ||
|
||
The `user_access` property of an agent determines whether the agent is allowed to interact directly with human users. If `user_access` is set to `True`, the agent can use special tools, such as `talk_to_human()`, to send messages to and receive input from human users. This feature is useful for tasks that require human feedback or intervention. | ||
|
||
|
||
## Conclusion | ||
|
||
Agents are a fundamental concept in the ControlFlow framework, representing the AI entities responsible for executing tasks and collaborating to achieve desired outcomes. By defining agents with specific capabilities, tools, and user access permissions, and assigning them to tasks within a workflow, you can create powerful and adaptable AI-powered applications. | ||
|
||
ControlFlow provides a flexible and intuitive way to orchestrate the interaction between agents and tasks, enabling developers to focus on defining the objectives and dependencies of their workflows while the framework handles the complexities of agent coordination and communication. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Flows | ||
|
||
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. | ||
|
||
## The Role of Flows | ||
|
||
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. | ||
|
||
Key aspects of flows include: | ||
|
||
- **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. | ||
|
||
- **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. | ||
|
||
- **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. | ||
|
||
- **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. | ||
|
||
## Creating a Flow | ||
|
||
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. | ||
|
||
```python | ||
from controlflow import flow | ||
|
||
@flow | ||
def my_flow(): | ||
# Define tasks, agents, and tools here | ||
... | ||
``` | ||
|
||
Alternatively, you can create a flow object directly using the `Flow` class: | ||
|
||
```python | ||
from controlflow import Flow | ||
|
||
flow = Flow() | ||
``` | ||
|
||
## Flow Properties | ||
|
||
Flows have several key properties that define their behavior and capabilities: | ||
|
||
- `thread` (Thread): The thread associated with the flow, which stores the conversation history and context. | ||
- `tools` (list[AssistantTool | Callable]): A list of tools that are available to all agents in the flow. | ||
- `agents` (list[Agent]): The default agents for the flow, which are used for tasks that do not specify agents explicitly. | ||
- `context` (dict): Additional context or information that is shared across tasks and agents in the flow. | ||
|
||
## Running a Flow | ||
|
||
To run a flow, you can simply call the decorated function: | ||
|
||
```python | ||
@flow | ||
def my_flow(): | ||
# Define tasks, agents, and tools here | ||
... | ||
|
||
my_flow() | ||
``` | ||
|
||
When a flow is run, it executes the defined tasks, assigning agents and tools as needed. The flow manages the context across agents. | ||
|
||
|
||
|
||
## Conclusion | ||
|
||
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. | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Iterative Control | ||
|
||
Iterative control lies at the core of agentic workflows, enabling the creation of dynamic and adaptive AI-powered applications. In traditional approaches, the iterative logic is often deeply nested within monolithic AI models, making it challenging to understand, customize, and maintain. ControlFlow takes a different approach by elevating iterative control to a first-class citizen in its API, empowering developers to harness the power of iteration with ease and flexibility. | ||
|
||
## The Importance of Iteration in Agentic Workflows | ||
|
||
Agentic workflows are characterized by their ability to make decisions, take actions, and adapt based on feedback and changing conditions. This inherent adaptability is achieved through iteration - the process of repeatedly executing a series of steps until a desired outcome is reached. | ||
|
||
Consider a simple example of an AI-powered task management system. The system needs to continuously monitor incoming tasks, prioritize them based on predefined criteria, assign them to appropriate agents, and track their progress until completion. This workflow requires iterative control to handle the dynamic nature of tasks and to ensure that the system remains responsive and efficient. | ||
|
||
Without iterative control, the system would be limited to handling a fixed set of tasks in a predefined order, lacking the flexibility to adapt to real-world scenarios. Iterative control allows the system to continuously loop through the task management process, making decisions and taking actions based on the current state of tasks and agents. | ||
|
||
## ControlFlow: Making Iterative Control Accessible | ||
|
||
ControlFlow recognizes the critical role of iterative control in agentic workflows and provides a high-level API that makes it accessible and intuitive for developers. By bringing the concept of iteration to the forefront, ControlFlow enables developers to focus on defining the logic and behavior of their workflows, without getting bogged down in low-level implementation details. | ||
|
||
At the heart of ControlFlow's iterative control mechanism lies the `Task` class. A task represents a unit of work that needs to be accomplished by one or more agents. It encapsulates the necessary information, such as the objective, dependencies, and agents responsible for its execution. | ||
|
||
To iterate over tasks, ControlFlow provides the `run()` method. This method abstracts away the underlying while loop, allowing developers to express their workflow logic in a concise and readable manner. Under the hood, `run()` intelligently selects agents, manages dependencies, and orchestrates the execution of tasks until the desired outcome is achieved. | ||
|
||
Here's an example of how iterative control can be achieved using `run()`: | ||
|
||
```python | ||
task = Task(objective="Analyze sales data") | ||
task.run() | ||
``` | ||
|
||
In this example, the `run()` method takes care of the iterative control flow, repeatedly executing the necessary steps until the task is marked as complete. It handles agent selection, dependency resolution, and progress tracking, freeing developers from the complexities of manual iteration. | ||
|
||
## Granular Control with `run_once()` and `agent.run()` | ||
|
||
While `run()` provides a high-level abstraction for iterative control, ControlFlow also offers more granular control options through the `run_once()` method and the `agent.run()` function. | ||
|
||
The `run_once()` method allows developers to take control of the iteration process by executing a single step at a time. It provides the flexibility to inject custom logic, perform additional checks, or handle specific edge cases within each iteration. By combining `while task.is_incomplete()` with `run_once()`, developers can create custom iteration patterns tailored to their specific requirements. | ||
|
||
Here's an example showcasing the usage of `run_once()`: | ||
|
||
```python | ||
while task.is_incomplete(): | ||
task.run_once() | ||
# Perform additional checks or custom logic | ||
if some_condition: | ||
break | ||
``` | ||
|
||
In this example, the `run_once()` method is called repeatedly within a while loop until the task is marked as complete. This granular control enables developers to incorporate custom logic, such as breaking out of the loop based on certain conditions or performing additional actions between iterations. | ||
|
||
For even more fine-grained control, ControlFlow provides the `agent.run()` function. This function allows developers to explicitly invoke a specific agent to execute a task, bypassing the automated agent selection process. It gives developers complete control over which agent handles a particular task and enables them to create custom agent orchestration patterns. | ||
|
||
Here's an example demonstrating the usage of `agent.run()`: | ||
|
||
```python | ||
agent1 = Agent(name="DataAnalyst") | ||
agent2 = Agent(name="ReportGenerator") | ||
|
||
task1 = Task(objective="Analyze sales data") | ||
task2 = Task(objective="Generate sales report") | ||
|
||
agent1.run(task1) | ||
agent2.run(task2) | ||
``` | ||
|
||
In this example, `agent1` is explicitly assigned to execute `task1`, while `agent2` is assigned to execute `task2`. This level of control is particularly useful when dealing with specialized agents or when implementing complex workflows that require precise agent assignment. | ||
|
||
## Balancing Simplicity and Control | ||
|
||
One of the key strengths of ControlFlow is its ability to provide a high-level API for iterative control without sacrificing the ability to dive into lower-level details when needed. The framework strikes a balance between simplicity and control, catering to the needs of both rapid development and fine-grained customization. | ||
|
||
Developers can start by using the high-level `run()` method to quickly prototype and iterate on their workflows. As their requirements grow more complex, they can gradually transition to using `run_once()` and `agent.run()` to incorporate custom logic and take control of the iteration process. | ||
|
||
This gradual descent into lower-level control is made possible by ControlFlow's thoughtful API design. The lower-level methods, such as `run_once()` and `agent.run()`, are not buried deep within the framework but are readily accessible as part of the public API. This accessibility ensures that developers can seamlessly transition between different levels of control without having to navigate through complex abstractions or modify the underlying framework. | ||
|
||
Moreover, even at the lowest level of control, ControlFlow maintains a relatively high level of abstraction compared to traditional approaches. Developers can focus on expressing their workflow logic using intuitive concepts like tasks, agents, and dependencies, rather than dealing with raw loops, conditionals, and state management. | ||
|
||
This balance between simplicity and control empowers developers to build sophisticated agentic workflows without getting overwhelmed by complexity. It enables them to start simple, iterate quickly, and gradually introduce more advanced control mechanisms as their understanding of the problem domain grows. | ||
|
||
## Conclusion | ||
|
||
Iterative control is the driving force behind agentic workflows, enabling the creation of dynamic, adaptive, and intelligent AI-powered applications. ControlFlow recognizes the importance of iteration and provides a high-level API that makes it accessible and intuitive for developers. | ||
|
||
By offering a spectrum of control options, from the high-level `run()` method to the more granular `run_once()` and `agent.run()` functions, ControlFlow empowers developers to choose the level of control that best suits their needs. Whether they prefer the simplicity of automatic iteration or the precision of manual control, ControlFlow provides a seamless and expressive way to build iterative workflows. | ||
|
||
As developers explore the capabilities of ControlFlow, they can leverage the power of iterative control to create sophisticated agentic systems. They can start with the high-level abstractions, gradually diving into lower-level control mechanisms as their requirements evolve. This progressive approach to iterative control enables developers to build robust, adaptive, and maintainable AI-powered workflows. | ||
|
||
With ControlFlow, the iterative control flow is no longer an obscure concept hidden within monolithic models but a central and accessible part of the development process. By embracing the power of iteration and leveraging ControlFlow's intuitive API, developers can unlock the full potential of agentic workflows and create intelligent, dynamic, and efficient AI-powered applications. |
Oops, something went wrong.