내장 도구와 함수 호출 결합하기
내장 도구와 함수 호출 결합하기
Preview: 내장 도구·커스텀 도구 조합은 Preview 단계이며 Gemini 3 모델에서만 지원돼요.
Gemini는 도구 호출의 컨텍스트 이력을 보존·노출함으로써 google_search 같은 내장 도구와 함수 호출(또는 커스텀 도구)을 단일 상호작용에서 결합할 수 있게 해 줘요. 내장·커스텀 도구 조합은 예를 들어 모델이 특정 비즈니스 로직을 호출하기 전에 실시간 웹 데이터에 근거를 둘 수 있는 복잡한 에이전트 워크플로를 가능하게 해요.
google_search와 커스텀 함수 getWeather로 내장·커스텀 도구 조합을 활성화하는 예제는 다음과 같아요.
# This will only work for SDK newer than 2.0.0
from google import genai
client = genai.Client()
getWeather = {
"type": "function",
"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"],
},
}
# The Interactions API manages context automatically across tool calls.
# The model will first use Google Search, then call getWeather.
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="What is the northernmost city in the United States? What's the weather like there today?",
tools=[
{"type": "google_search"},
getWeather,
],
)
# Process steps: the interaction contains search results and a function call
for step in interaction.steps:
if step.type == "function_call":
print(f"Function call: {step.name} with args: {step.arguments}")
# In a real application, you would execute the function here
# and provide the result back to the model.
// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const getWeather = {
type: "function",
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"]
}
};
// The Interactions API manages context automatically across tool calls.
// The model will first use Google Search, then call getWeather.
const interaction = await client.interactions.create({
model: "gemini-3.8-flash",
input: "What is the northernmost city in the United States? What's the weather like there today?",
tools: [
{ type: "google_search" },
getWeather,
],
});
// Process steps: the interaction contains search results and a function call
for (const step of interaction.steps) {
if (step.type === "function_call") {
console.log(`Function call: ${step.name} with args: ${JSON.stringify(step.arguments)}`);
// In a real application, you would execute the function here
// and provide the result back to the model.
}
}
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Function;
import com.google.genai.gaos.models.interactions.GoogleSearch;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Client client = new Client();
Map<String, Object> parameters = new HashMap<>();
parameters.put("type", "object");
Function customFunc =
Function.builder()
.name("get_user_location")
.description("Retrieves user current location.")
.parameters(parameters)
.build();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("What is the weather like where I am right now?"))
.tools(Arrays.asList(customFunc, new GoogleSearch()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
customFunc := interactions.NewTool(interactions.Function{
Name: genai.Ptr("get_user_location"),
Description: genai.Ptr("Retrieves user current location."),
Parameters: map[string]any{
"type": "object",
},
})
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("What is the weather like where I am right now?"),
Tools: []interactions.Tool{
customFunc,
interactions.NewTool(interactions.GoogleSearch{}),
},
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputText != nil {
fmt.Println(*res.Interaction.OutputText)
}
}
# Specifies the API revision to avoid breaking changes when they become default
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: YOUR_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "What is the northernmost city in the United States? What'\''s the weather like there today?",
"tools": [
{ "type": "google_search" },
{
"type": "function",
"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"]
}
}
]
}'
출처: 원문
본문
작동 방식
Gemini 3 모델은 내장·커스텀 도구 조합을 가능하게 하는 도구 컨텍스트 순환(tool context circulation)을 사용해요. 도구 컨텍스트 순환을 통해 내장 도구의 컨텍스트를 보존·노출하고 같은 상호작용 안의 커스텀 도구와 공유할 수 있어요.
도구 조합 활성화
- 사용하려는 내장 도구와 함께 function_declarations를 포함해 조합 동작을 트리거하세요.
API가 steps를 반환
상호작용 응답에서 API는 내장 도구 호출과 함수(커스텀 도구) 호출에 대해 별도의 steps를 반환해요.
- 내장 도구 steps: API가 이를 자동으로 관리하며 턴 간 컨텍스트를 보존해요.
- 함수 호출 steps: API는 커스텀 함수에 대해
function_callsteps를 반환해요. 함수를 실행하고 결과를 다시 제공해요.
반환된 steps의 중요 필드
반환된 steps의 특정 필드는 도구 컨텍스트 유지와 도구 조합 활성화에 중요해요.
- id:
function_call와function_responsesteps에 있음. 호출을 응답에 매핑하는 고유 식별자. - signature:
thoughtsteps와, Gemini 3+ 모델의 모든 도구 호출(예:function_call)·결과(예:function_response) steps에 있음. 이 암호화된 컨텍스트가 상호작용 간 도구 컨텍스트 순환을 가능하게 해요.
이 필드들 관리하기:
- 상태 저장 모드(권장):
previous_interaction_id를 사용하면 서버가id와signature필드를 모두 자동 처리해요. - 무상태 모드: 대화 이력을 수동 관리할 때는 이후 요청에서
id와signature필드를 모두 모델에 다시 전달해 진위를 검증하고 컨텍스트를 유지해야 해요. 공식 SDK는 전체 응답 객체를 이력에 전달하면 이를 자동 처리해요.
도구별 데이터
일부 내장 도구는 도구 유형 특유의 사용자 가시 데이터 인자를 반환해요.
| 도구 | 사용자 가시 도구 호출 인자(있는 경우) | 사용자 가시 도구 응답(있는 경우) |
|---|---|---|
| google_search | queries |
search_suggestions |
| google_maps | queries |
places google_maps_widget_context_token |
| url_context | urls 탐색할 URL |
status: 탐색 상태 retrieved_url: 탐색된 URL |
| file_search | 없음 | 없음 |
토큰과 가격
요청의 내장 도구 호출 파트는 prompt_token_count에 계산돼요. 이 중간 도구 steps가 이제 보이고 반환되므로 대화 이력의 일부가 돼요. 이는 응답이 아닌 요청에만 해당돼요.
Google Search 도구는 이 규칙의 예외예요. Google Search는 이미 쿼리 수준에서 자체 가격 모델을 적용하므로 토큰이 이중 청구되지 않아요(Pricing 페이지 참고).
자세한 내용은 Tokens 페이지를 읽어보세요.
한계
- 도구 컨텍스트 순환이 활성화되면 기본적으로
validated모드를 사용해요(auto모드는 지원되지 않아요). google_search같은 내장 도구는 위치·현재 시간 정보에 의존하므로system_instruction이나function_declaration.description에 이와 충돌하는 위치·시간 정보가 있으면 도구 조합 기능이 잘 작동하지 않을 수 있어요.
지원 도구
표준 도구 컨텍스트 순환은 서버 측(내장) 도구에 적용돼요. Code Execution도 서버 측 도구지만 컨텍스트 순환에 대한 자체 내장 솔루션이 있어요. Computer Use와 함수 호출은 클라이언트 측 도구이며 역시 컨텍스트 순환에 대한 내장 솔루션이 있어요.
| 도구 | 실행 측 | 컨텍스트 순환 지원 |
|---|---|---|
| Google Search | 서버 측 | 지원 |
| Google Maps | 서버 측 | 지원 |
| URL Context | 서버 측 | 지원 |
| File Search | 서버 측 | 지원 |
| Code Execution | 서버 측 | 지원(내장, code_execution·code_execution_result steps 사용) |
| Computer Use | 클라이언트 측 | 지원(내장, function_call·function_response steps 사용) |
| 커스텀 함수 | 클라이언트 측 | 지원(내장, function_call·function_response steps 사용) |
다음 단계
- Gemini API의 Function calling에 대해 더 알아보세요.
- 지원 도구 탐색: Google Search, Google Maps, URL Context, File Search