Updates to Workflows
New Features
So far this course has been focused on how you could create Workflows with Griptape before v0.27.0. However, with some new features added in v0.27.0, it's now possible to use a more intuitive syntax for specifying parent-child relationships in workflow tasks. With Imperative declaration - you are defining a specific series of tasks and then define their relationship. With Declarative, we are defining the goal - the tasks are described in terms of their relationships instead of specifically calling the steps to create them. On this page, we'll take a look at these changes.
Note
Here is a link to the documentation for Workflows. This page will explain further what we are able to do with these new features.
The code below demonstrates how we've been creating workflows throughout the course - by creating a start and end task. Then inserting tasks between them.
A better way to build Workflows
There are now two ways to manage the hierarchy of the workflow.
One way is to use the add_parent
and add_child
commands to quickly add a hierarchy relationship to a task.
For example:
start_task
as a parent to my_task
.
The second way is to declare the relationship while creating the Task. For example:
Here, we've used the parent_ids
parameter to tell the task the id
of the task that will be it's parent. Notice it's a list - you can have multiple parents for any task. The same is true of children.
Finally, once you've defined the relationships, you will need to add the tasks to the Workflow using the tasks parameter.
For example:
We'll get into greater detail on all these updates in the following sections. Read along to learn more.
Updates to Parent-Child relationships
Previously in Griptape v0.26.0, declaring parent-child relationships wasn't always very intuitive. First, you would’ve had to add the start and end Tasks, and then insert all children Tasks between the parent and the last child. With Griptape v0.27.0, this process is not only easier to visualize, but also easier to use. Let's take a look at imperatively declaring parent-children relationships.
Imperatively specifying Parent-Child relationships:
Tip
The *
in front of the Tasks list unpacks each element and inserts them into the new list as separate items. For example, if you had a list of tasks like this:
my_tasks = [task_1, task_2, task_3]
and then did something like:
tasks=[start_task, *my_tasks, end_task]
It would resolve to:
tasks=[start_task, task_1, task_2, task_3, end_task]
As seen above, we declared the children of the start_task
, then added the end_task
as a child.
These both output the following graph:
graph TB
subgraph " "
direction TB
B(start_task):::main --> C(TASK_Toy story) --> E(END):::main
B --> D(TASK_The Matrix) --> E
end
classDef main fill:#4274ff1a, stroke:#426eff
If you added a few more movies, the graph would appear as:
graph TB
subgraph " "
direction TB
B(start_task):::main --> C(TASK_Toy story) --> E(END):::main
B --> D(TASK_The Matrix) --> E
B --> F(TASK_Spiderman) --> E
B --> G(TASK_Spiderman 2) --> E
end
classDef main fill:#4274ff1a, stroke:#426eff
Now that we've seen how we can imperatively declare Parent-Child relationships, let's learn how to do it declaratively! Remember, with Declarative, we are defining the goal - the Tasks are described in terms of their relationships instead of specifically calling the steps to create them. The example has been changed in order to better explain how this works.
Declaratively specifying Parent-Child relationships
Declaratively specifying Parent relationships:
Note
Always remember to set ID's for your Tasks, if you don't, your Workflow can become discombobulated.
As you can see above, on line 8, we are now able to create Tasks within the Tasks list within the Workflow Structure! Awesome right? Similarly to above, we set the parent_ids
of child Tasks as we create them. This allows for quick additions to your prompting of the LLM, with significantly less code.
Likewise, we can also specify children relationships within the Workflow:
graph TB
subgraph " "
direction TB
B(start_task):::main --> C(COMPARE) --> E(RANK_END):::main
B --> D(SUMMARIZE) --> E
end
classDef main fill:#4274ff1a, stroke:#426eff
Full example
Start by emptying your file, all that should be left is the import statements and the load_dotenv().
from dotenv import load_dotenv
# Griptape
from griptape.structures import Workflow
from griptape.tasks import PromptTask
# Load env variables
load_dotenv()
# Under the rank_end_task
workflow = Workflow(
tasks = [start_task, summary_task, compare_task, rank_end_task]
)
workflow.run()
Note
With the add_parents()
command, you can specify multiple parents. Remember to put brackets within the parentheses. For example:
add_parents([parent_task1, parent_task2]).
After having set the Parent-Child relationships, run the Workflow and see what you get. The responses are very interesting.
Code Checkpoint
This is what your code should look like:
Let's add a couple more Tasks and see the power of Workflows on display.
Tip
Don't forget to declare the Parents of the new Tasks. Once you do that, add them to the Workflow:
workflow = Workflow(
tasks = [
themes_task,
compare_task,
plot_task,
summary_task,
rank_end_task,
start_task
],
)
workflow.run()
Note
You can now place Tasks in whatever order you see fit within the Tasks list inside of the Workflow Structure call. This is because we are declaring the Parent-Child relationships Imperatively.
Your output should be something like this:
Based on the provided summaries, here is a ranking of the movies from 1 to 2,
considering the depth of their themes and the significance of their plot holes:
1. **The Matrix (1999)**
- **Themes:** "The Matrix" delves into profound philosophical questions about reality versus
illusion, the impact of technology on humanity, and the journey of self-discovery and
enlightenment. These themes are deeply interwoven into the narrative, making the film a
thought-provoking experience that challenges viewers' perceptions of reality.
- **Plot Holes:** While "The Matrix" has some notable plot holes, such as the scientifically
questionable concept of humans as batteries and the inconsistent abilities of the Agents, these
do not significantly detract from the film's overall impact. The film's exploration of complex
themes and its groundbreaking visual effects have cemented its status as a seminal work in
science fiction cinema.
2. **Jurassic Park (1993)**
- **Themes:** "Jurassic Park" explores themes of human hubris, the ethical implications of
genetic engineering, and the unpredictability of nature. It also touches on the double-edged
sword of technological advancement and the primal instinct for survival. These themes are
compelling and relevant, contributing to the film's enduring appeal.
- **Plot Holes:** The plot holes in "Jurassic Park," such as the inadequate security systems,
lack of backup systems, and scientifically dubious concept of DNA preservation, are more glaring
and can be more distracting to the narrative. However, the film's thrilling adventure and
groundbreaking special effects have made it a beloved classic.
In conclusion, while both films have their narrative inconsistencies, "The Matrix" edges out
"Jurassic Park" due to its deeper thematic exploration and the less distracting nature of its
plot holes.
Note
Output edited for brevity.
Here's what your Workflow looks like in a graph:
graph TB
subgraph " "
direction TB
B(START):::main --> C(COMPARE) -->H(PLOT) --> E(RANK_END):::main
B --> D(SUMMARIZE) --> F(THEMES) --> E
end
classDef main fill:#4274ff1a, stroke:#426eff
Finished
Great job! Now we are done with going over the updates to Workflows. These updates will undoubtedly help you create larger, more complex Workflows. We covered:
- Creating complex relationships between Tasks
- Imperative Syntax.
- Declarative Syntax.
- The new way to create Workflows(The old way still works).
We hope you enjoyed this course! Go out and create some cool stuff!