Gemini ช่วยให้คุณใช้เครื่องมือในตัว เช่น google_search และการเรียกใช้ฟังก์ชัน
(หรือที่เรียกว่าเครื่องมือที่กำหนดเอง) ร่วมกันได้ในการสร้างครั้งเดียวโดยการเก็บรักษาและแสดงประวัติบริบทของการเรียกใช้เครื่องมือ การผสมผสานเครื่องมือในตัวและเครื่องมือที่กำหนดเองช่วยให้
เวิร์กโฟลว์ที่ซับซ้อนและมีเอเจนต์ทำงานได้ เช่น โมเดลสามารถอ้างอิง
ข้อมูลเว็บแบบเรียลไทม์ก่อนที่จะเรียกตรรกะทางธุรกิจที่เฉพาะเจาะจงของคุณ
ตัวอย่างที่เปิดใช้ชุดค่าผสมของเครื่องมือในตัวและเครื่องมือที่กำหนดเองด้วย
google_search และฟังก์ชันที่กำหนดเอง getWeather มีดังนี้
Python
from google import genai
from google.genai import types
client = genai.Client()
getWeather = {
"name": "getWeather",
"description": "Gets the weather for a requested city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city and state, e.g. Utqiaġvik, Alaska",
},
},
"required": ["city"],
},
}
# Turn 1: Initial request with Google Search (built-in) and getWeather (custom) tools enabled
response = client.models.generate_content(
model="gemini-3-flash-preview",
contents="What is the northernmost city in the United States? What's the weather like there today?",
config=types.GenerateContentConfig(
tools=[
types.Tool(
google_search=types.ToolGoogleSearch(), # Built-in tool
function_declarations=[getWeather] # Custom tool
),
],
include_server_side_tool_invocations=True
),
)
for part in response.candidates[0].content.parts:
if part.tool_call:
print(f"Tool call: {part.tool_call.tool_type} (ID: {part.tool_call.id})")
if part.tool_response:
print(f"Tool response: {part.tool_response.tool_type} (ID: {part.tool_response.id})")
if part.function_call:
print(f"Function call: {part.function_call.name} (ID: {part.function_call.id})")
# Turn 2: Manually build history to circulate both tool and function context
history = [
types.Content(
role="user",
parts=[types.Part(text="What is the northernmost city in the United States? What's the weather like there today?")]
),
# Response from Turn 1 includes tool_call, tool_response, and thought_signatures
response.candidates[0].content,
# Return the function_response
types.Content(
role="user",
parts=[types.Part(
function_response=types.FunctionResponse(
name="getWeather",
response={"response": "Very cold. 22 degrees Fahrenheit."},
id=response.candidates[0].content.parts[2].function_call.id # Match the ID from the function_call
)
)]
)
]
response_2 = client.models.generate_content(
model="gemini-3-flash-preview",
contents=history,
config=types.GenerateContentConfig(
tools=[
types.Tool(
google_search=types.ToolGoogleSearch(),
function_declarations=[getWeather]
),
],
# This flag needs to be enabled for built-in tool context circulation and tool combination
include_server_side_tool_invocations=True
),
)
for part in response_2.candidates[0].content.parts:
if part.text:
print(part.text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const getWeather = {
name: "getWeather",
description: "Get the weather in a given location",
parameters: {
type: "OBJECT",
properties: {
location: {
type: "STRING",
description: "The city and state, e.g. San Francisco, CA"
}
},
required: ["location"]
}
};
async function run() {
const model = client.getGenerativeModel({
model: "gemini-3-flash-preview",
});
const tools = [
{ googleSearch: {} },
{ functionDeclarations: [getWeather] }
];
// This flag needs to be enabled for built-in tool context circulation and tool combination
const toolConfig = { includeServerSideToolInvocations: true };
// Turn 1: Initial request with Google Search (built-in) and getWeather (custom) tools enabled
const result1 = await model.generateContent({
contents: [{role: "user", parts: [{text: "What is the northernmost city in the United States? What's the weather like there today?"}]}],
tools: tools,
toolConfig: toolConfig,
});
const response1 = result1.response;
for (const part of response1.candidates[0].content.parts) {
if (part.toolCall) {
console.log(`Tool call: ${part.toolCall.toolType} (ID: ${part.toolCall.id})`);
}
if (part.toolResponse) {
console.log(`Tool response: ${part.toolResponse.toolType} (ID: ${part.toolResponse.id})`);
}
if (part.functionCall) {
console.log(`Function call: ${part.functionCall.name} (ID: ${part.functionCall.id})`);
}
}
const functionCallId = response1.candidates[0].content.parts.find(p => p.functionCall)?.functionCall?.id;
// Turn 2: Manually build history to circulate both tool and function context
const history = [
{
role: "user",
parts:[{text: "What is the northernmost city in the United States? What's the weather like there today?"}]
},
// Response from Turn 1 includes tool_call, tool_response, and thought_signatures
response1.candidates[0].content,
// Return the function_response
{
role: "user",
parts: [{
functionResponse: {
name: "getWeather",
response: {response: "Very cold. 22 degrees Fahrenheit."},
id: functionCallId // Match the ID from the function_call
}
}]
}
];
const result2 = await model.generateContent({
contents: history,
tools: tools,
toolConfig: toolConfig,
});
for (const part of result2.response.candidates[0].content.parts) {
if (part.text) {
console.log(part.text);
}
}
}
run();
Go
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/google/generative-ai-go/genai"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
if err != nil {
log.Exit(err)
}
defer client.Close()
getWeather := &genai.FunctionDeclaration{
Name: "getWeather",
Description: "Get the weather in a given location",
Parameters: &genai.Schema{
Type: genai.Object,
Properties: map[string]*genai.Schema{
"location": {
Type: genai.String,
Description: "The city and state, e.g. San Francisco, CA",
},
},
Required: []string{"location"},
},
}
model := client.GenerativeModel("gemini-3-flash-preview")
model.Tools = []*genai.Tool{
{GoogleSearch: &genai.GoogleSearch{}}, // Built-in tool
{FunctionDeclarations: []*genai.FunctionDeclaration{getWeather}}, // Custom tool
}
ist := true
model.ToolConfig = &genai.ToolConfig{
IncludeServerSideToolInvocations: &ist, // This flag needs to be enabled for built-in tool context circulation and tool combination
}
chat := model.StartChat()
// Turn 1: Initial request with Google Search (built-in) and getWeather (custom) tools enabled
prompt := genai.Text("What is the northernmost city in the United States? What's the weather like there today?")
resp1, err := chat.SendMessage(ctx, prompt)
if err != nil {
log.Exitf("SendMessage failed: %v", err)
}
if resp1 == nil || len(resp1.Candidates) == 0 || resp1.Candidates[0].Content == nil {
log.Exit("empty response from model")
}
var functionCallID string
for _, part := range resp1.Candidates[0].Content.Parts {
switch p := part.(type) {
case genai.FunctionCall:
fmt.Printf("Function call: %s (ID: %s)\n", p.Name, p.ID)
if p.Name == "getWeather" {
functionCallID = p.ID
}
case genai.ToolCallPart:
fmt.Printf("Tool call: %s (ID: %s)\n", p.ToolType, p.ID)
case genai.ToolResponsePart:
fmt.Printf("Tool response: %s (ID: %s)\n", p.ToolType, p.ID)
}
}
if functionCallID == "" {
log.Exit("no getWeather function call in response")
}
// Turn 2: Provide function result back to model.
// Chat history automatically includes tool_call, tool_response, and thought_signatures from Turn 1.
fr := genai.FunctionResponse{
Name: "getWeather",
ID: functionCallID,
Response: map[string]any{
"response": "Very cold. 22 degrees Fahrenheit.",
},
}
resp2, err := chat.SendMessage(ctx, fr)
if err != nil {
log.Exitf("SendMessage for turn 2 failed: %v", err)
}
if resp2 == nil || len(resp2.Candidates) == 0 || resp2.Candidates[0].Content == nil {
log.Exit("empty response from model in turn 2")
}
for _, part := range resp2.Candidates[0].Content.Parts {
if txt, ok := part.(genai.Text); ok {
fmt.Println(string(txt))
}
}
}
REST
# Turn 1: Initial request with Google Search (built-in) and getWeather (custom) tools enabled
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"role": "user",
"parts": [{
"text": "What is the northernmost city in the United States? What'\''s the weather like there today?"
}]
}],
"tools": [{
"googleSearch": {}
}, {
"functionDeclarations": [{
"name": "getWeather",
"description": "Get the weather in a given location",
"parameters": {
"type": "OBJECT",
"properties": {
"location": {
"type": "STRING",
"description": "The city and state, e.g. San Francisco, CA"
}
},
"required": ["location"]
}
}]
}],
"toolConfig": {
"includeServerSideToolInvocations": true
}
}'
# Turn 2: Manually build history to circulate both tool and function context
# The following request assumes you have captured candidates[0].content from Turn 1 response,
# and extracted function_call.id for getWeather.
# Replace FUNCTION_CALL_ID and insert candidate content from turn 1.
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [
{
"role": "user",
"parts": [{"text": "What is the northernmost city in the United States? What'\''s the weather like there today?"}]
},
YOUR_CANDIDATE_CONTENT_FROM_TURN_1_RESPONSE,
{
"role": "user",
"parts": [{
"functionResponse": {
"name": "getWeather",
"id": "FUNCTION_CALL_ID",
"response": {"response": "Very cold. 22 degrees Fahrenheit."}
}
}]
}
],
"tools": [{
"googleSearch": {}
}, {
"functionDeclarations": [{
"name": "getWeather",
"description": "Get the weather in a given location",
"parameters": {
"type": "OBJECT",
"properties": {
"location": {
"type": "STRING",
"description": "The city and state, e.g. San Francisco, CA"
}
},
"required": ["location"]
}
}]
}],
"toolConfig": {
"includeServerSideToolInvocations": true
}
}'
วิธีการทำงาน
โมเดล Gemini 3 ใช้การหมุนเวียนบริบทของเครื่องมือเพื่อเปิดใช้ชุดค่าผสมของเครื่องมือในตัวและเครื่องมือที่กำหนดเอง การหมุนเวียนบริบทของเครื่องมือช่วยให้สามารถรักษาและ แสดงบริบทของเครื่องมือในตัว รวมถึงแชร์กับเครื่องมือที่กำหนดเองในการเรียกใช้เดียวกัน ได้แบบเทิร์นต่อเทิร์น
เปิดใช้การรวมเครื่องมือ
- คุณต้องตั้งค่าแฟล็ก
include_server_side_tool_invocationsเป็นtrueเพื่อ เปิดใช้การหมุนเวียนบริบทของเครื่องมือ - ใส่
function_declarationsพร้อมกับเครื่องมือในตัวที่ต้องการใช้เพื่อเรียกใช้ลักษณะการทำงานร่วมกัน- หากคุณไม่รวม
function_declarationsการหมุนเวียนบริบทของเครื่องมือ จะยังคงทำงานกับเครื่องมือในตัวที่รวมไว้ ตราบใดที่ตั้งค่า Flag ไว้
- หากคุณไม่รวม
API แสดงผลชิ้นส่วน
ในคำตอบเดียว API จะแสดงผลส่วน toolCall และ toolResponse
สำหรับการเรียกเครื่องมือในตัว สำหรับการเรียกฟังก์ชัน (เครื่องมือที่กำหนดเอง) API จะ
แสดงส่วนการเรียก functionCall ซึ่งผู้ใช้จะระบุส่วน functionResponse ในรอบถัดไป
toolCallและtoolResponse: API จะแสดงส่วนเหล่านี้เพื่อรักษาบริบทของเครื่องมือที่เรียกใช้ในฝั่งเซิร์ฟเวอร์ และผลลัพธ์ของการดำเนินการสำหรับรอบถัดไปfunctionCallและfunctionResponse: API จะส่งการเรียกฟังก์ชันให้ผู้ใช้กรอก และผู้ใช้จะส่งผลลัพธ์กลับมาในการตอบกลับฟังก์ชัน (ส่วนเหล่านี้เป็นมาตรฐานสำหรับการเรียกฟังก์ชันทั้งหมดใน Gemini API ไม่ได้มีเฉพาะฟีเจอร์การรวมเครื่องมือ)- (เครื่องมือการเรียกใช้โค้ดเท่านั้น)
executableCodeและcodeExecutionResult: เมื่อใช้เครื่องมือการเรียกใช้โค้ด แทนที่จะเป็นfunctionCallและfunctionResponseAPI จะแสดงexecutableCode(โค้ดที่โมเดลสร้างขึ้น ซึ่งมีไว้สำหรับการเรียกใช้) และcodeExecutionResult(ผลลัพธ์ของโค้ดที่เรียกใช้ได้)
คุณต้องส่งคืนชิ้นส่วนทั้งหมด รวมถึงฟิลด์ทั้งหมดที่ชิ้นส่วนเหล่านั้นมี กลับไปยังโมเดลในแต่ละรอบเพื่อรักษาบริบทและเปิดใช้การรวมเครื่องมือ
ฟิลด์ที่สำคัญในชิ้นส่วนที่ส่งคืน
ชิ้นส่วนบางอย่างที่ API แสดงผลจะมีฟิลด์ id,
tool_type และ thought_signature ฟิลด์เหล่านี้มีความสําคัญต่อการรักษาบริบทของเครื่องมือ (และด้วยเหตุนี้จึงมีความสําคัญต่อการรวมเครื่องมือ) คุณต้องส่งคืนทุกส่วนตามที่ระบุไว้ในการตอบกลับในคําขอที่ตามมา
id: ตัวระบุที่ไม่ซ้ำกันซึ่งแมปการเรียกไปยังการตอบกลับidจะตั้งค่าเป็น การตอบกลับการเรียกใช้ฟังก์ชันทั้งหมด ไม่ว่าการหมุนเวียนบริบทของเครื่องมือจะเป็นอย่างไร คุณต้องระบุidเดียวกันในการตอบกลับของฟังก์ชัน ที่ API ระบุในการเรียกฟังก์ชัน เครื่องมือในตัวจะแชร์idระหว่างการเรียกใช้เครื่องมือและการตอบกลับเครื่องมือโดยอัตโนมัติ- พบในส่วนที่เกี่ยวข้องกับเครื่องมือทั้งหมด:
toolCall,toolResponse,functionCall,functionResponse,executableCode,codeExecutionResult
- พบในส่วนที่เกี่ยวข้องกับเครื่องมือทั้งหมด:
tool_type: ระบุเครื่องมือที่ใช้โดยเฉพาะ เครื่องมือในตัวที่แท้จริง หรือ (เช่นURL_CONTEXT) หรือชื่อฟังก์ชัน (เช่นgetWeather)- พบในส่วน
toolCallและtoolResponse
- พบในส่วน
thought_signature: บริบทที่เข้ารหัสจริงซึ่งฝังอยู่ในแต่ละ ส่วนที่ API แสดงผล ระบบจะสร้างบริบทขึ้นใหม่ไม่ได้หากไม่มีลายเซ็นความคิด หากคุณไม่ส่งคืนลายเซ็นความคิดสำหรับทุกส่วนในทุกๆ เทิร์น โมเดลจะแสดงข้อผิดพลาด- พบได้ในทุกส่วน
ข้อมูลเฉพาะของเครื่องมือ
เครื่องมือในตัวบางอย่างจะแสดงอาร์กิวเมนต์ข้อมูลที่ผู้ใช้มองเห็นได้ซึ่งเจาะจงสำหรับประเภทเครื่องมือ
| เครื่องมือ | อาร์กิวเมนต์การเรียกใช้เครื่องมือที่ผู้ใช้มองเห็น (หากมี) | การตอบกลับของเครื่องมือที่ผู้ใช้มองเห็น (หากมี) |
|---|---|---|
| GOOGLE_SEARCH | queries |
search_suggestions |
| GOOGLE_MAPS | queries |
placesgoogle_maps_widget_context_token |
| URL_CONTEXT | urlsURL ที่จะเรียกดู |
urls_metadataretrieved_url: URL ที่เข้าชมurl_retrieval_status: สถานะการเรียกดู |
| FILE_SEARCH | ไม่มี | ไม่มี |
ตัวอย่างโครงสร้างคำขอรวมเครื่องมือ
โครงสร้างคำขอต่อไปนี้แสดงโครงสร้างคำขอของพรอมต์ "เมืองที่อยู่เหนือสุดในสหรัฐอเมริกาคือเมืองอะไร
วันนี้อากาศที่นั่นเป็นยังไงบ้าง" โดยจะรวมเครื่องมือ 3 อย่าง ได้แก่ เครื่องมือ Gemini ในตัว google_search
และ code_execution รวมถึงฟังก์ชันที่กำหนดเอง get_weather
{
"model": "models/gemini-3-flash-preview",
"contents": [{
"parts": [{
"text": "What is the northernmost city in the United States? What's the weather like there today?"
}],
"role": "user"
}, {
"parts": [{
"thoughtSignature": "...",
"toolCall": {
"toolType": "GOOGLE_SEARCH_WEB",
"args": {
"queries": ["northernmost city in the United States"]
},
"id": "a7b3k9p2"
}
}, {
"thoughtSignature": "...",
"toolResponse": {
"toolType": "GOOGLE_SEARCH_WEB",
"response": {
"search_suggestions": "..."
},
"id": "a7b3k9p2"
}
}, {
"functionCall": {
"name": "getWeather",
"args": {
"city": "Utqiaġvik, Alaska"
},
"id": "m4q8z1v6"
},
"thoughtSignature": "..."
}],
"role": "model"
}, {
"parts": [{
"functionResponse": {
"name": "getWeather",
"response": {
"response": "Very cold. 22 degrees Fahrenheit."
},
"id": "m4q8z1v6"
}
}],
"role": "user"
}],
"tools": [{
"functionDeclarations": [{
"name": "getWeather"
}]
}, {
"googleSearch": {
}
}, {
"codeExecution": {
}
}],
"toolConfig": {
"includeServerSideToolInvocations": true
}
}
โทเค็นและการกำหนดราคา
โปรดทราบว่าส่วน toolCall และ toolResponse ในคำขอจะนับรวมใน prompt_token_count เนื่องจากตอนนี้คุณสามารถเห็นขั้นตอนเครื่องมือระดับกลางเหล่านี้และระบบจะส่งคืนให้คุณ ขั้นตอนเหล่านี้จึงเป็นส่วนหนึ่งของประวัติการสนทนา ซึ่งจะเกิดขึ้นกับคำขอเท่านั้น ไม่ใช่การตอบกลับ
เครื่องมือ Google Search เป็นข้อยกเว้นของกฎนี้ Google Search ใช้โมเดลการกำหนดราคาของตัวเองที่ระดับคำค้นหาอยู่แล้ว จึงไม่มีการเรียกเก็บเงินจากโทเค็นซ้ำ (ดูหน้าการกำหนดราคา)
อ่านข้อมูลเพิ่มเติมได้ที่หน้าโทเค็น
ข้อจำกัด
- ค่าเริ่มต้นจะเป็นโหมด
VALIDATED(ไม่รองรับโหมดAUTO) เมื่อเปิดใช้ฟีเจอร์include_server_side_tool_invocations - เครื่องมือในตัว เช่น
google_searchจะอิงตามข้อมูลตำแหน่งและเวลาปัจจุบัน ดังนั้นหากsystem_instructionหรือfunction_declaration.descriptionมีข้อมูลตำแหน่งและเวลา ที่ขัดแย้งกัน ฟีเจอร์การรวมเครื่องมืออาจทำงานได้ไม่ดี
เครื่องมือที่รองรับ
การหมุนเวียนบริบทของเครื่องมือมาตรฐานจะใช้กับเครื่องมือฝั่งเซิร์ฟเวอร์ (ในตัว) การดำเนินการโค้ดเป็นเครื่องมือฝั่งเซิร์ฟเวอร์เช่นกัน แต่มีโซลูชันในตัวของตัวเองสำหรับ การหมุนเวียนบริบท การใช้คอมพิวเตอร์และการเรียกใช้ฟังก์ชันเป็นเครื่องมือฝั่งไคลเอ็นต์ และยังมีโซลูชันในตัวสำหรับการหมุนเวียนบริบทด้วย
| เครื่องมือ | ฝั่งที่ดำเนินการ | การสนับสนุนการหมุนเวียนบริบท |
|---|---|---|
| Google Search | ฝั่งเซิร์ฟเวอร์ | รองรับ |
| Google Maps | ฝั่งเซิร์ฟเวอร์ | รองรับ |
| บริบท URL | ฝั่งเซิร์ฟเวอร์ | รองรับ |
| การค้นหาไฟล์ | ฝั่งเซิร์ฟเวอร์ | รองรับ |
| การรันโค้ด | ฝั่งเซิร์ฟเวอร์ | รองรับ (ติดตั้งในตัว ใช้ชิ้นส่วน executableCode และ codeExecutionResult) |
| การใช้คอมพิวเตอร์ | ฝั่งไคลเอ็นต์ | รองรับ (ติดตั้งในตัว ใช้ชิ้นส่วน functionCall และ functionResponse) |
| ฟังก์ชันที่กำหนดเอง | ฝั่งไคลเอ็นต์ | รองรับ (ติดตั้งในตัว ใช้ชิ้นส่วน functionCall และ functionResponse) |
ขั้นตอนถัดไป
- ดูข้อมูลเพิ่มเติมเกี่ยวกับการเรียกฟังก์ชันใน Gemini API
- สำรวจเครื่องมือที่รองรับ