[LLM] Agent Development Kit (ADK)

[์›๋ณธ ๋งํฌ]

Agent Development Kit(์ดํ•˜ ADK)๋Š” ๊ตฌ๊ธ€์—์„œ ๋ฐœํ‘œํ•œ ์—์ด์ „ํŠธ ๊ฐœ๋ฐœ์šฉ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค.
์ฑ„ํŒ…์œผ๋กœ ๋Œ€ํ‘œ๋˜๋Š” LLM ์—์ด์ „ํŠธ ๊ฐœ๋ฐœ์šฉ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

ํ˜„์žฌ๋Š” Python๊ณผ Java ์ •๋„๋งŒ ์ง€์›๋œ๋‹ค. ๋ฉ”์ธ์€ ๋‹น์—ฐํžˆ Python์ด๋‹ค.

๊ตฌ๊ธ€์—์„œ ์ œ๊ณตํ•˜๋Š” Gemini๋‚˜ vertex API๋ฅผ ์ฃผ๋กœ ์“ด๋‹ค๋Š” ๊ฐ€์ • ํ•˜์— ์นœ์ ˆํ•˜๊ฒŒ ๊พธ๋ฉฐ๋†“์€ ๋ชจ์–‘์ƒˆ๋‹ค. ๋ฌผ๋ก  Gemini์— ์ข…์†๋œ ๊ตฌ์กฐ๋Š” ์•„๋‹ˆ๋ผ์„œ Claude๋‚˜ GPT ๊ฐ™์€ LLM ๋ชจ๋ธ๋“ค๊ณผ๋„ ํ†ตํ•ฉ์ด ๊ฐ€๋Šฅํ•˜๊ธด ํ•˜๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” ๊ฐœ๋žต์ ์ธ ์‚ฌ์šฉ ๊ตฌ์กฐ์™€ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ œ ์ •๋„๋งŒ์„ ๋‹ค๋ค„๋ณธ๋‹ค.




๊ตฌ์กฐ

๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๋‚˜ ๋ฐฉ๋ฒ•๋ก  ์ž์ฒด๋Š” ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ํŽธ์ด๋‹ค.
๋ณ„๋„์˜ ์—์ด์ „ํŠธ ๋‹จ์œ„๋ฅผ ํด๋ž˜์Šค ๋‹จ์œ„๋กœ ์ •์˜ํ•˜๊ณ , ๊ทธ๊ฑธ ํ•„์š”์— ๋”ฐ๋ผ์„œ ์—ฐ๊ฒฐํ•˜๊ณ  ์ƒํ˜ธ๊ฐ„์— ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ์—ฎ์–ด์ฃผ๋Š” ๊ฒƒ์ด ๊ณจ์ž๋‹ค.

๊ทธ ์™ธ์—๋„ ์ด๊ฒƒ์ €๊ฒƒ ์ง€์›ํ•˜๊ธด ํ•œ๋‹ค.
tool ๊ด€๋ฆฌ ๊ธฐ๋Šฅ๋„ ์žˆ๊ณ , ๊ฐœ๋ฐœ/๋””๋ฒ„๊น… ๋ณด์กฐ์šฉ ๋„๊ตฌ๋“ค์„ ์•ฝ๊ฐ„ ์ง€์›ํ•œ๋‹ค.




์„ค์น˜

์„ค์น˜ ์ž์ฒด๋Š” ๊ฐ„๋‹จํ•˜๋‹ค. ๋‹จ์ผ ์ข…์†์„ฑ์œผ๋กœ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

uv add google-adk

ํฌ๊ธฐ๋Š” 340mb์ฏค ๋œ๋‹ค. ๋–ก์น ์„ ํ•˜๋„ ํ•ด๋Œ€์„œ ์ข€ ๋น„๋Œ€ํ•œ ํŽธ์ด๋‹ค.





ํ”„๋กœ์ ํŠธ ๊ธฐ๋ณธ ๊ตฌ์กฐ

๋จผ์ €, LLM์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ API Key๋ฅผ ์ค€๋น„ํ•ด์•ผ ํ•œ๋‹ค.
GCP API๋ฅผ ํ†ตํ•ด์„œ Gemini๋ฅผ ์“ด๋‹ค๋ฉด, ์ด๋ ‡๊ฒŒ .env ํŒŒ์ผ์„ ํ†ตํ•ด์„œ GOOGLE_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ํ‚ค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๊ฑด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๊ฒฝ๋กœ์— ์žˆ์–ด๋„ ๋˜๊ณ , ์—์ด์ „ํŠธ๋ณ„ ๋ณ„๋„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ์–ด๋„ ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒŒ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋ณธ์ ์ธ ํ˜•ํƒœ๋‹ค.
์—์ด์ „ํŠธ๋งˆ๋‹ค ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ , agent.py๋ผ๋Š” ๊ธฐ๋ณธ ์ง„์ž…์  ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

๊ฐ agent.py์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—์ด์ „ํŠธ ์ •์˜๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉด ๋œ๋‹ค.

from google.adk.agents import Agent

root_agent = Agent(
    name="hello_agent",
    model="gemini-2.0-flash",
    description=("Agent to say hello."),
    instruction=(
        "You are an agent who handles greetings and basic daily conversations."
    ),
    tools=[],
)

description์€ ๋Œ€๋žต์ ์ธ agent์˜ ์—ญํ• ์„ ๋ช…์‹œํ•˜๊ณ , instruction์€ ์„ธ๋ถ€์ ์ธ ์ง€์‹œ์‚ฌํ•ญ๋“ค์€ ์ •์˜ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.
tools๋Š” ์™ธ๋ถ€ ์†Œ์Šค๋‚˜ ๋ญ ๊ทธ๋Ÿฐ๊ฑธ ์ถ”๊ฐ€ํ•˜๋Š”๊ฑด๋ฐ, ๊ทธ๊ฑด ์ถ”ํ›„์— ๋‹ค์‹œ ์ •๋ฆฌํ•ด๋ณด๊ฒ ๋‹ค.




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

adk CLI๋ฅผ ํ†ตํ•ด์„œ ์ œ์–ดํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

adk web์„ ์‚ฌ์šฉํ•˜๋ฉด, ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ธฐ์ค€์œผ๋กœ ์—์ด์ „ํŠธ ๊ตฌ์„ฑ์„ ์ฝ์–ด์„œ ๋””๋ฒ„๊ทธ์šฉ ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ด๋Ÿฐ ์ž˜ ๊พธ๋ฉฐ์ง„ ํŽ˜์ด์ง€๊ฐ€ ๋œจ๊ณ 

์—์ด์ „ํŠธ๋ฅผ ๊ณจ๋ผ์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ

์ฆ‰์‹œ ๋Œ๋ ค๋ณด๋ฉด์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

api_server ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ์ €๊ธฐ์„œ ๊ทธ๋ƒฅ API ์„œ๋ฒ„๋งŒ ์‹คํ–‰๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ข€ ๋ญ๊ฐ€ ๋งŽ๊ธด ํ•˜๋‹ค.




ํ”„๋กฌํ”„ํŠธ ์„ค์ • - instruction

LLM์˜ ํ–‰๋™ ๋ฐฉ์‹์„ ์ œ์–ดํ•˜๋ ค๋ฉด, instruction ํ•„๋“œ๋ฅผ ํ†ตํ•ด์„œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค.

๋™์ž‘ ๋ฐฉ์‹ ์ž์ฒด๋Š” ๋‹จ์ˆœํ•˜๋‹ค.

๋งŒ์•ฝ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋™์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, before_model_callback ๋“ฑ์„ ํ†ตํ•ด์„œ state๋ฅผ ์กฐ์ž‘ํ•˜๊ณ , state variable ๊ธฐ๋ฐ˜์œผ๋กœ ํ”„๋กฌํ”„ํŠธ ํ…์ŠคํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ฒŒ๋” ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
์—ฌ๊ธฐ์„œ๋Š” ์ž์„ธํ•œ ๊ฒƒ๊นŒ์ง€๋Š” ๋‹ค๋ฃจ์ง€ ์•Š๊ณ  ๋„˜์–ด๊ฐ„๋‹ค.




Tools

tools๋Š” ADK์—์„œ ์™ธ๋ถ€ ์†Œ์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด๋‹ค.
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋‹ค๊ฑฐ๋‚˜, ๋‚ ์”จ๋‚˜ ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค๊ฑฐ๋‚˜ ํ•˜๋Š”, LLM ์ž์ฒด์ ์œผ๋กœ ํš๋“ํ•  ์ˆ˜ ์—†๋Š” ์†Œ์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ LLM์— ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋Ÿฐ ์‹์œผ๋กœ tool์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ๋‚ด ๊ตฌํ˜„์ด ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€๋Š” ๊ทธ๋‹ค์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค.
ํ•จ์ˆ˜ ๋‚ด ์ฝ”๋ฉ˜ํŠธ๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น tool ํ•จ์ˆ˜์˜ ๋™์ž‘๊ณผ, ์ž…๋ ฅ/์ถœ๋ ฅ๊ฐ’์„ ์ž˜ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.


๊ทธ๋ฆฌ๊ณ  ์ €๊ฑธ tools์— ๋„˜๊ฒจ์ฃผ๋ฉด ๋์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฉด Agent๊ฐ€ ์ € ์ฝ”๋ฉ˜ํŠธ์— ๊ธฐ๋ฐ˜ํ•ด์„œ, ํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋Š” tool์„ ์ž์œจ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๊ณ  ๋‚˜์„œ ์‹คํ–‰ํ•ด๋ณด๋ฉด

์ด๋Ÿฐ ์‹์œผ๋กœ ํ˜ธ์ถœํ•ด์„œ LLM์ด ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ›์•„๋‹ค๊ฐ€ ์“ฐ๊ฒŒ ๋œ๋‹ค.




๋ฉ€ํ‹ฐ ์—์ด์ „ํŠธ ๊ตฌ์„ฑ

์ด๋Ÿฐ ์—์ด์ „ํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์“ฐ๋Š” ์ฃผ์š”ํ•œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๊ฐ€, ์—ฌ๋Ÿฌ๊ฐœ์˜ ์—์ด์ „ํŠธ๋กœ ๊ตฌ์„ฑ๋œ ๋ฉ€ํ‹ฐ ์—์ด์ „ํŠธ ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.


from google.adk.agents import Agent

dev_agent = Agent(
    name="dev_agent",
    model="gemini-2.0-flash",
    description=("Agent informing about programming"),
    instruction="""
        1. You are an agent who handles programming-related queries.
        2. You must always answer about programming.
        """,
    tools=[],
)

food_agent = Agent(
    name="food_agent",
    model="gemini-2.0-flash",
    description=("Agent informing about food"),
    instruction="""
        1. You are an agent who handles food-related queries.
        2. You must always answer about food.
        """,
    tools=[],
)

root_agent = Agent(
    name="root_agent",
    model="gemini-2.0-flash",
    description=("Root agent"),
    instruction="""
        1. You are the root agent.
        2. You must always answer about programming or food.
        """,
    tools=[],
    sub_agents=[dev_agent, food_agent],
)

์ด๋Ÿฐ ์‹์œผ๋กœ, ์–ด๋–ค ์—์ด์ „ํŠธ๊ฐ€ ๋‹ค๋ฅธ ์—์ด์ „ํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด sub_agents๋กœ ๋‹ค๋ฅธ ์—์ด์ „ํŠธ ์ •์˜๋ฅผ ๊ตฌ๊ฒจ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.
์ด ๊ฒฝ์šฐ์—๋Š” "๊ฐœ๋ฐœ"๊ณผ "์Œ์‹"์— ๋Œ€ํ•œ ์—์ด์ „ํŠธ๋ฅผ ๋ณ„๋„๋กœ ์ •์˜ํ•˜๊ณ , root ์—์ด์ „ํŠธ๊ฐ€ ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ๋‹ค.


๊ทธ๋Ÿฌ๋ฉด ์ด๋Ÿฐ ์‹์œผ๋กœ root => food์˜ ์ˆœ์„œ๋กœ ์—์ด์ „ํŠธ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•  ๊ฒƒ์ด๋‹ค.


์˜†์— ์‹คํ–‰ ๋กœ๊ทธ๋„ ์ด๋ฒคํŠธ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.



์ฐธ์กฐ
https://developers.googleblog.com/en/agent-development-kit-easy-to-build-multi-agent-applications/
https://google.github.io/adk-docs/agents/llm-agents/
https://dev.to/masahide/smarter-adk-prompts-inject-state-and-artifact-data-dynamically-placeholders-2dcm