URL 컨텍스트

URL 컨텍스트 (URL context)

URL 컨텍스트 도구는 URL 형태로 모델에 추가 컨텍스트를 제공해요. 요청에 URL을 포함하면, 모델이 해당 페이지의 콘텐츠에 접근해 응답을 풍부하게 해줘요.

출처: 원문

본문

URL 컨텍스트 도구는 URL 형태로 모델에 추가 컨텍스트를 제공해요. 요청에 URL을 포함하면 모델이 제한 사항에 나열된 유형이 아니라면 해당 페이지의 콘텐츠에 접근해서 응답을 알리고 향상시켜요.

URL 컨텍스트 도구는 다음과 같은 작업에 유용해요:

  • 데이터 추출: 여러 URL에서 가격, 이름, 핵심 발견 같은 특정 정보를 뽑아내기.
  • 문서 비교: 여러 보고서, 기사, PDF를 분석해 차이를 식별하고 추세를 추적하기.
  • 종합·콘텐츠 생성: 여러 출처 URL의 정보를 결합해 정확한 요약, 블로그 포스트, 보고서 생성하기.
  • 코드·문서 분석: GitHub 저장소나 기술 문서를 가리켜 코드를 설명하거나, 설정 지침을 생성하거나, 질문에 답하기.

다음 예시는 서로 다른 웹사이트의 두 레시피를 비교하는 방법을 보여줘요.

Python

# This will only work for SDK newer than 2.0.0
from google import genai

client = genai.Client()

url1 = "https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592"
url2 = "https://www.allrecipes.com/recipe/21151/simple-whole-roast-chicken/"

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=f"Compare the ingredients and cooking times from the recipes at {url1} and {url2}",
    tools=[{"type": "url_context"}]
)

# Print the model's text response and its source annotations
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("\nSources:")
                    for annotation in content_block.annotations:
                        if annotation.type == "url_citation":
                            print(f"  - {annotation.title}: {annotation.url}")

JavaScript

// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});

async function main() {
  const interaction = await client.interactions.create({
    model: "gemini-3.8-flash",
    input: "Compare the ingredients and cooking times from the recipes at https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592 and https://www.allrecipes.com/recipe/21151/simple-whole-roast-chicken/",
    tools: [{ type: "url_context" }]
  });

  // Print the model's text response and its source annotations
  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("\nSources:");
            for (const annotation of contentBlock.annotations) {
              if (annotation.type === 'url_citation') {
                console.log(`  - ${annotation.title}: ${annotation.url}`);
              }
            }
          }
        }
      }
    }
  }
}

await main();

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)
    }

    url1 := "https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592"
    url2 := "https://www.allrecipes.com/recipe/21151/simple-whole-roast-chicken/"

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput(
                fmt.Sprintf("Compare the ingredients and cooking times from the recipes at %s and %s", url1, url2),
            ),
            Tools: []interactions.Tool{
                interactions.NewTool(interactions.URLContext{}),
            },
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Print the model's text response and its source annotations
    for _, step := range res.Interaction.Steps {
        if step.ModelOutputStep != nil {
            for _, contentBlock := range step.ModelOutputStep.Content {
                if contentBlock.TextContent != nil {
                    fmt.Println(contentBlock.TextContent.Text)
                    if len(contentBlock.TextContent.Annotations) > 0 {
                        fmt.Println("\nSources:")
                        for _, annotation := range contentBlock.TextContent.Annotations {
                            if annotation.URLCitation != nil {
                                fmt.Printf("  - %s: %s\n", annotation.URLCitation.GetTitle(), annotation.URLCitation.GetURL())
                            }
                        }
                    }
                }
            }
        }
    }
}

REST

# Specifies the API revision to avoid breaking changes when they become default
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": "Compare the ingredients and cooking times from the recipes at https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592 and https://www.allrecipes.com/recipe/21151/simple-whole-roast-chicken/",
      "tools": [{"type": "url_context"}]
  }'

동작 방식

URL 컨텍스트 도구는 속도·비용·신선한 데이터 접근의 균형을 맞추기 위해 두 단계 검색 프로세스를 사용해요. URL을 제공하면 도구가 먼저 내부 인덱스 캐시에서 콘텐츠를 가져오려고 해요. 이것은 고도로 최적화된 캐시 역할을 해요. URL이 인덱스에 없으면(예: 아주 새로운 페이지), 도구가 자동으로 라이브 페치로 폴백해 실시간으로 콘텐츠를 가져와요.

다른 도구와 결합

URL 컨텍스트 도구를 다른 도구와 결합해 더 강력한 워크플로를 만들 수 있어요.

Gemini 3 모델은 내장 도구(URL 컨텍스트 등)와 커스텀 도구(함수 호출)의 결합을 지원해요. 자세한 내용은 도구 결합 페이지를 참고하세요.

검색 접지와 함께 사용

URL 컨텍스트와 Google 검색 접지를 모두 활성화하면, 모델이 검색 기능으로 온라인에서 관련 정보를 찾은 뒤 URL 컨텍스트 도구로 찾은 페이지를 더 깊이 이해할 수 있어요. 이 접근법은 광범위한 검색과 특정 페이지의 심층 분석이 모두 필요한 프롬프트에 강력해요.

Python

# This will only work for SDK newer than 2.0.0
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Give me three day events schedule based on YOUR_URL. Also let me know what needs to taken care of considering weather and commute.",
    tools=[
        {"type": "url_context"},
        {"type": "google_search"}
    ]
)

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)

JavaScript

// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});

async function main() {
  const interaction = await client.interactions.create({
    model: "gemini-3.8-flash",
    input: "Give me three day events schedule based on YOUR_URL. Also let me know what needs to taken care of considering weather and commute.",
    tools: [
      { type: "url_context" },
      { type: "google_search" }
    ]
  });

  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);
      }
    }
  }
}

await main();

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)
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput("Give me three day events schedule based on YOUR_URL. Also let me know what needs to taken care of considering weather and commute."),
            Tools: []interactions.Tool{
                interactions.NewTool(interactions.URLContext{}),
                interactions.NewTool(interactions.GoogleSearch{}),
            },
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, step := range res.Interaction.Steps {
        if step.ModelOutputStep != nil {
            for _, contentBlock := range step.ModelOutputStep.Content {
                if contentBlock.TextContent != nil {
                    fmt.Println(contentBlock.TextContent.Text)
                }
            }
        }
    }
}

REST

# Specifies the API revision to avoid breaking changes when they become default
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": "Give me three day events schedule based on YOUR_URL. Also let me know what needs to taken care of considering weather and commute.",
      "tools": [
          {"type": "url_context"},
          {"type": "google_search"}
      ]
  }'

응답 이해하기

모델이 URL 컨텍스트 도구를 사용하면 텍스트 응답에 텍스트 콘텐츠 블록에 인라인 url_citation 주석이 포함돼요. 각 주석은 응답 텍스트의 일부 세그먼트를(start_index와 end_index를 통해) 파생된 출처 URL에 연결해요. 이것이 애플리케이션에서 인용을 표시하는 주요 방법이에요 — 추출 방법은 위의 메인 예시를 참고하세요.

응답에는 각 URL 검색 시도에 대한 메타데이터(상태, 검색된 URL)가 있는 url_context_result 단계도 포함돼요. 주로 디버깅에 유용해요.

안전 검사

시스템은 URL이 안전 기준을 충족하는지 콘텐츠 검열을 수행해요. URL이 이 검사에 실패하면 해당 url_context_result 단계의 status가 "unsafe"로 표시돼요.

토큰 수

프롬프트에 지정한 URL에서 검색한 콘텐츠는 입력 토큰의 일부로 계산돼요. 토큰 수는 인터랙션의 usage 객체에서 확인할 수 있어요. 예시:

'usage': {
  'output_tokens': 45,
  'input_tokens': 27,
  'input_tokens_details': [{'modality': 'TEXT', 'token_count': 27}],
  'thoughts_tokens': 31,
  'tool_use_input_tokens': 10309,
  'tool_use_input_tokens_details': [{'modality': 'TEXT', 'token_count': 10309}],
  'total_tokens': 10412
}

토큰당 가격은 사용하는 모델에 따라 달라지며, 자세한 내용은 가격 페이지를 참고하세요.

지원 모델

모델 URL 컨텍스트
Gemini 3.8 Flash ✔️
Gemini 3.7 Flash ✔️
Gemini 3.6 Flash ✔️
Gemini 3.5 Flash-Lite ✔️
Gemini 3.5 Flash ✔️
Gemini 3.1 Pro Preview ✔️
Gemini 3.1 Flash-Lite ✔️
Gemini 3 Flash Preview ✔️
Gemini 2.5 Pro ✔️
Gemini 2.5 Flash ✔️
Gemini 2.5 Flash-Lite ✔️

모범 사례

  • 구체적인 URL 제공: 최상의 결과를 위해 모델이 분석할 콘텐츠의 직접 URL을 제공하세요. 모델은 제공한 URL의 콘텐츠만 검색하며, 중첩 링크의 콘텐츠는 검색하지 않아요.
  • 접근성 확인: 제공하는 URL이 로그인이 필요하거나 페이월 뒤에 있는 페이지가 아닌지 확인하세요.
  • 전체 URL 사용: 프로토콜을 포함한 전체 URL을 제공하세요 (예: google.com 대신 https://www.google.com).

제한 사항

  • 요청 한도: 도구는 요청당 최대 20개 URL을 처리할 수 있어요.
  • URL 콘텐츠 크기: 단일 URL에서 검색한 콘텐츠의 최대 크기는 34MB예요.
  • 공개 접근성: URL은 웹에서 공개적으로 접근 가능해야 해요. 로컬호스트 주소(예: localhost, 127.0.0.1), 사설 네트워크, 터널링 서비스(예: ngrok, pinggy)는 지원되지 않아요.

지원·미지원 콘텐츠 유형

도구는 다음 콘텐츠 유형의 URL에서 콘텐츠를 추출할 수 있어요:

  • 텍스트 (text/html, application/json, text/plain, text/xml, text/css, text/javascript, text/csv, text/rtf)
  • 이미지 (image/png, image/jpeg, image/bmp, image/webp)
  • PDF (application/pdf)

다음 콘텐츠 유형은 지원되지 않아요:

  • 페이월 콘텐츠
  • YouTube 비디오 (YouTube URL 처리 방법은 비디오 이해 참고)
  • Google 문서, 스프레드시트 같은 Google 워크스페이스 파일
  • 비디오와 오디오 파일

더 알아보기 (Learn more)