Flows

Flow adalah fungsi gabungan dengan beberapa karakteristik tambahan dibandingkan panggilan langsung: flow memiliki definisi jenis yang jelas, dapat di-streaming, dapat dipanggil secara lokal dan dari jarak jauh, serta dapat diamati sepenuhnya. Firebase Genkit menyediakan alat CLI dan UI developer untuk menjalankan dan melakukan proses debug terhadap flow.

Menentukan flow

Dalam bentuk yang paling sederhana, flow hanya menggabungkan fungsi:

menuSuggestionFlow := genkit.DefineFlow(
	"menuSuggestionFlow",
	func(ctx context.Context, restaurantTheme string) (string, error) {
		suggestion := makeMenuItemSuggestion(restaurantTheme)
		return suggestion, nil
	})

Dengan melakukannya, Anda dapat menjalankan fungsi dari Genkit CLI dan UI developer, serta merupakan persyaratan untuk banyak fitur Genkit, termasuk deployment dan kemampuan observasi.

Keuntungan penting yang dimiliki flow Genkit daripada memanggil API model secara langsung adalah keamanan jenis input dan output. Argumen dan jenis hasil flow dapat berupa nilai sederhana atau terstruktur. Genkit akan menghasilkan skema JSON untuk nilai ini menggunakan invopop/jsonschema.

Flow berikut menggunakan string sebagai input dan menghasilkan struct:

type MenuSuggestion struct {
	ItemName    string `json:"item_name"`
	Description string `json:"description"`
	Calories    int    `json:"calories"`
}

menuSuggestionFlow := genkit.DefineFlow(
	"menuSuggestionFlow",
	func(ctx context.Context, restaurantTheme string) (MenuSuggestion, error) {
		suggestion := makeStructuredMenuItemSuggestion(restaurantTheme)
		return suggestion, nil
	},
)

Flow yang berjalan

Untuk menjalankan flow dalam kode Anda:

suggestion, err := menuSuggestionFlow.Run(context.Background(), "French")

Anda juga dapat menggunakan CLI untuk menjalankan flow:

genkit flow:run menuSuggestionFlow '"French"'

Di-streaming

Berikut adalah contoh sederhana flow yang dapat melakukan streaming terhadap nilai:

// Types for illustrative purposes.
type InputType string
type OutputType string
type StreamType string

menuSuggestionFlow := genkit.DefineStreamingFlow(
	"menuSuggestionFlow",
	func(
		ctx context.Context,
		restaurantTheme InputType,
		callback func(context.Context, StreamType) error,
	) (OutputType, error) {
		var menu strings.Builder
		menuChunks := make(chan StreamType)
		go makeFullMenuSuggestion(restaurantTheme, menuChunks)
		for {
			chunk, ok := <-menuChunks
			if !ok {
				break
			}
			if callback != nil {
				callback(context.Background(), chunk)
			}
			menu.WriteString(string(chunk))
		}
		return OutputType(menu.String()), nil
	},
)

Perhatikan bahwa callback streaming mungkin tidak ditentukan. Ini hanya ditentukan jika klien yang memanggil meminta respons yang di-streaming.

Untuk memanggil flow dalam mode streaming:

menuSuggestionFlow.Stream(
	context.Background(),
	"French",
)(func(sfv *genkit.StreamFlowValue[OutputType, StreamType], err error) bool {
	if err != nil {
		// handle err
		return false
	}
	if !sfv.Done {
		fmt.Print(sfv.Stream)
		return true
	} else {
		fmt.Print(sfv.Output)
		return false
	}
})

Jika flow tidak mengimplementasikan streaming, StreamFlow() berperilaku sama dengan RunFlow().

Anda juga dapat menggunakan CLI untuk melakukan streaming terhadap flow:

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

Men-deploy flow

Jika Anda ingin dapat mengakses flow melalui HTTP, Anda harus men-deploy-nya terlebih dahulu. Untuk men-deploy flow menggunakan Cloud Run dan layanan serupa, tentukan flow Anda, lalu panggil Init():

func main() {
	genkit.DefineFlow(
		"menuSuggestionFlow",
		func(ctx context.Context, restaurantTheme string) (string, error) {
			// ...
			return "", nil
		},
	)
	if err := genkit.Init(context.Background(), nil); err != nil {
		log.Fatal(err)
	}
}

Init memulai server net/http yang mengekspos flow Anda sebagai endpoint HTTP (misalnya, http://localhost:3400/menuSuggestionFlow).

Parameter kedua adalah Options opsional yang menentukan hal berikut:

  • FlowAddr: Alamat dan port untuk diproses. Jika tidak ditentukan, server akan melakukan proses pada port yang ditentukan oleh variabel lingkungan PORT; jika kosong, defaultnya adalah port 3400.
  • Flows: Flow yang akan dilayani. Jika tidak ditentukan, Init akan melayani semua flow yang Anda tentukan.

Jika Anda ingin melayani flow pada host dan port yang sama dengan endpoint lainnya, Anda dapat menetapkan FlowAddr ke - dan memanggil NewFlowServeMux() untuk mendapatkan handler flow Genkit, yang dapat Anda gandakan dengan handler rute lainnya:

mainMux := http.NewServeMux()
mainMux.Handle("POST /flow/", http.StripPrefix("/flow/", genkit.NewFlowServeMux(nil)))

Kemampuan observasi flow

Terkadang, saat menggunakan SDK pihak ketiga yang tidak mendukung kemampuan observasi, Anda mungkin ingin melihatnya sebagai langkah trace terpisah di UI Developer. Anda hanya perlu menggabungkan kode dalam fungsi run.

genkit.DefineFlow(
	"menuSuggestionFlow",
	func(ctx context.Context, restaurantTheme string) (string, error) {
		themes, err := genkit.Run(ctx, "find-similar-themes", func() (string, error) {
			// ...
			return "", nil
		})

		// ...
		return themes, err
	})