Skip to content

用于评估的环境模拟

ADK 已支持Python v1.24.0

当评估依赖外部依赖项(如 API、数据库或第三方服务)的智能体时,在测试期间实时运行这些工具可能会很慢、昂贵且不可靠。环境模拟器 (Environment Simulator) 允许你在智能体执行期间安全地拦截这些工具调用,并将其替换为受控的、确定性的响应,而无需修改智能体本身。这种方法可以填补智能体改进循环中的关键空白,允许你创建封闭的(Hermetic)、离线的测试运行,从而隔离智能体逻辑以获得可靠的评分。

总的来说,该功能允许你:

  • 测试智能体如何处理 API 错误或边界案例响应。
  • 离线运行评估,无需访问实时后端。
  • 使用 LLM 自动生成逼真的模拟响应。
  • 通过设定概率注入的种子来产生可重现的测试运行。

环境模拟通过 before_tool_callback 钩子或 插件系统 与 ADK 的工具执行流水线集成,因此无需更改你的智能体代码。

实验性功能

环境模拟是一项实验性功能。其 API 可能会在未来的版本中发生变化。

工作原理

如果说 用户模拟 (User Simulation) 推动了对话的进行,那么环境模拟则提供了稳定的后端。从高层级来看,环境模拟器位于你的智能体及其工具之间。当智能体调用工具时,模拟器会拦截该调用并决定是返回合成响应(预定义的注入或 LLM 生成的模拟),还是让真实工具执行。

对于每个配置的工具,决策逻辑遵循以下顺序:

  1. 注入配置 (Injection configs):首先按顺序检查。如果找到了匹配的注入(基于参数匹配和概率),则立即返回其错误或响应。
  2. 模拟策略 (Mock strategy):如果没有注入配置适用,则作为备选方案使用。模拟器会调用 LLM,根据工具的模式(Schema)和任何有状态的上下文生成逼真的响应。
  3. 无操作 (No-op):如果工具不在模拟器配置中,则返回 (None),允许真实工具正常执行。

集成方式

EnvironmentSimulationFactory 类提供了两个集成点:

  • create_callback() — 返回一个异步调用项,适用于作为任何 LlmAgentbefore_tool_callback
  • create_plugin() — 返回一个 EnvironmentSimulationPlugin 实例,与 ADK 插件系统集成。

作为回调使用

以下示例展示了如何将环境模拟创建为 ADK 智能体回调之一。

from google.adk.agents import LlmAgent
from google.adk.tools.environment_simulation import EnvironmentSimulationFactory
from google.adk.tools.environment_simulation.environment_simulation_config import (
    EnvironmentSimulationConfig,
    InjectedError,
    InjectionConfig,
    ToolSimulationConfig,
)

config = EnvironmentSimulationConfig(
    tool_simulation_configs=[
        ToolSimulationConfig(
            tool_name="get_user_profile",
            injection_configs=[
                InjectionConfig(
                    injected_error=InjectedError(
                        injected_http_error_code=503,
                        error_message="Service temporarily unavailable.",
                    )
                )
            ],
        )
    ]
)

agent = LlmAgent(
    name="my_agent",
    model="gemini-2.5-flash",
    tools=[get_user_profile],
    before_tool_callback=EnvironmentSimulationFactory.create_callback(config),
)

作为插件使用

以下示例展示了如何将环境模拟创建为 ADK 智能体插件。

from google.adk.apps import App
from google.adk.tools.environment_simulation import EnvironmentSimulationFactory
from google.adk.tools.environment_simulation.environment_simulation_config import (
    EnvironmentSimulationConfig,
    MockStrategy,
    ToolSimulationConfig,
)

config = EnvironmentSimulationConfig(
    tool_simulation_configs=[
        ToolSimulationConfig(
            tool_name="search_products",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        )
    ]
)

app = App(
    agent=my_agent,
    plugins=[EnvironmentSimulationFactory.create_plugin(config)],
)

配置参考

你可以使用一系列数据类(Dataclasses)来配置环境模拟器。以下部分提供了每个配置对象的详细参考。

EnvironmentSimulationConfig

顶级配置对象。

字段名 类型 默认值 描述
tool_simulation_configs List[ToolSimulationConfig] 必填 每个要模拟的工具对应一个条目。不能为空,且工具名称必须唯一。
simulation_model str "gemini-2.5-flash" 用于工具连接分析和模拟响应生成的 LLM。
simulation_model_configuration GenerateContentConfig 启用思维链 内部模拟器调用的 LLM 生成配置。
environment_data str \| None None 可选的环境上下文(例如 JSON 数据库快照),传递给模拟策略以生成更逼真的响应。
tracing str \| None None 追踪数据(例如 JSON 字符串格式的先前智能体运行追踪),以提供历史上下文。

ToolSimulationConfig

定义如何模拟单个命名工具。

字段名 类型 默认值 描述
tool_name str 必填 必须与工具的注册名称完全匹配。
injection_configs List[InjectionConfig] [] 零个或多个注入配置,在模拟策略之前按顺序检查。
mock_strategy_type MockStrategy MOCK_STRATEGY_UNSPECIFIED 未触发注入时的备选策略。

InjectionConfig

控制可以注入到工具调用中的单个合成响应。injected_errorinjected_response 必须且只能设置其中一个。

字段名 类型 默认值 描述
injected_error InjectedError \| None None 要返回的错误(与 injected_response 互斥)。
injected_response Dict[str, Any] \| None None 要返回的固定响应字典(与 injected_error 互斥)。
injection_probability float 1.0 此注入触发的概率 [0.0, 1.0]
match_args Dict[str, Any] \| None None 如果设置,仅当工具参数包含 match_args 中的所有键值对时,注入才会触发。
injected_latency_seconds float 0.0 返回注入结果之前添加的人为延迟(≤ 120 秒)。
random_seed int \| None None 概率检查的种子,实现确定性的注入行为。

InjectedError

定义 HTTP 样式的错误响应。

字段名 类型 描述
injected_http_error_code int 作为工具响应中的 "error_code" 呈现的 HTTP 状态码。
error_message str 作为工具响应中的 "error_message" 呈现的人类可读消息。

MockStrategy

用于控制未触发注入时模拟器如何生成响应的枚举。

取值 描述
MOCK_STRATEGY_TOOL_SPEC 使用工具的模式和有状态的上下文来提示 LLM 生成逼真的响应。
MOCK_STRATEGY_TRACING (已弃用) 请使用带有追踪输入的 MOCK_STRATEGY_TOOL_SPEC

注入模式

使用注入配置来测试特定的故障或边缘情况场景。注入按列表顺序进行评估;应用第一个满足 match_args 标准(且通过概率检查)的注入。

注入错误

以下示例展示了如何向智能体注入具有特定错误代码和错误消息的错误。

from google.adk.tools.environment_simulation.environment_simulation_config import (
    InjectedError,
    InjectionConfig,
    ToolSimulationConfig,
)

ToolSimulationConfig(
    tool_name="charge_payment",
    injection_configs=[
        InjectionConfig(
            injected_error=InjectedError(
                injected_http_error_code=402,
                error_message="Payment declined.",
            )
        )
    ],
)

智能体将收到 {"error_code": 402, "error_message": "Payment declined."} 而不是真实的工具结果,从而允许你评估智能体如何处理支付失败。

注入固定响应

使用以下 InjectionConfig 指定具有固定响应负载的成功响应。

InjectionConfig(
    injected_response={"status": "ok", "order_id": "ORD-9999"}
)

带有参数匹配的条件注入

使用 match_args 仅在传递特定参数时进行注入。

InjectionConfig(
    match_args={"item_id": "ITEM-404"},
    injected_error=InjectedError(
        injected_http_error_code=404,
        error_message="Item not found.",
    ),
)

在这里,仅当使用 item_id="ITEM-404" 调用工具时才会注入错误。所有其他调用将传递到下一个注入配置或模拟策略。

概率注入

injection_probability 设置为 0.01.0 之间的值来模拟不稳定(Flaky)行为。为了实现可重现的测试运行,请使用 random_seed 固定随机结果。

InjectionConfig(
    injection_probability=0.3,
    random_seed=42,
    injected_error=InjectedError(
        injected_http_error_code=500,
        error_message="Internal server error.",
    ),
)

注入延迟

使用 injected_latency_seconds 模拟慢速后端响应,这对于测试超时处理或降级条件下的用户体验非常有用。

InjectionConfig(
    injected_latency_seconds=5.0,
    injected_response={"result": "slow but successful"},
)

组合多个注入配置

单个工具上的多个注入配置会按顺序检查。你可以组合它们来测试多个场景:

ToolSimulationConfig(
    tool_name="get_inventory",
    injection_configs=[
        # 对于特定的缺货商品始终失败
        InjectionConfig(
            match_args={"sku": "OOS-001"},
            injected_response={"quantity": 0, "available": False},
        ),
        # 对于所有其他商品,有 20% 的时间随机失败
        InjectionConfig(
            injection_probability=0.2,
            random_seed=7,
            injected_error=InjectedError(
                injected_http_error_code=503,
                error_message="Inventory service unavailable.",
            ),
        ),
    ],
)

模拟策略模式

当你希望模拟器自动生成合理的响应——而不是返回手工编写的值时——请使用 MOCK_STRATEGY_TOOL_SPEC

模拟器使用 LLM 来执行以下操作:

  1. 分析智能体有权访问的所有工具的模式,并识别它们之间的有状态依赖关系(例如,create_order 工具产生一个 order_id,而 get_order 会消耗该 ID)。
  2. 跟踪在会话期间创建的 ID 和资源的状态存储
  3. 生成与工具模式和当前状态一致的响应——如果消耗型工具请求了一个从未创建过的资源,则返回 404 样式的错误。
from google.adk.tools.environment_simulation.environment_simulation_config import (
    EnvironmentSimulationConfig,
    MockStrategy,
    ToolSimulationConfig,
)

config = EnvironmentSimulationConfig(
    tool_simulation_configs=[
        ToolSimulationConfig(
            tool_name="create_order",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        ),
        ToolSimulationConfig(
            tool_name="get_order",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        ),
        ToolSimulationConfig(
            tool_name="cancel_order",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        ),
    ]
)

通过此配置,当 create_order 被模拟时,模拟器将自动生成一个 order_id;当随后调用 get_ordercancel_order 时,它将使用该 ID 返回一致的结果(或未找到错误)。

提供环境数据

通过 environment_data 传递特定领域的上下文,使模拟响应更加真实。这可以是一个 JSON 字符串,代表你的数据库快照或 LLM 在生成响应时应使用的任何结构化上下文。

import json

db_snapshot = {
    "products": [
        {"id": "P-001", "name": "Wireless Headphones", "price": 79.99, "stock": 12},
        {"id": "P-002", "name": "USB-C Hub", "price": 34.99, "stock": 0},
    ],
    "warehouse_location": "US-WEST-2",
}

config = EnvironmentSimulationConfig(
    tool_simulation_configs=[
        ToolSimulationConfig(
            tool_name="search_products",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        ),
    ],
    environment_data=json.dumps(db_snapshot),
)

LLM 将使用此数据返回与你的领域相匹配的产品名称、价格和库存水平,而不是生成任意的占位符值。

提供追踪数据

将智能体中生成的要模拟的追踪信息通过 tracing 喂入,使模拟响应更加真实。

import json

agent_traces = [
    {
        "invocation_id": "inv-001",
        "user_content": {"role": "user", "parts": [{"text": "Search for high-end headphones"}]},
        "intermediate_data": {
            "tool_uses": [
                {
                    "name": "search_products",
                    "args": {"query": "high-end headphones"},
                    "response": {"products": [{"id": "P-123", "name": "Premium Wireless ANC Headphones"}]}
                }
            ]
        }
    }
]

config = EnvironmentSimulationConfig(
    tool_simulation_configs=[
        ToolSimulationConfig(
            tool_name="search_products",
            mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
        ),
    ],
    tracing=json.dumps(agent_traces),
)

LLM 将使用此数据返回与你的领域相匹配的产品名称、价格和库存水平,而不是生成任意的占位符值。

混合使用注入和模拟策略

注入配置和模拟策略可以组合在同一个工具上。注入始终首先被检查;模拟策略仅在没有注入适用时才会触发。

ToolSimulationConfig(
    tool_name="send_notification",
    injection_configs=[
        # 对于已知的坏接收者始终失败
        InjectionConfig(
            match_args={"recipient_id": "INVALID"},
            injected_error=InjectedError(
                injected_http_error_code=400,
                error_message="Invalid recipient.",
            ),
        ),
    ],
    # 对于所有其他接收者,生成合理的成功响应
    mock_strategy_type=MockStrategy.MOCK_STRATEGY_TOOL_SPEC,
)