Tool use with Live API

การใช้เครื่องมือช่วยให้ Live API ทำได้มากกว่าการสนทนา โดยเปิดใช้การดำเนินการในโลกแห่งความเป็นจริงและดึงบริบทภายนอกมาใช้งานขณะที่ยังคงเชื่อมต่อแบบเรียลไทม์ คุณกำหนดเครื่องมือต่างๆ เช่น การเรียกฟังก์ชัน, การเรียกใช้โค้ด และ Google Search ได้ด้วย Live API

ภาพรวมของเครื่องมือที่รองรับ

ภาพรวมคร่าวๆ ของเครื่องมือที่ใช้ได้สำหรับแต่ละรุ่นมีดังนี้

เครื่องมือ โมเดลที่ซ้อนกัน
gemini-2.0-flash-live-001
gemini-2.5-flash-preview-native-audio-dialog gemini-2.5-flash-exp-native-audio-thinking-dialog
ค้นหา ใช่ ได้ ใช่
การเรียกใช้ฟังก์ชัน ใช่ ได้ ไม่
การเรียกใช้โค้ด ใช่ ไม่ได้ ไม่
บริบท URL ใช่ ไม่ได้ ไม่

การเรียกใช้ฟังก์ชัน

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

คุณสามารถกําหนดการประกาศฟังก์ชันเป็นส่วนหนึ่งของการกําหนดค่าเซสชันได้ หลังจากได้รับการเรียกใช้เครื่องมือแล้ว ไคลเอ็นต์ควรตอบกลับด้วยรายการออบเจ็กต์ FunctionResponse โดยใช้เมธอด session.send_tool_response

ดูข้อมูลเพิ่มเติมได้ในบทแนะนำการเรียกใช้ฟังก์ชัน

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

# Simple function definitions
turn_on_the_lights = {"name": "turn_on_the_lights"}
turn_off_the_lights = {"name": "turn_off_the_lights"}

tools = [{"function_declarations": [turn_on_the_lights, turn_off_the_lights]}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "Turn on the lights please"
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

        async for chunk in session.receive():
            if chunk.server_content:
                if chunk.text is not None:
                    print(chunk.text)
            elif chunk.tool_call:
                function_responses = []
                for fc in chunk.tool_call.function_calls:
                    function_response = types.FunctionResponse(
                        id=fc.id,
                        name=fc.name,
                        response={ "result": "ok" } # simple, hard-coded function response
                    )
                    function_responses.append(function_response)

                await session.send_tool_response(function_responses=function_responses)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

// Simple function definitions
const turn_on_the_lights = { name: "turn_on_the_lights" } // , description: '...', parameters: { ... }
const turn_off_the_lights = { name: "turn_off_the_lights" }

const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]

const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      } else if (message.toolCall) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Turn on the lights please';
  session.sendClientContent({ turns: inputTurns });

  let turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
      }
    }
    else if (turn.toolCall) {
      const functionResponses = [];
      for (const fc of turn.toolCall.functionCalls) {
        functionResponses.push({
          id: fc.id,
          name: fc.name,
          response: { result: "ok" } // simple, hard-coded function response
        });
      }

      console.debug('Sending tool response...\n');
      session.sendToolResponse({ functionResponses: functionResponses });
    }
  }

  // Check again for new messages
  turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
      }
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

จากพรอมต์เดียว โมเดลสามารถสร้างการเรียกใช้ฟังก์ชันหลายรายการและโค้ดที่จําเป็นต่อเชื่อมเอาต์พุต โค้ดนี้จะทํางานในสภาพแวดล้อมแซนด์บ็อกซ์ ซึ่งจะสร้างข้อความ BidiGenerateContentToolCall ตามมา

การเรียกใช้ฟังก์ชันแบบอะซิงโครนัส

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

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

Python

  # Non-blocking function definitions
  turn_on_the_lights = {"name": "turn_on_the_lights", "behavior": "NON_BLOCKING"} # turn_on_the_lights will run asynchronously
  turn_off_the_lights = {"name": "turn_off_the_lights"} # turn_off_the_lights will still pause all interactions with the model

JavaScript

import { GoogleGenAI, Modality, Behavior } from '@google/genai';

// Non-blocking function definitions
const turn_on_the_lights = {name: "turn_on_the_lights", behavior: Behavior.NON_BLOCKING}

// Blocking function definitions
const turn_off_the_lights = {name: "turn_off_the_lights"}

const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]

NON-BLOCKING ช่วยให้ฟังก์ชันทำงานแบบไม่พร้อมกันขณะที่คุณโต้ตอบกับโมเดลต่อไปได้

จากนั้นคุณต้องบอกให้โมเดลทราบว่าจะทําอย่างไรเมื่อได้รับ FunctionResponse โดยใช้พารามิเตอร์ scheduling โดยสามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้

  • ขัดจังหวะสิ่งที่กำลังทำอยู่และบอกคุณเกี่ยวกับคำตอบที่ได้รับทันที (scheduling="INTERRUPT"),
  • โปรดรอจนกว่าระบบจะดำเนินการเสร็จสิ้น (scheduling="WHEN_IDLE")
  • หรือจะไม่ต้องดำเนินการใดๆ และใช้ความรู้นั้นในภายหลังในการสนทนาก็ได้ (scheduling="SILENT")

Python

# for a non-blocking function definition, apply scheduling in the function response:
  function_response = types.FunctionResponse(
      id=fc.id,
      name=fc.name,
      response={
          "result": "ok",
          "scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
      }
  )

JavaScript

import { GoogleGenAI, Modality, Behavior, FunctionResponseScheduling } from '@google/genai';

// for a non-blocking function definition, apply scheduling in the function response:
const functionResponse = {
  id: fc.id,
  name: fc.name,
  response: {
    result: "ok",
    scheduling: FunctionResponseScheduling.INTERRUPT  // Can also be WHEN_IDLE or SILENT
  }
}

การดำเนินการกับโค้ด

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

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

tools = [{'code_execution': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "Compute the largest prime palindrome under 100000."
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

        async for chunk in session.receive():
            if chunk.server_content:
                if chunk.text is not None:
                    print(chunk.text)

                model_turn = chunk.server_content.model_turn
                if model_turn:
                    for part in model_turn.parts:
                      if part.executable_code is not None:
                        print(part.executable_code.code)

                      if part.code_execution_result is not None:
                        print(part.code_execution_result.output)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

const tools = [{codeExecution: {}}]
const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      } else if (message.toolCall) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Compute the largest prime palindrome under 100000.';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
        else if (part.executableCode) {
          console.debug('executableCode: %s\n', part.executableCode.code);
        }
        else if (part.codeExecutionResult) {
          console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
        }
      }
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

คุณสามารถเปิดใช้การกราวด์กับ Google Search เป็นส่วนหนึ่งของการกำหนดค่าเซสชันได้ ซึ่งจะช่วยเพิ่มความแม่นยำของ Live API และป้องกันภาพหลอน ดูข้อมูลเพิ่มเติมได้ในบทแนะนำการต่อสายกราวด์

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

tools = [{'google_search': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "When did the last Brazil vs. Argentina soccer match happen?"
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

        async for chunk in session.receive():
            if chunk.server_content:
                if chunk.text is not None:
                    print(chunk.text)

                # The model might generate and execute Python code to use Search
                model_turn = chunk.server_content.model_turn
                if model_turn:
                    for part in model_turn.parts:
                      if part.executable_code is not None:
                        print(part.executable_code.code)

                      if part.code_execution_result is not None:
                        print(part.code_execution_result.output)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

const tools = [{googleSearch: {}}]
const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      } else if (message.toolCall) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'When did the last Brazil vs. Argentina soccer match happen?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
        else if (part.executableCode) {
          console.debug('executableCode: %s\n', part.executableCode.code);
        }
        else if (part.codeExecutionResult) {
          console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
        }
      }
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

การรวมเครื่องมือหลายอย่างเข้าด้วยกัน

คุณรวมเครื่องมือหลายอย่างภายใน Live API ได้ ซึ่งจะช่วยเพิ่มความสามารถของแอปพลิเคชันให้ดียิ่งขึ้น

Python

prompt = """
Hey, I need you to do three things for me.

1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights

Thanks!
"""

tools = [
    {"google_search": {}},
    {"code_execution": {}},
    {"function_declarations": [turn_on_the_lights, turn_off_the_lights]},
]

config = {"response_modalities": ["TEXT"], "tools": tools}

# ... remaining model call

JavaScript

const prompt = `Hey, I need you to do three things for me.

1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights

Thanks!
`

const tools = [
  { googleSearch: {} },
  { codeExecution: {} },
  { functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }
]

const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

// ... remaining model call

ขั้นตอนถัดไป