Workflows
A Workflow
in LlamaIndexTS is an event-driven abstraction used to chain together several events. Workflows are made up of steps
, with each step responsible for handling certain event types and emitting new events.
Workflows in LlamaIndexTS work by defining step functions that handle specific event types and emit new events.
When a step function is added to a workflow, you need to specify the input and optionally the output event types (used for validation). The specification of the input events ensures each step only runs when an accepted event is ready.
You can create a Workflow
to do anything! Build an agent, a RAG flow, an extraction flow, or anything else you want.
Getting Started
As an illustrative example, let's consider a naive workflow where a joke is generated and then critiqued.
There's a few moving pieces here, so let's go through this piece by piece.
Defining Workflow Events
Events are user-defined classes that extend WorkflowEvent
and contain arbitrary data provided as template argument. In this case, our workflow relies on a single user-defined event, the JokeEvent
with a joke
attribute of type string
.
Setting up the Workflow Class
Our workflow is implemented by initiating the Workflow
class with three generic types: the context type (unknown), input type (string), and output type (string). The context type is unknown
, as we're not using a shared context in this example.
For simplicity, we created an OpenAI
llm instance that we're using for inference in our workflow.
Workflow Entry Points
Here, we come to the entry-point of our workflow. While events are user-defined, there are two special-case events, the StartEvent
and the StopEvent
. These events are predefined, but we can specify the payload type using generic types. We're using StartEvent<string>
to indicate that we're going to send an input of type string.
To add this step to the workflow, we use the addStep
method with an object specifying the input and output event types:
Workflow Exit Points
Here, we have our second and last step in the workflow. We know it's the last step because the special StopEvent
is returned. When the workflow encounters a returned StopEvent
, it immediately stops the workflow and returns the result. Note that we're using the generic type StopEvent<string>
to indicate that we're returning a string.
Add this step to the workflow:
Running the Workflow
Lastly, we run the workflow. The .run()
method is async, so we use await here to wait for the result.
Working with Shared Context/State
Optionally, you can choose to use a shared context between steps by specifying a context type when creating the workflow. Here's an example where multiple steps access a shared state:
Waiting for Multiple Events
The context does more than just hold data, it also provides utilities to buffer and wait for multiple events.
For example, you might have a step that waits for a query and retrieved nodes before synthesizing a response:
Passing multiple events, we can buffer and wait for ALL expected events to arrive. The receiving step function will only be called once all events have arrived.
Manually Triggering Events
Normally, events are triggered by returning another event during a step. However, events can also be manually dispatched using the ctx.sendEvent(event)
method within a workflow.
Examples
You can find many useful examples of using workflows in the examples folder.
Last updated on