Skip to main content
Functions in Pipecat Flows serve two key purposes:
  1. Process data by interfacing with external systems and APIs to read or write information
  2. Progress the conversation by transitioning between nodes in your flow

How Functions Work

When designing your nodes, clearly define the task in the task_messages and reference the available functions. The LLM will use these functions to complete the task and signal when it’s ready to move forward. For example, if your node’s job is to collect a user’s favorite color:
  1. The LLM asks the question
  2. The user provides their answer
  3. The LLM calls the function with the answer
  4. The function processes the data and determines the next node

Function Definition

Flows provides a universal FlowsFunctionSchema that works across all LLM providers:

Function Handlers

Each function has a corresponding handler where you implement your application logic and specify the next node:

Handler Return Values

Function handlers can return any JSON-serializable value (string, dict, list, etc.) that gets passed to the LLM. To also specify the next node, return a tuple:
  • Result: Data provided to the LLM for context in subsequent completions, or None. Any JSON-serializable value is accepted.
  • Next Node: The NodeConfig for Flows to transition to next, or None
Some handlers may not want to transition conversational state, in which case you can return None for the next node. Other handlers may only want to transition conversational state without doing other work, in which case you can return None for the result.

Direct Functions

For more concise code, you can optionally use Direct Functions where the function definition and handler are combined in a single function. The function signature and docstring are automatically used to generate the function schema:
This approach eliminates the need for separate FlowsFunctionSchema definitions while maintaining the same functionality. To control interruption behavior, use the @flows_direct_function decorator: