Megumin-chat / docs /Google-ADK.md
Junhoee's picture
Upload 3 files
eae04fe verified

A newer version of the Gradio SDK is available: 6.11.0

Upgrade

Google ADK ํ•ต์‹ฌ ๊ฐœ๋… ์™„์ „ ๊ฐ€์ด๋“œ

์ด ๋ฌธ์„œ๋Š” Google Agent Development Kit (ADK)์˜ ํ•ต์‹ฌ ๊ฐœ๋…๋“ค์„ ์ฒด๊ณ„์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์ค‘์š” ์š”์†Œ๋“ค์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“š ๋ชฉ์ฐจ

  1. ์ „์ฒด ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”
  2. Session (์„ธ์…˜)
  3. State (์ƒํƒœ)
  4. Event (์ด๋ฒคํŠธ)
  5. Context (์ปจํ…์ŠคํŠธ)
  6. Runner (๋Ÿฌ๋„ˆ)
  7. Memory (๋ฉ”๋ชจ๋ฆฌ)
  8. Callbacks (์ฝœ๋ฐฑ)
  9. Tools (๋„๊ตฌ)
  10. ํ•ต์‹ฌ ๊ฐœ๋… ๊ฐ„์˜ ๊ด€๊ณ„

1. ์ „์ฒด ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”

ADK์˜ ํ•ต์‹ฌ ์ฒ ํ•™

ADK๋Š” "์—์ด์ „ํŠธ ๊ฐœ๋ฐœ์„ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์ฒ˜๋Ÿผ" ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ AI ์—์ด์ „ํŠธ ์‹œ์Šคํ…œ์„ ๋ชจ๋“ˆํ™”ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ ๋‹ค์ด์–ด๊ทธ๋žจ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        ์‚ฌ์šฉ์ž (User)                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     Runner (๋Ÿฌ๋„ˆ/์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ)                   โ”‚
โ”‚  - ์‹คํ–‰ ๋ฃจํ”„ ๊ด€๋ฆฌ                                                 โ”‚
โ”‚  - ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐ ๋ผ์šฐํŒ…                                          โ”‚
โ”‚  - ์„œ๋น„์Šค ์กฐ์œจ                                                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                    โ”‚                    โ”‚
            โ–ผ                    โ–ผ                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  SessionService  โ”‚  โ”‚  MemoryService   โ”‚  โ”‚ ArtifactService  โ”‚
โ”‚  (์„ธ์…˜ ๊ด€๋ฆฌ)      โ”‚  โ”‚  (์žฅ๊ธฐ ๊ธฐ์–ต)      โ”‚  โ”‚  (ํŒŒ์ผ/๋ฐ์ดํ„ฐ)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚
            โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Session (์„ธ์…˜)                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚   State     โ”‚  โ”‚   Events    โ”‚  โ”‚  Metadata (ID, User)    โ”‚ โ”‚
โ”‚  โ”‚  (์ƒํƒœ)     โ”‚  โ”‚  (์ด๋ฒคํŠธ๋“ค)  โ”‚  โ”‚                         โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Agent (์—์ด์ „ํŠธ)                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  InvocationContext (ํ˜ธ์ถœ ์ปจํ…์ŠคํŠธ)                        โ”‚   โ”‚
โ”‚  โ”‚  - session, state, services ์ ‘๊ทผ                        โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                              โ”‚                                   โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”‚
โ”‚              โ–ผ               โ–ผ               โ–ผ                  โ”‚
โ”‚        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚        โ”‚ Tools   โ”‚     โ”‚ LLM     โ”‚     โ”‚Callbacksโ”‚             โ”‚
โ”‚        โ”‚ (๋„๊ตฌ)  โ”‚     โ”‚ (๋ชจ๋ธ)  โ”‚     โ”‚ (์ฝœ๋ฐฑ)  โ”‚             โ”‚
โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2. Session (์„ธ์…˜)

๊ฐœ๋…

Session์€ ์‚ฌ์šฉ์ž์™€ ์—์ด์ „ํŠธ ๊ฐ„์˜ ๋‹จ์ผ ๋Œ€ํ™” ์Šค๋ ˆ๋“œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ „ํ™” ํ†ตํ™”์— ๋น„์œ ํ•˜๋ฉด, ํ•˜๋‚˜์˜ ํ†ตํ™”๊ฐ€ ํ•˜๋‚˜์˜ ์„ธ์…˜์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ์†์„ฑ

from google.adk.sessions import Session

# Session์˜ ์ฃผ์š” ์†์„ฑ
session.id           # ์„ธ์…˜ ๊ณ ์œ  ID
session.app_name     # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„
session.user_id      # ์‚ฌ์šฉ์ž ID
session.state        # ์ƒํƒœ ๋”•์…”๋„ˆ๋ฆฌ (State)
session.events       # ์ด๋ฒคํŠธ ํžˆ์Šคํ† ๋ฆฌ ๋ฆฌ์ŠคํŠธ
session.last_update_time  # ๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„

SessionService

์„ธ์…˜์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

from google.adk.sessions import InMemorySessionService

# ์„ธ์…˜ ์„œ๋น„์Šค ์ƒ์„ฑ
session_service = InMemorySessionService()

# ์ƒˆ ์„ธ์…˜ ์ƒ์„ฑ
session = await session_service.create_session(
    app_name="my_app",
    user_id="user_123",
    state={"initial_key": "initial_value"}  # ์ดˆ๊ธฐ ์ƒํƒœ ์„ค์ • ๊ฐ€๋Šฅ
)

# ๊ธฐ์กด ์„ธ์…˜ ์กฐํšŒ
session = await session_service.get_session(
    app_name="my_app",
    user_id="user_123",
    session_id="session_abc"
)

# ์„ธ์…˜ ๋ชฉ๋ก ์กฐํšŒ
sessions = await session_service.list_sessions(
    app_name="my_app",
    user_id="user_123"
)

# ์„ธ์…˜ ์‚ญ์ œ
await session_service.delete_session(
    app_name="my_app",
    user_id="user_123",
    session_id="session_abc"
)

SessionService ๊ตฌํ˜„์ฒด ์ข…๋ฅ˜

๊ตฌํ˜„์ฒด ์ €์žฅ ์œ„์น˜ ์˜์†์„ฑ ์šฉ๋„
InMemorySessionService ๋ฉ”๋ชจ๋ฆฌ โŒ (์•ฑ ์žฌ์‹œ์ž‘ ์‹œ ์†Œ๋ฉธ) ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ
DatabaseSessionService SQL DB โœ… ํ”„๋กœ๋•์…˜
VertexAISessionService Google Cloud โœ… ํด๋ผ์šฐ๋“œ ๋ฐฐํฌ

์„ธ์…˜ ์ƒ๋ช…์ฃผ๊ธฐ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   CREATE    โ”‚ โ”€โ”€โ–ถ โ”‚   UPDATE    โ”‚ โ”€โ”€โ–ถ โ”‚   DELETE    โ”‚
โ”‚  (์ƒ์„ฑ)     โ”‚     โ”‚ (์ด๋ฒคํŠธ ์ถ”๊ฐ€)โ”‚     โ”‚   (์ข…๋ฃŒ)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                          โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚   State     โ”‚
                    โ”‚   ๋ณ€๊ฒฝ      โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3. State (์ƒํƒœ)

๊ฐœ๋…

State๋Š” ์„ธ์…˜ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ํ‚ค-๊ฐ’ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ์—์ด์ „ํŠธ์˜ "๋ฉ”๋ชจ์žฅ" ์—ญํ• ์„ ํ•˜๋ฉฐ, ๋Œ€ํ™” ์ค‘ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค.

State์˜ ๋ฒ”์œ„ (Prefix)

ADK์—์„œ State๋Š” prefix๋กœ ๋ฒ”์œ„๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค:

Prefix ๋ฒ”์œ„ ์„ค๋ช…
(์—†์Œ) ์„ธ์…˜ ์ „์ฒด ๊ธฐ๋ณธ๊ฐ’, ์„ธ์…˜ ๋™์•ˆ ์œ ์ง€
app: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ™์€ ์•ฑ์˜ ๋ชจ๋“  ์„ธ์…˜์—์„œ ๊ณต์œ 
user: ์‚ฌ์šฉ์ž ๊ฐ™์€ ์‚ฌ์šฉ์ž์˜ ๋ชจ๋“  ์„ธ์…˜์—์„œ ๊ณต์œ 
temp: ํ˜„์žฌ ํ˜ธ์ถœ ํ˜„์žฌ invocation์—์„œ๋งŒ ์œ ์ง€, ํ˜ธ์ถœ ์ข…๋ฃŒ ์‹œ ์‚ญ์ œ
# State ์‚ฌ์šฉ ์˜ˆ์‹œ
ctx.session.state["user_name"] = "ํ™๊ธธ๋™"           # ์„ธ์…˜ ๋ฒ”์œ„
ctx.session.state["app:settings"] = {"theme": "dark"}  # ์•ฑ ์ „์ฒด ๊ณต์œ 
ctx.session.state["user:preferences"] = {"lang": "ko"} # ์‚ฌ์šฉ์ž ๊ณต์œ 
ctx.session.state["temp:current_step"] = 3         # ํ˜„์žฌ ํ˜ธ์ถœ๋งŒ

State ์ฝ๊ธฐ/์“ฐ๊ธฐ

1. output_key๋ฅผ ํ†ตํ•œ ์ž๋™ ์ €์žฅ (LlmAgent)

from google.adk.agents import LlmAgent

# ์—์ด์ „ํŠธ ์‘๋‹ต์ด ์ž๋™์œผ๋กœ state['analysis_result']์— ์ €์žฅ๋จ
agent = LlmAgent(
    name="Analyzer",
    instruction="๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜์„ธ์š”.",
    output_key="analysis_result"  # โ† ์ž๋™ ์ €์žฅ
)

2. Instruction ํ…œํ”Œ๋ฆฟ์—์„œ ์ฝ๊ธฐ

agent = LlmAgent(
    name="Reporter",
    instruction="""
    ์ด์ „ ๋ถ„์„ ๊ฒฐ๊ณผ: {analysis_result}
    ์œ„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ณด๊ณ ์„œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
    """  # โ† {key} ํ˜•์‹์œผ๋กœ ์ž๋™ ์ฃผ์ž…
)

3. Tool/Callback์—์„œ ์ง์ ‘ ์ ‘๊ทผ

from google.adk.tools import ToolContext

def my_tool(context: ToolContext, query: str) -> dict:
    # ์ฝ๊ธฐ
    user_name = context.state.get("user_name", "Unknown")

    # ์“ฐ๊ธฐ (์ž๋™์œผ๋กœ state_delta์— ์ถ”์ ๋จ)
    context.state["last_query"] = query
    context.state["query_count"] = context.state.get("query_count", 0) + 1

    return {"result": f"Hello {user_name}, processed: {query}"}

โš ๏ธ State ์ˆ˜์ • ์‹œ ์ฃผ์˜์‚ฌํ•ญ

# โŒ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•: ์„ธ์…˜ ๊ฐ์ฒด ์ง์ ‘ ์ˆ˜์ •
session = await session_service.get_session(...)
session.state["key"] = "value"  # ์ถ”์ ๋˜์ง€ ์•Š์Œ!

# โœ… ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•: Context๋ฅผ ํ†ตํ•ด ์ˆ˜์ •
def my_callback(context: CallbackContext):
    context.state["key"] = "value"  # ์ž๋™ ์ถ”์ ๋จ

4. Event (์ด๋ฒคํŠธ)

๊ฐœ๋…

Event๋Š” ์„ธ์…˜ ๋‚ด์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ํ™œ๋™์˜ ๊ธฐ๋ก ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€, ์—์ด์ „ํŠธ ์‘๋‹ต, ๋„๊ตฌ ํ˜ธ์ถœ, ์ƒํƒœ ๋ณ€๊ฒฝ ๋“ฑ ๋ชจ๋“  ๊ฒƒ์ด ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.

Event ๊ตฌ์กฐ

from google.adk.events import Event, EventActions

event = Event(
    # ์‹๋ณ„ ์ •๋ณด
    id="event_123",              # ๊ณ ์œ  ID
    invocation_id="inv_456",     # ์†Œ์† invocation ID
    author="MyAgent",            # ์ƒ์„ฑ์ž (์—์ด์ „ํŠธ๋ช…)

    # ๋‚ด์šฉ
    content=types.Content(       # ์‹ค์ œ ๋ฉ”์‹œ์ง€/๋ฐ์ดํ„ฐ
        parts=[types.Part(text="์•ˆ๋…•ํ•˜์„ธ์š”!")]
    ),

    # ์•ก์…˜/๋ณ€๊ฒฝ์‚ฌํ•ญ
    actions=EventActions(
        state_delta={"key": "value"},  # ์ƒํƒœ ๋ณ€๊ฒฝ
        artifact_delta={},              # ์•„ํ‹ฐํŒฉํŠธ ๋ณ€๊ฒฝ
        escalate=False,                 # ๋ฃจํ”„ ์ข…๋ฃŒ ์‹ ํ˜ธ
        transfer_to_agent="OtherAgent", # ์—์ด์ „ํŠธ ์ „ํ™˜
    ),

    # ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
    timestamp=1234567890.0,
    partial=False,               # ์ŠคํŠธ๋ฆฌ๋ฐ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ ์—ฌ๋ถ€
)

Event ์œ ํ˜•

์œ ํ˜• ์„ค๋ช… ์‹๋ณ„ ๋ฐฉ๋ฒ•
์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ event.content.role == "user"
ํ…์ŠคํŠธ ์‘๋‹ต ์—์ด์ „ํŠธ ํ…์ŠคํŠธ ์‘๋‹ต event.content.parts[0].text
๋„๊ตฌ ํ˜ธ์ถœ LLM์ด ๋„๊ตฌ ํ˜ธ์ถœ ์š”์ฒญ event.get_function_calls()
๋„๊ตฌ ๊ฒฐ๊ณผ ๋„๊ตฌ ์‹คํ–‰ ๊ฒฐ๊ณผ event.get_function_responses()
์ƒํƒœ ๋ณ€๊ฒฝ State ์—…๋ฐ์ดํŠธ event.actions.state_delta
์ŠคํŠธ๋ฆฌ๋ฐ ์ฒญํฌ ๋ถ€๋ถ„ ์‘๋‹ต event.partial == True

EventActions

์ด๋ฒคํŠธ์— ์—ฐ๊ฒฐ๋œ **๋ถ€์ˆ˜ ํšจ๊ณผ(side effects)**๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค:

from google.adk.events import EventActions

actions = EventActions(
    # ์ƒํƒœ ๋ณ€๊ฒฝ
    state_delta={"new_key": "new_value"},

    # ๋ฃจํ”„ ์ข…๋ฃŒ ์‹ ํ˜ธ (LoopAgent์—์„œ ์‚ฌ์šฉ)
    escalate=True,

    # ์—์ด์ „ํŠธ ์ „ํ™˜ (LLM Transfer)
    transfer_to_agent="TargetAgentName",

    # ์•„ํ‹ฐํŒฉํŠธ(ํŒŒ์ผ) ๋ณ€๊ฒฝ
    artifact_delta={"file.txt": "content"},
)

Event ์ฒ˜๋ฆฌ ํ๋ฆ„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     Event ์ƒ์„ฑ ๋ฐ ์ฒ˜๋ฆฌ ํ๋ฆ„                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1. Event ์ƒ์„ฑ
   Agent/Tool/Callback โ†’ yield Event(...)

2. Runner ์ˆ˜์‹ 
   Runner๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์Œ

3. SessionService ์ฒ˜๋ฆฌ
   - state_delta๋ฅผ session.state์— ๋ณ‘ํ•ฉ
   - artifact_delta ์ฒ˜๋ฆฌ
   - events ํžˆ์Šคํ† ๋ฆฌ์— ์ถ”๊ฐ€

4. ํด๋ผ์ด์–ธํŠธ ์ „๋‹ฌ
   - UI/API๋กœ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ

5. Context (์ปจํ…์ŠคํŠธ)

๊ฐœ๋…

Context๋Š” ํ˜„์žฌ ์‹คํ–‰ ์ƒํ™ฉ์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ๋‹ด์€ ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค. ์—์ด์ „ํŠธ, ๋„๊ตฌ, ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Context ์œ ํ˜•

1. InvocationContext (ํ˜ธ์ถœ ์ปจํ…์ŠคํŠธ)

๊ฐ€์žฅ ์ƒ์œ„ ๋ ˆ๋ฒจ์˜ ์ปจํ…์ŠคํŠธ๋กœ, ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ์š”์ฒญ ์ฒ˜๋ฆฌ ์ „์ฒด๋ฅผ ๊ด€์žฅํ•ฉ๋‹ˆ๋‹ค.

from google.adk.agents import BaseAgent
from google.adk.agents.invocation_context import InvocationContext

class MyAgent(BaseAgent):
    async def _run_async_impl(self, ctx: InvocationContext):
        # ์„ธ์…˜ ์ •๋ณด ์ ‘๊ทผ
        session_id = ctx.session.id
        user_id = ctx.session.user_id

        # ์ƒํƒœ ์ ‘๊ทผ
        state_value = ctx.session.state.get("key")

        # ์„œ๋น„์Šค ์ ‘๊ทผ
        memory_service = ctx.memory_service
        artifact_service = ctx.artifact_service

        # ํ˜„์žฌ ์—์ด์ „ํŠธ ์ •๋ณด
        agent_name = ctx.agent.name

        # ํ˜ธ์ถœ ์ œ์–ด
        ctx.end_invocation = True  # ํ˜ธ์ถœ ์ข…๋ฃŒ ์‹ ํ˜ธ

        yield Event(author=self.name, content=...)

2. CallbackContext (์ฝœ๋ฐฑ ์ปจํ…์ŠคํŠธ)

์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, InvocationContext์˜ ์„œ๋ธŒ์…‹์ž…๋‹ˆ๋‹ค.

from google.adk.agents.callback_context import CallbackContext

def my_before_agent_callback(ctx: CallbackContext):
    # ์—์ด์ „ํŠธ ์ •๋ณด
    agent_name = ctx.agent_name
    invocation_id = ctx.invocation_id

    # ์ƒํƒœ ์ฝ๊ธฐ/์“ฐ๊ธฐ
    ctx.state["processed"] = True

    # ์‚ฌ์šฉ์ž ์ž…๋ ฅ ํ™•์ธ
    user_content = ctx.user_content

    return None  # ๊ณ„์† ์ง„ํ–‰ (๋˜๋Š” Content ๋ฐ˜ํ™˜ ์‹œ ์—์ด์ „ํŠธ ๊ฑด๋„ˆ๋œ€)

3. ToolContext (๋„๊ตฌ ์ปจํ…์ŠคํŠธ)

๋„๊ตฌ(Tool) ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋„๊ตฌ ์‹คํ–‰์— ํ•„์š”ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

from google.adk.tools import ToolContext

def my_tool(context: ToolContext, query: str) -> dict:
    # ์ƒํƒœ ์ ‘๊ทผ (CallbackContext์™€ ๋™์ผ)
    context.state["last_query"] = query

    # ๋„๊ตฌ ์ „์šฉ ๊ธฐ๋Šฅ
    function_call_id = context.function_call_id  # ํ˜„์žฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ ID

    # ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
    results = await context.search_memory("๊ฒ€์ƒ‰์–ด")

    # ์•„ํ‹ฐํŒฉํŠธ ๋ชฉ๋ก
    artifacts = context.list_artifacts()

    # ์ธ์ฆ ์š”์ฒญ (OAuth ๋“ฑ)
    credential = await context.get_auth_response(auth_config)

    return {"result": "success"}

Context ๊ณ„์ธต ๊ตฌ์กฐ

InvocationContext (์ตœ์ƒ์œ„)
โ”œโ”€โ”€ session
โ”‚   โ”œโ”€โ”€ state
โ”‚   โ””โ”€โ”€ events
โ”œโ”€โ”€ agent (ํ˜„์žฌ ์—์ด์ „ํŠธ)
โ”œโ”€โ”€ services (memory, artifact, session)
โ””โ”€โ”€ invocation_id

    โ–ผ ํŒŒ์ƒ

CallbackContext (์ฝœ๋ฐฑ์šฉ)
โ”œโ”€โ”€ state (์ฝ๊ธฐ/์“ฐ๊ธฐ)
โ”œโ”€โ”€ agent_name
โ”œโ”€โ”€ user_content
โ””โ”€โ”€ invocation_id

    โ–ผ ํ™•์žฅ

ToolContext (๋„๊ตฌ์šฉ)
โ”œโ”€โ”€ (CallbackContext์˜ ๋ชจ๋“  ๊ฒƒ)
โ”œโ”€โ”€ function_call_id
โ”œโ”€โ”€ search_memory()
โ”œโ”€โ”€ list_artifacts()
โ””โ”€โ”€ request_credential()

6. Runner (๋Ÿฌ๋„ˆ)

๊ฐœ๋…

Runner๋Š” ์—์ด์ „ํŠธ ์‹คํ–‰์˜ ์ค‘์•™ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„ ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์„œ๋น„์Šค๋“ค์„ ์กฐ์œจํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

from google.adk.runners import InMemoryRunner, Runner
from google.adk.sessions import InMemorySessionService

# ๋ฐฉ๋ฒ• 1: InMemoryRunner (๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ์šฉ)
runner = InMemoryRunner(
    agent=my_agent,
    app_name="my_app"
)

# ๋ฐฉ๋ฒ• 2: Runner (์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•„์š” ์‹œ)
session_service = InMemorySessionService()
runner = Runner(
    agent=my_agent,
    app_name="my_app",
    session_service=session_service,
    # memory_service=my_memory_service,  # ์˜ต์…˜
    # artifact_service=my_artifact_service,  # ์˜ต์…˜
)

์—์ด์ „ํŠธ ์‹คํ–‰

# ๋น„๋™๊ธฐ ์‹คํ–‰ (์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•)
async for event in runner.run_async(
    user_id="user_123",
    session_id="session_456",  # ์ƒˆ ์„ธ์…˜์ด๋ฉด ์ž๋™ ์ƒ์„ฑ
    new_message="์•ˆ๋…•ํ•˜์„ธ์š”!"
):
    if event.content and event.content.parts:
        for part in event.content.parts:
            if hasattr(part, 'text') and part.text:
                print(f"[{event.author}]: {part.text}")

# ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ (์Œ์„ฑ/์˜์ƒ)
async for event in runner.run_live(...):
    ...

Runner ์‹คํ–‰ ํ๋ฆ„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Runner.run_async() ํ๋ฆ„                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1. ์„ธ์…˜ ์ค€๋น„
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ get/create      โ”‚ โ† ์„ธ์…˜ ์กฐํšŒ ๋˜๋Š” ์ƒ์„ฑ
   โ”‚ Session         โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ–ผ
2. ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋ฅผ ์ด๋ฒคํŠธ๋กœ ์ถ”๊ฐ€
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ append_event    โ”‚ โ† ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์„ธ์…˜ ํžˆ์Šคํ† ๋ฆฌ์— ์ถ”๊ฐ€
   โ”‚ (user message)  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ–ผ
3. InvocationContext ์ƒ์„ฑ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ Create          โ”‚ โ† ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด ์ค€๋น„
   โ”‚ InvocationContextโ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ–ผ
4. ์—์ด์ „ํŠธ ์‹คํ–‰ ๋ฃจํ”„
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
   โ”‚  โ”‚ Agent.run()     โ”‚ โ† ์—์ด์ „ํŠธ ์‹คํ–‰        โ”‚
   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ”‚          โ–ผ                                   โ”‚
   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
   โ”‚  โ”‚ yield Event     โ”‚ โ† ์ด๋ฒคํŠธ ์ƒ์„ฑ          โ”‚
   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ”‚          โ–ผ                                   โ”‚
   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
   โ”‚  โ”‚ Process Event   โ”‚ โ† ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ          โ”‚
   โ”‚  โ”‚ - state_delta   โ”‚   (์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋“ฑ)    โ”‚
   โ”‚  โ”‚ - append to     โ”‚                        โ”‚
   โ”‚  โ”‚   session       โ”‚                        โ”‚
   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ”‚          โ–ผ                                   โ”‚
   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
   โ”‚  โ”‚ yield to caller โ”‚ โ† ํ˜ธ์ถœ์ž์—๊ฒŒ ์ „๋‹ฌ      โ”‚
   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ”‚          โ–ผ                                   โ”‚
   โ”‚  [๋” ๋งŽ์€ ์ด๋ฒคํŠธ?] โ”€โ”€Yesโ”€โ”€โ–ถ (๋ฐ˜๋ณต)           โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ”‚         No                                   โ”‚
   โ”‚          โ”‚                                   โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
              โ–ผ
5. ์‹คํ–‰ ์™„๋ฃŒ

Invocation vs Agent Call vs Step

Invocation (ํ˜ธ์ถœ)
โ”‚  ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ โ†’ ์ตœ์ข… ์‘๋‹ต๊นŒ์ง€์˜ ์ „์ฒด ์‚ฌ์ดํด
โ”‚
โ”œโ”€โ”€ Agent Call 1 (์—์ด์ „ํŠธ ํ˜ธ์ถœ)
โ”‚   โ”‚  ํ•˜๋‚˜์˜ ์—์ด์ „ํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋‹จ์œ„
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ Step 1 (์Šคํ…)
โ”‚   โ”‚   โ””โ”€โ”€ LLM ํ˜ธ์ถœ 1ํšŒ + ๋„๊ตฌ ์‹คํ–‰
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ Step 2
โ”‚   โ”‚   โ””โ”€โ”€ LLM ํ˜ธ์ถœ 1ํšŒ + ๋„๊ตฌ ์‹คํ–‰
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ (transfer_to_agent ๋ฐœ์ƒ)
โ”‚
โ”œโ”€โ”€ Agent Call 2 (๋‹ค๋ฅธ ์—์ด์ „ํŠธ๋กœ ์ „ํ™˜)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ Step 1
โ”‚   โ”‚   โ””โ”€โ”€ LLM ํ˜ธ์ถœ + ์ตœ์ข… ์‘๋‹ต
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ (์™„๋ฃŒ)
โ”‚
โ””โ”€โ”€ Invocation ์ข…๋ฃŒ

7. Memory (๋ฉ”๋ชจ๋ฆฌ)

๊ฐœ๋…

Memory๋Š” ์žฅ๊ธฐ ๊ธฐ์–ต ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ์„ธ์…˜์ด ์ข…๋ฃŒ๋œ ํ›„์—๋„ ์œ ์ง€๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ์„ธ์…˜์— ๊ฑธ์ณ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Session State vs Memory ๋น„๊ต

ํŠน์„ฑ Session State Memory
๋ฒ”์œ„ ํ˜„์žฌ ์„ธ์…˜ ๋‚ด ์—ฌ๋Ÿฌ ์„ธ์…˜ ๊ฑธ์ณ
์ˆ˜๋ช… ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ (๋ณดํ†ต) ์‚ญ์ œ ์˜๊ตฌ ์ €์žฅ
์ ‘๊ทผ ๋ฐฉ์‹ Key-Value ์ง์ ‘ ์ ‘๊ทผ ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ
์šฉ๋„ ๋Œ€ํ™” ์ค‘ ์ž„์‹œ ๋ฐ์ดํ„ฐ ๊ณผ๊ฑฐ ์ •๋ณด ์ฐธ์กฐ
๋น„์œ  ๋Œ€ํ™” ์ค‘ ๋ฉ”๋ชจ์žฅ ๋„์„œ๊ด€ ์•„์นด์ด๋ธŒ

MemoryService ์‚ฌ์šฉ

from google.adk.memory import InMemoryMemoryService

# ๋ฉ”๋ชจ๋ฆฌ ์„œ๋น„์Šค ์ƒ์„ฑ
memory_service = InMemoryMemoryService()

# ์„ธ์…˜์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ (๋Œ€ํ™” ์ข…๋ฃŒ ํ›„)
await memory_service.add_session_to_memory(session)

# ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
results = await memory_service.search_memory(
    app_name="my_app",
    user_id="user_123",
    query="์ด์ „์— ์ถ”์ฒœ๋ฐ›์€ ์Œ์‹์ "
)

for result in results.memories:
    print(result.content)

MemoryService ๊ตฌํ˜„์ฒด

๊ตฌํ˜„์ฒด ์ €์žฅ ๋ฐฉ์‹ ๊ฒ€์ƒ‰ ๋ฐฉ์‹ ์šฉ๋„
InMemoryMemoryService ๋ฉ”๋ชจ๋ฆฌ ํ‚ค์›Œ๋“œ ๋งค์นญ ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ
VertexAIMemoryBankService Vertex AI ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ํ”„๋กœ๋•์…˜

๋ฉ”๋ชจ๋ฆฌ ์›Œํฌํ”Œ๋กœ์šฐ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Memory ์›Œํฌํ”Œ๋กœ์šฐ                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1. ์„ธ์…˜ ๋Œ€ํ™” ์ง„ํ–‰
   User โ†” Agent (Session์— Events ์ถ•์ )

2. ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ
   memory_service.add_session_to_memory(session)
   โ””โ”€โ”€ ์„ธ์…˜์˜ ์ฃผ์š” ์ •๋ณด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ

3. ์ดํ›„ ์„ธ์…˜์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
   results = memory_service.search_memory(query)
   โ””โ”€โ”€ ๊ณผ๊ฑฐ ๋Œ€ํ™”์—์„œ ๊ด€๋ จ ์ •๋ณด ๊ฒ€์ƒ‰

4. ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ํ˜„์žฌ ๋Œ€ํ™”์— ํ™œ์šฉ
   Agent๊ฐ€ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์‘๋‹ต

์—์ด์ „ํŠธ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ

from google.adk.tools import preload_memory_tool

# ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰ ๋„๊ตฌ ์ถ”๊ฐ€
agent = LlmAgent(
    name="MemoryAgent",
    instruction="์‚ฌ์šฉ์ž์˜ ๊ณผ๊ฑฐ ๋Œ€ํ™”๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š”.",
    tools=[preload_memory_tool.PreloadMemoryTool()]
)

# ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ ์ž๋™ ์ €์žฅ ์ฝœ๋ฐฑ
async def auto_save_to_memory(callback_context):
    await callback_context._invocation_context.memory_service.add_session_to_memory(
        callback_context._invocation_context.session
    )

agent = LlmAgent(
    name="AutoSaveAgent",
    after_agent_callback=auto_save_to_memory
)

8. Callbacks (์ฝœ๋ฐฑ)

๊ฐœ๋…

Callback์€ ์—์ด์ „ํŠธ ์‹คํ–‰ ์ค‘ ํŠน์ • ์‹œ์ ์— ๊ฐœ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ํ›…(hook)์ž…๋‹ˆ๋‹ค. ๊ฐ€๋“œ๋ ˆ์ผ, ๋กœ๊น…, ์ˆ˜์ • ๋“ฑ ๋‹ค์–‘ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ์ข…๋ฅ˜ ๋ฐ ์‹คํ–‰ ์‹œ์ 

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      ์ฝœ๋ฐฑ ์‹คํ–‰ ์‹œ์                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

์‚ฌ์šฉ์ž ์ž…๋ ฅ
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ before_agent_callback โ”‚  โ† ์—์ด์ „ํŠธ ์‹คํ–‰ ์ „
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ before_model_callback โ”‚  โ† LLM ํ˜ธ์ถœ ์ „
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
[LLM ํ˜ธ์ถœ]
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ after_model_callback  โ”‚  โ† LLM ์‘๋‹ต ํ›„
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ before_tool_callback  โ”‚  โ† ๋„๊ตฌ ์‹คํ–‰ ์ „
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
[๋„๊ตฌ ์‹คํ–‰]
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ after_tool_callback   โ”‚  โ† ๋„๊ตฌ ์‹คํ–‰ ํ›„
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ after_agent_callback  โ”‚  โ† ์—์ด์ „ํŠธ ์‹คํ–‰ ํ›„
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
์ตœ์ข… ์‘๋‹ต

์ฝœ๋ฐฑ ์ •์˜ ๋ฐ ์‚ฌ์šฉ

before_agent_callback

from google.adk.agents import LlmAgent
from google.adk.agents.callback_context import CallbackContext
from google.genai import types

def check_access(ctx: CallbackContext) -> types.Content | None:
    """์—์ด์ „ํŠธ ์‹คํ–‰ ์ „ ์ ‘๊ทผ ์ œ์–ด"""
    user_id = ctx.session.user_id

    # ์ฐจ๋‹จํ•  ์‚ฌ์šฉ์ž ์ฒดํฌ
    if user_id in BLOCKED_USERS:
        # Content ๋ฐ˜ํ™˜ ์‹œ ์—์ด์ „ํŠธ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€
        return types.Content(
            parts=[types.Part(text="์ ‘๊ทผ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")]
        )

    # None ๋ฐ˜ํ™˜ ์‹œ ์ •์ƒ ์ง„ํ–‰
    return None

agent = LlmAgent(
    name="SecureAgent",
    before_agent_callback=check_access
)

before_model_callback (๊ฐ€๋“œ๋ ˆ์ผ)

from google.adk.models import LlmRequest, LlmResponse

def content_guardrail(ctx: CallbackContext, request: LlmRequest) -> LlmResponse | None:
    """LLM ํ˜ธ์ถœ ์ „ ์ž…๋ ฅ ๊ฒ€์‚ฌ"""
    user_text = ctx.user_content.parts[0].text

    # ๊ธˆ์ง€์–ด ์ฒดํฌ
    if any(word in user_text for word in FORBIDDEN_WORDS):
        return LlmResponse(
            content=types.Content(
                parts=[types.Part(text="๋ถ€์ ์ ˆํ•œ ๋‚ด์šฉ์ด ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")]
            )
        )

    # ํ”„๋กฌํ”„ํŠธ ์ˆ˜์ •
    # request.contents๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์‹œ์Šคํ…œ ์ง€์‹œ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ

    return None  # ์ •์ƒ ์ง„ํ–‰

agent = LlmAgent(
    name="GuardedAgent",
    before_model_callback=content_guardrail
)

after_model_callback

def post_process_response(ctx: CallbackContext, response: LlmResponse) -> LlmResponse | None:
    """LLM ์‘๋‹ต ํ›„์ฒ˜๋ฆฌ"""
    # ์‘๋‹ต ๋กœ๊น…
    print(f"LLM Response: {response.content}")

    # ์‘๋‹ต ์ˆ˜์ • (ํ•„์š”์‹œ)
    # return modified_response

    return None  # ์›๋ณธ ์‘๋‹ต ์œ ์ง€

agent = LlmAgent(
    name="LoggingAgent",
    after_model_callback=post_process_response
)

before_tool_callback / after_tool_callback

def tool_guardrail(ctx: ToolContext, tool_name: str, args: dict) -> dict | None:
    """๋„๊ตฌ ์‹คํ–‰ ์ „ ๊ฒ€์‚ฌ"""
    if tool_name == "delete_file" and not ctx.state.get("admin"):
        return {"error": "๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค."}  # ๋„๊ตฌ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€
    return None

def log_tool_result(ctx: ToolContext, tool_name: str, result: dict) -> dict | None:
    """๋„๊ตฌ ์‹คํ–‰ ํ›„ ๋กœ๊น…"""
    print(f"Tool {tool_name} returned: {result}")
    return None  # ๊ฒฐ๊ณผ ์œ ์ง€

agent = LlmAgent(
    name="ToolAuditAgent",
    before_tool_callback=tool_guardrail,
    after_tool_callback=log_tool_result
)

์ฝœ๋ฐฑ ๋ฐ˜ํ™˜๊ฐ’์˜ ์˜๋ฏธ

์ฝœ๋ฐฑ ๋ฐ˜ํ™˜๊ฐ’ ํšจ๊ณผ
before_agent None ์—์ด์ „ํŠธ ์ •์ƒ ์‹คํ–‰
before_agent Content ์—์ด์ „ํŠธ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ Content ์‚ฌ์šฉ
before_model None LLM ์ •์ƒ ํ˜ธ์ถœ
before_model LlmResponse LLM ํ˜ธ์ถœ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ ์‘๋‹ต ์‚ฌ์šฉ
before_tool None ๋„๊ตฌ ์ •์ƒ ์‹คํ–‰
before_tool dict ๋„๊ตฌ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ ๊ฒฐ๊ณผ ์‚ฌ์šฉ

9. Tools (๋„๊ตฌ)

๊ฐœ๋…

Tool์€ ์—์ด์ „ํŠธ์—๊ฒŒ ์™ธ๋ถ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. API ํ˜ธ์ถœ, ๊ณ„์‚ฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Tool ์œ ํ˜•

1. FunctionTool (ํ•จ์ˆ˜ ๋„๊ตฌ)

Python ํ•จ์ˆ˜๋ฅผ ๋„๊ตฌ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

from google.adk.tools import FunctionTool

def get_weather(city: str, unit: str = "celsius") -> dict:
    """
    ํŠน์ • ๋„์‹œ์˜ ๋‚ ์”จ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

    Args:
        city: ์กฐํšŒํ•  ๋„์‹œ ์ด๋ฆ„
        unit: ์˜จ๋„ ๋‹จ์œ„ (celsius ๋˜๋Š” fahrenheit)

    Returns:
        ๋‚ ์”จ ์ •๋ณด ๋”•์…”๋„ˆ๋ฆฌ
    """
    # ์‹ค์ œ API ํ˜ธ์ถœ ๋˜๋Š” ์‹œ๋ฎฌ๋ ˆ์ด์…˜
    return {"city": city, "temp": 20, "unit": unit}

# ํ•จ์ˆ˜๋ฅผ ๋„๊ตฌ๋กœ ๋ณ€ํ™˜
weather_tool = FunctionTool(func=get_weather)

# ์—์ด์ „ํŠธ์— ๋„๊ตฌ ์ถ”๊ฐ€
agent = LlmAgent(
    name="WeatherAgent",
    tools=[weather_tool]
)

2. AgentTool (์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ๋กœ)

๋‹ค๋ฅธ ์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from google.adk.tools import agent_tool

# ์ „๋ฌธ ์—์ด์ „ํŠธ ์ •์˜
translator = LlmAgent(
    name="Translator",
    description="ํ…์ŠคํŠธ๋ฅผ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๋‹ค."
)

# ์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ๋กœ ๋ž˜ํ•‘
translator_tool = agent_tool.AgentTool(agent=translator)

# ๋‹ค๋ฅธ ์—์ด์ „ํŠธ์—์„œ ๋„๊ตฌ๋กœ ์‚ฌ์šฉ
main_agent = LlmAgent(
    name="MainAgent",
    tools=[translator_tool]
)

ToolContext ํ™œ์šฉ

๋„๊ตฌ ํ•จ์ˆ˜ ๋‚ด์—์„œ Context์— ์ ‘๊ทผํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from google.adk.tools import ToolContext

def advanced_tool(context: ToolContext, query: str) -> dict:
    # 1. ์ƒํƒœ ์ฝ๊ธฐ/์“ฐ๊ธฐ
    context.state["last_query"] = query
    previous = context.state.get("history", [])

    # 2. ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
    memory_results = await context.search_memory(query)

    # 3. ์•„ํ‹ฐํŒฉํŠธ ๋ชฉ๋ก ์กฐํšŒ
    artifacts = context.list_artifacts()

    # 4. ์ธ์ฆ ์ฒ˜๋ฆฌ
    if needs_auth:
        cred = await context.get_auth_response(oauth_config)

    return {"result": "processed"}

๋„๊ตฌ ์‹คํ–‰ ํ๋ฆ„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      ๋„๊ตฌ ์‹คํ–‰ ํ๋ฆ„                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1. LLM์ด ๋„๊ตฌ ํ˜ธ์ถœ ๊ฒฐ์ •
   LLM Response: FunctionCall(name="get_weather", args={"city": "์„œ์šธ"})

2. ADK๊ฐ€ ๋„๊ตฌ ์ฐพ๊ธฐ
   tools ๋ชฉ๋ก์—์„œ "get_weather" ์ฐพ์Œ

3. before_tool_callback ์‹คํ–‰ (์žˆ์œผ๋ฉด)
   ๊ฐ€๋“œ๋ ˆ์ผ, ๋กœ๊น… ๋“ฑ

4. ๋„๊ตฌ ํ•จ์ˆ˜ ์‹คํ–‰
   result = get_weather(city="์„œ์šธ")

5. after_tool_callback ์‹คํ–‰ (์žˆ์œผ๋ฉด)
   ๊ฒฐ๊ณผ ํ›„์ฒ˜๋ฆฌ, ๋กœ๊น… ๋“ฑ

6. FunctionResponse ์ด๋ฒคํŠธ ์ƒ์„ฑ
   Event(content=FunctionResponse(name="get_weather", response=result))

7. LLM์—๊ฒŒ ๊ฒฐ๊ณผ ์ „๋‹ฌ
   LLM์ด ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ  ๋‹ค์Œ ์‘๋‹ต ์ƒ์„ฑ

10. ํ•ต์‹ฌ ๊ฐœ๋… ๊ฐ„์˜ ๊ด€๊ณ„

์ „์ฒด ๊ด€๊ณ„๋„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          ADK ํ•ต์‹ฌ ๊ฐœ๋… ๊ด€๊ณ„๋„                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚      Runner         โ”‚
                    โ”‚   (์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ)   โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ–ผ               โ–ผ               โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ SessionSvc  โ”‚  โ”‚  MemorySvc  โ”‚  โ”‚ ArtifactSvc โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚               โ”‚
              โ–ผ               โ”‚
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
     โ”‚    Session      โ”‚      โ”‚
     โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚      โ”‚
     โ”‚  โ”‚   State   โ”‚โ—€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€ ์—์ด์ „ํŠธ๊ฐ€ ์ฝ๊ณ /์”€
     โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚      โ”‚
     โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚      โ”‚
     โ”‚  โ”‚  Events   โ”‚  โ”‚      โ”‚
     โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚      โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
              โ”‚               โ”‚
              โ–ผ               โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚          InvocationContext              โ”‚
     โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
     โ”‚  โ”‚ session, state, services, agent โ”‚   โ”‚
     โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ–ผ             โ–ผ             โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ Callbacks  โ”‚ โ”‚  Agent   โ”‚ โ”‚  Tools   โ”‚
   โ”‚            โ”‚ โ”‚          โ”‚ โ”‚          โ”‚
   โ”‚ Callback   โ”‚ โ”‚          โ”‚ โ”‚  Tool    โ”‚
   โ”‚ Context    โ”‚ โ”‚          โ”‚ โ”‚ Context  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚             โ”‚             โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ–ผ
                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                 โ”‚   Event    โ”‚
                 โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
                 โ”‚  โ”‚Actionsโ”‚ โ”€โ”€โ–ถ state_delta
                 โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚    escalate
                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    transfer

๋ฐ์ดํ„ฐ ํ๋ฆ„ ์š”์•ฝ

1. ์‚ฌ์šฉ์ž ์ž…๋ ฅ
   โ””โ”€โ”€โ–ถ Runner.run_async(message)

2. ์„ธ์…˜ ์ค€๋น„
   โ””โ”€โ”€โ–ถ SessionService.get_session() โ†’ Session

3. ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ
   โ””โ”€โ”€โ–ถ InvocationContext(session, services, ...)

4. ์ฝœ๋ฐฑ ์‹คํ–‰
   โ””โ”€โ”€โ–ถ before_agent_callback(CallbackContext)

5. ์—์ด์ „ํŠธ ์‹คํ–‰
   โ””โ”€โ”€โ–ถ Agent.run(InvocationContext)
        โ”‚
        โ”œโ”€โ”€โ–ถ before_model_callback
        โ”œโ”€โ”€โ–ถ LLM ํ˜ธ์ถœ
        โ”œโ”€โ”€โ–ถ after_model_callback
        โ”‚
        โ”œโ”€โ”€โ–ถ [๋„๊ตฌ ํ˜ธ์ถœ ์‹œ]
        โ”‚    โ”œโ”€โ”€โ–ถ before_tool_callback
        โ”‚    โ”œโ”€โ”€โ–ถ Tool ์‹คํ–‰(ToolContext)
        โ”‚    โ””โ”€โ”€โ–ถ after_tool_callback
        โ”‚
        โ””โ”€โ”€โ–ถ yield Event

6. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
   โ””โ”€โ”€โ–ถ SessionService.append_event(event)
        โ””โ”€โ”€โ–ถ state_delta ์ ์šฉ
        โ””โ”€โ”€โ–ถ events ํžˆ์Šคํ† ๋ฆฌ ์ถ”๊ฐ€

7. ์ฝœ๋ฐฑ ์‹คํ–‰
   โ””โ”€โ”€โ–ถ after_agent_callback(CallbackContext)

8. ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
   โ””โ”€โ”€โ–ถ yield event to caller

ํ•ต์‹ฌ ํฌ์ธํŠธ ์ •๋ฆฌ

๊ฐœ๋… ์—ญํ•  ๋น„์œ 
Session ๋Œ€ํ™” ์ปจํ…Œ์ด๋„ˆ ์ „ํ™” ํ†ตํ™” ํ•œ ๊ฑด
State ๋Œ€ํ™” ์ค‘ ๋ฉ”๋ชจ ๋ฉ”๋ชจ์žฅ/์Šคํฌ๋ž˜์น˜ํŒจ๋“œ
Event ํ™œ๋™ ๊ธฐ๋ก ๋‹จ์œ„ ๋Œ€ํ™” ๊ธฐ๋ก์˜ ํ•œ ์ค„
Context ์‹คํ–‰ ์ •๋ณด ๋ฌถ์Œ ์—…๋ฌด ๋ฌธ๋งฅ/๋ฐฐ๊ฒฝ ์ •๋ณด
Runner ์‹คํ–‰ ์กฐ์œจ์ž ์ง€ํœ˜์ž
Memory ์žฅ๊ธฐ ๊ธฐ์–ต ๋„์„œ๊ด€ ์•„์นด์ด๋ธŒ
Callback ์‹คํ–‰ ์ค‘ ๊ฐœ์ž…์  ์ฒดํฌํฌ์ธํŠธ/๊ด€๋ฌธ
Tool ์™ธ๋ถ€ ๊ธฐ๋Šฅ ๋„๊ตฌ ์ƒ์ž

๋ถ€๋ก: ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ (FAQ)

Q1: State์™€ Memory์˜ ์ฐจ์ด๋Š”?

  • State: ํ˜„์žฌ ์„ธ์…˜ ๋‚ด์—์„œ๋งŒ ์œ ํšจ, ํ‚ค-๊ฐ’ ์ง์ ‘ ์ ‘๊ทผ
  • Memory: ์—ฌ๋Ÿฌ ์„ธ์…˜์— ๊ฑธ์ณ ์œ ์ง€, ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ๋กœ ์ ‘๊ทผ

Q2: output_key๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?

์—์ด์ „ํŠธ์˜ ์‘๋‹ต์ด state์— ์ž๋™ ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์—์ด์ „ํŠธ์—์„œ ์ด์ „ ์‘๋‹ต์„ ์ฐธ์กฐํ•˜๋ ค๋ฉด output_key๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜, ์ง์ ‘ ์ฝœ๋ฐฑ/๋„๊ตฌ์—์„œ state๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Q3: InMemorySessionService๋Š” ํ”„๋กœ๋•์…˜์—์„œ ์“ธ ์ˆ˜ ์žˆ๋‚˜์š”?

๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ฑ ์žฌ์‹œ์ž‘ ์‹œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜์—์„œ๋Š” Database-backed ๋˜๋Š” Cloud-based ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

Q4: ์ฝœ๋ฐฑ์—์„œ Content๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋‚˜์š”?

before_agent_callback์—์„œ Content๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์—์ด์ „ํŠธ ์‹คํ–‰์ด ๊ฑด๋„ˆ๋›ฐ์–ด์ง€๊ณ , ๋ฐ˜ํ™˜๋œ Content๊ฐ€ ์—์ด์ „ํŠธ์˜ ์‘๋‹ต์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด๋ถ€ ๋‹จ์ถ•(short-circuit)์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q5: LoopAgent์˜ escalate๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋‚˜์š”?

sub_agent๊ฐ€ Event๋ฅผ ์ƒ์„ฑํ•  ๋•Œ actions=EventActions(escalate=True)๋ฅผ ์„ค์ •ํ•˜๋ฉด, LoopAgent๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ฆ‰์‹œ ๋ฃจํ”„๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. max_iterations์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์กฐ๊ฑด๋ถ€๋กœ ์ข…๋ฃŒํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ