์ฝ˜ํ…์ธ ๋กœ ์ด๋™

ADK์šฉ Java ๋น ๋ฅธ ์‹œ์ž‘

์ด ๊ฐ€์ด๋“œ๋Š” ADK(Agent Development Kit) for Java๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์ด ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

  • Java 17 ์ด์ƒ
  • Maven 3.9 ์ด์ƒ

์—์ด์ „ํŠธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

๋‹ค์Œ ํŒŒ์ผ ๋ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋กœ ์—์ด์ „ํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

my_agent/
    src/main/java/com/example/agent/
                        HelloTimeAgent.java # ๋ฉ”์ธ ์—์ด์ „ํŠธ ์ฝ”๋“œ
                        AgentCliRunner.java # ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค
    pom.xml                                 # ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ
    .env                                    # API ํ‚ค ๋˜๋Š” ํ”„๋กœ์ ํŠธ ID
๋ช…๋ น์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์ƒ์„ฑ
mkdir my_agent\src\main\java\com\example\agent
type nul > my_agent\src\main\java\com\example\agent\HelloTimeAgent.java
type nul > my_agent\src\main\java\com\example\agent\AgentCliRunner.java
type nul > my_agent\pom.xml
type nul > my_agent\.env
mkdir -p my_agent/src/main/java/com/example/agent && \
    touch my_agent/src/main/java/com/example/agent/HelloTimeAgent.java && \
    touch my_agent/src/main/java/com/example/agent/AgentCliRunner.java && \
    touch my_agent/pom.xml my_agent/.env

์—์ด์ „ํŠธ ์ฝ”๋“œ ์ •์˜

ADK ํ•จ์ˆ˜ ๋„๊ตฌ์˜ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„์ธ getCurrentTime()์„ ํฌํ•จํ•˜์—ฌ ๊ธฐ๋ณธ ์—์ด์ „ํŠธ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์˜ HelloTimeAgent.java ํŒŒ์ผ์— ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

my_agent/src/main/java/com/example/agent/HelloTimeAgent.java
package com.example.agent;

import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;

import java.util.Map;

public class HelloTimeAgent {

    public static BaseAgent ROOT_AGENT = initAgent();

    private static BaseAgent initAgent() {
        return LlmAgent.builder()
            .name("hello-time-agent")
            .description("์ง€์ •๋œ ๋„์‹œ์˜ ํ˜„์žฌ ์‹œ๊ฐ„์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.")
            .instruction("""
                ๋‹น์‹ ์€ ์ง€์ •๋œ ๋„์‹œ์˜ ํ˜„์žฌ ์‹œ๊ฐ„์„ ์•Œ๋ ค์ฃผ๋Š” ์œ ์šฉํ•œ ๋„์šฐ๋ฏธ์ž…๋‹ˆ๋‹ค.
                ์ด๋ฅผ ์œ„ํ•ด 'getCurrentTime' ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
                """)
            .model("gemini-flash-latest")
            .tools(FunctionTool.create(HelloTimeAgent.class, "getCurrentTime"))
            .build();
    }

    /** Mock ๋„๊ตฌ ๊ตฌํ˜„ */
    @Schema(description = "์ฃผ์–ด์ง„ ๋„์‹œ์— ๋Œ€ํ•œ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.")
    public static Map<String, String> getCurrentTime(
        @Schema(name = "city", description = "์‹œ๊ฐ„์„ ๊ฐ€์ ธ์˜ฌ ๋„์‹œ ์ด๋ฆ„") String city) {
        return Map.of(
            "city", city,
            "forecast", "์‹œ๊ฐ„์€ ์˜ค์ „ 10์‹œ 30๋ถ„์ž…๋‹ˆ๋‹ค."
        );
    }
}

์ฃผ์˜: Gemini 3 ํ˜ธํ™˜์„ฑ

ADK Java v0.3.0 ์ดํ•˜๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ๋Œ€ํ•œ ์‚ฌ๊ณ  ์„œ๋ช… ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด Gemini 3 Pro Preview์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  Gemini 2.5 ์ดํ•˜ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

ํ”„๋กœ์ ํŠธ ๋ฐ ์ข…์†์„ฑ ๊ตฌ์„ฑ

ADK ์—์ด์ „ํŠธ ํ”„๋กœ์ ํŠธ๋Š” pom.xml ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์— ๋‹ค์Œ ์ข…์†์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

my_agent/pom.xml (์ผ๋ถ€)
<dependencies>
    <dependency>
        <groupId>com.google.adk</groupId>
        <artifactId>google-adk</artifactId>
        <version>1.12.0</version>
    </dependency>
</dependencies>

pom.xml ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์ด ์ข…์†์„ฑ๊ณผ ์ถ”๊ฐ€ ์„ค์ •์„ ๋‹ค์Œ ๊ตฌ์„ฑ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์™„์ „ํ•œ pom.xml ๊ตฌ์„ฑ

๋‹ค์Œ ์ฝ”๋“œ๋Š” ์ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์™„์ „ํ•œ pom.xml ๊ตฌ์„ฑ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

my_agent/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.agent</groupId>
    <artifactId>adk-agents</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- ์‚ฌ์šฉํ•  Java ๋ฒ„์ „ ์ง€์ • -->
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- ADK ์ฝ”์–ด ์ข…์†์„ฑ -->
        <dependency>
            <groupId>com.google.adk</groupId>
            <artifactId>google-adk</artifactId>
            <version>1.12.0</version>
        </dependency>
        <!-- ์—์ด์ „ํŠธ๋ฅผ ๋””๋ฒ„๊ทธํ•˜๊ธฐ ์œ„ํ•œ ADK ๊ฐœ๋ฐœ ์›น UI -->
        <dependency>
            <groupId>com.google.adk</groupId>
            <artifactId>google-adk-dev</artifactId>
            <version>1.12.0</version>
        </dependency>
    </dependencies>

</project>

API ํ‚ค ์„ค์ •

์ด ํ”„๋กœ์ ํŠธ๋Š” API ํ‚ค๊ฐ€ ํ•„์š”ํ•œ Gemini API๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Gemini API ํ‚ค๊ฐ€ ์•„์ง ์—†๋Š” ๊ฒฝ์šฐ Google AI Studio์˜ API ํ‚ค ํŽ˜์ด์ง€์—์„œ ํ‚ค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ„ฐ๋ฏธ๋„ ์ฐฝ์—์„œ ํ”„๋กœ์ ํŠธ์˜ .env ํŒŒ์ผ์— API ํ‚ค๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ: my_agent/.env
echo 'export GOOGLE_API_KEY="YOUR_API_KEY"' > .env
์—…๋ฐ์ดํŠธ: my_agent/env.bat
echo 'set GOOGLE_API_KEY="YOUR_API_KEY"' > env.bat
์—…๋ฐ์ดํŠธ: my_agent/env.bat
echo set GOOGLE_API_KEY="YOUR_API_KEY" > env.bat
ADK์—์„œ ๋‹ค๋ฅธ AI ๋ชจ๋ธ ์‚ฌ์šฉ

ADK๋Š” ๋‹ค์–‘ํ•œ ์ƒ์„ฑํ˜• AI ๋ชจ๋ธ ์‚ฌ์šฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ADK ์—์ด์ „ํŠธ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ชจ๋ธ ๋ฐ ์ธ์ฆ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์—์ด์ „ํŠธ ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ

AgentCliRunner.java ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ช…๋ น์ค„์—์„œ HelloTimeAgent๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ RunConfig ๊ฐ์ฒด์™€ ์‹คํ–‰ ์ค‘์ธ ์—์ด์ „ํŠธ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•œ Session ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

my_agent/src/main/java/com/example/agent/AgentCliRunner.java
package com.example.agent;

import com.google.adk.agents.RunConfig;
import com.google.adk.events.Event;
import com.google.adk.runner.InMemoryRunner;
import com.google.adk.sessions.Session;
import com.google.genai.types.Content;
import com.google.genai.types.Part;
import io.reactivex.rxjava3.core.Flowable;
import java.util.Scanner;

import static java.nio.charset.StandardCharsets.UTF_8;

public class AgentCliRunner {

    public static void main(String[] args) {
        RunConfig runConfig = RunConfig.builder().build();
        InMemoryRunner runner = new InMemoryRunner(HelloTimeAgent.ROOT_AGENT);

        Session session = runner
                .sessionService()
                .createSession(runner.appName(), "user1234")
                .blockingGet();

        try (Scanner scanner = new Scanner(System.in, UTF_8)) {
            while (true) {
                System.out.print("\nYou > ");
                String userInput = scanner.nextLine();
                if ("quit".equalsIgnoreCase(userInput)) {
                    break;
                }

                Content userMsg = Content.fromParts(Part.fromText(userInput));
                Flowable<Event> events = runner.runAsync(session.userId(), session.id(), userMsg, runConfig);

                System.out.print("\nAgent > ");
                events.blockingForEach(event -> {
                    if (event.finalResponse()) {
                        System.out.println(event.stringifyContent());
                    }
                });
            }
        }
    }
}

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

์ •์˜ํ•œ ๋Œ€ํ™”ํ˜• ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค AgentCliRunner ํด๋ž˜์Šค ๋˜๋Š” AdkWebServer ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ADK์—์„œ ์ œ๊ณตํ•˜๋Š” ADK ์›น ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ADK ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์„ ํ†ตํ•ด ์—์ด์ „ํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‹คํ–‰

๋‹ค์Œ Maven ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค AgentCliRunner ํด๋ž˜์Šค๋กœ ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

# ํ‚ค ๋ฐ ์„ค์ • ๋กœ๋“œ: source .env ๋˜๋Š” env.bat
mvn compile exec:java -Dexec.mainClass="com.example.agent.AgentCliRunner"

adk-run.png

์›น ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‹คํ–‰

๋‹ค์Œ Maven ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ADK ์›น ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

# ํ‚ค ๋ฐ ์„ค์ • ๋กœ๋“œ: source .env ๋˜๋Š” env.bat
mvn compile exec:java \
    -Dexec.mainClass="com.google.adk.web.AdkWebServer" \
    -Dexec.args="--adk.agents.source-dir=target --server.port=8000"

์ด ๋ช…๋ น์€ ์—์ด์ „ํŠธ์šฉ ์ฑ„ํŒ… ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ๋Š” ์›น ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์›น ์ธํ„ฐํŽ˜์ด์Šค๋Š” (http://localhost:8000)์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™ผ์ชฝ ์ƒ๋‹จ ๋ชจ์„œ๋ฆฌ์—์„œ ์—์ด์ „ํŠธ๋ฅผ ์„ ํƒํ•˜๊ณ  ์š”์ฒญ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

adk-web-dev-ui-chat.png

์ฃผ์˜: ADK Web์€ ๊ฐœ๋ฐœ์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”

ADK Web์€ ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ADK Web์€ ๊ฐœ๋ฐœ ๋ฐ ๋””๋ฒ„๊น… ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”.

๋‹ค์Œ: ์—์ด์ „ํŠธ ๋นŒ๋“œ

์ด์ œ ADK๊ฐ€ ์„ค์น˜๋˜์—ˆ๊ณ  ์ฒซ ๋ฒˆ์งธ ์—์ด์ „ํŠธ๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ฏ€๋กœ ์ด์ œ ๋นŒ๋“œ ๊ฐ€์ด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ๋งŒ์˜ ์—์ด์ „ํŠธ๋ฅผ ๋นŒ๋“œํ•ด ๋ณด์„ธ์š”.

```