Google Search로 Grounding
Google Search로 Grounding
Google Search로 Grounding(Grounding with Google Search)은 Gemini 모델을 실시간 웹 콘텐츠에 연결하며 모든 지원 언어에서 동작해요. 이를 통해 Gemini는 지식 컷오프를 넘어선 주제에서도 더 정확한 답변을 제공하고 검증 가능한 출처를 인용할 수 있어요.
Grounding은 다음을 할 수 있는 애플리케이션을 구축하는 데 도움을 줘요:
- 사실 정확도 향상: 실제 세계 정보를 바탕으로 응답해 모델 환각(hallucination)을 줄여요.
- 실시간 정보 접근: 최근 사건과 주제에 대한 질문에 답해요.
- 인용 제공: 모델 주장의 출처를 보여줘 사용자 신뢰를 구축해요.
출처: 원문
본문
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Who won the euro 2024?",
tools=[{"type": "google_search"}]
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: "gemini-3.8-flash",
input: "Who won the euro 2024?",
tools: [{ type: "google_search" }]
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
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;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Who won the euro 2024?"))
.tools(Arrays.asList(GoogleSearch.builder().build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Go
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)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Who won the euro 2024?"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.GoogleSearch{}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Interaction.GetOutputText())
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: *** \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Who won the euro 2024?",
"tools": [{"type": "google_search"}]
}'
Google Search Grounding의 동작 방식
google_search 도구를 활성화하면 모델이 검색, 처리, 인용의 전체 워크플로를 자동으로 처리해요.
- 사용자 프롬프트: 애플리케이션이
google_search도구를 활성화한 채 사용자 프롬프트를 Gemini API에 보내요. - 프롬프트 분석: 모델이 프롬프트를 분석하고 Google 검색이 답변을 개선할 수 있는지 판단해요.
- Google 검색: 필요하면 모델이 하나 또는 여러 검색 쿼리를 자동 생성하고 실행해요.
- 검색 결과 처리: 모델이 검색 결과를 처리하고 정보를 종합해 응답을 구성해요.
- Grounded 응답: API가 검색 결과에 근거한 최종 사용자 친화적 응답을 반환해요. 이 응답에는 인용이 담긴 인라인
annotations가 있는 모델의 텍스트 답변과, 검색 쿼리와 검색 제안이 담긴google_search_call,google_search_result단계가 포함돼요.
Grounding 응답 이해하기
응답이 성공적으로 grounding되면 모델의 텍스트 출력에는 텍스트 콘텐츠 블록에 직접 인라인 annotations가 포함돼요. 이러한 주석은 응답의 일부를 출처에 연결하는 인용 정보를 제공해요.
{
"steps": [
{
"type": "thought",
"summary": [
{
"type": "text",
"text": "The user is asking for the winner of Euro 2024. I need to search for the result of the Euro 2024 final."
}
],
"signature": "CoMDAXLI2nynRYojJIy6B1Jh9os2crpWLfB0..."
},
{
"type": "google_search_call",
"arguments": {
"queries": ["UEFA Euro 2024 winner"]
}
},
{
"type": "google_search_result",
"call_id": "search_001",
"result": [
{
"search_suggestions": "<!-- HTML and CSS for the search widget -->"
}
]
},
{
"type": "model_output",
"content": [
{
"type": "text",
"text": "Spain won Euro 2024, defeating England 2-1 in the final. This victory marks Spain's record fourth European Championship title.",
"annotations": [
{
"type": "url_citation",
"url": "https://www.aljazeera.com/sports/euro-2024-final",
"title": "aljazeera.com",
"start_index": 0,
"end_index": 56
},
{
"type": "url_citation",
"url": "https://www.uefa.com/euro2024/news/spain-wins-euro-2024",
"title": "uefa.com",
"start_index": 57,
"end_index": 124
}
]
}
]
}
]
}
응답의 핵심 필드:
google_search_call: 모델이 실행한 검색queries를 포함해요.google_search_result: UI에서 검색 제안을 렌더링하기 위한 HTML 스니펫인search_suggestions를 포함해요. 전체 사용 요건은 서비스 약관에 설명되어 있어요.annotations가 있는text: 인라인 인용이 포함된 모델의 종합 답변이에요. 각url_citation주석은 텍스트 세그먼트(start_index와end_index로 정의)를 소스 URL에 연결해요. 이것이 인라인 인용을 구축하는 핵심이에요.
Google Search로 Grounding은 URL context 도구와 함께 사용해 공개 웹 데이터와 사용자가 제공한 특정 URL 모두에서 응답을 grounding할 수도 있어요.
인라인 인용으로 출처 표시
API는 텍스트 콘텐츠 블록에 인라인 url_citation 주석을 반환해서 사용자 인터페이스에서 출처를 표시하는 방법을 완전히 제어할 수 있게 해줘요. 각 주석에는 인용하는 텍스트 부분을 식별하는 start_index와 end_index가 포함돼요. 추출하고 표시하는 방법은 다음과 같아요.
Python
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if content_block.type == "text":
print(content_block.text)
if content_block.annotations:
print("\nCitations:")
for annotation in content_block.annotations:
if annotation.type == "url_citation":
cited_text = content_block.text[annotation.start_index:annotation.end_index]
print(f" [{annotation.title}]({annotation.url})")
print(f" Cited text: \"{cited_text}\"")
JavaScript
for (const step of interaction.steps) {
if (step.type === 'model_output') {
for (const contentBlock of step.content) {
if (contentBlock.type === 'text') {
console.log(contentBlock.text);
if (contentBlock.annotations) {
console.log("\nCitations:");
for (const annotation of contentBlock.annotations) {
if (annotation.type === 'url_citation') {
const citedText = contentBlock.text.slice(annotation.startIndex, annotation.endIndex);
console.log(` [${annotation.title}](${annotation.url})`);
console.log(` Cited text: "${citedText}"`);
}
}
}
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
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.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.interactions.URLCitation;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
Client client = new Client();
CreateModelInteraction params =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Who won the euro 2024?"))
.tools(Arrays.asList(GoogleSearch.builder().build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
if (interaction.steps().isPresent()) {
for (Step step : interaction.steps().get()) {
if (step instanceof ModelOutputStep) {
ModelOutputStep outputStep = (ModelOutputStep) step;
if (outputStep.content().isPresent()) {
for (Content contentBlock : outputStep.content().get()) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
String text = textContent.text().orElse("");
System.out.println(text);
if (textContent.annotations().isPresent()
&& !textContent.annotations().get().isEmpty()) {
System.out.println("\nCitations:");
for (Annotation annotation : textContent.annotations().get()) {
if (annotation instanceof URLCitation) {
URLCitation citation = (URLCitation) annotation;
int start = citation.startIndex().orElse(0);
int end = citation.endIndex().orElse(0);
String citedText =
(start >= 0 && end <= text.length() && start <= end)
? text.substring(start, end)
: "";
System.out.printf(
" [%s](%s)%n", citation.title().orElse(""), citation.url().orElse(""));
System.out.printf(" Cited text: \"%s\"%n", citedText);
}
}
}
}
}
}
}
}
}
Go
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)
}
resp, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(
interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Who won the euro 2024?"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.GoogleSearch{}),
},
},
),
})
if err != nil {
log.Fatal(err)
}
for _, step := range resp.Interaction.Steps {
if step.ModelOutputStep != nil {
for _, content := range step.ModelOutputStep.Content {
if content.TextContent != nil {
text := content.TextContent.Text
fmt.Println(text)
if len(content.TextContent.Annotations) > 0 {
fmt.Println("\nCitations:")
for _, annotation := range content.TextContent.Annotations {
if annotation.URLCitation != nil {
c := annotation.URLCitation
start := 0
if c.StartIndex != nil {
start = *c.StartIndex
}
end := 0
if c.EndIndex != nil {
end = *c.EndIndex
}
citedText := ""
if start >= 0 && end <= len(text) && start <= end {
citedText = text[start:end]
}
title := ""
if c.Title != nil {
title = *c.Title
}
url := ""
if c.URL != nil {
url = *c.URL
}
fmt.Printf(" [%s](%s)\n", title, url)
fmt.Printf(" Cited text: %q\n", citedText)
}
}
}
}
}
}
}
}
출력은 텍스트 다음에 인용을 보여줘요:
Spain won Euro 2024, defeating England 2-1 in the final. This victory marks Spain's record fourth European Championship title.
Citations:
[aljazeera.com](https://www.aljazeera.com/sports/euro-2024-final)
Cited text: "Spain won Euro 2024, defeating England 2-1 in the final."
[uefa.com](https://www.uefa.com/euro2024/news/spain-wins-euro-2024)
Cited text: "This victory marks Spain's record fourth European Championship title."
가격(Pricing)
Gemini 3와 함께 Google Search Grounding을 사용할 때, 프로젝트는 모델이 실행하기로 결정한 각 검색 쿼리에 대해 청구돼요. 모델이 단일 프롬프트에 답하기 위해 여러 검색 쿼리를 실행하기로 결정하면(예: 같은 API 호출에서 "UEFA Euro 2024 winner"와 "Spain vs England Euro 2024 final score"를 검색), 해당 요청의 도구 사용이 두 번 청구되는 것으로 계산돼요. 청구 목적상 고유 쿼리를 셀 때 빈 웹 검색 쿼리는 무시해요. 이 청구 모델은 Gemini 3 모델에만 적용돼요. Gemini 2.5 또는 이전 모델로 검색 grounding을 사용하면 프로젝트가 프롬프트당 청구돼요.
자세한 가격 정보는 Gemini API 가격 페이지를 참고하세요.
지원 모델
전체 기능은 모델 개요 페이지에서 확인할 수 있어요.
| 모델 | Google Search Grounding |
|---|---|
| Gemini 3.8 Flash | ✔️ |
| Gemini 3.7 Flash | ✔️ |
| Gemini 3.6 Flash | ✔️ |
| Gemini 3.5 Flash-Lite | ✔️ |
| Gemini 3.5 Flash | ✔️ |
| Gemini 3.1 Flash Image Preview | ✔️ |
| Gemini 3.1 Pro Preview | ✔️ |
| Gemini 3 Pro Image Preview | ✔️ |
| Gemini 3 Flash Preview | ✔️ |
| Gemini 2.5 Pro | ✔️ |
| Gemini 2.5 Flash | ✔️ |
| Gemini 2.5 Flash-Lite | ✔️ |
| Gemini 2.0 Flash | ✔️ |
참고: 이전 모델은 google_search_retrieval 도구를 사용해요. 모든 현재 모델에는 예시와 같이 google_search 도구를 사용하세요.
지원 도구 조합
Google Search Grounding은 코드 실행, URL context, Google Maps Grounding(Gemini 3.5 Flash 이후 모델에서 지원) 같은 다른 도구와 함께 사용해 더 복잡한 사용 사례를 구현할 수 있어요. Gemini 3 모델은 이러한 내장 도구를 커스텀 도구(함수 호출)와 결합하는 것도 지원해요. 도구 조합 페이지에서 자세히 알아보세요.
더 알아보기 (Learn more)
- 함수 호출 같은 다른 도구 알아보기
- URL context 도구로 특정 URL로 프롬프트 보강하는 방법 알아보기