Google GenAI

Google GenAI

google-genai Python SDK를 LlamaIndex와 함께 사용해서 Google GenAI 모델과 상호작용하는 방법을 보여 주는 가이드예요. 기본 사용법부터 스트리밍, 비동기, Vertex AI, 캐시, 멀티모달, 구조화 예측, 도구 호출까지 폭넓게 다룹니다.

출처: 문서

본문

colab에서 이 노트북을 열었다면 LlamaIndex 🦙와 google-genai Python SDK를 설치해야 해요.

%pip install llama-index-llms-google-genai llama-index

기본 사용법 (Basic Usage)

Google AI Studio에서 API 키를 받아야 해요. 키를 얻으면 모델에 직접 전달하거나 GOOGLE_API_KEY 환경 변수를 사용할 수 있어요.

import os


os.environ["GOOGLE_API_KEY"] = "..."

프롬프트로 complete를 호출할 수 있어요.

from llama_index.llms.google_genai import GoogleGenAI


llm = GoogleGenAI(
    model="gemini-2.5-flash",
    # api_key="some key",  # 기본적으로 GOOGLE_API_KEY 환경 변수 사용
)


resp = llm.complete("Who is Paul Graham?")
print(resp)
Paul Graham is a prominent figure in the tech world, best known for his work as a programmer, essayist, and venture capitalist. Here's a breakdown of his key contributions:

*   **Programmer and Hacker:** He's a skilled programmer, particularly in Lisp. He co-founded Viaweb, which was one of the first software-as-a-service (SaaS) companies, providing tools for building online stores. Yahoo acquired Viaweb in 1998, and it became Yahoo! Store.

*   **Essayist:** Graham is a prolific and influential essayist. His essays cover a wide range of topics, including startups, programming, design, and societal trends. His writing style is known for being clear, concise, and thought-provoking. Many of his essays are considered essential reading for entrepreneurs and those interested in technology.

*   **Venture Capitalist and Founder of Y Combinator:** Perhaps his most significant contribution is co-founding Y Combinator (YC) in 2005. YC is a highly successful startup accelerator that provides seed funding, mentorship, and networking opportunities to early-stage startups. YC has funded many well-known companies, including Airbnb, Dropbox, Reddit, Stripe, and many others. Graham stepped down from his day-to-day role at YC in 2014 but remains involved.

In summary, Paul Graham is a multifaceted individual who has made significant contributions to the tech industry as a programmer, essayist, and venture capitalist. He is particularly known for his role in founding and shaping Y Combinator, one of the world's leading startup accelerators.

채팅 메시지 목록으로 chat도 호출할 수 있어요.

from llama_index.core.llms import ChatMessage
from llama_index.llms.google_genai import GoogleGenAI


messages = [
    ChatMessage(
        role="system", content="You are a pirate with a colorful personality"
    ),
    ChatMessage(role="user", content="Tell me a story"),
]
llm = GoogleGenAI(model="gemini-2.5-flash")
resp = llm.chat(messages)


print(resp)
assistant: Ahoy there, matey! Gather 'round, ye landlubbers, and listen to a tale that'll shiver yer timbers and curl yer toes! This be the story of One-Eyed Jack's Lost Parrot and the Great Mango Mayhem!

Now, One-Eyed Jack, bless his barnacle-encrusted heart, was a fearsome pirate, alright. He could bellow louder than a hurricane, swing a cutlass like a dervish, and drink rum like a fish. But he had a soft spot, see? A soft spot for his parrot, Polly. Polly wasn't just any parrot, mind ye. She could mimic the captain's every cuss word, predict the weather by the way she ruffled her feathers, and had a particular fondness for shiny trinkets.

One day, we were anchored off the coast of Mango Island, a lush paradise overflowing with the juiciest, sweetest mangoes ye ever did see. Jack, bless his greedy soul, decided we needed a cargo hold full of 'em. "For scurvy prevention!" he declared, winking with his good eye. More like for his own personal mango-eating contest, if ye ask me.

We stormed ashore, cutlasses gleaming, ready to plunder the mango groves. But Polly, the little feathered devil, decided she'd had enough of the ship. She squawked, "Shiny! Shiny!" and took off like a green streak towards the heart of the island.

Jack went ballistic! "Polly! Polly, ye feathered fiend! Get back here!" He chased after her, bellowing like a lovesick walrus. The rest of us, well, we were left to pick mangoes and try not to laugh ourselves silly.

Now, Mango Island wasn't just full of mangoes. It was also home to a tribe of mischievous monkeys, the Mango Marauders, they were called. They were notorious for their love of pranks and their uncanny ability to steal anything that wasn't nailed down.

Turns out, Polly had landed right in the middle of their territory. And those monkeys, they took one look at her shiny feathers and decided she was the perfect addition to their collection of stolen treasures. They snatched her up, chattering and screeching, and whisked her away to their hidden lair, a giant mango tree hollowed out by time.

Jack, bless his stubborn heart, followed the sound of Polly's squawks. He hacked through vines, dodged falling mangoes, and even wrestled a particularly grumpy iguana, all in pursuit of his feathered friend.

Finally, he reached the mango tree. He peered inside and saw Polly, surrounded by a horde of monkeys, all admiring her shiny feathers. And Polly? She was having the time of her life, mimicking the monkeys' chattering and stealing their mangoes!

Jack, instead of getting angry, started to laugh. A hearty, booming laugh that shook the very foundations of the tree. The monkeys, startled, dropped their mangoes and stared at him.

Then, Polly, seeing her captain, squawked, "Rum! Rum for everyone!"

And that, me hearties, is how One-Eyed Jack ended up sharing a barrel of rum with a tribe of mango-loving monkeys. We spent the rest of the day feasting on mangoes, drinking rum, and listening to Polly mimic the monkeys' antics. We even managed to fill the cargo hold with mangoes, though I suspect a good portion of them were already half-eaten by the monkeys.

So, the moral of the story, me lads? Even the fiercest pirate has a soft spot, and sometimes, the best treasures are the ones you least expect. And always, ALWAYS, keep an eye on yer parrot! Now, who's for another round of grog?

스트리밍 지원 (Streaming Support)

모든 메서드는 stream_ 접두사로 스트리밍을 지원해요.

from llama_index.llms.google_genai import GoogleGenAI


llm = GoogleGenAI(model="gemini-2.5-flash")


resp = llm.stream_complete("Who is Paul Graham?")
for r in resp:
    print(r.delta, end="")
Paul Graham is a prominent figure in the tech world, best known for his work as a computer programmer, essayist, venture capitalist, and co-founder of the startup accelerator Y Combinator. Here's a breakdown of his key accomplishments and contributions:

*   **Computer Programmer and Author:** Graham holds a Ph.D. in computer science from Harvard University. He is known for his work on Lisp, a programming language, and for developing Viaweb, one of the first software-as-a-service (SaaS) companies, which was later acquired by Yahoo! and became Yahoo! Store. He's also the author of several influential books on programming and entrepreneurship, including "On Lisp," "ANSI Common Lisp," "Hackers & Painters," and "A Plan for Spam."

*   **Essayist:** Graham is a prolific essayist, writing on a wide range of topics including technology, startups, art, philosophy, and society. His essays are known for their insightful observations, clear writing style, and often contrarian viewpoints. They are widely read and discussed in the tech community. You can find his essays on his website, paulgraham.com.

*   **Venture Capitalist and Y Combinator:** Graham co-founded Y Combinator (YC) in 2005 with Jessica Livingston, Robert Morris, and Trevor Blackwell. YC is a highly successful startup accelerator that provides seed funding, mentorship, and networking opportunities to early-stage startups. YC has funded many well-known companies, including Airbnb, Dropbox, Reddit, Stripe, and many others. While he stepped down from day-to-day operations at YC in 2014, his influence on the organization and the startup ecosystem remains significant.

In summary, Paul Graham is a multifaceted individual who has made significant contributions to computer science, entrepreneurship, and the broader tech culture. He is highly regarded for his technical expertise, insightful writing, and his role in shaping the modern startup landscape.
from llama_index.core.llms import ChatMessage


messages = [
    ChatMessage(role="user", content="Who is Paul Graham?"),
]


resp = llm.stream_chat(messages)
for r in resp:
    print(r.delta, end="")
Paul Graham is a prominent figure in the tech world, best known for his work as a programmer, essayist, and venture capitalist. Here's a breakdown of his key contributions:

*   **Programmer and Hacker:** He is a skilled programmer, particularly in Lisp. He co-founded Viaweb, one of the first software-as-a-service (SaaS) companies, which was later acquired by Yahoo! and became Yahoo! Store.

*   **Essayist:** Graham is a prolific and influential essayist, writing on topics ranging from programming and startups to art, philosophy, and social commentary. His essays are known for their clarity, insight, and often contrarian viewpoints. They are widely read and discussed in the tech community.

*   **Venture Capitalist:** He co-founded Y Combinator (YC) in 2005, a highly successful startup accelerator. YC has funded and mentored numerous well-known companies, including Airbnb, Dropbox, Reddit, Stripe, and many others. Graham's approach to early-stage investing and startup mentorship has had a significant impact on the startup ecosystem.

In summary, Paul Graham is a multifaceted individual who has made significant contributions to the tech industry as a programmer, essayist, and venture capitalist. He is particularly influential in the startup world through his work with Y Combinator.

비동기 사용 (Async Usage)

모든 동기 메서드에는 비동기 대응 메서드가 있어요.

from llama_index.llms.google_genai import GoogleGenAI


llm = GoogleGenAI(model="gemini-2.5-flash")


resp = await llm.astream_complete("Who is Paul Graham?")
async for r in resp:
    print(r.delta, end="")
Paul Graham is a prominent figure in the tech world, best known for his work as a programmer, essayist, and venture capitalist. Here's a breakdown of his key accomplishments and roles:

*   **Programmer and Hacker:** He holds a Ph.D. in computer science from Harvard and is known for his work on Lisp, a programming language. He co-founded Viaweb, one of the first software-as-a-service (SaaS) companies, which was later acquired by Yahoo! and became Yahoo! Store.

*   **Essayist:** Graham is a prolific and influential essayist, writing on topics ranging from programming and startups to art, philosophy, and social commentary. His essays are widely read and discussed in the tech community.

*   **Venture Capitalist:** He co-founded Y Combinator (YC) in 2005, a highly successful startup accelerator that has funded companies like Airbnb, Dropbox, Reddit, Stripe, and many others. YC provides seed funding, mentorship, and networking opportunities to early-stage startups. While he stepped back from day-to-day operations at YC in 2014, he remains a significant figure in the venture capital world.

In summary, Paul Graham is a multifaceted individual who has made significant contributions to the fields of computer science, entrepreneurship, and venture capital. He is highly regarded for his insightful writing and his role in shaping the modern startup ecosystem.
messages = [
    ChatMessage(role="user", content="Who is Paul Graham?"),
]


resp = await llm.achat(messages)
print(resp)
assistant: Paul Graham is a prominent figure in the tech world, best known for his work as a programmer, essayist, and venture capitalist. Here's a breakdown of his key accomplishments and contributions:

*   **Programmer and Hacker:** He is a skilled programmer, particularly in Lisp. He co-founded Viaweb, one of the first software-as-a-service (SaaS) companies, which was later acquired by Yahoo! and became Yahoo! Store.

*   **Essayist:** Graham is a prolific and influential essayist, writing on topics ranging from programming and startups to art, design, and societal trends. His essays are known for their insightful observations, contrarian viewpoints, and clear writing style. Many of his essays are available on his website, paulgraham.com.

*   **Venture Capitalist and Y Combinator:** He co-founded Y Combinator (YC) in 2005, a highly successful startup accelerator that has funded numerous well-known companies, including Airbnb, Dropbox, Reddit, Stripe, and many others. YC provides seed funding, mentorship, and networking opportunities to early-stage startups. Graham played a key role in shaping YC's philosophy and approach to investing.

*   **Author:** He has written several books, including "On Lisp" and "Hackers & Painters: Big Ideas from the Age of Enlightenment."

In summary, Paul Graham is a multifaceted individual who has made significant contributions to the tech industry as a programmer, essayist, and venture capitalist. He is particularly influential in the startup world through his work with Y Combinator.

Vertex AI 지원 (Vertex AI Support)

region과 project_id 파라미터를 제공하면(환경 변수 또는 직접 전달) Vertex AI를 통해 사용할 수 있어요.

# 환경 변수 설정
!export GOOGLE_GENAI_USE_VERTEXAI=true
!export GOOGLE_CLOUD_PROJECT='your-project-id'
!export GOOGLE_CLOUD_LOCATION='us-central1'
from llama_index.llms.google_genai import GoogleGenAI


# 또는 파라미터를 직접 설정
llm = GoogleGenAI(
    model="gemini-2.5-flash",
    vertexai_config={"project": "your-project-id", "location": "us-central1"},
    # 모델의 최대 입력 토큰으로 컨텍스트 윈도우를 설정해야 합니다
    context_window=200000,
    max_tokens=512,
)
Paul Graham is a prominent figure in the tech and startup world, best known for his roles as:

*   **Co-founder of Y Combinator (YC):** This is arguably his most influential role. YC is a highly successful startup accelerator that has funded companies like Airbnb, Dropbox, Stripe, Reddit, and many others. Graham's approach to funding and mentoring startups has significantly shaped the startup ecosystem.

*   **Essayist and Programmer:** Before YC, Graham was a programmer and essayist. He's known for his insightful and often contrarian essays on a wide range of topics, including programming, startups, design, and societal trends. His essays are widely read and discussed in the tech community.

*   **Founder of Viaweb (later Yahoo! Store):** Graham founded Viaweb, one of the first application service providers, which allowed users to build and manage online stores. It was acquired by Yahoo! in 1998 and became Yahoo! Store.

In summary, Paul Graham is a highly influential figure in the startup world, known for his role in creating Y Combinator, his insightful essays, and his earlier success as a programmer and entrepreneur.

캐시된 콘텐츠 지원 (Cached Content Support)

Google GenAI는 여러 요청에서 큰 컨텍스트를 재사용할 때 성능과 비용 효율을 높이기 위해 캐시된 콘텐츠(cached content)를 지원해요. RAG 애플리케이션, 문서 분석, 일관된 컨텍스트를 갖는 다중 턴 대화에 특히 유용해요.

장점 (Benefits)

  • 더 빠른 응답 (Faster responses)
  • 입력 토큰 사용량 감소를 통한 비용 절감 (Cost savings)
  • 여러 쿼리에 걸친 일관된 컨텍스트 (Consistent context)
  • 대용량 파일을 다루는 문서 분석에 적합 (Perfect for document analysis)

캐시된 콘텐츠 만들기 (Creating Cached Content)

먼저 Google GenAI SDK로 캐시된 콘텐츠를 만들어요.

from google import genai
from google.genai.types import CreateCachedContentConfig, Content, Part
import time


client = genai.Client(api_key="your-api-key")


# VertexAI용
# client = genai.Client(
#     http_options=HttpOptions(api_version="v1"),
#     project="your-project-id",
#     location="us-central1",
#     vertexai="True"
# )

옵션 1: 로컬 파일 업로드

# 로컬 PDF 파일 업로드 및 처리
pdf_file = client.files.upload(file="./your_document.pdf")
while pdf_file.state.name == "PROCESSING":
    print("Waiting for PDF to be processed.")
    time.sleep(2)
    pdf_file = client.files.get(name=pdf_file.name)


# 업로드한 파일로 캐시 생성
cache = client.caches.create(
    model="gemini-2.5-flash",
    config=CreateCachedContentConfig(
        display_name="Document Analysis Cache",
        system_instruction=(
            "You are an expert document analyzer. Answer questions "
            "based on the provided documents with accuracy and detail."
        ),
        contents=[pdf_file],  # 파일을 직접 참조
        ttl="3600s",  # 1시간 동안 캐시
    ),
)

옵션 2: 콘텐츠 구조를 갖는 여러 파일

# 여러 파일 또는 VertexAI의 Cloud Storage 파일
contents = [
    Content(
        role="user",
        parts=[
            Part.from_uri(
                # file_uri=pdf_file.uri,    # 업로드한 파일의 URI도 사용 가능
                file_uri="gs://cloud-samples-data/generative-ai/pdf/2312.11805v3.pdf",
                mime_type="application/pdf",
            ),
            Part.from_uri(
                file_uri="gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf",
                mime_type="application/pdf",
            ),
        ],
    )
]


cache = client.caches.create(
    model="gemini-2.5-flash",
    config=CreateCachedContentConfig(
        display_name="Multi-Document Cache",
        system_instruction=(
            "You are an expert researcher. Analyze and compare "
            "information across the provided documents."
        ),
        contents=contents,
        ttl="3600s",
    ),
)


print(f"Cache created: {cache.name}")
print(f"Cached tokens: {cache.usage_metadata.total_token_count}")
Cache created: projects/391.../locations/us-central1/cachedContents/267...
Cached tokens: 43102

LlamaIndex로 캐시된 콘텐츠 사용하기

캐시를 만들었다면 LlamaIndex에서 사용해요.

from llama_index.llms.google_genai import GoogleGenAI
from llama_index.core.llms import ChatMessage


llm = GoogleGenAI(
    model="gemini-2.5-flash",
    api_key="your-api-key",
    cached_content=cache.name,
)


# VertexAI용
# llm = GoogleGenAI(
#     model="gemini-2.5-flash",
#     vertexai_config={"project": "your-project-id", "location": "us-central1"},
#     cached_content=cache.name
# )


# 캐시된 콘텐츠 사용
message = ChatMessage(
    role="user", content="Summarize the key findings from Chapter 4."
)
response = llm.chat([message])
print(response)
assistant: Chapter 4, "The Abstraction: The Process," introduces the concept of a process as a running program, which is a fundamental abstraction provided by the operating system (OS). Here are the key findings:

1.  **Process Definition:** A process is essentially a running program, characterized by its machine state, including memory (address space), registers (including the program counter and stack pointer), and I/O information.

2.  **Process API:** The OS provides a process API that includes functions for creating processes (Create), destroying processes (Destroy), waiting for processes to complete (Wait), controlling processes (Miscellaneous Control), and obtaining status information (Status).

3.  **Process Creation:** Creating a process involves loading code and static data into memory, allocating memory for the stack and heap, initializing the stack, and then starting the program at its entry point (main()).

4.  **Process States:** A process can be in one of three states: Running (executing on a processor), Ready (ready to run but not currently running), or Blocked (waiting for an event, such as I/O completion).

5.  **Data Structures:** The OS maintains data structures, such as a process list, to track the state of each process. These structures contain information like the register context (saved register values) and the process state.

In essence, Chapter 4 lays the groundwork for understanding how the OS manages and virtualizes the CPU by introducing the concept of a process and its associated attributes and states.

생성 설정(Generation Config)에서 캐시된 콘텐츠 사용

요청 수준의 캐시 제어를 하려면:

import google.genai.types as types


# 요청별로 캐시된 콘텐츠 지정
config = types.GenerateContentConfig(
    cached_content=cache.name, temperature=0.1, max_output_tokens=1024
)


llm = GoogleGenAI(model="gemini-2.5-flash", generation_config=config)


response = llm.complete("List the first five chapters of the document")
print(response)
Here are the first five chapters of the document, as listed in the Table of Contents:

1.  A Dialogue on the Book
2.  Introduction to Operating Systems
3.  A Dialogue on Virtualization
4.  The Abstraction: The Process
5.  Interlude: Process API

캐시 관리 (Cache Management)

# 모든 캐시 나열
caches = client.caches.list()
for cache_item in caches:
    print(f"Cache: {cache_item.display_name} ({cache_item.name})")
    print(f"Tokens: {cache_item.usage_metadata.total_token_count}")


# 캐시 상세 조회
cache_info = client.caches.get(name=cache.name)
print(f"Created: {cache_info.create_time}")
print(f"Expires: {cache_info.expire_time}")


# 사용 후 캐시 삭제
client.caches.delete(name=cache.name)
print("Cache deleted")
Cache: Document Analysis Cache (cachedContents/8v3va2x...)
Tokens: 77421
Created: 2025-07-08 16:06:11.821190+00:00
Expires: 2025-07-08 17:06:10.813310+00:00
Cache deleted

멀티모달 지원 (Multi-Modal Support)

ChatMessage 객체를 사용해서 이미지와 텍스트를 LLM에 전달할 수 있어요.

!wget https://cdn.pixabay.com/photo/2021/12/12/20/00/play-6865967_640.jpg -O image.jpg
--2025-03-14 10:59:00--  https://cdn.pixabay.com/photo/2021/12/12/20/00/play-6865967_640.jpg
Resolving cdn.pixabay.com (cdn.pixabay.com)... 104.18.40.96, 172.64.147.160
Connecting to cdn.pixabay.com (cdn.pixabay.com)|104.18.40.96|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 71557 (70K) [binary/octet-stream]
Saving to: 'image.jpg'


image.jpg           100%[===================>]  69.88K  --.-KB/s    in 0.003s


2025-03-14 10:59:00 (24.8 MB/s) - 'image.jpg' saved [71557/71557]
from llama_index.core.llms import ChatMessage, TextBlock, ImageBlock
from llama_index.llms.google_genai import GoogleGenAI


llm = GoogleGenAI(model="gemini-2.5-flash")


messages = [
    ChatMessage(
        role="user",
        blocks=[
            ImageBlock(path="image.jpg", image_mimetype="image/jpeg"),
            TextBlock(text="What is in this image?"),
        ],
    )
]


resp = llm.chat(messages)
print(resp)
assistant: The image contains four wooden dice with black dots on a dark gray surface. Each die shows a different number of dots, indicating different values.

문서도 전달할 수 있어요.

from llama_index.core.llms import DocumentBlock


messages = [
    ChatMessage(
        role="user",
        blocks=[
            DocumentBlock(
                path="/path/to/your/test.pdf",
                document_mimetype="application/pdf",
            ),
            TextBlock(text="Describe the document in a sentence."),
        ],
    )
]


resp = llm.chat(messages)
print(resp)
assistant: This research paper assesses and mitigates multi-turn jailbreak vulnerabilities in recent large language models (LLMs) using the Crescendo attack, evaluating prompt hardening and LLM-as-guardrail strategies across various task categories.

마지막으로 동영상도 전달할 수 있어요.

from llama_index.core.llms import VideoBlock


messages = [
    ChatMessage(
        role="user",
        blocks=[
            VideoBlock(
                path="/path/to/your/video.mp4", video_mimetype="video/mp4"
            ),
            TextBlock(text="Describe this video in a sentence."),
        ],
    )
]


resp = llm.chat(messages)
print(resp)
assistant: A white SpaceX Crew Dragon capsule is shown approaching and docking with a module of the International Space Station, with the Earth's curvature visible in the background.

구조화 예측 (Structured Prediction)

LlamaIndex는 structured_predict를 통해 어떤 LLM이든 구조화된 LLM으로 바꿔 주는 직관적인 인터페이스를 제공해요. 대상 Pydantic 클래스(중첩 가능)만 정의하면, 프롬프트가 주어졌을 때 원하는 객체를 추출해 줍니다.

from llama_index.llms.google_genai import GoogleGenAI
from llama_index.core.prompts import PromptTemplate
from llama_index.core.bridge.pydantic import BaseModel
from typing import List




class MenuItem(BaseModel):
    """A menu item in a restaurant."""


    course_name: str
    is_vegetarian: bool




class Restaurant(BaseModel):
    """A restaurant with name, city, and cuisine."""


    name: str
    city: str
    cuisine: str
    menu_items: List[MenuItem]




llm = GoogleGenAI(model="gemini-2.5-flash")
prompt_tmpl = PromptTemplate(
    "Generate a restaurant in a given city {city_name}"
)


# 옵션 1: `as_structured_llm` 사용
restaurant_obj = (
    llm.as_structured_llm(Restaurant)
    .complete(prompt_tmpl.format(city_name="Miami"))
    .raw
)
# 옵션 2: `structured_predict` 사용
# restaurant_obj = llm.structured_predict(Restaurant, prompt_tmpl, city_name="Miami")
print(restaurant_obj)
name='Pasta Mia' city='Miami' cuisine='Italian' menu_items=[MenuItem(course_name='pasta', is_vegetarian=False)]

스트리밍이 포함된 구조화 예측

as_structured_llm으로 감싼 LLM은 stream_chat을 통해 스트리밍을 지원해요.

from llama_index.core.llms import ChatMessage
from IPython.display import clear_output
from pprint import pprint


input_msg = ChatMessage.from_str("Generate a restaurant in San Francisco")


sllm = llm.as_structured_llm(Restaurant)
stream_output = sllm.stream_chat([input_msg])
for partial_output in stream_output:
    clear_output(wait=True)
    pprint(partial_output.raw.dict())
    restaurant_obj = partial_output.raw


restaurant_obj
{'city': 'San Francisco',
 'cuisine': 'Italian',
 'menu_items': [{'course_name': 'pasta', 'is_vegetarian': False}],
 'name': 'Italian Delight'}




/var/folders/lw/xwsz_3yj4ln1gvkxhyddbvvw0000gn/T/ipykernel_76091/1885953561.py:11: PydanticDeprecatedSince20: The `dict` method is deprecated; use `model_dump` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
  pprint(partial_output.raw.dict())




Restaurant(name='Italian Delight', city='San Francisco', cuisine='Italian', menu_items=[MenuItem(course_name='pasta', is_vegetarian=False)])

도구/함수 호출 (Tool/Function Calling)

Google GenAI는 API를 통한 직접적인 도구/함수 호출을 지원해요. LlamaIndex를 사용하면 핵심 에이전트 도구 호출 패턴을 구현할 수 있어요.

from llama_index.core.tools import FunctionTool
from llama_index.core.llms import ChatMessage
from llama_index.llms.google_genai import GoogleGenAI
from datetime import datetime


llm = GoogleGenAI(model="gemini-2.5-flash")




def get_current_time(timezone: str) -> dict:
    """Get the current time"""
    return {
        "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "timezone": timezone,
    }




# 도구 이름, 타입 어노테이션, docstring으로 도구를 설명합니다
tool = FunctionTool.from_defaults(fn=get_current_time)

도구를 한 번만 호출해서 결과를 얻을 수도 있어요.

resp = llm.predict_and_call([tool], "What is the current time in New York?")
print(resp)
{'time': '2025-03-14 10:59:05', 'timezone': 'America/New_York'}

더 저수준의 API로 에이전트 도구 호출 루프를 구현할 수도 있어요.

chat_history = [
    ChatMessage(role="user", content="What is the current time in New York?")
]
tools_by_name = {t.metadata.name: t for t in [tool]}


resp = llm.chat_with_tools([tool], chat_history=chat_history)
tool_calls = llm.get_tool_calls_from_response(
    resp, error_on_no_tool_call=False
)


if not tool_calls:
    print(resp)
else:
    while tool_calls:
        # LLM의 응답을 채팅 히스토리에 추가
        chat_history.append(resp.message)


        for tool_call in tool_calls:
            tool_name = tool_call.tool_name
            tool_kwargs = tool_call.tool_kwargs


            print(f"Calling {tool_name} with {tool_kwargs}")
            tool_output = tool.call(**tool_kwargs)
            print("Tool output: ", tool_output)
            chat_history.append(
                ChatMessage(
                    role="tool",
                    content=str(tool_output),
                    # Gemini, Anthropic, OpenAI 등 대부분의 LLM은 tool call id를 알아야 합니다
                    additional_kwargs={"tool_call_id": tool_call.tool_id},
                )
            )


            resp = llm.chat_with_tools([tool], chat_history=chat_history)
            tool_calls = llm.get_tool_calls_from_response(
                resp, error_on_no_tool_call=False
            )
    print("Final response: ", resp.message.content)
Calling get_current_time with {'timezone': 'America/New_York'}
Tool output:  {'time': '2025-03-14 10:59:06', 'timezone': 'America/New_York'}
Final response:  The current time in New York is 2025-03-14 10:59:06.

한 번의 요청으로 여러 도구를 동시에 호출할 수도 있어요. 서로 다른 유형의 정보가 필요한 복잡한 쿼리에 효율적이에요.

# 온도를 위한 또 다른 도구 정의
def get_temperature(city: str) -> dict:
    """Get the current temperature for a city"""
    return {
        "city": city,
        "temperature": "25°C",
    }




# 함수로 도구 만들기
tool1 = FunctionTool.from_defaults(fn=get_current_time)
tool2 = FunctionTool.from_defaults(fn=get_temperature)


# 두 도구가 모두 필요한 질문을 던짐
chat_history = [
    ChatMessage(
        role="user",
        content="What is the current time and temperature in New York?",
    )
]


# 모델이 호출할 도구를 지능적으로 결정
resp = llm.chat_with_tools([tool1, tool2], chat_history=chat_history)
tool_calls = llm.get_tool_calls_from_response(
    resp, error_on_no_tool_call=False
)


print(f"Model made {len(tool_calls)} tool calls:")
for i, tool_call in enumerate(tool_calls, 1):
    print(f"{i}. {tool_call.tool_name} with args: {tool_call.tool_kwargs}")
Model made 2 tool calls:
1. get_current_time with args: {'timezone': 'America/New_York'}
2. get_temperature with args: {'city': 'New York'}

Google Search 접지 (Google Search Grounding)

Google Gemini 2.0과 2.5 모델은 Google Search 접지(grounding)를 지원해요. 모델이 실시간 정보를 검색하고 웹 검색 결과로 응답을 접지할 수 있게 해 줍니다. 최신 정보를 얻는 데 특히 유용해요.

built_in_tool 파라미터는 Google Search 도구를 받아서, 모델이 Google Search 결과의 실세계 데이터로 응답을 접지하게 해 줍니다.

from llama_index.llms.google_genai import GoogleGenAI
from llama_index.core.llms import ChatMessage
from google.genai import types


# Google Search 접지 도구 생성
grounding_tool = types.Tool(google_search=types.GoogleSearch())


llm = GoogleGenAI(
    model="gemini-2.5-flash",
    built_in_tool=grounding_tool,
)


resp = llm.complete("When is the next total solar eclipse in the US?")
print(resp)
The next total solar eclipse visible in the United States will occur on August 23, 2044. However, totality will only be visible in Montana, North Dakota, and South Dakota. Another total solar eclipse will occur on August 12, 2045, with a path spanning from California to Florida.

Google Search 접지 도구는 여러 이점을 제공해요.

  • 실시간 정보: 최신 이벤트와 최신 데이터 접근
  • 사실 정확도: 실제 검색 결과에 기반한 응답
  • 출처 귀속: 접지 메타데이터에 검색 소스 포함
  • 자동 검색 결정: 쿼리에 따라 모델이 언제 검색할지 결정

채팅 메시지와도 접지 도구를 사용할 수 있어요.

# 채팅 메시지와 Google Search 사용
messages = [ChatMessage(role="user", content="Who won the Euro 2024?")]


resp = llm.chat(messages)
print(resp)


# raw 응답에서 접지 메타데이터에 접근
if hasattr(resp, "raw") and "grounding_metadata" in resp.raw:
    print(resp.raw["grounding_metadata"])
else:
    print("\nNo grounding metadata in this response")
assistant: Spain won Euro 2024, defeating England 2-1 in the final. The match took place at the Olympiastadion in Berlin. This victory marks Spain's fourth European Championship title, surpassing Germany for the most wins in the competition.


{'grounding_chunks': [{'retrieved_context': None, 'web': {'domain': None, 'title': 'olympics.com', 'uri': 'https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEkqnG_iRjkf89rilwO5fSBjbAADgm-Ad83fhYOhtAgW2qoG5Y8Gkselc-GshmvpqgMzke0vSUmkc6B8WwmXuxGBl9IPk3YWsytW2nOvGo1n8MlxqcrCpP62vvqjYFoo3wDQsb-tZ3RfZYTjKSTdKfVEBhvSfi4wSKMIgbnQkRx50DLqr2w3sjYI3hyZGWdsFyJFfviXdPSnVCZqQ=='}}, {'retrieved_context': None, 'web': {'domain': None, 'title': 'aljazeera.com', 'uri': 'https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFHwRYxryu8EgG5hG-Gwgdn9sRn88H8iehIOG7KPis7rpJcRo35EAc0onyC_5hqcjUozIddtikyjHmUdK2oIBX8_3ENpLTqpu8TyYb97EibGX6_-ZtRtlPnOsd4TukiRVwfiWMk5sk9FZCsNUEFTWb9OJzPhSjOiAPW78aoAQkM9LSKLBY5vBNyQtUsNvb7k6WEd23pHAKtofxi5i7W_qYrtZPiSkqOBTqtyJ2N69oYDw=='}}, {'retrieved_context': None, 'web': {'domain': None, 'title': 'wikipedia.org', 'uri': 'https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF2WEgQILX6A9y0uLZzBXY9UsduYELn9ahnW-FBNNHBvTQPWkuc_9cwyKmUEbfx0iton_BcIGh_85ibG5hkoE3kPvyBFfh6dEdy3UG2Vvn9gIprxruYLiUKtx8o6I06ZyFiERJqUzboU8s8Dvbd'}}, {'retrieved_context': None, 'web': {'domain': None, 'title': 'thehindu.com', 'uri': 'https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHqXK-zKOuGkYtQFyc48K49_TYwib-bRIvPqnn5UmjUcVI69vTxIiXnpXXkJtSMHa5-cBZ6Ht_4cAuWs5GuKZSzHeAQ-sHJQ2BEk52qIzjTvSteXGf7v0oBOQ_AUTqdTOpH8vXEVhqnp3o6WFVchKfexDT2sk1IDBqlqLxqQrKD9PrMsMOvU8_kfuGqH3IR_V2GHHnrPgwgR93LpiYvFdtVDlo3Wi12kj1FAgqDHHjkqyZpSc-pJ-522x0VgcdKGX6mXZ0Ssd7-aLK0YYO028ex6-o8ZeKEqeSpC9H7GP3bnw=='}}], 'grounding_supports': [{'confidence_scores': [0.97524184, 0.950235, 0.64699775], 'grounding_chunk_indices': [0, 1, 2], 'segment': {'end_index': 55, 'part_index': None, 'start_index': None, 'text': 'Spain won Euro 2024, defeating England 2-1 in the final'}}, {'confidence_scores': [0.9290034, 0.9209086], 'grounding_chunk_indices': [2, 3], 'segment': {'end_index': 109, 'part_index': None, 'start_index': 57, 'text': 'The match took place at th... [truncated]

코드 실행 (Code Execution)

built_in_tool 파라미터는 코드 실행 도구도 지원해요. 모델이 문제 해결, 계산 수행, 데이터 분석을 위해 Python 코드를 작성하고 실행하게 해 줍니다. 수학 계산, 데이터 분석, 시각화 생성에 특히 유용해요.

from llama_index.llms.google_genai import GoogleGenAI
from llama_index.core.llms import ChatMessage
from google.genai import types


# 코드 실행 도구 생성
code_execution_tool = types.Tool(code_execution=types.ToolCodeExecution())


llm = GoogleGenAI(
    model="gemini-2.5-flash",
    built_in_tool=code_execution_tool,
)


resp = llm.complete("Calculate 20th fibonacci number.")
print(resp)
Okay, I can calculate the 20th Fibonacci number. I will use a python script to do this.



The 20th Fibonacci number is 6765.

코드 실행 세부 정보 접근 (Accessing Code Execution Details)

모델이 코드 실행을 사용하면 raw 응답을 통해 실행된 코드, 결과, 기타 메타데이터에 접근할 수 있어요. 여기에는 다음이 포함됩니다.

  • executable_code: 실제로 실행된 Python 코드
  • code_execution_result: 코드를 실행한 출력
  • text: 모델의 설명과 해설

이를 직접 확인해 봅시다.

# 코드 실행을 사용할 만한 계산 요청
messages = [
    ChatMessage(
        role="user", content="What is the sum of the first 50 prime numbers?"
    )
]


resp = llm.chat(messages)


# raw 응답에서 코드 실행 세부 정보 접근
if hasattr(resp, "raw") and "content" in resp.raw:
    parts = resp.raw["content"].get("parts", [])


    for i, part in enumerate(parts):
        print(f"Part {i+1}:")


        if "text" in part and part["text"]:
            print(f"  Text: {part['text'][:100]}", end="")
            print(" ..." if len(part["text"]) > 100 else "")


        if "executable_code" in part and part["executable_code"]:
            print(f"  Executable Code: {part['executable_code']}")


        if "code_execution_result" in part and part["code_execution_result"]:
            print(f"  Code Result: {part['code_execution_result']}")
else:
    print("No detailed parts found in raw response")
Part 1:
  Text: Okay, I need to calculate the sum of the first 50 prime numbers. I can use a python script to genera ...
Part 2:
  Executable Code: {'code': "def is_prime(n):\n    if n <= 1:\n        return False\n    if n <= 3:\n        return True\n    if n % 2 == 0 or n % 3 == 0:\n        return False\n    i = 5\n    while i * i <= n:\n        if n % i == 0 or n % (i + 2) == 0:\n            return False\n        i += 6\n    return True\n\nprimes = []\nnum = 2\nwhile len(primes) < 50:\n    if is_prime(num):\n        primes.append(num)\n    num += 1\n\nprint(f'{sum(primes)=}')\n", 'language': <Language.PYTHON: 'PYTHON'>}
Part 3:
  Code Result: {'outcome': <Outcome.OUTCOME_OK: 'OUTCOME_OK'>, 'output': 'sum(primes)=5117\n'}
Part 4:
  Text: The sum of the first 50 prime numbers is 5117.

이미지 생성 (Image Generation)

일부 모델은 이미지 입력뿐 아니라 이미지 출력도 지원해요. response_modalities 설정을 사용하면 Gemini 모델로 이미지를 생성하고 편집할 수 있어요!

from llama_index.llms.google_genai import GoogleGenAI
import google.genai.types as types


config = types.GenerateContentConfig(
    temperature=0.1, response_modalities=["Text", "Image"]
)


llm = GoogleGenAI(
    model="gemini-2.5-flash-image-preview", generation_config=config
)
from llama_index.core.llms import ChatMessage, TextBlock, ImageBlock


messages = [
    ChatMessage(role="user", content="Please generate an image of a cute dog")
]


resp = llm.chat(messages)
from PIL import Image
from IPython.display import display


for block in resp.message.blocks:
    if isinstance(block, ImageBlock):
        image = Image.open(block.resolve_image())
        display(image)
    elif isinstance(block, TextBlock):
        print(block.text)
Here's a cute dog for you!

png

이미지를 편집할 수도 있어요.

messages.append(resp.message)
messages.append(
    ChatMessage(
        role="user",
        content="Please edit the image to make the dog a mini-schnauzer, but keep the same overall pose, framing, background, and art style.",
    )
)


resp = llm.chat(messages)


for block in resp.message.blocks:
    if isinstance(block, ImageBlock):
        image = Image.open(block.resolve_image())
        display(image)
    elif isinstance(block, TextBlock):
        print(block.text)
Here's your mini-schnauzer!

png

더 알아보기 (Learn more)