การเรียกใช้เครื่องมือ

การเรียกใช้เครื่องมือหรือที่เรียกว่าการเรียกใช้ฟังก์ชันเป็นวิธีที่เป็นระเบียบเพื่อให้ LLM ส่งคำขอกลับไปยังแอปพลิเคชันที่เรียกใช้ คุณจะกำหนดเครื่องมือที่ต้องการให้โมเดลใช้งานได้ และโมเดลจะส่งคำขอเครื่องมือไปยังแอปของคุณตามที่จำเป็นเพื่อดำเนินการตามพรอมต์ที่คุณให้ไว้

โดยทั่วไปแล้ว Use Case ของการเรียกใช้เครื่องมือจะแบ่งออกเป็น 2-3 ธีม ดังนี้

การให้ LLM เข้าถึงข้อมูลที่ไม่ได้ใช้ฝึก

  • ข้อมูลที่มีการเปลี่ยนแปลงบ่อยครั้ง เช่น ราคาหุ้นหรือสภาพอากาศปัจจุบัน
  • ข้อมูลเฉพาะสำหรับโดเมนแอป เช่น ข้อมูลผลิตภัณฑ์หรือโปรไฟล์ผู้ใช้

โปรดทราบว่ามีบางส่วนที่ทับซ้อนกับการสร้างที่เพิ่มการดึงข้อมูล (RAG) ซึ่งเป็นวิธีให้ LLM ผสานรวมข้อมูลข้อเท็จจริงไว้ในการสร้างด้วย RAG เป็นโซลูชันที่หนักกว่าซึ่งเหมาะสําหรับกรณีที่คุณมีข้อมูลจํานวนมากหรือข้อมูลที่เกี่ยวข้องกับพรอมต์มากที่สุดมีความคลุมเครือ ในทางกลับกัน หากการดึงข้อมูลที่ LLM ต้องการเป็นการเรียกใช้ฟังก์ชันธรรมดาหรือการค้นหาฐานข้อมูล การเรียกใช้เครื่องมือจะเหมาะสมกว่า

การนําระดับการกําหนดลงในเวิร์กโฟลว์ LLM

  • ดำเนินการคํานวณที่ LLM ทําให้เสร็จสมบูรณ์ไม่ได้
  • การบังคับให้ LLM สร้างข้อความแบบคำต่อคำในบางสถานการณ์ เช่น เมื่อตอบคำถามเกี่ยวกับข้อกำหนดในการให้บริการของแอป

การดำเนินการเมื่อ LLM เริ่มต้น

  • การเปิดและปิดไฟในบ้านที่ทำงานด้วย LLM
  • การจองโต๊ะในตัวแทนร้านอาหารที่ทำงานด้วย LLM

ก่อนเริ่มต้น

หากต้องการเรียกใช้ตัวอย่างโค้ดในหน้านี้ ให้ทำตามขั้นตอนในคู่มือการเริ่มต้นใช้งานก่อน ตัวอย่างทั้งหมดจะถือว่าคุณได้ตั้งค่าโปรเจ็กต์ที่ติดตั้งข้อกําหนดของ Genkit แล้ว

หน้านี้กล่าวถึงฟีเจอร์ขั้นสูงอย่างหนึ่งของการแยกแยะโมเดล Genkit ดังนั้นก่อนลงลึก คุณควรทำความคุ้นเคยกับเนื้อหาในหน้าการสร้างเนื้อหาด้วยโมเดล AI นอกจากนี้ คุณควรทำความคุ้นเคยกับระบบของ Genkit ในการกําหนดสคีมาอินพุตและเอาต์พุต ซึ่งจะกล่าวถึงในหน้าโฟลว์

ภาพรวมของการเรียกใช้เครื่องมือ

ระดับภาพรวมของการโต้ตอบแบบเรียกใช้เครื่องมือกับ LLM มีลักษณะดังนี้

  1. แอปพลิเคชันที่เรียกใช้จะแสดงพรอมต์คำขอต่อ LLM และระบุรายการเครื่องมือที่ LLM สามารถใช้เพื่อสร้างคำตอบในพรอมต์ด้วย
  2. LLM จะสร้างคำตอบที่สมบูรณ์หรือสร้างคำขอเรียกใช้เครื่องมือในรูปแบบที่เฉพาะเจาะจง
  3. หากผู้โทรได้รับการตอบกลับที่สมบูรณ์ ระบบจะดำเนินการตามคำขอและสิ้นสุดการโต้ตอบ แต่หากผู้โทรได้รับการเรียกใช้เครื่องมือ ระบบจะดำเนินการตามตรรกะที่เหมาะสมและส่งคำขอใหม่ไปยัง LLM ซึ่งมีพรอมต์เดิมหรือพรอมต์ที่เปลี่ยนแปลงไปเล็กน้อย รวมถึงผลลัพธ์ของการเรียกใช้เครื่องมือ
  4. LLM จะจัดการพรอมต์ใหม่ตามขั้นตอนที่ 2

ฟีเจอร์นี้ใช้ได้ก็ต่อเมื่อมีคุณสมบัติตรงตามข้อกำหนดต่อไปนี้

  • โมเดลต้องได้รับการฝึกให้ส่งคําขอเครื่องมือเมื่อจําเป็นต้องใช้เพื่อดำเนินการตามพรอมต์ โมเดลขนาดใหญ่ส่วนใหญ่ที่ให้บริการผ่าน Web API เช่น Gemini และ Claude จะทำสิ่งนี้ได้ แต่โมเดลขนาดเล็กและเฉพาะเจาะจงมักจะทำไม่ได้ Genkit จะแสดงข้อผิดพลาดหากคุณพยายามใส่เครื่องมือในรุ่นที่ไม่รองรับ
  • แอปพลิเคชันที่เรียกใช้ต้องระบุคำจำกัดความของเครื่องมือให้กับโมเดลในรูปแบบที่คาดไว้
  • แอปพลิเคชันที่เรียกใช้ต้องแจ้งให้โมเดลสร้างคําขอการเรียกใช้เครื่องมือในรูปแบบที่แอปพลิเคชันคาดหวัง

การเรียกใช้เครื่องมือด้วย Genkit

Genkit มีอินเทอร์เฟซเดียวสําหรับการเรียกใช้เครื่องมือกับโมเดลที่รองรับ ปลั๊กอินแต่ละรูปแบบต้องเป็นไปตามเกณฑ์ 2 ข้อสุดท้ายข้างต้น และฟังก์ชัน generate() ของอินสแตนซ์ Genkit จะเรียกใช้ลูปการเรียกใช้เครื่องมือที่อธิบายไว้ก่อนหน้านี้โดยอัตโนมัติ

การรองรับโมเดล

การรองรับการเรียกใช้เครื่องมือจะขึ้นอยู่กับรุ่น API ของรุ่น และปลั๊กอิน Genkit โปรดดูเอกสารประกอบที่เกี่ยวข้องเพื่อพิจารณาว่าระบบมีแนวโน้มที่จะรองรับการเรียกใช้เครื่องมือหรือไม่ นอกจากนี้

  • Genkit จะแสดงข้อผิดพลาดหากคุณพยายามใส่เครื่องมือในโมเดลที่ไม่รองรับ
  • หากปลั๊กอินส่งออกข้อมูลอ้างอิงรูปแบบ พร็อพเพอร์ตี้ info.supports.tools จะระบุว่ารองรับการเรียกใช้เครื่องมือหรือไม่

เครื่องมือกำหนด

ใช้ฟังก์ชัน defineTool() ของอินสแตนซ์ Genkit เพื่อเขียนคําจํากัดความของเครื่องมือ

import { genkit, z } from 'genkit';
import { googleAI } from '@genkitai/google-ai';

const ai = genkit({
  plugins: [googleAI()],
  model: googleAI.model('gemini-2.0-flash'),
});

const getWeather = ai.defineTool(
  {
    name: 'getWeather',
    description: 'Gets the current weather in a given location',
    inputSchema: z.object({ 
      location: z.string().describe('The location to get the current weather for')
    }),
    outputSchema: z.string(),
  },
  async (input) => {
    // Here, we would typically make an API call or database query. For this
    // example, we just return a fixed value.
    return `The current weather in ${input.location} is 63°F and sunny.`;
  }
);

ไวยากรณ์ที่นี่ดูเหมือนไวยากรณ์ defineFlow() แต่จะต้องใช้พารามิเตอร์ name, description และ inputSchema เมื่อเขียนคำจำกัดความของเครื่องมือ ให้ระมัดระวังเป็นพิเศษเกี่ยวกับถ้อยคำและความชัดเจนของพารามิเตอร์เหล่านี้ ข้อมูลเหล่านี้มีความสำคัญต่อ LLM ในการใช้เครื่องมือที่มีอยู่อย่างมีประสิทธิภาพ

การใช้เครื่องมือ

ใส่เครื่องมือที่กําหนดไว้ในพรอมต์เพื่อสร้างเนื้อหา

สร้าง

const response = await ai.generate({
  prompt: 'What is the weather in Baltimore?',
  tools: [getWeather],
});

definePrompt

const weatherPrompt = ai.definePrompt(
  {
    name: 'weatherPrompt',
    tools: [getWeather],
  },
  'What is the weather in {{location}}?'
);

const response = await weatherPrompt({ location: 'Baltimore' });

ไฟล์พรอมต์

---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
  schema:
    location: string
---

What is the weather in {{location}}?

จากนั้นเรียกใช้พรอมต์ในโค้ดของคุณดังนี้

// assuming prompt file is named weatherPrompt.prompt
const weatherPrompt = ai.prompt('weatherPrompt');

const response = await weatherPrompt({ location: 'Baltimore' });

แชท

const chat = ai.chat({
  system: 'Answer questions using the tools you have.',
  tools: [getWeather],
});

const response = await chat.send('What is the weather in Baltimore?');

// Or, specify tools that are message-specific 
const response = await chat.send({
  prompt: 'What is the weather in Baltimore?',
  tools: [getWeather],
});

Genkit จะจัดการการเรียกใช้เครื่องมือโดยอัตโนมัติหาก LLM ต้องใช้เครื่องมือ getWeather เพื่อตอบกลับพรอมต์

การกําหนดเครื่องมือแบบไดนามิกขณะรันไทม์

เช่นเดียวกับสิ่งต่างๆ ส่วนใหญ่ใน Genkit คุณต้องกำหนดเครื่องมือไว้ล่วงหน้าระหว่างการเริ่มต้นแอป ซึ่งจําเป็นเพื่อให้คุณโต้ตอบกับเครื่องมือจาก UI ของนักพัฒนาซอฟต์แวร์ Genkit ได้ ซึ่งโดยปกติแล้วเป็นวิธีที่แนะนำ อย่างไรก็ตาม อาจมีบางกรณีที่ต้องกำหนดเครื่องมือแบบไดนามิกตามคำขอของผู้ใช้

คุณกําหนดเครื่องมือแบบไดนามิกได้โดยใช้ฟังก์ชัน ai.dynamicTool ฟังก์ชันนี้คล้ายกับเมธอด ai.defineTool มาก อย่างไรก็ตาม รันไทม์ Genkit จะไม่ติดตามเครื่องมือแบบไดนามิก คุณจึงใช้ UI สําหรับนักพัฒนาซอฟต์แวร์ของ Genkit เพื่อโต้ตอบกับเครื่องมือดังกล่าวไม่ได้ แต่คุณต้องส่งผ่านไปยังai.generateการเรียกใช้โดยอ้างอิง (สําหรับเครื่องมือทั่วไป คุณสามารถใช้ชื่อเครื่องมือสตริงได้เช่นกัน)

import { genkit, z } from "genkit";
import { googleAI } from "@genkit-ai/googleai";

const ai = genkit({
  plugins: [googleAI()],
  model: googleAI.model("gemini-2.0-flash"),
});

const weatherFlow = ai.defineFlow("weatherFlow", async () => {
  const getWeather = ai.dynamicTool(
    {
      name: "getWeather",
      description: "Gets the current weather in a given location",
      inputSchema: z.object({
        location: z
          .string()
          .describe("The location to get the current weather for"),
      }),
      outputSchema: z.string(),
    },
    async (input) => {
      return `The current weather in ${input.location} is 63°F and sunny.`;
    }
  );

  const { text } = await ai.generate({
    prompt: "What is the weather in Baltimore?",
    tools: [getWeather],
  });

  return text;
});

เมื่อกำหนดเครื่องมือแบบไดนามิก หากต้องการระบุสคีมาอินพุตและเอาต์พุต คุณจะใช้ Zod ตามที่แสดงในตัวอย่างก่อนหน้านี้ หรือจะส่งสคีมา JSON ที่สร้างขึ้นด้วยตนเองก็ได้

const getWeather = ai.dynamicTool(
  {
    name: "getWeather",
    description: "Gets the current weather in a given location",
    inputJsonSchema: myInputJsonSchema,
    outputJsonSchema: myOutputJsonSchema,
  },
  async (input) => { /* ... */ }
);

เครื่องมือแบบไดนามิกไม่จําเป็นต้องใช้ฟังก์ชันการติดตั้งใช้งาน หากคุณไม่ได้ส่งผ่านฟังก์ชัน เครื่องมือจะทํางานแบบขัดจังหวะและคุณจะจัดการการเรียกใช้เครื่องมือด้วยตนเองได้ ดังนี้

const getWeather = ai.dynamicTool(
  {
    name: "getWeather",
    description: "Gets the current weather in a given location",
    inputJsonSchema: myInputJsonSchema,
    outputJsonSchema: myOutputJsonSchema,
  }
);

หยุดการวนเครื่องมือชั่วคราวโดยใช้การขัดจังหวะ

โดยค่าเริ่มต้น Genkit จะเรียก LLM ซ้ำๆ จนกว่าการเรียกใช้เครื่องมือทั้งหมดจะได้รับการแก้ไข คุณสามารถหยุดการดําเนินการชั่วคราวแบบมีเงื่อนไขได้ในสถานการณ์ที่ต้องการ เช่น

  • ถามคำถามผู้ใช้หรือแสดง UI
  • ยืนยันการดำเนินการที่อาจมีความเสี่ยงกับผู้ใช้
  • ขอการอนุมัติการดำเนินการนอกแบนด์

การขัดจังหวะเป็นเครื่องมือพิเศษที่สามารถหยุดลูปและส่งการควบคุมกลับไปยังโค้ดเพื่อให้คุณจัดการกับสถานการณ์ขั้นสูงได้ ไปที่คู่มือการขัดจังหวะเพื่อดูวิธีใช้

การจัดการการเรียกใช้เครื่องมืออย่างชัดแจ้ง

หากต้องการควบคุมลูปการเรียกใช้เครื่องมือนี้อย่างเต็มรูปแบบ เช่น เพื่อใช้ตรรกะที่ซับซ้อนมากขึ้น ให้ตั้งค่าพารามิเตอร์ returnToolRequests เป็น true ตอนนี้คุณมีหน้าที่รับผิดชอบในการตรวจสอบว่าคำขอเครื่องมือทั้งหมดได้รับการดำเนินการแล้ว โดยทำดังนี้

const getWeather = ai.defineTool(
  {
    // ... tool definition ...
  },
  async ({ location }) => {
    // ... tool implementation ...
  },
);

const generateOptions: GenerateOptions = {
  prompt: "What's the weather like in Baltimore?",
  tools: [getWeather],
  returnToolRequests: true,
};

let llmResponse;
while (true) {
  llmResponse = await ai.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 getWeather(part.toolRequest.input),
            },
          };
        default:
          throw Error('Tool not found');
      }
    })
  );
  generateOptions.messages = llmResponse.messages;
  generateOptions.prompt = toolResponses;
}