Bagaimana Firebase Genkit berkontribusi menambahkan AI ke aplikasi Compass kami

MEI 15, 2024
Alexander Nohe Developer Relations Engineer
Arthur Thompson Developer Relations Engineer

Mengintegrasikan AI generatif ke dalam aplikasi dapat mendiferensiasikan bisnis dan memuaskan pengguna Anda. Namun, mengembangkan dan menyempurnakan fitur yang didukung AI untuk melebihi prototipe masih menjadi tantangan. Setelah berbicara dengan para developer aplikasi yang baru saja memulai perjalanan pengembangan AI, kami mengetahui bahwa banyak dari mereka yang kewalahan dengan banyaknya konsep baru yang harus dipelajari dan tugas untuk membuat fitur-fitur tersebut skalabel, aman, dan dapat diandalkan dalam produksi.

Itulah alasan kami mengembangkan Firebase Genkit, sebuah framework open source untuk membangun fitur AI yang canggih ke dalam aplikasi Anda dengan pola dan paradigma yang mudah digunakan oleh developer. Framework ini menyediakan library, alat, dan plugin untuk membantu developer membangun, menguji, men-deploy, dan memantau beban kerja AI. Framework tersebut saat ini tersedia untuk JavaScript/TypeScript, dengan dukungan Go yang akan segera hadir.

Dalam postingan ini, pelajari tentang beberapa kemampuan utama Genkit dan bagaimana cara kami menggunakannya untuk menambahkan AI generatif ke dalam Compass, aplikasi perencanaan perjalanan kami.


Alat developer yang andal

Karena sifatnya yang unik dan tidak dapat diprediksi, AI generatif memerlukan alat khusus yang membantu Anda mengeksplorasi dan mengevaluasi berbagai kemungkinan solusi secara efisien, dalam upaya mencapai hasil yang konsisten dan memenuhi standar kualitas produksi.

Genkit menawarkan pengalaman alat yang andal melalui CLI khusus dan UI developer lokal berbasis browser. Dengan Genkit CLI, Anda dapat melakukan inisialisasi alur AI dalam hitungan detik, lalu Anda dapat meluncurkan UI developer untuk dijalankan secara lokal. UI developer adalah platform yang memungkinkan Anda berinteraksi dengan komponen Genkit seperti alur (logika menyeluruh Anda), model, prompt, pengindeks, pengambil data, alat, dan lainnya. Komponen-komponen ini tersedia untuk dijalankan berdasarkan kode Anda dan plugin yang dikonfigurasi. Hal ini memudahkan Anda untuk menguji komponen dengan berbagai prompt dan kueri, serta melakukan iterasi dengan cepat atas hasilnya melalui hot reloading.

Welcome to Firebase Genkit

Kemampuan observasi menyeluruh dengan alur

Semua komponen Genkit dilengkapi dengan Open Telemetry dan metadata kustom untuk memungkinkan kemampuan observasi dan pemantauan hilir. Genkit menyediakan konsep dasar “alur” sebagai cara untuk menggabungkan beberapa langkah dan komponen AI ke dalam alur kerja menyeluruh yang terpadu. Alur adalah fungsi khusus yang memiliki tipe data yang spesifik, dapat dialirkan, dapat dipanggil baik secara lokal maupun dari jarak jauh, dan dapat diamati sepenuhnya.

Berkat instrumentasi yang luar biasa ini, ketika menjalankan alur di UI developer, Anda dapat “memeriksanya” untuk melihat jejak dan metrik setiap langkah dan komponen di dalamnya. Jejak ini mencakup input dan output untuk setiap langkah, sehingga memudahkan Anda untuk men-debug logika AI atau menemukan hambatan yang dapat diperbaiki. Anda bahkan dapat melihat jejak untuk alur yang di-deploy dan dijalankan dalam produksi.

AI flow in Genkit

Manajemen prompt dengan dotprompt

Engineering prompt lebih dari sekadar menyesuaikan teks. Model yang digunakan, parameter yang diberikan, dan format yang diminta, semuanya memengaruhi kualitas output Anda.

Genkit menawarkan dotprompt, sebuah format file yang memungkinkan Anda untuk menggabungkan semuanya ke dalam satu file yang disimpan bersama dengan kode Anda untuk memudahkan pengujian dan pengorganisasian. Artinya, Anda dapat mengelola prompt bersama dengan kode biasa, melacaknya dalam sistem kontrol versi yang sama, dan men-deploy secara bersamaan. File dotprompt memungkinkan Anda untuk menentukan model dan konfigurasinya, menyediakan pembuatan templat yang fleksibel berdasarkan handlebar, serta menentukan skema input dan output sehingga Genkit dapat membantu memvalidasi interaksi model Anda selama pengembangan.

---
model: vertexai/gemini-1.0-pro
config:
  temperature: 1.0
input:
  schema:
    properties:
      place: {type: string}
    required: [place]
  default:
    place: New York City
output:
  schema:
    type: object
    properties:
      hotelName: {type: string, description: "hotelName"}
      description: {type: string, description: "description"}
---
 
Given this location: {{place}} come up with a fictional hotel name and a
fictional description of the hotel that suites the {{place}}.

Ekosistem plugin: Google Cloud, Firebase, Vertex AI, dan lainnya!

Genkit memberikan akses ke komponen dan integrasi yang telah dibuat sebelumnya untuk model, penyimpanan vektor, alat, evaluator, kemampuan observasi, dan lainnya melalui ekosistem terbuka plugin yang dibangun oleh Google dan komunitas. Untuk daftar plugin yang ada dari Google dan komunitas, jelajahi kata kunci #genkit-plugin di npm.

Di aplikasi Compass, kami menggunakan plugin Google Cloud untuk mengekspor data telemetri ke Google Cloud Logging and Monitoring, plugin Firebase mengekspor jejak ke Cloud Firestore, dan plugin Vertex AI untuk mendapatkan akses ke model Gemini terbaru dari Google.


Cara kami menggunakan Genkit

Untuk memberi Anda gambaran langsung tentang kemampuan Genkit, kami menciptakan Compass, sebuah aplikasi perencanaan perjalanan yang didesain untuk menampilkan kasus penggunaan yang familier.

Genkit-Inline-2 (1)

Versi awal Compass menawarkan pengalaman perencanaan perjalanan berbasis formulir standar, tetapi kami penasaran: seperti apa jadinya jika menambahkan pengalaman perencanaan perjalanan yang didukung AI dengan Genkit?


Membuat sematan (embeded) untuk atribut lokasi

Karena memiliki database konten yang sudah ada, kami menambahkan sematan (embeded) eksternal untuk konten kami menggunakan ekstensi pgvector untuk Postgres dan textembedding-gecko API dari Vertex AI dalam Go. Tujuan kami adalah untuk memungkinkan pengguna menelusuri berdasarkan apa yang "dikenal" dari setiap tempat atau deskripsi umumnya. Agar dapat mencapai hal ini, kami mengekstrak atribut "knownFor" untuk setiap lokasi, membuat sematan (embeded) untuk lokasi tersebut, dan menyisipkan data bersama dengan data ke dalam tabel yang sudah ada untuk mempermudah kueri.

// generateEmbeddings membuat sematan (embeded) dari teks yang disediakan.
func GenerateEmbeddings(
	contentToEmbed,
	project,
	location,
	publisher,
	model,
	titleOfContent string) ([]float64, error) {
	ctx := context.Background()
 
	apiEndpoint := fmt.Sprintf(
		"%s-aiplatform.googleapis.com:443", location)
 
	client, err := aiplatform.NewPredictionClient(
		ctx, option.WithEndpoint(apiEndpoint))
	handleError(err)
	defer client.Close()
 
	base := fmt.Sprintf(
		"projects/%s/locations/%s/publishers/%s/models",
		project,
		location,
		publisher)
 
	url := fmt.Sprintf("%s/%s", base, model)
 
	promptValue, err := structpb.NewValue(
		map[string]interface{}{
			"content":   contentToEmbed,
			"task_type": "RETRIEVAL_DOCUMENT",
			"title":     titleOfContent,
		})
	handleError(err)
 
	// PredictRequest: create the model prediction request
	req := &aiplatformpb.PredictRequest{
		Endpoint:  url,
		Instances: []*structpb.Value{promptValue},
	}
 
	// PredictResponse: receive the response from the model
	resp, err := client.Predict(ctx, req)
	handleError(err)
	pred := resp.Predictions[0]
 
	embeddings := pred.GetStructValue().AsMap()["embeddings"]
	embedInt, ok := embeddings.(map[string]interface{})
	if !ok {
		fmt.Printf("Cannot convert")
	}
	predSlice := embedInt["values"]
	outSlice := make([]float64, 0)
	for _, v := range predSlice.([]any) {
		outSlice = append(outSlice, v.(float64))
	}
 
	return outSlice, nil
}

Penelusuran semantik untuk lokasi yang relevan

Kami kemudian membuat pengambil data untuk menelusuri data yang relevan secara semantik berdasarkan kueri pengguna, dengan fokus pada kolom "knownFor" dari lokasi kami. Agar dapat mencapai hal ini, kami menggunakan fungsi sematkan Genkit untuk menghasilkan sematan (embeded) kueri pengguna. Sematan (embeded) ini kemudian diteruskan ke sistem pengambil data kami, yang secara efisien mengkueri database kami dan menampilkan hasil lokasi yang paling relevan berdasarkan kemiripan semantik antara kueri dan atribut "knownFor".

export const placeRetriever = defineRetriever(
  {
    name: "postgres/placeRetriever",
    configSchema: QueryOptions,
  },
  async (input, options) => {
    const inputEmbedding = await embed({
      embedder: textEmbeddingGecko,
      content: input,
    });
    const results = await sql`
      SELECT ref, name, country, continent, "knownFor", tags, "imageUrl"
        FROM public.places
        ORDER BY embedding <#> ${toSql(inputEmbedding)} LIMIT ${options.k ?? 3};
    `;
    return {
      documents: results.map((row) => {
        const { knownFor, ...metadata } = row;
        return Document.fromText(knownFor, metadata);
      }),
    };
  },
);

Menyempurnakan prompt

Kami mengatur prompt sebagai file dotprompt di dalam direktori khusus/prompt di root project Genkit kami. Untuk iterasi prompt, kami memiliki dua jalur:

  1. Pengujian dalam Alur: Memuat prompt ke dalam alur yang mengambil data dari pengambil data dan memberikannya ke prompt, seperti cara kerjanya pada aplikasi akhir.

2. Pengujian UI Developer: Memuat prompt ke UI Developer. Dengan cara ini, kami dapat memperbarui prompt di file prompt dan langsung menguji perubahan pada prompt untuk mengevaluasi dampaknya pada kualitas output.

Saat sudah puas dengan prompt tersebut, kami menggunakan plugin evaluator untuk menilai metrik LLM yang umum, seperti kesetiaan, relevansi, dan kemungkinan bahaya dengan menggunakan LLM lain untuk menilai responsnya.


Di-deploy ke Cloud Run

Deployment sudah menjadi DNA Genkit. Meskipun secara alami terintegrasi dengan Cloud Functions for Firebase (termasuk Firebase Authentication dan App Check), kami memilih menggunakan Cloud Run untuk project ini. Sejak men-deploy ke Cloud Run, kami menggunakan defineFlow, yang secara otomatis menghasilkan endpoint HTTPS untuk setiap alur yang dideklarasikan saat di-deploy.

Genkit-Inline-3 (1)

Coba Genkit sendiri

​​Genkit menyederhanakan proses pengembangan AI kami, mulai dari pengembangan hingga produksi. UI developer yang intuitif menjadi faktor pembeda, membuat iterasi prompt—bagian yang sangat penting dalam menambahkan fitur perencanaan perjalanan AI kami—menjadi sangat mudah. Plugin memungkinkan pemantauan performa yang mulus serta integrasi dengan berbagai produk dan layanan AI. Dengan alur dan prompt Genkit yang terkontrol versi dengan rapi, kami membuat perubahan dengan percaya diri karena tahu bahwa kami dapat dengan mudah mengembalikannya jika diperlukan. Jelajahi dokumen Firebase Genkit untuk mengetahui bagaimana Genkit dapat membantu Anda menambahkan kemampuan AI pada aplikasi Anda, dan coba codelab Firebase Genkit ini untuk menerapkan solusi serupa!