Meneruskan informasi melalui konteks

Ada berbagai kategori informasi yang dapat ditangani secara bersamaan oleh developer yang bekerja dengan LLM:

  • Input: Informasi yang relevan secara langsung untuk memandu respons LLM untuk panggilan tertentu. Contohnya adalah teks yang perlu diringkas.
  • Konteks Pembuatan: Informasi yang relevan dengan LLM, tetapi tidak spesifik untuk panggilan. Contohnya adalah waktu saat ini atau nama pengguna.
  • Konteks Eksekusi: Informasi yang penting bagi kode di sekitar panggilan LLM, tetapi tidak untuk LLM itu sendiri. Contohnya adalah token autentikasi saat ini milik pengguna.

Genkit menyediakan objek context yang konsisten yang dapat menyebarkan konteks pembuatan dan eksekusi di seluruh proses. Konteks ini tersedia untuk semua tindakan, termasuk alur, alat, dan perintah.

Konteks secara otomatis disebarkan ke semua tindakan yang dipanggil dalam cakupan eksekusi: Konteks yang diteruskan ke alur disediakan untuk perintah yang dijalankan dalam alur. Konteks yang diteruskan ke metode generate() tersedia untuk alat yang dipanggil dalam loop pembuatan.

Mengapa konteks itu penting?

Sebagai praktik terbaik, Anda harus memberikan jumlah informasi minimum ke LLM yang diperlukan untuk menyelesaikan tugas. Hal ini penting karena beberapa alasan:

  • Makin sedikit informasi yang tidak relevan yang dimiliki LLM, makin besar kemungkinannya untuk tampil dengan baik dalam tugasnya.
  • Jika LLM perlu meneruskan informasi seperti ID pengguna atau akun ke alat, LLM tersebut berpotensi ditipu untuk membocorkan informasi.

Konteks memberi Anda saluran informasi samping yang dapat digunakan oleh kode Anda, tetapi tidak harus dikirim ke LLM. Misalnya, Anda dapat membatasi kueri alat ke cakupan yang tersedia untuk pengguna saat ini.

Struktur konteks

Konteks harus berupa objek, tetapi Anda dapat menentukan propertinya. Dalam beberapa situasi, Genkit akan otomatis mengisi konteks. Misalnya, saat menggunakan sesi persisten, properti state akan otomatis ditambahkan ke konteks.

Salah satu penggunaan konteks yang paling umum adalah untuk menyimpan informasi tentang pengguna saat ini. Sebaiknya tambahkan konteks autentikasi dalam format berikut:

{
  auth: {
    uid: "...", // the user's unique identifier
    token: {...}, // the decoded claims of a user's id token
    rawToken: "...", // the user's raw encoded id token
    // ...any other fields
  }
}

Objek konteks dapat menyimpan informasi apa pun yang mungkin perlu Anda ketahui di tempat lain dalam alur eksekusi.

Menggunakan konteks dalam tindakan

Untuk menggunakan konteks dalam tindakan, Anda dapat mengakses helper konteks yang secara otomatis disediakan ke definisi fungsi Anda:

Flow

const summarizeHistory = ai.defineFlow({
  name: 'summarizeMessages',
  inputSchema: z.object({friendUid: z.string()}),
  outputSchema: z.string();
}, async ({friendUid}, {context}) => {
  if (!context.auth?.uid) throw new Error("Must supply auth context.");
  const messages = await listMessagesBetween(friendUid, context.auth.uid);
  const {text} = await ai.generate({
    prompt:
      `Summarize the content of these messages: ${JSON.stringify(messages)}`,
  });
  return text;
});

Alat

const searchNotes = ai.defineTool({
  name: 'searchNotes',
  description: "search the current user's notes for info",
  inputSchema: z.object({query: z.string()}),
  outputSchmea: z.array(NoteSchema);
}, async ({query}, {context}) => {
  if (!context.auth?.uid) throw new Error("Must be called by a signed-in user.");
  return searchUserNotes(context.auth.uid, query);
});

File perintah

Saat menggunakan template Dotprompt, konteks disediakan dengan awalan variabel @. Misalnya, objek konteks {auth: {name: 'Michael'}} dapat diakses dalam template perintah seperti ini:

---
input:
  schema:
    pirateStyle?: boolean
---

{{#if pirateStyle}}
Avast, {{@auth.name}}, how be ye today?
{{else}}
Hello, {{@auth.name}}, how are you today?
{{/if}}

Memberikan konteks saat runtime

Untuk memberikan konteks ke tindakan, Anda meneruskan objek konteks sebagai opsi saat memanggil tindakan.

Flows

const summarizeHistory = ai.defineFlow(/* ... */);

const summary = await summarizeHistory(friend.uid, {context: {auth: currentUser}});

Generation

const {text} = await ai.generate({
  prompt: "Find references to ocelots in my notes.",
  // the context will propagate to tool calls
  tools: [searchNotes],
  context: {auth: currentUser},
});

Perintah

const helloPrompt = ai.prompt('sayHello');
helloPrompt({pirateStyle: true}, {context: {auth: currentUser}});

Penerapan dan penggantian konteks

Secara default, saat Anda memberikan konteks, konteks tersebut akan otomatis disebarkan ke semua tindakan yang dipanggil sebagai hasil dari panggilan asli Anda. Jika alur Anda memanggil alur lain, atau alat panggilan generasi Anda, konteks yang sama akan diberikan.

Jika ingin mengganti konteks dalam tindakan, Anda dapat meneruskan objek konteks yang berbeda untuk menggantikan objek yang ada:

const otherFlow = ai.defineFlow(/* ... */);

const myFlow = ai.defineFlow({
  // ...
}, (input, {context}) => {
  // override the existing context completely
  otherFlow({/*...*/}, {context: {newContext: true}});
  // or selectively override
  otherFlow({/*...*/}, {context: {...context, updatedContext: true}});
}); 

Saat diganti, konteks akan disebarkan dengan cara yang sama. Dalam contoh ini, setiap tindakan yang dipanggil otherFlow selama eksekusi akan mewarisi konteks yang diganti.