Skip to content
Supported in ADKPython v0.1.0Go v0.1.0Java v0.1.0

LlmAgent(通常也简称为 Agent)是 ADK 的核心组件,它是你应用中"思考"的部分。它利用大语言模型(LLM)的强大能力,进行推理、理解自然语言、做出决策、生成回复并与工具交互。

与遵循预定义执行路径的确定性工作流智能体不同,LlmAgent 的行为是非确定性的。它利用 LLM 来解释指令和上下文,动态决定如何推进、使用哪些工具(如果有)、或是否将控制权转移给其他智能体。

构建一个高效的 LlmAgent 需要定义其身份,通过指令清晰引导其行为,并为其配备必要的工具和能力。

定义智能体的身份和目的

首先,你需要确定这个智能体是什么以及它用来做什么

  • name(必填): 每个智能体都需要一个唯一的字符串标识符。这个 name 对内部操作至关重要,尤其是在多智能体系统中,智能体需要相互引用或委派任务。选择一个能反映智能体功能的描述性名称(例如,customer_support_routerbilling_inquiry_agent)。避免使用像 user 这样的保留名称。

  • description(可选,多智能体推荐): 提供一个简洁的智能体能力摘要。这个描述主要由其他 LLM 智能体用来确定是否应该将任务路由到这个智能体。使其足够具体以区分它与其他智能体(例如,"处理关于当前账单明细的查询",而不仅仅是"账单智能体")。

  • model(必填): 指定将为此智能体的推理提供支持的底层 LLM。这是一个字符串标识符,如 "gemini-2.0-flash"。模型的选择会影响智能体的能力、成本和性能。查看模型页面了解可用选项和考虑因素。

# 示例:定义基本身份
capital_agent = LlmAgent(
    model="gemini-2.0-flash",
    name="capital_agent",
    description="回答用户关于某个国家首都的问题。"
    # instruction 和 tools 会在后面添加
)
// Example: Defining the basic identity
agent, err := llmagent.New(llmagent.Config{
    Name:        "capital_agent",
    Model:       model,
    Description: "Answers user questions about the capital city of a given country.",
    // instruction and tools will be added next
})
// 示例:定义基本身份
LlmAgent capitalAgent =
    LlmAgent.builder()
        .model("gemini-2.0-flash")
        .name("capital_agent")
        .description("回答用户关于某个国家首都的问题。")
        // instruction 和 tools 会在后面添加
        .build();

指导智能体:指令(instruction

指令是你提供给智能体的自然语言指导,告诉它如何行为。精心编写的指令对于智能体的成功至关重要,它们应包括:

  • 其核心任务或目标。
  • 其个性或角色(例如,"你是一个乐于助人的助手","你是一个机智的海盗")。
  • 对其行为的约束(例如,"只回答关于 X 的问题","永远不要透露 Y")。
  • 如何以及何时使用其 tools。你应该解释每个工具的用途以及应该在什么情况下调用它,补充工具本身的任何描述。
  • 其输出的期望格式(例如,"以 JSON 形式回应","提供一个项目符号列表")。

有效指令的技巧:

  • 清晰明确: 避免含糊不清。清楚地说明期望的行动和结果。
  • 使用 Markdown: 使用标题、列表等提高复杂指令的可读性。
  • 提供示例(少样本): 对于复杂任务或特定输出格式,直接在指令中包含示例。
  • 指导工具使用: 不仅仅是列出工具;解释智能体何时为什么应该使用它们。

状态:

  • 指令是一个字符串模板,你可以使用 {var} 语法向指令中插入动态值。
  • {var} 用于插入名为 var 的状态变量的值。
  • {artifact.var} 用于插入名为 var 的人工制品的文本内容。
  • 如果状态变量或人工制品不存在,智能体将引发错误。如果你想忽略错误,可以在变量名后附加 ?,如 {var?}

```python

示例:添加指令

capital_agent = LlmAgent( model="gemini-2.0-flash", name="capital_agent", description="回答用户关于某个国家首都的问题。", instruction="""你是一个提供国家首都信息的智能体。

当用户询问某个国家的首都时:

  1. 从用户的提问中识别国家名称。
  2. 使用 get_capital_city 工具查找首都。
  3. 明确地回复用户,说明该国家的首都。 示例提问:"What's the capital of {country}?" 示例回复:"The capital of France is Paris." """, # tools 会在后面添加 )

    ```

    // Example: Adding instructions
    agent, err := llmagent.New(llmagent.Config{
        Name:        "capital_agent",
        Model:       model,
        Description: "Answers user questions about the capital city of a given country.",
        Instruction: `You are an agent that provides the capital city of a country.
When a user asks for the capital of a country:
1. Identify the country name from the user's query.
2. Use the 'get_capital_city' tool to find the capital.
3. Respond clearly to the user, stating the capital city.
Example Query: "What's the capital of {country}?"
Example Response: "The capital of France is Paris."`,
        // tools will be added next
    })
// 示例:添加指令
LlmAgent capitalAgent =
    LlmAgent.builder()
        .model("gemini-2.0-flash")
        .name("capital_agent")
        .description("回答用户关于某个国家首都的问题。")
        .instruction(
            """
            你是一个提供国家首都信息的智能体。
            当用户询问某个国家的首都时:
            1. 从用户的提问中识别国家名称。
            2. 使用 `get_capital_city` 工具查找首都。
            3. 明确地回复用户,说明该国家的首都。
            示例提问:\"What's the capital of {country}?\"
            示例回复:\"The capital of France is Paris.\"
            """)
        // tools 会在后面添加
        .build();

(注意:对于应用于系统中所有智能体的指令,考虑在根智能体上使用 global_instruction,在 多智能体 部分中有详细说明。)

为智能体装备:工具(tools

工具赋予你的 LlmAgent 超越 LLM 内置知识或推理的能力。它们允许智能体与外部世界交互,执行计算,获取实时数据,或执行特定操作。

  • tools(可选): 提供一个智能体可用的工具列表。列表中的每一项可以是:
  • 一个原生函数或方法(在 Python 中自动包装为 FunctionTool,在 Java 中需显式用 FunctionTool.create(...) 包装)。
  • 继承自 BaseTool 的类的实例。
  • 另一个智能体的实例(AgentTool,实现智能体间委托——见多智能体)。

LLM 会根据函数/工具名称、描述(来自文档字符串或 description 字段)和参数模式,结合对话和指令,决定调用哪个工具。

# 定义一个工具函数
def get_capital_city(country: str) -> str:
  """检索指定国家的首都。"""
  # 替换为实际逻辑(如 API 调用、数据库查询)
  capitals = {"france": "Paris", "japan": "Tokyo", "canada": "Ottawa"}
  return capitals.get(country.lower(), f"抱歉,我不知道 {country} 的首都是什么。")

# 将工具添加到智能体
capital_agent = LlmAgent(
    model="gemini-2.0-flash",
    name="capital_agent",
    description="回答用户关于某个国家首都的问题。",
    instruction="""你是一个提供国家首都信息的智能体...(前述指令文本)""",
    tools=[get_capital_city] # 直接传递函数
)
// Define a tool function
type getCapitalCityArgs struct {
    Country string `json:"country" jsonschema:"The country to get the capital of."`
}
getCapitalCity := func(ctx tool.Context, args getCapitalCityArgs) (map[string]any, error) {
    // Replace with actual logic (e.g., API call, database lookup)
    capitals := map[string]string{"france": "Paris", "japan": "Tokyo", "canada": "Ottawa"}
    capital, ok := capitals[strings.ToLower(args.Country)]
    if !ok {
        return nil, fmt.Errorf("Sorry, I don't know the capital of %s.", args.Country)
    }
    return map[string]any{"result": capital}, nil
}

// Add the tool to the agent
capitalTool, err := functiontool.New(
    functiontool.Config{
        Name:        "get_capital_city",
        Description: "Retrieves the capital city for a given country.",
    },
    getCapitalCity,
)
if err != nil {
    log.Fatal(err)
}
agent, err := llmagent.New(llmagent.Config{
    Name:        "capital_agent",
    Model:       model,
    Description: "Answers user questions about the capital city of a given country.",
    Instruction: "You are an agent that provides the capital city of a country... (previous instruction text)",
    Tools:       []tool.Tool{capitalTool},
})
// 定义一个工具函数
// 检索指定国家的首都。
public static Map<String, Object> getCapitalCity(
        @Schema(name = "country", description = "要查询首都的国家")
        String country) {
  // 替换为实际逻辑(如 API 调用、数据库查询)
  Map<String, String> countryCapitals = new HashMap<>();
  countryCapitals.put("canada", "Ottawa");
  countryCapitals.put("france", "Paris");
  countryCapitals.put("japan", "Tokyo");

  String result =
          countryCapitals.getOrDefault(
                  country.toLowerCase(), "抱歉,我找不到 " + country + " 的首都。");
  return Map.of("result", result); // 工具必须返回 Map
}

// 将工具添加到智能体
FunctionTool capitalTool = FunctionTool.create(experiment.getClass(), "getCapitalCity");
LlmAgent capitalAgent =
    LlmAgent.builder()
        .model("gemini-2.0-flash")
        .name("capital_agent")
        .description("回答用户关于某个国家首都的问题。")
        .instruction("你是一个提供国家首都信息的智能体...(前述指令文本)")
        .tools(capitalTool) // 以 FunctionTool 包装的函数
        .build();

工具 部分了解更多关于工具的信息。

高级配置与控制

除了核心参数外,LlmAgent 还提供几个选项来进行更精细的控制:

配置 LLM 生成 (generate_content_config)

你可以使用 generate_content_config 调整底层 LLM 生成响应的方式。

  • generate_content_config(可选): 传递 google.genai.types.GenerateContentConfig 的实例来控制参数,如 temperature(随机性)、max_output_tokens(响应长度)、top_ptop_k 和安全设置。
from google.genai import types

agent = LlmAgent(
    # ... 其他参数
    generate_content_config=types.GenerateContentConfig(
        temperature=0.2, # 更确定性的输出
        max_output_tokens=250,
        safety_settings=[
            types.SafetySetting(
                category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
                threshold=types.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
            )
        ]
    )
)
import "google.golang.org/genai"

temperature := float32(0.2)
agent, err := llmagent.New(llmagent.Config{
    Name:  "gen_config_agent",
    Model: model,
    GenerateContentConfig: &genai.GenerateContentConfig{
        Temperature:     &temperature,
        MaxOutputTokens: 250,
    },
})
import com.google.genai.types.GenerateContentConfig;

LlmAgent agent =
    LlmAgent.builder()
        // ... 其他参数
        .generateContentConfig(GenerateContentConfig.builder()
            .temperature(0.2F) // 更确定性的输出
            .maxOutputTokens(250)
            .build())
        .build();

结构化数据 (input_schema, output_schema, output_key)

对于需要与 LLM Agent 进行结构化数据交换的场景,ADK 提供了通过 schema 定义输入和输出格式的机制。

  • input_schema(可选): 定义期望输入结构的 schema。如果设置,传递给该智能体的用户消息内容必须是符合此 schema 的 JSON 字符串。你的指令应引导用户或前序智能体按此格式提供输入。

  • output_schema(可选): 定义表示期望输出结构的 schema。如果设置,智能体的最终回复必须是符合此 schema 的 JSON 字符串。

  • output_key(可选): 提供一个字符串键。如果设置,智能体最终响应的文本内容将自动保存到会话状态字典下的此键下。这在智能体之间或工作流步骤之间传递结果时非常有用。

    • 在 Python 中,这可能看起来像:session.state[output_key] = agent_response_text
    • 在 Java 中:session.state().put(outputKey, agentResponseText)
    • 在 Golang 中,在回调处理器内:ctx.State().Set(output_key, agentResponseText)

输入和输出 schema 通常是 Pydantic 的 BaseModel。

from pydantic import BaseModel, Field

class CapitalOutput(BaseModel):
    capital: str = Field(description="该国家的首都。")

structured_capital_agent = LlmAgent(
    # ... name, model, description
    instruction="""你是一个首都信息智能体。给定一个国家,只能以 JSON 对象形式回复首都。格式:{"capital": "capital_name"}""",
    output_schema=CapitalOutput, # 强制输出为 JSON
    output_key="found_capital"  # 结果存入 state['found_capital']
    # 此时无法有效使用 tools=[get_capital_city]
)

The input and output schema is a google.genai.types.Schema object.

capitalOutput := &genai.Schema{
    Type:        genai.TypeObject,
    Description: "Schema for capital city information.",
    Properties: map[string]*genai.Schema{
        "capital": {
            Type:        genai.TypeString,
            Description: "The capital city of the country.",
        },
    },
}

agent, err := llmagent.New(llmagent.Config{
    Name:         "structured_capital_agent",
    Model:        model,
    Description:  "Provides capital information in a structured format.",
    Instruction:  `You are a Capital Information Agent. Given a country, respond ONLY with a JSON object containing the capital. Format: {"capital": "capital_name"}`,
    OutputSchema: capitalOutput,
    OutputKey:    "found_capital",
    // Cannot use the capitalTool tool effectively here
})

输入和输出 schema 是 google.genai.types.Schema 对象。

private static final Schema CAPITAL_OUTPUT =
    Schema.builder()
        .type("OBJECT")
        .description("首都信息的 schema。")
        .properties(
            Map.of(
                "capital",
                Schema.builder()
                    .type("STRING")
                    .description("该国家的首都。")
                    .build()))
        .build();

LlmAgent structuredCapitalAgent =
    LlmAgent.builder()
        // ... name, model, description
        .instruction(
                "你是一个首都信息智能体。给定一个国家,只能以 JSON 对象形式回复首都。格式:{\"capital\": \"capital_name\"}")
        .outputSchema(capitalOutput) // 强制输出为 JSON
        .outputKey("found_capital") // 结果存入 state.get("found_capital")
        // 此时无法有效使用 tools(getCapitalCity)
        .build();

管理上下文 (include_contents)

控制智能体是否接收之前的对话历史。

  • include_contents(可选,默认值:'default'): 确定是否将 contents(历史记录)发送给 LLM。
  • 'default':智能体接收相关的对话历史。
  • 'none':智能体不接收之前的 contents。它仅基于当前的指令和在当前轮次提供的任何输入进行操作(适用于无状态任务或强制特定上下文)。
stateless_agent = LlmAgent(
    # ... 其他参数
    include_contents='none'
)
import "google.golang.org/adk/agent/llmagent"

agent, err := llmagent.New(llmagent.Config{
    Name:            "stateless_agent",
    Model:           model,
    IncludeContents: llmagent.IncludeContentsNone,
})
import com.google.adk.agents.LlmAgent.IncludeContents;

LlmAgent statelessAgent =
    LlmAgent.builder()
        // ... other params
        .includeContents(IncludeContents.NONE)
        .build();

规划器

Supported in ADKPython v0.1.0

planner(可选): 分配一个 BasePlanner 实例以启用执行前的多步推理和规划。主要有两种 planner:

  • BuiltInPlanner 利用模型内置的规划能力(如 Gemini 的 thinking 特性)。详见 Gemini Thinking

    其中,thinking_budget 参数用于指导模型在生成响应时可用的思考 token 数量。include_thoughts 参数控制模型是否在响应中包含其原始思考和内部推理过程。

    from google.adk import Agent
    from google.adk.planners import BuiltInPlanner
    from google.genai import types
    
    my_agent = Agent(
        model="gemini-2.5-flash",
        planner=BuiltInPlanner(
            thinking_config=types.ThinkingConfig(
                include_thoughts=True,
                thinking_budget=1024,
            )
        ),
        # ... 你的工具
    )
    
  • PlanReActPlanner 该 planner 指示模型在输出中遵循特定结构:先制定计划,再执行动作(如调用工具),并为其步骤提供推理。这对于没有内置"思考"特性的模型特别有用

    from google.adk import Agent
    from google.adk.planners import PlanReActPlanner
    
    my_agent = Agent(
        model="gemini-2.0-flash",
        planner=PlanReActPlanner(),
        # ... 你的工具
    )
    

    智能体的响应将遵循如下结构:

    [user]: ai news
    [google_search_agent]: /*PLANNING*/
    1. 执行 Google 搜索"latest AI news",以获取与人工智能相关的最新动态和头条。
    2. 综合搜索结果,提供近期 AI 新闻摘要。
    
    /*ACTION*/
    /*REASONING*/
    搜索结果提供了近期 AI 新闻的全面概览,涵盖公司动态、研究突破和应用。我已获得足够信息来回答用户请求。
    
    /*FINAL_ANSWER*/
    Here's a summary of recent AI news:
    ....
    

使用内置规划器的示例:

from dotenv import load_dotenv


import asyncio
import os

from google.genai import types
from google.adk.agents.llm_agent import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService # 可选
from google.adk.planners import BasePlanner, BuiltInPlanner, PlanReActPlanner
from google.adk.models import LlmRequest

from google.genai.types import ThinkingConfig
from google.genai.types import GenerateContentConfig

import datetime
from zoneinfo import ZoneInfo

APP_NAME = "weather_app"
USER_ID = "1234"
SESSION_ID = "session1234"

def get_weather(city: str) -> dict:
    """检索指定城市的当前天气报告。

    Args:
        city (str): 要检索天气报告的城市名称。

    Returns:
        dict: 状态和结果或错误消息。
    """
    if city.lower() == "new york":
        return {
            "status": "success",
            "report": (
                "纽约的天气晴朗,温度为 25 摄氏度"
                "(77 华氏度)。"
            ),
        }
    else:
        return {
            "status": "error",
            "error_message": f"'{city}' 的天气信息不可用。",
        }


def get_current_time(city: str) -> dict:
    """返回指定城市的当前时间。

    Args:
        city (str): 要检索当前时间的城市名称。

    Returns:
        dict: 状态和结果或错误消息。
    """

    if city.lower() == "new york":
        tz_identifier = "America/New_York"
    else:
        return {
            "status": "error",
            "error_message": (
                f"抱歉,我没有 {city} 的时区信息。"
            ),
        }

    tz = ZoneInfo(tz_identifier)
    now = datetime.datetime.now(tz)
    report = (
        f'{city} 的当前时间是 {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
    )
    return {"status": "success", "report": report}

# 步骤 1:创建 ThinkingConfig {: #step-1-create-thinkingconfig}
thinking_config = ThinkingConfig(
    include_thoughts=True,   # 要求模型在响应中包含其思考
    thinking_budget=256      # 将"思考"限制为 256 个 token(根据需要调整)
)
print("ThinkingConfig:", thinking_config)

# 步骤 2:实例化 BuiltInPlanner {: #step-2-instantiate-builtinplanner}
planner = BuiltInPlanner(
    thinking_config=thinking_config
)
print("BuiltInPlanner 已创建。")

# 步骤 3:将规划器包装在 LlmAgent 中 {: #step-3-wrap-planner-in-llmagent}
agent = LlmAgent(
    model="gemini-2.5-pro-preview-03-25",  # 设置你的模型名称
    name="weather_and_time_agent",
    instruction="你是一个返回时间和天气的智能体",
    planner=planner,
    tools=[get_weather, get_current_time]
)

# 会话和运行器 {: #session-and-runner}
session_service = InMemorySessionService()
session = session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID)
runner = Runner(agent=agent, app_name=APP_NAME, session_service=session_service)

# 智能体交互 {: #agent-interaction}
def call_agent(query):
    content = types.Content(role='user', parts=[types.Part(text=query)])
    events = runner.run(user_id=USER_ID, session_id=SESSION_ID, new_message=content)

    for event in events:
        print(f"\nDEBUG EVENT: {event}\n")
        if event.is_final_response() and event.content:
            final_answer = event.content.parts[0].text.strip()
            print("\n🟢 最终答案\n", final_answer, "\n")

call_agent("If it's raining in New York right now, what is the current temperature?")

代码执行

Supported in ADKPython v0.1.0Java v0.1.0
  • code_executor (可选): 提供一个 BaseCodeExecutor 实例以允许智能体执行在 LLM 响应中找到的代码块。(参见 工具/内置工具)。
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import asyncio
from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.code_executors import BuiltInCodeExecutor
from google.genai import types

AGENT_NAME = "calculator_agent"
APP_NAME = "calculator"
USER_ID = "user1234"
SESSION_ID = "session_code_exec_async"
GEMINI_MODEL = "gemini-2.0-flash"

# Agent Definition
code_agent = LlmAgent(
    name=AGENT_NAME,
    model=GEMINI_MODEL,
    code_executor=BuiltInCodeExecutor(),
    instruction="""You are a calculator agent.
    When given a mathematical expression, write and execute Python code to calculate the result.
    Return only the final numerical result as plain text, without markdown or code blocks.
    """,
    description="Executes Python code to perform calculations.",
)

# Session and Runner
session_service = InMemorySessionService()
session = asyncio.run(session_service.create_session(
    app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID
))
runner = Runner(agent=code_agent, app_name=APP_NAME,
                session_service=session_service)

# Agent Interaction (Async)
async def call_agent_async(query):
    content = types.Content(role="user", parts=[types.Part(text=query)])
    print(f"\n--- Running Query: {query} ---")
    final_response_text = "No final text response captured."
    try:
        # Use run_async
        async for event in runner.run_async(
            user_id=USER_ID, session_id=SESSION_ID, new_message=content
        ):
            print(f"Event ID: {event.id}, Author: {event.author}")

            # --- Check for specific parts FIRST ---
            has_specific_part = False
            if event.content and event.content.parts:
                for part in event.content.parts:  # Iterate through all parts
                    if part.executable_code:
                        # Access the actual code string via .code
                        print(
                            f"  Debug: Agent generated code:\n```python\n{part.executable_code.code}\n```"
                        )
                        has_specific_part = True
                    elif part.code_execution_result:
                        # Access outcome and output correctly
                        print(
                            f"  Debug: Code Execution Result: {part.code_execution_result.outcome} - Output:\n{part.code_execution_result.output}"
                        )
                        has_specific_part = True
                    # Also print any text parts found in any event for debugging
                    elif part.text and not part.text.isspace():
                        print(f"  Text: '{part.text.strip()}'")
                        # Do not set has_specific_part=True here, as we want the final response logic below

            # --- Check for final response AFTER specific parts ---
            # Only consider it final if it doesn't have the specific code parts we just handled
            if not has_specific_part and event.is_final_response():
                if (
                    event.content
                    and event.content.parts
                    and event.content.parts[0].text
                ):
                    final_response_text = event.content.parts[0].text.strip()
                    print(f"==> Final Agent Response: {final_response_text}")
                else:
                    print(
                        "==> Final Agent Response: [No text content in final event]")

    except Exception as e:
        print(f"ERROR during agent run: {e}")
    print("-" * 30)


# Main async function to run the examples
async def main():
    await call_agent_async("Calculate the value of (5 + 7) * 3")
    await call_agent_async("What is 10 factorial?")


# Execute the main async function
try:
    asyncio.run(main())
except RuntimeError as e:
    # Handle specific error when running asyncio.run in an already running loop (like Jupyter/Colab)
    if "cannot be called from a running event loop" in str(e):
        print("\nRunning in an existing event loop (like Colab/Jupyter).")
        print("Please run `await main()` in a notebook cell instead.")
        # If in an interactive environment like a notebook, you might need to run:
        # await main()
    else:
        raise e  # Re-raise other runtime errors
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.runner.Runner;
import com.google.adk.sessions.InMemorySessionService;
import com.google.adk.sessions.Session;
import com.google.adk.tools.BuiltInCodeExecutionTool;
import com.google.common.collect.ImmutableList;
import com.google.genai.types.Content;
import com.google.genai.types.Part;

public class CodeExecutionAgentApp {

  private static final String AGENT_NAME = "calculator_agent";
  private static final String APP_NAME = "calculator";
  private static final String USER_ID = "user1234";
  private static final String SESSION_ID = "session_code_exec_sync";
  private static final String GEMINI_MODEL = "gemini-2.0-flash";

  /**
   * Calls the agent with a query and prints the interaction events and final response.
   *
   * @param runner The runner instance for the agent.
   * @param query The query to send to the agent.
   */
  public static void callAgent(Runner runner, String query) {
    Content content =
        Content.builder().role("user").parts(ImmutableList.of(Part.fromText(query))).build();

    InMemorySessionService sessionService = (InMemorySessionService) runner.sessionService();
    Session session =
        sessionService
            .createSession(APP_NAME, USER_ID, /* state= */ null, SESSION_ID)
            .blockingGet();

    System.out.println("\n--- Running Query: " + query + " ---");
    final String[] finalResponseText = {"No final text response captured."};

    try {
      runner
          .runAsync(session.userId(), session.id(), content)
          .forEach(
              event -> {
                System.out.println("Event ID: " + event.id() + ", Author: " + event.author());

                boolean hasSpecificPart = false;
                if (event.content().isPresent() && event.content().get().parts().isPresent()) {
                  for (Part part : event.content().get().parts().get()) {
                    if (part.executableCode().isPresent()) {
                      System.out.println(
                          "  Debug: Agent generated code:\n```python\n"
                              + part.executableCode().get().code()
                              + "\n```");
                      hasSpecificPart = true;
                    } else if (part.codeExecutionResult().isPresent()) {
                      System.out.println(
                          "  Debug: Code Execution Result: "
                              + part.codeExecutionResult().get().outcome()
                              + " - Output:\n"
                              + part.codeExecutionResult().get().output());
                      hasSpecificPart = true;
                    } else if (part.text().isPresent() && !part.text().get().trim().isEmpty()) {
                      System.out.println("  Text: '" + part.text().get().trim() + "'");
                    }
                  }
                }

                if (!hasSpecificPart && event.finalResponse()) {
                  if (event.content().isPresent()
                      && event.content().get().parts().isPresent()
                      && !event.content().get().parts().get().isEmpty()
                      && event.content().get().parts().get().get(0).text().isPresent()) {
                    finalResponseText[0] =
                        event.content().get().parts().get().get(0).text().get().trim();
                    System.out.println("==> Final Agent Response: " + finalResponseText[0]);
                  } else {
                    System.out.println(
                        "==> Final Agent Response: [No text content in final event]");
                  }
                }
              });
    } catch (Exception e) {
      System.err.println("ERROR during agent run: " + e.getMessage());
      e.printStackTrace();
    }
    System.out.println("------------------------------");
  }

  public static void main(String[] args) {
    BuiltInCodeExecutionTool codeExecutionTool = new BuiltInCodeExecutionTool();

    BaseAgent codeAgent =
        LlmAgent.builder()
            .name(AGENT_NAME)
            .model(GEMINI_MODEL)
            .tools(ImmutableList.of(codeExecutionTool))
            .instruction(
                """
                                You are a calculator agent.
                                When given a mathematical expression, write and execute Python code to calculate the result.
                                Return only the final numerical result as plain text, without markdown or code blocks.
                                """)
            .description("Executes Python code to perform calculations.")
            .build();

    InMemorySessionService sessionService = new InMemorySessionService();
    Runner runner = new Runner(codeAgent, APP_NAME, null, sessionService);

    callAgent(runner, "Calculate the value of (5 + 7) * 3");
    callAgent(runner, "What is 10 factorial?");
  }
}

综合示例

代码

这是完整的基本 capital_agent

# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# --- Full example code demonstrating LlmAgent with Tools vs. Output Schema ---
import json # Needed for pretty printing dicts
import asyncio 

from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from pydantic import BaseModel, Field

# --- 1. Define Constants ---
APP_NAME = "agent_comparison_app"
USER_ID = "test_user_456"
SESSION_ID_TOOL_AGENT = "session_tool_agent_xyz"
SESSION_ID_SCHEMA_AGENT = "session_schema_agent_xyz"
MODEL_NAME = "gemini-2.0-flash"

# --- 2. Define Schemas ---

# Input schema used by both agents
class CountryInput(BaseModel):
    country: str = Field(description="The country to get information about.")

# Output schema ONLY for the second agent
class CapitalInfoOutput(BaseModel):
    capital: str = Field(description="The capital city of the country.")
    # Note: Population is illustrative; the LLM will infer or estimate this
    # as it cannot use tools when output_schema is set.
    population_estimate: str = Field(description="An estimated population of the capital city.")

# --- 3. Define the Tool (Only for the first agent) ---
def get_capital_city(country: str) -> str:
    """Retrieves the capital city of a given country."""
    print(f"\n-- Tool Call: get_capital_city(country='{country}') --")
    country_capitals = {
        "united states": "Washington, D.C.",
        "canada": "Ottawa",
        "france": "Paris",
        "japan": "Tokyo",
    }
    result = country_capitals.get(country.lower(), f"Sorry, I couldn't find the capital for {country}.")
    print(f"-- Tool Result: '{result}' --")
    return result

# --- 4. Configure Agents ---

# Agent 1: Uses a tool and output_key
capital_agent_with_tool = LlmAgent(
    model=MODEL_NAME,
    name="capital_agent_tool",
    description="Retrieves the capital city using a specific tool.",
    instruction="""You are a helpful agent that provides the capital city of a country using a tool.
The user will provide the country name in a JSON format like {"country": "country_name"}.
1. Extract the country name.
2. Use the `get_capital_city` tool to find the capital.
3. Respond clearly to the user, stating the capital city found by the tool.
""",
    tools=[get_capital_city],
    input_schema=CountryInput,
    output_key="capital_tool_result", # Store final text response
)

# Agent 2: Uses output_schema (NO tools possible)
structured_info_agent_schema = LlmAgent(
    model=MODEL_NAME,
    name="structured_info_agent_schema",
    description="Provides capital and estimated population in a specific JSON format.",
    instruction=f"""You are an agent that provides country information.
The user will provide the country name in a JSON format like {{"country": "country_name"}}.
Respond ONLY with a JSON object matching this exact schema:
{json.dumps(CapitalInfoOutput.model_json_schema(), indent=2)}
Use your knowledge to determine the capital and estimate the population. Do not use any tools.
""",
    # *** NO tools parameter here - using output_schema prevents tool use ***
    input_schema=CountryInput,
    output_schema=CapitalInfoOutput, # Enforce JSON output structure
    output_key="structured_info_result", # Store final JSON response
)

# --- 5. Set up Session Management and Runners ---
session_service = InMemorySessionService()

# Create a runner for EACH agent
capital_runner = Runner(
    agent=capital_agent_with_tool,
    app_name=APP_NAME,
    session_service=session_service
)
structured_runner = Runner(
    agent=structured_info_agent_schema,
    app_name=APP_NAME,
    session_service=session_service
)

# --- 6. Define Agent Interaction Logic ---
async def call_agent_and_print(
    runner_instance: Runner,
    agent_instance: LlmAgent,
    session_id: str,
    query_json: str
):
    """Sends a query to the specified agent/runner and prints results."""
    print(f"\n>>> Calling Agent: '{agent_instance.name}' | Query: {query_json}")

    user_content = types.Content(role='user', parts=[types.Part(text=query_json)])

    final_response_content = "No final response received."
    async for event in runner_instance.run_async(user_id=USER_ID, session_id=session_id, new_message=user_content):
        # print(f"Event: {event.type}, Author: {event.author}") # Uncomment for detailed logging
        if event.is_final_response() and event.content and event.content.parts:
            # For output_schema, the content is the JSON string itself
            final_response_content = event.content.parts[0].text

    print(f"<<< Agent '{agent_instance.name}' Response: {final_response_content}")

    current_session = await session_service.get_session(app_name=APP_NAME,
                                                  user_id=USER_ID,
                                                  session_id=session_id)
    stored_output = current_session.state.get(agent_instance.output_key)

    # Pretty print if the stored output looks like JSON (likely from output_schema)
    print(f"--- Session State ['{agent_instance.output_key}']: ", end="")
    try:
        # Attempt to parse and pretty print if it's JSON
        parsed_output = json.loads(stored_output)
        print(json.dumps(parsed_output, indent=2))
    except (json.JSONDecodeError, TypeError):
         # Otherwise, print as string
        print(stored_output)
    print("-" * 30)


# --- 7. Run Interactions ---
async def main():
    # Create separate sessions for clarity, though not strictly necessary if context is managed
    print("--- Creating Sessions ---")
    await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID_TOOL_AGENT)
    await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID_SCHEMA_AGENT)

    print("--- Testing Agent with Tool ---")
    await call_agent_and_print(capital_runner, capital_agent_with_tool, SESSION_ID_TOOL_AGENT, '{"country": "France"}')
    await call_agent_and_print(capital_runner, capital_agent_with_tool, SESSION_ID_TOOL_AGENT, '{"country": "Canada"}')

    print("\n\n--- Testing Agent with Output Schema (No Tool Use) ---")
    await call_agent_and_print(structured_runner, structured_info_agent_schema, SESSION_ID_SCHEMA_AGENT, '{"country": "France"}')
    await call_agent_and_print(structured_runner, structured_info_agent_schema, SESSION_ID_SCHEMA_AGENT, '{"country": "Japan"}')

# --- Run the Agent ---
# Note: In Colab, you can directly use 'await' at the top level.
# If running this code as a standalone Python script, you'll need to use asyncio.run() or manage the event loop.
if __name__ == "__main__":
    asyncio.run(main())    
package main

import (
    "context"
    "encoding/json"
    "errors"
    "fmt"
    "log"
    "strings"

    "google.golang.org/adk/agent"
    "google.golang.org/adk/agent/llmagent"
    "google.golang.org/adk/model/gemini"
    "google.golang.org/adk/runner"
    "google.golang.org/adk/session"
    "google.golang.org/adk/tool"
    "google.golang.org/adk/tool/functiontool"

    "google.golang.org/genai"
)

// --- Main Runnable Example ---

const (
    modelName = "gemini-2.0-flash"
    appName   = "agent_comparison_app"
    userID    = "test_user_456"
)

type getCapitalCityArgs struct {
    Country string `json:"country" jsonschema:"The country to get the capital of."`
}

// getCapitalCity retrieves the capital city of a given country.
func getCapitalCity(ctx tool.Context, args getCapitalCityArgs) (map[string]any, error) {
    fmt.Printf("\n-- Tool Call: getCapitalCity(country='%s') --\n", args.Country)
    capitals := map[string]string{
        "united states": "Washington, D.C.",
        "canada":        "Ottawa",
        "france":        "Paris",
        "japan":         "Tokyo",
    }
    capital, ok := capitals[strings.ToLower(args.Country)]
    if !ok {
        result := fmt.Sprintf("Sorry, I couldn't find the capital for %s.", args.Country)
        fmt.Printf("-- Tool Result: '%s' --\n", result)
        return nil, errors.New(result)
    }
    fmt.Printf("-- Tool Result: '%s' --\n", capital)
    return map[string]any{"result": capital}, nil
}

// callAgent is a helper function to execute an agent with a given prompt and handle its output.
func callAgent(ctx context.Context, a agent.Agent, outputKey string, prompt string) {
    fmt.Printf("\n>>> Calling Agent: '%s' | Query: %s\n", a.Name(), prompt)
    // Create an in-memory session service to manage agent state.
    sessionService := session.InMemoryService()

    // Create a new session for the agent interaction.
    sessionCreateResponse, err := sessionService.Create(ctx, &session.CreateRequest{
        AppName: appName,
        UserID:  userID,
    })
    if err != nil {
        log.Fatalf("Failed to create the session service: %v", err)
    }

    session := sessionCreateResponse.Session

    // Configure the runner with the application name, agent, and session service.
    config := runner.Config{
        AppName:        appName,
        Agent:          a,
        SessionService: sessionService,
    }

    // Create a new runner instance.
    r, err := runner.New(config)
    if err != nil {
        log.Fatalf("Failed to create the runner: %v", err)
    }

    // Prepare the user's message to send to the agent.
    sessionID := session.ID()
    userMsg := &genai.Content{
        Parts: []*genai.Part{
            genai.NewPartFromText(prompt),
        },
        Role: string(genai.RoleUser),
    }

    // Run the agent and process the streaming events.
    for event, err := range r.Run(ctx, userID, sessionID, userMsg, agent.RunConfig{
        StreamingMode: agent.StreamingModeSSE,
    }) {
        if err != nil {
            fmt.Printf("\nAGENT_ERROR: %v\n", err)
        } else if event.Partial {
            // Print partial responses as they are received.
            for _, p := range event.Content.Parts {
                fmt.Print(p.Text)
            }
        }
    }

    // After the run, check if there's an expected output key in the session state.
    if outputKey != "" {
        storedOutput, error := session.State().Get(outputKey)
        if error == nil {
            // Pretty-print the stored output if it's a JSON string.
            fmt.Printf("\n--- Session State ['%s']: ", outputKey)
            storedString, isString := storedOutput.(string)
            if isString {
                var prettyJSON map[string]interface{}
                if err := json.Unmarshal([]byte(storedString), &prettyJSON); err == nil {
                    indentedJSON, err := json.MarshalIndent(prettyJSON, "", "  ")
                    if err == nil {
                        fmt.Println(string(indentedJSON))
                    } else {
                        fmt.Println(storedString)
                    }
                } else {
                    fmt.Println(storedString)
                }
            } else {
                fmt.Println(storedOutput)
            }
            fmt.Println(strings.Repeat("-", 30))
        }
    }
}

func main() {
    ctx := context.Background()

    model, err := gemini.NewModel(ctx, modelName, &genai.ClientConfig{})
    if err != nil {
        log.Fatalf("Failed to create model: %v", err)
    }

    capitalTool, err := functiontool.New(
        functiontool.Config{
            Name:        "get_capital_city",
            Description: "Retrieves the capital city for a given country.",
        },
        getCapitalCity,
    )
    if err != nil {
        log.Fatalf("Failed to create function tool: %v", err)
    }

    countryInputSchema := &genai.Schema{
        Type:        genai.TypeObject,
        Description: "Input for specifying a country.",
        Properties: map[string]*genai.Schema{
            "country": {
                Type:        genai.TypeString,
                Description: "The country to get information about.",
            },
        },
        Required: []string{"country"},
    }

    capitalAgentWithTool, err := llmagent.New(llmagent.Config{
        Name:        "capital_agent_tool",
        Model:       model,
        Description: "Retrieves the capital city using a specific tool.",
        Instruction: `You are a helpful agent that provides the capital city of a country using a tool.
The user will provide the country name in a JSON format like {"country": "country_name"}.
1. Extract the country name.
2. Use the 'get_capital_city' tool to find the capital.
3. Respond clearly to the user, stating the capital city found by the tool.`,
        Tools:       []tool.Tool{capitalTool},
        InputSchema: countryInputSchema,
        OutputKey:   "capital_tool_result",
    })
    if err != nil {
        log.Fatalf("Failed to create capital agent with tool: %v", err)
    }

    capitalInfoOutputSchema := &genai.Schema{
        Type:        genai.TypeObject,
        Description: "Schema for capital city information.",
        Properties: map[string]*genai.Schema{
            "capital": {
                Type:        genai.TypeString,
                Description: "The capital city of the country.",
            },
            "population_estimate": {
                Type:        genai.TypeString,
                Description: "An estimated population of the capital city.",
            },
        },
        Required: []string{"capital", "population_estimate"},
    }
    schemaJSON, _ := json.Marshal(capitalInfoOutputSchema)
    structuredInfoAgentSchema, err := llmagent.New(llmagent.Config{
        Name:        "structured_info_agent_schema",
        Model:       model,
        Description: "Provides capital and estimated population in a specific JSON format.",
        Instruction: fmt.Sprintf(`You are an agent that provides country information.
The user will provide the country name in a JSON format like {"country": "country_name"}.
Respond ONLY with a JSON object matching this exact schema:
%s
Use your knowledge to determine the capital and estimate the population. Do not use any tools.`, string(schemaJSON)),
        InputSchema:  countryInputSchema,
        OutputSchema: capitalInfoOutputSchema,
        OutputKey:    "structured_info_result",
    })
    if err != nil {
        log.Fatalf("Failed to create structured info agent: %v", err)
    }

    fmt.Println("--- Testing Agent with Tool ---")
    callAgent(ctx, capitalAgentWithTool, "capital_tool_result", `{"country": "France"}`)
    callAgent(ctx, capitalAgentWithTool, "capital_tool_result", `{"country": "Canada"}`)

    fmt.Println("\n\n--- Testing Agent with Output Schema (No Tool Use) ---")
    callAgent(ctx, structuredInfoAgentSchema, "structured_info_result", `{"country": "France"}`)
    callAgent(ctx, structuredInfoAgentSchema, "structured_info_result", `{"country": "Japan"}`)
}
// --- Full example code demonstrating LlmAgent with Tools vs. Output Schema ---

import com.google.adk.agents.LlmAgent;
import com.google.adk.events.Event;
import com.google.adk.runner.Runner;
import com.google.adk.sessions.InMemorySessionService;
import com.google.adk.sessions.Session;
import com.google.adk.tools.Annotations;
import com.google.adk.tools.FunctionTool;
import com.google.genai.types.Content;
import com.google.genai.types.Part;
import com.google.genai.types.Schema;
import io.reactivex.rxjava3.core.Flowable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class LlmAgentExample {

  // --- 1. Define Constants ---
  private static final String MODEL_NAME = "gemini-2.0-flash";
  private static final String APP_NAME = "capital_agent_tool";
  private static final String USER_ID = "test_user_456";
  private static final String SESSION_ID_TOOL_AGENT = "session_tool_agent_xyz";
  private static final String SESSION_ID_SCHEMA_AGENT = "session_schema_agent_xyz";

  // --- 2. Define Schemas ---

  // Input schema used by both agents
  private static final Schema COUNTRY_INPUT_SCHEMA =
      Schema.builder()
          .type("OBJECT")
          .description("Input for specifying a country.")
          .properties(
              Map.of(
                  "country",
                  Schema.builder()
                      .type("STRING")
                      .description("The country to get information about.")
                      .build()))
          .required(List.of("country"))
          .build();

  // Output schema ONLY for the second agent
  private static final Schema CAPITAL_INFO_OUTPUT_SCHEMA =
      Schema.builder()
          .type("OBJECT")
          .description("Schema for capital city information.")
          .properties(
              Map.of(
                  "capital",
                  Schema.builder()
                      .type("STRING")
                      .description("The capital city of the country.")
                      .build(),
                  "population_estimate",
                  Schema.builder()
                      .type("STRING")
                      .description("An estimated population of the capital city.")
                      .build()))
          .required(List.of("capital", "population_estimate"))
          .build();

  // --- 3. Define the Tool (Only for the first agent) ---
  // Retrieves the capital city of a given country.
  public static Map<String, Object> getCapitalCity(
      @Annotations.Schema(name = "country", description = "The country to get capital for")
      String country) {
    System.out.printf("%n-- Tool Call: getCapitalCity(country='%s') --%n", country);
    Map<String, String> countryCapitals = new HashMap<>();
    countryCapitals.put("united states", "Washington, D.C.");
    countryCapitals.put("canada", "Ottawa");
    countryCapitals.put("france", "Paris");
    countryCapitals.put("japan", "Tokyo");

    String result =
        countryCapitals.getOrDefault(
            country.toLowerCase(), "Sorry, I couldn't find the capital for " + country + ".");
    System.out.printf("-- Tool Result: '%s' --%n", result);
    return Map.of("result", result); // Tools must return a Map
  }

  public static void main(String[] args){
    LlmAgentExample agentExample = new LlmAgentExample();
    FunctionTool capitalTool = FunctionTool.create(agentExample.getClass(), "getCapitalCity");

    // --- 4. Configure Agents ---

    // Agent 1: Uses a tool and output_key
    LlmAgent capitalAgentWithTool =
        LlmAgent.builder()
            .model(MODEL_NAME)
            .name("capital_agent_tool")
            .description("Retrieves the capital city using a specific tool.")
            .instruction(
              """
              You are a helpful agent that provides the capital city of a country using a tool.
              1. Extract the country name.
              2. Use the `get_capital_city` tool to find the capital.
              3. Respond clearly to the user, stating the capital city found by the tool.
              """)
            .tools(capitalTool)
            .inputSchema(COUNTRY_INPUT_SCHEMA)
            .outputKey("capital_tool_result") // Store final text response
            .build();

    // Agent 2: Uses an output schema
    LlmAgent structuredInfoAgentSchema =
        LlmAgent.builder()
            .model(MODEL_NAME)
            .name("structured_info_agent_schema")
            .description("Provides capital and estimated population in a specific JSON format.")
            .instruction(
                String.format("""
                You are an agent that provides country information.
                Respond ONLY with a JSON object matching this exact schema: %s
                Use your knowledge to determine the capital and estimate the population. Do not use any tools.
                """, CAPITAL_INFO_OUTPUT_SCHEMA.toJson()))
            // *** NO tools parameter here - using output_schema prevents tool use ***
            .inputSchema(COUNTRY_INPUT_SCHEMA)
            .outputSchema(CAPITAL_INFO_OUTPUT_SCHEMA) // Enforce JSON output structure
            .outputKey("structured_info_result") // Store final JSON response
            .build();

    // --- 5. Set up Session Management and Runners ---
    InMemorySessionService sessionService = new InMemorySessionService();

    sessionService.createSession(APP_NAME, USER_ID, null, SESSION_ID_TOOL_AGENT).blockingGet();
    sessionService.createSession(APP_NAME, USER_ID, null, SESSION_ID_SCHEMA_AGENT).blockingGet();

    Runner capitalRunner = new Runner(capitalAgentWithTool, APP_NAME, null, sessionService);
    Runner structuredRunner = new Runner(structuredInfoAgentSchema, APP_NAME, null, sessionService);

    // --- 6. Run Interactions ---
    System.out.println("--- Testing Agent with Tool ---");
    agentExample.callAgentAndPrint(
        capitalRunner, capitalAgentWithTool, SESSION_ID_TOOL_AGENT, "{\"country\": \"France\"}");
    agentExample.callAgentAndPrint(
        capitalRunner, capitalAgentWithTool, SESSION_ID_TOOL_AGENT, "{\"country\": \"Canada\"}");

    System.out.println("\n\n--- Testing Agent with Output Schema (No Tool Use) ---");
    agentExample.callAgentAndPrint(
        structuredRunner,
        structuredInfoAgentSchema,
        SESSION_ID_SCHEMA_AGENT,
        "{\"country\": \"France\"}");
    agentExample.callAgentAndPrint(
        structuredRunner,
        structuredInfoAgentSchema,
        SESSION_ID_SCHEMA_AGENT,
        "{\"country\": \"Japan\"}");
  }

  // --- 7. Define Agent Interaction Logic ---
  public void callAgentAndPrint(Runner runner, LlmAgent agent, String sessionId, String queryJson) {
    System.out.printf(
        "%n>>> Calling Agent: '%s' | Session: '%s' | Query: %s%n",
        agent.name(), sessionId, queryJson);

    Content userContent = Content.fromParts(Part.fromText(queryJson));
    final String[] finalResponseContent = {"No final response received."};
    Flowable<Event> eventStream = runner.runAsync(USER_ID, sessionId, userContent);

    // Stream event response
    eventStream.blockingForEach(event -> {
          if (event.finalResponse() && event.content().isPresent()) {
            event
                .content()
                .get()
                .parts()
                .flatMap(parts -> parts.isEmpty() ? Optional.empty() : Optional.of(parts.get(0)))
                .flatMap(Part::text)
                .ifPresent(text -> finalResponseContent[0] = text);
          }
        });

    System.out.printf("<<< Agent '%s' Response: %s%n", agent.name(), finalResponseContent[0]);

    // Retrieve the session again to get the updated state
    Session updatedSession =
        runner
            .sessionService()
            .getSession(APP_NAME, USER_ID, sessionId, Optional.empty())
            .blockingGet();

    if (updatedSession != null && agent.outputKey().isPresent()) {
      // Print to verify if the stored output looks like JSON (likely from output_schema)
      System.out.printf("--- Session State ['%s']: ", agent.outputKey().get());
      }
  }
}

(此示例演示了核心概念。更复杂的智能体可能包含 schema、上下文控制、规划等。)

虽然本页涵盖了 LlmAgent 的核心配置,但在其他地方详细介绍了几个提供更高级控制的相关概念:

  • 回调: 使用 before_model_callbackafter_model_callback 等拦截执行点(模型调用前/后,工具调用前/后)。参见回调
  • 多智能体控制: 智能体交互的高级策略,包括规划(planner)、控制智能体转移(disallow_transfer_to_parentdisallow_transfer_to_peers)以及系统范围的指令(global_instruction)。参见多智能体