Skip to main content

Flows

Flows are wrapped functions with some additional characteristics over direct calls: they are strongly typed, streamable, locally and remotely callable, and fully observable. Firebase Genkit provides CLI and developer UI tooling for running and debugging flows.

Defining flows

In its simplest form, a flow just wraps a function:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="flow1" adjust_indentation="auto" %}

Doing so lets you run the function from the Genkit CLI and developer UI, and is a requirement for many of Genkit's features, including deployment and observability.

An important advantage Genkit flows have over directly calling a model API is type safety of both inputs and outputs. The argument and result types of a flow can be simple or structured values. Genkit will produce JSON schemas for these values using invopop/jsonschema.

The following flow takes a string as input and outputs a struct:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="msug" adjust_indentation="auto" %}
{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="flow2" adjust_indentation="auto" %}

Running flows

To run a flow in your code:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="run1" adjust_indentation="auto" %}

You can use the CLI to run flows as well:

genkit flow:run menuSuggestionFlow '"French"'

Streamed

Here's a simple example of a flow that can stream values:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="streaming-types" adjust_indentation="auto" %}
{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="streaming" adjust_indentation="auto" %}

Note that the streaming callback can be undefined. It's only defined if the invoking client is requesting streamed response.

To invoke a flow in streaming mode:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="invoke-streaming" adjust_indentation="auto" %}

If the flow doesn't implement streaming, StreamFlow() behaves identically to RunFlow().

You can use the CLI to stream flows as well:

genkit flow:run menuSuggestionFlow '"French"' -s

Deploying flows

If you want to be able to access your flow over HTTP you will need to deploy it first. To deploy flows using Cloud Run and similar services, define your flows, and then call Init():

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="main" adjust_indentation="auto" %}

Init starts a net/http server that exposes your flows as HTTP endpoints (for example, http://localhost:3400/menuSuggestionFlow).

The second parameter is an optional Options that specifies the following:

  • FlowAddr: Address and port to listen on. If not specified, the server listens on the port specified by the PORT environment variable; if that is empty, it uses the default of port 3400.
  • Flows: Which flows to serve. If not specified, Init serves all of your defined flows.

If you want to serve flows on the same host and port as other endpoints, you can set FlowAddr to - and instead call NewFlowServeMux() to get a handler for your Genkit flows, which you can multiplex with your other route handlers:

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="mux" adjust_indentation="auto" %}

Flow observability

Sometimes when using 3rd party SDKs that are not instrumented for observability, you might want to see them as a separate trace step in the Developer UI. All you need to do is wrap the code in the run function.

{% includecode github_path="firebase/genkit/go/internal/doc-snippets/flows.go" region_tag="run" adjust_indentation="auto" %}