جریان می یابد

جریان ها توابع پیچیده ای هستند با برخی ویژگی های اضافی بیش از تماس های مستقیم: آنها به شدت تایپ شده، قابل پخش، قابل فراخوانی محلی و از راه دور و کاملاً قابل مشاهده هستند. Firebase Genkit ابزار CLI و UI توسعه دهنده را برای اجرای و اشکال زدایی جریان ها ارائه می دهد.

تعریف جریان ها

در ساده‌ترین شکل آن، یک جریان فقط یک تابع را می‌پیچد:

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

انجام این کار به شما امکان می دهد عملکرد را از Genkit CLI و UI توسعه دهنده اجرا کنید، و برای بسیاری از ویژگی های Genkit، از جمله استقرار و قابلیت مشاهده، لازم است.

یک مزیت مهم جریان های Genkit نسبت به فراخوانی مستقیم API مدل، ایمنی نوع ورودی و خروجی است. انواع آرگومان و نتیجه یک جریان می تواند مقادیر ساده یا ساختار یافته باشد. Genkit طرحواره های JSON را برای این مقادیر با استفاده از invopop/jsonschema تولید می کند.

جریان زیر یک string به عنوان ورودی می گیرد و یک 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
	},
)

در حال اجرا جریان دارد

برای اجرای یک جریان در کد خود:

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

می توانید از CLI برای اجرای جریان ها نیز استفاده کنید:

genkit flow:run menuSuggestionFlow '"French"'

پخش شد

در اینجا یک مثال ساده از یک جریان است که می تواند مقادیر را جریان دهد:

// 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
	},
)

توجه داشته باشید که پاسخ تماس جریانی می تواند تعریف نشده باشد. تنها در صورتی تعریف می‌شود که کلاینت فراخوان درخواست پاسخ جریانی را داشته باشد.

برای فراخوانی یک جریان در حالت پخش:

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
	}
})

اگر جریان پخش جریانی را اجرا نکند، StreamFlow() یکسان با RunFlow() رفتار می کند.

همچنین می‌توانید از CLI برای استریم جریان‌ها استفاده کنید:

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

استقرار جریان ها

اگر می خواهید بتوانید به جریان خود از طریق HTTP دسترسی داشته باشید، ابتدا باید آن را مستقر کنید. برای استقرار جریان‌ها با استفاده از Cloud Run و سرویس‌های مشابه، جریان‌های خود را تعریف کنید و سپس 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 یک سرور net/http راه‌اندازی می‌کند که جریان‌های شما را به‌عنوان نقاط پایانی HTTP نمایش می‌دهد (به عنوان مثال، http://localhost:3400/menuSuggestionFlow ).

پارامتر دوم یک Options اختیاری است که موارد زیر را مشخص می کند:

  • FlowAddr : آدرس و پورت برای گوش دادن. اگر مشخص نشده باشد، سرور به پورت مشخص شده توسط متغیر محیطی PORT گوش می دهد. اگر خالی باشد، از پیش فرض پورت 3400 استفاده می کند.
  • Flows : که برای خدمت جریان دارد. اگر مشخص نشده باشد، Init تمام جریان های تعریف شده شما را ارائه می دهد.

اگر می‌خواهید جریان‌ها را در همان میزبان و پورت مانند سایر نقاط پایانی ارائه دهید، می‌توانید FlowAddr روی - تنظیم کنید و در عوض NewFlowServeMux() را فراخوانی کنید تا یک هندلر برای جریان‌های Genkit خود دریافت کنید، که می‌توانید آن را با سایر کنترل‌کننده‌های مسیر خود مالتیپلکس کنید:

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

قابلیت مشاهده جریان

گاهی اوقات هنگام استفاده از SDK های شخص ثالث که برای مشاهده قابل مشاهده نیستند، ممکن است بخواهید آنها را به عنوان یک مرحله ردیابی جداگانه در رابط کاربری توسعه دهنده ببینید. تنها کاری که باید انجام دهید این است که کد را در تابع 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
	})