Panggilan alat

Panggilan alat, disebut juga panggilan fungsi, adalah cara terstruktur untuk memberi LLM yang memiliki kemampuan untuk membuat permintaan kembali ke aplikasi yang memanggilnya. Anda mendefinisikan alat yang ingin Anda sediakan untuk model, dan model akan membuat permintaan alat ke aplikasi Anda seperlunya untuk memenuhi prompt yang Anda berikan.

Kasus penggunaan panggilan alat umumnya terbagi dalam beberapa tema:

Memberi LLM akses ke informasi yang tidak memberinya pelatihan

  • Informasi yang sering berubah, seperti menu harian restoran atau status inventaris toko Anda.
  • Informasi khusus untuk domain aplikasi Anda, seperti informasi produk.

Perhatikan tumpang-tindih dengan retrieval-Augmented Generation (RAG), yang juga memungkinkan LLM mengintegrasikan informasi faktual ke dalam generasinya. RAG adalah solusi yang lebih berat yang paling cocok ketika Anda memiliki banyak atau informasi yang paling relevan dengan prompt bersifat ambigu. Aktif di sisi lain, jika proses untuk mengambil informasi yang dibutuhkan LLM adalah fungsi sederhana pencarian data atau pencarian database, panggilan alat lebih tepat.

Memperkenalkan tingkat determinisme ke dalam alur kerja LLM

  • Melakukan perhitungan yang tidak dapat diselesaikan LLM dengan andal.
  • Memaksa LLM menghasilkan teks verbatim dalam keadaan tertentu, seperti saat menjawab pertanyaan tentang persyaratan layanan aplikasi.

Melakukan tindakan saat dimulai oleh LLM

  • Menyalakan dan mematikan lampu di asisten rumah yang didukung LLM
  • Melakukan reservasi meja di agen restoran yang didukung LLM

Sebelum memulai

Jika Anda ingin menjalankan contoh kode pada halaman ini, selesaikan langkah-langkah di panduan Memulai. Semua contoh tersebut berasumsi bahwa Anda sudah menyiapkan project dengan dependensi Genkit yang terinstal.

Halaman ini membahas salah satu fitur lanjutan abstraksi model Genkit dan generate() sekarang, jadi sebelum Anda menyelami terlalu dalam, Anda harus terbiasa dengan konten di halaman Membuat konten dengan model AI. Anda seharusnya memahami sistem Genkit untuk menentukan skema input dan output, yang dibahas di halaman Flows.

Ringkasan panggilan alat

Pada dasarnya, inilah interaksi alat-panggilan yang umum dengan LLM seperti ini:

  1. Aplikasi panggilan meminta LLM meminta dan juga menyertakan perintah yang mencantumkan daftar alat yang dapat digunakan LLM untuk menghasilkan respons.
  2. LLM menghasilkan respons lengkap atau menghasilkan panggilan alat dalam format tertentu.
  3. Jika pemanggil menerima respons lengkap, permintaan akan dipenuhi dan interaksi berakhir; tetapi jika pemanggil menerima panggilan alat, ia melakukan logika apa pun yang sesuai dan mengirimkan permintaan baru ke LLM yang berisi prompt asli atau beberapa variasinya serta hasil dari panggilan alat.
  4. LLM akan menangani perintah baru seperti di Langkah 2.

Agar hal ini berfungsi, beberapa persyaratan harus dipenuhi:

  • Model harus dilatih untuk membuat permintaan alat ketika diperlukan untuk menyelesaikan . Sebagian besar model yang lebih besar disediakan melalui API web, seperti Gemini dan Claude, bisa melakukannya, tapi model yang lebih kecil dan lebih terspesialisasi sering kali tidak bisa. Genkit akan menampilkan error jika Anda mencoba menyediakan alat pada model yang tidak mendukungnya.
  • Aplikasi panggilan harus menyediakan definisi alat pada model dalam format yang diharapkan.
  • Aplikasi panggilan harus memerintahkan model untuk membuat panggilan alat permintaan dalam format yang diharapkan oleh aplikasi.

Panggilan alat dengan Genkit

Genkit menyediakan satu antarmuka untuk panggilan alat dengan model yang mendukungnya. Setiap plugin model memastikan bahwa dua kriteria terakhir di atas telah terpenuhi, dan fungsi generate() secara otomatis menjalankan loop panggilan alat jelaskan sebelumnya.

Dukungan model

Dukungan panggilan alat bergantung pada model, API model, dan plugin Genkit. Baca dokumentasi yang relevan untuk menentukan apakah panggilan alat mungkin didukung. Selain itu:

  • Genkit akan menampilkan error jika Anda mencoba menyediakan alat pada model yang tidak mendukungnya.
  • Jika plugin mengekspor referensi model, properti info.supports.tools akan menunjukkan apakah alat itu mendukung pemanggilan alat.

Alat pendefinisian

Gunakan fungsi defineTool() untuk menulis definisi alat:

const specialToolInputSchema = z.object({ meal: z.enum(["breakfast", "lunch", "dinner"]) });
const specialTool = defineTool(
  {
    name: "specialTool",
    description: "Retrieves today's special for the given meal",
    inputSchema: specialToolInputSchema,
    outputSchema: z.string(),
  },
  async ({ meal }): Promise<string> => {
    // Retrieve up-to-date information and return it. Here, we just return a
    // fixed value.
    return "Baked beans on toast";
  }
);

Sintaksis di sini terlihat seperti sintaksis defineFlow(); namun, keempat dari parameter name, description, inputSchema, dan outputSchema tidak diperlukan. Saat menulis definisi {i>tool<i}, berhati-hatilah dengan kata-kata dan deskriptif dari parameter ini, karena mereka sangat penting bagi LLM untuk memanfaatkan secara efektif alat yang tersedia.

Menyertakan alat dengan perintah Anda

Setelah Anda mendefinisikan {i>tool<i} Anda, tentukan dalam parameter {i>tools<i} dari generate():

const llmResponse = await generate({
  model: gemini15Flash,
  prompt,
  tools: [specialTool],
});

Anda dapat menyediakan beberapa {i>tool<i}; LLM akan memanggil alat sesuai kebutuhan untuk menyelesaikan prompt.

Menangani panggilan alat secara eksplisit

Secara default, Genkit berulang kali memanggil LLM hingga setiap panggilan alat diselesaikan. Jika Anda menginginkan kontrol lebih besar atas loop panggilan alat ini, misalnya untuk terapkan logika yang lebih rumit, setel parameter returnToolRequests ke true. Sekarang Anda bertanggung jawab untuk memastikan semua permintaan alat terpenuhi:

let generateOptions: GenerateOptions = {
  model: gemini15Flash,
  prompt,
  tools: [specialTool],
  returnToolRequests: true,
};
let llmResponse;
while (true) {
  llmResponse = await generate(generateOptions);
  const toolRequests = llmResponse.toolRequests();
  if (toolRequests.length < 1) {
    break;
  }
  const toolResponses: ToolResponsePart[] = await Promise.all(
    toolRequests.map(async (part) => {
      switch (part.toolRequest.name) {
        case "specialTool":
          return {
            toolResponse: {
              name: part.toolRequest.name,
              ref: part.toolRequest.ref,
              output: await specialTool(specialToolInputSchema.parse(part.toolRequest?.input)),
            },
          };
        default:
          throw Error('Tool not found');
        }
      }));
    generateOptions.history = llmResponse.toHistory();
    generateOptions.prompt = toolResponses;
}