内置工具

ADK-Rust 提供了多种内置工具,无需自定义实现即可扩展代理功能。这些工具开箱即用,并与代理框架无缝集成。

提供商原生工具现在通过常规的 Tool API 声明,而不是通过提供商特定的 GenerateContentConfig.extensions blobs。这意味着您可以在同一个代理中混合使用原生工具,例如 Gemini Google Search、Anthropic Web Search 或 OpenAI Responses web search,以及普通的 FunctionTool 实例。

概述

工具目的用例
#[tool] macro零样板自定义工具任何自定义函数 — 参见 Function Tools
FunctionTool手动自定义工具注册动态工具,closures
GoogleSearchTool通过 Gemini 进行网络搜索实时信息检索
UrlContextToolGemini URL grounding总结或推理实时 URLs
GoogleMapsToolGemini Google Maps grounding地点、路线和本地上下文
GeminiCodeExecutionToolGemini 原生代码执行服务器端 Python 执行
WebSearchToolAnthropic 原生网页搜索Claude 服务器端网页搜索
OpenAIWebSearchToolOpenAI 响应网页搜索OpenAI-托管检索
AgentTool将代理封装为可调用工具代理组合与委托
ExitLoopTool循环终止控制 LoopAgent 迭代
LoadArtifactsTool工件加载访问存储的二进制数据

GoogleSearchTool

GoogleSearchTool 使代理能够使用 Google Search 搜索网络。此工具由 Gemini 模型通过 grounding feature 在内部处理,这意味着搜索是由模型本身在服务器端执行的。

基本用法

use adk_rust::prelude::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;

    // Create the GoogleSearchTool
    let search_tool = GoogleSearchTool;

    // Add to agent
    let agent = LlmAgentBuilder::new("research_assistant")
        .description("An assistant that can search the web for information")
        .instruction(
            "You are a research assistant. When asked about current events, \
             recent news, or factual information, use the google_search tool \
             to find accurate, up-to-date information."
        )
        .model(Arc::new(model))
        .tool(Arc::new(search_tool))
        .build()?;

    println!("Agent created with Google Search capability!");
    Ok(())
}

工作原理

与常规 FunctionTool 不同,GoogleSearchTool 的运作方式有所不同:

  1. 服务器端执行:搜索由 Gemini 的 grounding feature 执行,而非本地执行
  2. 自动调用:模型根据查询决定何时进行搜索
  3. 集成结果:搜索结果直接整合到模型的响应中

如果直接调用此工具实现,它将返回错误,因为实际搜索发生在 Gemini API 内部:

// This is handled internally - you don't call it directly
async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
    Err(AdkError::tool("GoogleSearch is handled internally by Gemini"))
}

工具详情

属性
名称google_search
描述"执行 Google 搜索以从网络检索信息。"
参数由 Gemini model 确定
执行服务器端 (Gemini grounding)

用途

  • 时事: “今天新闻发生了什么?”
  • 事实查询: “东京的人口是多少?”
  • 最新信息: “AI 的最新进展是什么?”
  • 研究任务: “查找有关可再生能源趋势的信息”

示例查询

// The agent will automatically use Google Search for queries like:
// - "What's the weather forecast for New York this week?"
// - "Who won the latest championship game?"
// - "What are the current stock prices for tech companies?"

AgentTool

AgentTool 将任何 agent 封装为一个可调用的 tool,从而实现 agent 组合,其中父 agent 可以将其 tool-calling workflow 的一部分作为子 agent 进行调用。子 agent 的状态变化和 artifact 会自动转发到父 context。

基本用法

use adk_rust::prelude::*;
use adk_tool::AgentTool;
use std::sync::Arc;

let sub_agent = LlmAgentBuilder::new("summarizer")
    .description("Summarizes text content")
    .instruction("Summarize the provided text concisely.")
    .model(model.clone())
    .build()?;

let agent_tool = AgentTool::new(Arc::new(sub_agent));

let coordinator = LlmAgentBuilder::new("coordinator")
    .instruction("Use the summarizer tool when asked to summarize content.")
    .model(model.clone())
    .tool(Arc::new(agent_tool))
    .build()?;

工作原理

  1. 父 agent 决定将封装的 agent 作为 tool 调用
  2. AgentTool 使用 StreamingMode::None 创建一个调用 context
  3. 子 agent 运行完成并累积其完整 response
  4. response 文本返回给父 agent
  5. 状态增量和 artifact 增量转发到父 context

Tool 详情

属性
名称与封装的 agent 的名称相同
描述与封装的 agent 的描述相同
参数request: string (发送给子 agent 的输入)
返回{"response": "..."} 包含子 agent 的文本输出

关键行为

  • 子代理在内部以非流式模式运行,以可靠地捕获响应
  • 子代理的状态变化 (output_key) 会传播到父会话
  • 子代理保存的工件会转发到父上下文
  • 有关代理组合模式的更多信息,请参阅 多代理系统

ExitLoopTool

ExitLoopTool 是一个控制工具,与 LoopAgent 结合使用,用于指示迭代过程何时终止。当被调用时,它会设置 escalate 标志,导致循环退出。

基本用法

use adk_rust::prelude::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;

    // Create an agent with ExitLoopTool for iterative refinement
    let refiner = LlmAgentBuilder::new("content_refiner")
        .description("Iteratively improves content quality")
        .instruction(
            "Review the content and improve it. Check for:\n\
             1. Clarity and readability\n\
             2. Grammar and spelling\n\
             3. Logical flow\n\n\
             If the content meets all quality standards, call the exit_loop tool.\n\
             Otherwise, provide an improved version."
        )
        .model(Arc::new(model))
        .tool(Arc::new(ExitLoopTool::new()))
        .build()?;

    // Use in a LoopAgent
    let loop_agent = LoopAgent::new(
        "iterative_refiner",
        vec![Arc::new(refiner)],
    ).with_max_iterations(5);

    println!("Loop agent created with exit capability!");
    Ok(())
}

工作原理

  1. 代理评估是继续还是退出
  2. 当准备退出时,代理调用 exit_loop
  3. 该工具设置 actions.escalate = trueactions.skip_summarization = true
  4. LoopAgent 检测到升级标志并停止迭代

工具详情

属性
名称exit_loop
描述"退出循环。仅当您收到指示时才调用此函数。"
参数
返回空对象 {}

最佳实践

  1. 明确的退出条件:在代理的指令中定义具体的条件
  2. 始终设置 max_iterations:作为安全措施,防止无限循环
  3. 有意义的指令:帮助代理理解何时退出
// Good: Clear exit criteria
.instruction(
    "Improve the text until it:\n\
     - Has no grammatical errors\n\
     - Is under 100 words\n\
     - Uses active voice\n\
     When all criteria are met, call exit_loop."
)

// Avoid: Vague criteria
.instruction("Improve the text. Exit when done.")

LoadArtifactsTool

LoadArtifactsTool 允许代理按名称检索存储的工件。当代理需要访问之前保存的文件、图像或其他二进制数据时,这非常有用。

基本用法

use adk_rust::prelude::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;

    // Create agent with artifact loading capability
    let agent = LlmAgentBuilder::new("document_analyzer")
        .description("Analyzes stored documents")
        .instruction(
            "You can load and analyze stored artifacts. \
             Use the load_artifacts tool to retrieve documents by name. \
             The tool accepts an array of artifact names."
        )
        .model(Arc::new(model))
        .tool(Arc::new(LoadArtifactsTool::new()))
        .build()?;

    println!("Agent created with artifact loading capability!");
    Ok(())
}

工具详情

属性
名称load_artifacts
描述"按名称加载 artifact 并返回其内容。接受 artifact 名称数组。"
参数artifact_names: 字符串数组
返回包含 artifacts 数组的对象

参数

该工具需要一个包含 artifact_names 数组的 JSON 对象:

{
  "artifact_names": ["document.txt", "image.png", "data.json"]
}

响应格式

该工具返回一个包含已加载工件的对象:

{
  "artifacts": [
    {
      "name": "document.txt",
      "content": "The text content of the document..."
    },
    {
      "name": "image.png",
      "content": {
        "mime_type": "image/png",
        "data": "base64-encoded-data..."
      }
    },
    {
      "name": "missing.txt",
      "error": "Artifact not found"
    }
  ]
}

要求

要使 LoadArtifactsTool 正常工作,您需要:

  1. 在 runner 中配置一个 ArtifactService
  2. 之前已保存到服务的工件
  3. 已添加到 Agent 的 Tool
use adk_rust::prelude::*;
use std::sync::Arc;

// Set up artifact service
let artifact_service = Arc::new(InMemoryArtifactService::new());

// Configure runner with artifact service
let runner = Runner::new(agent)
    .with_artifact_service(artifact_service);

组合内置 Tool

您可以将多个内置 Tool 结合使用:

use adk_rust::prelude::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;

    // Create agent with multiple built-in tools
    let agent = LlmAgentBuilder::new("research_agent")
        .description("Research agent with search and artifact capabilities")
        .instruction(
            "You are a research agent. You can:\n\
             - Search the web using google_search for current information\n\
             - Load stored documents using load_artifacts\n\
             Use these tools to help answer questions comprehensively."
        )
        .model(Arc::new(model))
        .tool(Arc::new(GoogleSearchTool))
        .tool(Arc::new(LoadArtifactsTool::new()))
        .build()?;

    println!("Multi-tool agent created!");
    Ok(())
}

创建自定义内置 Tool

您可以通过实现 Tool trait,按照与内置 Tool 相同的模式创建自己的 Tool:

use adk_rust::prelude::*;
use async_trait::async_trait;
use serde_json::{json, Value};
use std::sync::Arc;

pub struct MyCustomTool;

impl MyCustomTool {
    pub fn new() -> Self {
        Self
    }
}

#[async_trait]
impl Tool for MyCustomTool {
    fn name(&self) -> &str {
        "my_custom_tool"
    }

    fn description(&self) -> &str {
        "Description of what this tool does"
    }

    async fn execute(&self, ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
        // Your tool logic here
        Ok(json!({ "result": "success" }))
    }
}

API 参考

GoogleSearchTool

impl GoogleSearchTool {
    /// Create a new GoogleSearchTool instance
    pub fn new() -> Self;
}

ExitLoopTool

impl ExitLoopTool {
    /// Create a new ExitLoopTool instance
    pub fn new() -> Self;
}

LoadArtifactsTool

impl LoadArtifactsTool {
    /// Create a new LoadArtifactsTool instance
    pub fn new() -> Self;
}

impl Default for LoadArtifactsTool {
    fn default() -> Self;
}

上一页: ← Function Tools | 下一页: Browser Tools →