Membuat konten dengan model AI

Inti dari AI generatif adalah model AI. Dua contoh paling terkenal dari model generatif adalah model bahasa besar (LLM) dan model pembuatan gambar. Model ini menggunakan input, yang disebut prompt (biasanya berupa teks, gambar, atau kombinasi keduanya), dan menghasilkan teks, gambar, atau bahkan audio atau video sebagai output.

Output model ini dapat sangat meyakinkan: LLM menghasilkan teks yang tampak seperti ditulis oleh manusia, dan model pembuatan gambar dapat menghasilkan gambar yang sangat mirip dengan foto atau karya seni asli yang dibuat oleh manusia.

Selain itu, LLM telah terbukti mampu melakukan tugas di luar pembuatan teks sederhana:

  • Menulis program komputer.
  • Merencanakan subtugas yang diperlukan untuk menyelesaikan tugas yang lebih besar.
  • Mengatur data yang tidak teratur.
  • Memahami dan mengekstrak data informasi dari korpus teks.
  • Mengikuti dan melakukan aktivitas otomatis berdasarkan deskripsi teks aktivitas.

Ada banyak model yang tersedia untuk Anda dari beberapa penyedia yang berbeda. Setiap model memiliki kelebihan dan kekurangannya masing-masing dan satu model mungkin unggul dalam satu tugas, tetapi memiliki performa kurang baik dalam tugas lainnya. Aplikasi yang menggunakan AI generatif sering kali mendapatkan manfaat dari penggunaan beberapa model yang berbeda, bergantung pada tugas yang sedang dilakukan.

Sebagai developer aplikasi, Anda biasanya tidak berinteraksi dengan model AI generatif secara langsung, tetapi melalui layanan yang tersedia sebagai API web. Meskipun layanan ini sering kali memiliki fungsi yang serupa, semuanya disediakan melalui API yang berbeda dan tidak kompatibel. Jika ingin menggunakan beberapa layanan model, Anda harus menggunakan setiap SDK eksklusifnya, yang berpotensi tidak kompatibel satu sama lain. Selain itu, jika ingin mengupgrade dari satu model ke model terbaru dan paling canggih, Anda mungkin harus membangun integrasi tersebut dari awal lagi.

Genkit mengatasi tantangan ini dengan menyediakan satu antarmuka yang memisahkan detail akses ke layanan model AI generatif yang berpotensi, dengan beberapa implementasi bawaan yang sudah tersedia. Membangun aplikasi yang didukung AI di sekitar Genkit dapat menyederhanakan proses pembuatan panggilan AI generatif pertama Anda dan mempermudah penggabungan beberapa model atau menukar satu model dengan model lainnya saat model baru muncul.

Sebelum memulai

Jika Anda ingin menjalankan contoh kode di halaman ini, selesaikan langkah-langkah dalam panduan Memulai terlebih dahulu. Semua contoh mengasumsikan bahwa Anda telah menginstal Genkit sebagai dependensi dalam project.

Model yang didukung oleh Genkit

Genkit dirancang agar cukup fleksibel dalam menggunakan layanan model AI generatif apa pun. Library inti Genkit menentukan antarmuka umum yang akan digunakan oleh model, dan plugin model menentukan detail implementasi untuk menggunakan model tertentu beserta API-nya.

Tim Genkit mengelola plugin agar dapat menggunakan model yang disediakan oleh Vertex AI, AI Generatif Google, dan Ollama:

Memuat dan mengonfigurasi plugin model

Sebelum dapat menggunakan Genkit untuk mulai membuat konten, Anda perlu memuat dan mengonfigurasi plugin model. Jika telah menyelesaikan panduan Memulai, Anda telah melakukannya. Jika belum, lihat panduan Memulai atau dokumentasi plugin individual dan ikuti langkah-langkah di sana sebelum melanjutkan.

Fungsi genkit.Generate()

Di Genkit, antarmuka utama yang Anda gunakan untuk berinteraksi dengan model AI generatif adalah fungsi genkit.Generate().

Panggilan genkit.Generate() yang paling sederhana menentukan model yang ingin Anda gunakan beserta prompt teksnya:

import (
    "context"
    "log"

    "github.com/firebase/genkit/go/ai"
    "github.com/firebase/genkit/go/genkit"
    "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
    ctx := context.Background()

    g, err := genkit.Init(ctx,
        genkit.WithPlugins(&googlegenai.GoogleAI{}),
        genkit.WithDefaultModel("googleai/gemini-2.0-flash"),
    )
    if err != nil {
        log.Fatal(err)
    }

    resp, err := genkit.Generate(ctx, g,
        ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
    )
    if err != nil {
        log.Fatal(err)
    }

    log.Println(resp.Text())
}

Saat Anda menjalankan contoh singkat ini, beberapa informasi proses debug akan dicetak yang diikuti oleh output panggilan genkit.Generate(), dan biasanya berupa teks Markdown seperti dalam contoh berikut:

## The Blackheart's Bounty

**A hearty stew of slow-cooked beef, spiced with rum and molasses, served in a
hollowed-out cannonball with a side of crusty bread and a dollop of tangy
pineapple salsa.**

**Description:** This dish is a tribute to the hearty meals enjoyed by pirates
on the high seas. The beef is tender and flavorful, infused with the warm spices
of rum and molasses. The pineapple salsa adds a touch of sweetness and acidity,
balancing the richness of the stew. The cannonball serving vessel adds a fun and
thematic touch, making this dish a perfect choice for any pirate-themed
adventure.

Jalankan kembali skrip dan Anda akan mendapatkan output yang berbeda.

Contoh kode sebelumnya mengirimkan permintaan pembuatan ke model default, yang Anda tentukan saat mengonfigurasi instance Genkit.

Anda juga dapat menentukan model untuk satu panggilan genkit.Generate():

resp, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-pro"),
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
)

ID string model terlihat seperti providerid/modelid, dengan ID penyedia (dalam hal ini, googleai) mengidentifikasi plugin, dan ID model adalah ID string khusus plugin untuk versi model tertentu.

Contoh ini juga menggambarkan poin penting: saat Anda menggunakan genkit.Generate() untuk melakukan panggilan model AI generatif, mengubah model yang ingin Anda gunakan adalah masalah meneruskan nilai yang berbeda ke parameter model. Dengan menggunakan genkit.Generate(), bukan SDK model native, Anda akan memiliki fleksibilitas untuk menggunakan beberapa model yang berbeda dalam aplikasi dengan lebih mudah dan mengubah model di masa mendatang.

Sejauh ini, Anda hanya melihat contoh panggilan genkit.Generate() yang paling sederhana. Namun, genkit.Generate() juga menyediakan antarmuka untuk interaksi lanjutan dengan model generatif, yang akan Anda lihat di bagian berikutnya.

Prompt sistem

Beberapa model mendukung penyediaan prompt sistem, yang memberikan petunjuk kepada model tentang bagaimana Anda ingin model merespons pesan dari pengguna. Anda dapat menggunakan prompt sistem untuk menentukan karakteristik seperti persona yang ingin diadopsi oleh model, nada respons model, dan format respons model.

Jika model yang Anda gunakan mendukung prompt sistem, Anda dapat menyediakan prompt sistem dengan opsi WithSystem():

resp, err := genkit.Generate(ctx, g,
    ai.WithSystem("You are a food industry marketing consultant."),
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
)

Untuk model yang tidak mendukung prompt sistem, WithSystem() simulasikan dengan mengubah permintaan agar terlihat seperti prompt sistem.

Parameter model

Fungsi genkit.Generate() menggunakan opsi WithConfig(), yang memungkinkan Anda menentukan setelan opsional yang mengontrol cara model membuat konten:

resp, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
    ai.WithConfig(&googlegenai.GeminiConfig{
        MaxOutputTokens: 500,
        StopSequences:   ["<end>", "<fin>"],
        Temperature:     0.5,
        TopP:            0.4,
        TopK:            50,
    }),
)

Parameter tepat yang didukung bergantung pada setiap model dan API model. Namun, parameter dalam contoh sebelumnya termasuk umum di hampir setiap model. Berikut adalah penjelasan parameter ini:

Parameter yang mengontrol panjang output

MaxOutputTokens

LLM beroperasi pada unit yang disebut token. Token biasanya, tetapi tidak selalu, dipetakan ke urutan karakter tertentu. Saat Anda meneruskan prompt ke model, salah satu langkah awal yang perlu dilakukan adalah membuat token string prompt menjadi urutan token. Kemudian, LLM menghasilkan urutan token dari input yang ditokenisasi. Terakhir, urutan token dikonversi kembali menjadi teks, yang merupakan output Anda.

Parameter token output maksimum menetapkan batas jumlah token yang akan dibuat menggunakan LLM. Setiap model berpotensi menggunakan tokenizer yang berbeda, tetapi sebaiknya pertimbangkan satu kata bahasa Inggris yang terdiri dari 2 hingga 4 token.

Seperti yang sudah disampaikan sebelumnya, beberapa token mungkin tidak dipetakan ke urutan karakter. Salah satu contohnya adalah sering kali ada token yang menunjukkan akhir urutan: saat LLM membuat token ini, token tersebut berhenti membuat token lainnya. Oleh karena itu, mungkin saja dan sering kali terjadi bahwa LLM membuat lebih sedikit token daripada jumlah maksimumnya karena LLM membuat token "stop".

StopSequences

Anda dapat menggunakan parameter ini untuk menetapkan token atau urutan token yang, saat dibuat, menunjukkan akhir output LLM. Nilai yang benar untuk digunakan di sini umumnya bergantung pada cara model dilatih, dan biasanya ditetapkan oleh plugin model. Namun, jika Anda telah meminta model untuk membuat urutan perhentian lain, Anda dapat menentukannya di sini.

Perhatikan bahwa Anda menentukan urutan karakter, bukan token. Pada umumnya, Anda akan menentukan urutan karakter yang dipetakan oleh tokenizer model ke satu token.

Parameter yang mengontrol "kreativitas"

Parameter temperature, top-p, dan top-k bersama-sama mengontrol tingkat "kreativitas" yang Anda inginkan untuk model. Bagian ini memberikan penjelasan yang sangat singkat tentang makna parameter ini, tetapi poin yang lebih penting adalah: parameter ini digunakan untuk menyesuaikan karakter output LLM. Nilai optimal untuk parameter tersebut bergantung pada sasaran dan preferensi Anda, serta kemungkinan besar hanya ditemukan melalui eksperimen.

Temperature

LLM pada dasarnya adalah mesin prediksi token. Untuk urutan token tertentu (seperti prompt), LLM memprediksi setiap token dalam kosakatanya, serta probabilitas token berikutnya dalam urutan. Temperature adalah faktor penskalaan yang digunakan untuk membagi prediksi ini sebelum dinormalisasi ke probabilitas antara 0 dan 1.

Nilai temperature rendah—antara 0,0 dan 1,0—akan memperkuat perbedaan probabilitas antara token, sehingga model akan lebih kecil kemungkinannya untuk menghasilkan token yang sudah dievaluasi sebagai tidak mungkin. Hal ini sering kali dianggap sebagai output yang kurang kreatif. Meskipun 0,0 secara teknis bukan nilai yang valid, banyak model memperlakukannya sebagai indikasi bahwa model harus berperilaku deterministik, dan hanya mempertimbangkan satu token yang paling mungkin.

Nilai temperature tinggi—lebih besar dari 1,0—mengompresi perbedaan probabilitas antara token, sehingga model menjadi lebih cenderung menghasilkan token yang sebelumnya dievaluasi sebagai tidak mungkin. Hal ini sering kali dianggap sebagai output yang lebih kreatif. Beberapa API model menerapkan temperature maksimum, biasanya 2,0.

TopP

Top-p adalah nilai antara 0,0 dan 1,0 yang mengontrol jumlah probabilitas token yang ingin dipertimbangkan oleh model, dengan menentukan probabilitas kumulatif token. Misalnya, nilai 1,0 berarti mempertimbangkan setiap probabilitas token (tetapi tetap memperhitungkan probabilitas setiap token). Nilai 0,4 berarti hanya mempertimbangkan token yang paling mungkin, yang probabilitasnya berjumlah 0,4, dan mengecualikan token lainnya dari pertimbangan.

TopK

Top-k adalah nilai bilangan bulat yang juga mengontrol jumlah probabilitas token yang ingin dipertimbangkan oleh model, tetapi kali ini dengan menentukan jumlah token maksimum secara eksplisit. Menentukan nilai 1 berarti model harus berperilaku deterministik.

Bereksperimen dengan parameter model

Anda dapat bereksperimen dengan efek parameter ini pada output yang dihasilkan oleh berbagai kombinasi model dan prompt menggunakan UI Developer. Mulai UI developer dengan perintah genkit start dan UI akan otomatis memuat semua model yang ditentukan oleh plugin yang dikonfigurasi dalam project Anda. Anda dapat dengan cepat mencoba berbagai prompt dan nilai konfigurasi tanpa harus berulang kali membuat perubahan dalam kode.

Menyambungkan model dengan konfigurasinya

Karena setiap penyedia atau bahkan model tertentu mungkin memiliki skema konfigurasi sendiri atau menjamin setelan tertentu, menetapkan opsi terpisah menggunakan WithModelName() dan WithConfig() mungkin rentan terhadap error karena opsi yang terakhir tidak memiliki jenis yang jelas dibandingkan dengan yang pertama.

Untuk menyambungkan model dengan konfigurasinya, Anda dapat membuat referensi model yang dapat diteruskan ke panggilan pembuatan:

model := googlegenai.GoogleAIModelRef("gemini-2.0-flash", &googlegenai.GeminiConfig{
    MaxOutputTokens: 500,
    StopSequences:   ["<end>", "<fin>"],
    Temperature:     0.5,
    TopP:            0.4,
    TopK:            50,
})

resp, err := genkit.Generate(ctx, g,
    ai.WithModel(model),
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
)
if err != nil {
    log.Fatal(err)
}

Konstruktor referensi model akan memastikan bahwa jenis konfigurasi yang benar diberikan guna mengurangi ketidakcocokan.

Output terstruktur

Saat menggunakan AI generatif sebagai komponen dalam aplikasi, Anda sering kali menginginkan output dalam format selain teks biasa. Meskipun hanya membuat konten yang akan ditampilkan kepada pengguna, Anda dapat memperoleh manfaat dari output terstruktur, yakni agar dapat menyajikannya dengan lebih menarik kepada pengguna. Namun, untuk aplikasi AI generatif yang lebih canggih, seperti penggunaan output model secara terprogram, atau memasukkan output dari satu model ke model lain, output terstruktur adalah suatu keharusan.

Di Genkit, Anda dapat meminta output terstruktur dari model dengan menentukan jenis output saat memanggil genkit.Generate():

type MenuItem struct {
    Name        string   `json:"name"`
    Description string   `json:"description"`
    Calories    int      `json:"calories"`
    Allergens   []string `json:"allergens"`
}

resp, err := genkit.Generate(ctx, g,
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
    ai.WithOutputType(MenuItem{}),
)
if err != nil {
  log.Fatal(err) // One possible error is that the response does not conform to the type.
}

Jenis output model ditentukan sebagai skema JSON menggunakan paket invopop/jsonschema. Jenis output ini menyediakan pemeriksaan jenis runtime, yang menjembatani kesenjangan antara jenis Go statis dan output model AI generatif yang tidak dapat diprediksi. Sistem ini memungkinkan Anda menulis kode dengan fakta bahwa panggilan pembuatan yang berhasil akan selalu menampilkan output yang sesuai dengan jenis Go Anda.

Saat Anda menentukan jenis output di genkit.Generate(), Genkit akan melakukan beberapa hal di balik layar:

  • Memperkuat prompt dengan panduan tambahan terkait format output yang diinginkan. Hal ini juga memiliki efek samping terkait penentuan model konten yang sebenarnya ingin Anda buat (misalnya, tidak hanya menyarankan item menu, tetapi juga membuat deskripsi, daftar alergen, dan sebagainya).
  • Memverifikasi bahwa output sesuai dengan skema.
  • Melakukan pengarahan output model menjadi jenis Go.

Untuk mendapatkan output terstruktur dari panggilan pembuatan yang berhasil, panggil Output() pada respons model dengan nilai jenis yang kosong:

var item MenuItem
if err := resp.Output(&item); err != nil {
    log.Fatalf(err)
}

log.Printf("%s (%d calories, %d allergens): %s\n",
    item.Name, item.Calories, len(item.Allergens), item.Description)

Atau, Anda dapat menggunakan genkit.GenerateData() untuk panggilan yang lebih ringkas:

item, resp, err := genkit.GenerateData[MenuItem](ctx, g,
    ai.WithPrompt("Invent a menu item for a pirate themed restaurant."),
)
if err != nil {
  log.Fatal(err)
}

log.Printf("%s (%d calories, %d allergens): %s\n",
    item.Name, item.Calories, len(item.Allergens), item.Description)

Fungsi ini memerlukan parameter jenis output, tetapi secara otomatis menetapkan opsi WithOutputType() dan memanggil resp.Output() sebelum menampilkan nilai.

Menangani error

Perhatikan dalam contoh sebelumnya bahwa panggilan genkit.Generate() dapat menimbulkan error. Salah satu kemungkinan error dapat terjadi saat model gagal menghasilkan output yang sesuai dengan skema. Strategi terbaik untuk menangani error tersebut bergantung pada kasus penggunaan Anda yang sebenarnya, tetapi berikut beberapa petunjuk umum:

  • Coba model lain. Agar output terstruktur berhasil, model harus mampu menghasilkan output dalam format JSON. LLM paling canggih seperti Gemini cukup fleksibel untuk melakukan hal ini. Namun, model yang lebih tradisional, seperti beberapa model lokal yang akan Anda gunakan dengan Ollama, mungkin tidak dapat menghasilkan output terstruktur secara andal kecuali jika telah dilatih secara khusus untuk melakukannya.

  • Sederhanakan skema. LLM mungkin mengalami masalah saat membuat jenis yang kompleks atau tersembunyi. Coba gunakan nama yang jelas, lebih sedikit kolom, atau struktur yang diratakan jika Anda tidak dapat membuat data terstruktur dengan andal.

  • Coba kembali panggilan genkit.Generate(). Jika model yang Anda pilih jarang sekali gagal menghasilkan output yang sesuai, Anda dapat memperlakukan error seperti Anda memperlakukan error jaringan, dan coba kembali permintaan menggunakan beberapa jenis strategi back-off inkremental.

Streaming

Saat membuat teks dalam jumlah besar, Anda dapat meningkatkan pengalaman pengguna dengan menampilkan output saat dibuat untuk melakukan streaming output. Contoh streaming yang sudah tidak asing lagi dapat dilihat di sebagian besar aplikasi chat LLM: pengguna dapat membaca respons model terhadap pesan mereka saat sedang dibuat. Hal ini meningkatkan responsivitas persepsi aplikasi dan meningkatkan ilusi mengobrol dengan rekan yang cerdas.

Di Genkit, Anda dapat melakukan streaming output menggunakan opsi WithStreaming():

resp, err := genkit.Generate(ctx, g,
    ai.WithPrompt("Suggest a complete menu for a pirate themed restaurant."),
    ai.WithStreaming(func(ctx context.Context, chunk *ai.ModelResponseChunk) error {
        // Do something with the chunk...
        log.Println(chunk.Text())
        return nil
    }),
)
if err != nil {
    log.Fatal(err)
}

log.Println(resp.Text())

Input multimodal

Contoh yang telah Anda lihat sejauh ini menggunakan string teks sebagai prompt model. Meskipun hal ini tetap menjadi cara paling umum untuk meminta model AI generatif, banyak model juga dapat menerima media lain sebagai prompt. Prompt media yang paling sering digunakan bersama dengan prompt teks yang menginstruksikan model untuk melakukan beberapa operasi pada media, seperti memberi teks pada gambar atau mentranskripsikan rekaman audio.

Kemampuan untuk menerima input media dan jenis media yang dapat Anda gunakan sepenuhnya bergantung pada model beserta API-nya. Misalnya, rangkaian model Gemini 2.0 dapat menerima gambar, video, dan audio sebagai prompt.

Untuk memberikan prompt media ke model yang mendukungnya, bukan meneruskan prompt teks sederhana ke genkit.Generate(), teruskan array yang terdiri dari bagian media dan bagian teks. Contoh ini menentukan gambar menggunakan URL HTTPS yang dapat diakses secara publik.

resp, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithMessages(
        NewUserMessage(
            NewMediaPart("image/jpeg", "https://example.com/photo.jpg"),
            NewTextPart("Compose a poem about this image."),
        ),
    ),
)

Anda juga dapat meneruskan data media secara langsung dengan mengenkodenya sebagai URL data. Misalnya:

image, err := ioutil.ReadFile("photo.jpg")
if err != nil {
    log.Fatal(err)
}

resp, err := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithMessages(
        NewUserMessage(
            NewMediaPart("image/jpeg", "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(image)),
            NewTextPart("Compose a poem about this image."),
        ),
    ),
)

Semua model yang mendukung input media juga mendukung URL data dan URL HTTPS. Beberapa plugin model menambahkan dukungan untuk sumber media lainnya. Misalnya, plugin Vertex AI juga memungkinkan Anda menggunakan URL Cloud Storage (gs://).

Langkah berikutnya

Pelajari Genkit lebih lanjut

  • Sebagai developer aplikasi, cara utama untuk memengaruhi output model AI generatif adalah melalui penulisan prompt. Baca Mengelola prompt dengan Dotprompt untuk mempelajari bagaimana Genkit membantu mengembangkan prompt yang efektif dan mengelolanya di codebase Anda.
  • Meskipun genkit.Generate() adalah inti dari setiap aplikasi yang didukung AI generatif, aplikasi di dunia nyata biasanya memerlukan tugas tambahan sebelum dan setelah memanggil model AI generatif. Untuk menggambarkan hal ini, Genkit memperkenalkan konsep flow, yang ditentukan seperti panggilan fungsi, tetapi menambahkan fitur tambahan seperti kemampuan observasi dan deployment yang disederhanakan. Untuk mempelajari lebih lanjut, lihat Menentukan alur kerja AI.

Penggunaan LLM lanjutan

Ada teknik yang dapat digunakan oleh aplikasi Anda untuk mendapatkan lebih banyak manfaat dari LLM.

  • Salah satu cara untuk meningkatkan kemampuan LLM adalah dengan meminta LLM untuk membuat daftar terkait cara meminta informasi lebih lanjut dari Anda, atau meminta Anda untuk melakukan beberapa tindakan. Hal ini dikenal sebagai panggilan alat atau panggilan fungsi. Model yang dilatih untuk mendukung kemampuan ini dapat merespons prompt dengan respons berformat khusus, yang menunjukkan kepada aplikasi pemanggil bahwa aplikasi tersebut harus melakukan beberapa tindakan dan mengirimkan hasilnya kembali ke LLM bersama dengan prompt asli. Genkit memiliki fungsi library yang mengotomatiskan pembuatan prompt dan elemen loop respons panggilan dari implementasi panggilan alat. Baca Panggilan alat untuk mempelajari lebih lanjut.
  • Retrieval-augmented generation (RAG) adalah teknik yang digunakan untuk memasukkan informasi khusus domain ke dalam output model. Hal ini dilakukan dengan menyisipkan informasi yang relevan ke dalam prompt sebelum meneruskannya ke model bahasa. Penerapan RAG yang lengkap mengharuskan Anda menggabungkan beberapa teknologi: model pembuatan embedding teks, database vektor, dan model bahasa besar. Baca Retrieval-augmented generation (RAG) untuk mempelajari bagaimana Genkit menyederhanakan proses koordinasi dari berbagai elemen tersebut.