内置工具
ADK-Rust 提供了多个内置工具,无需自定义实现即可扩展 agent 的功能。这些工具开箱即用,并能与 agent 框架无缝集成。
现在,提供商原生工具通过常规的 Tool API 进行声明,而不是使用特定于提供商的 GenerateContentConfig.extensions 数据块。这意味着你可以在同一个 agent 中,将 Gemini Google Search、Anthropic Web Search 或 OpenAI Responses web search 等原生工具与普通的 FunctionTool 实例混合使用。
概述
| 工具 | 用途 | 使用场景 |
|---|---|---|
#[tool] 宏 | 零样板自定义工具 | 任何自定义函数 — 参见函数工具 |
FunctionTool | 手动注册自定义工具 | 动态工具、闭包 |
GoogleSearchTool | 通过 Gemini 进行网络搜索 | 实时信息检索 |
UrlContextTool | Gemini URL 接地 | 对实时 URLs 进行总结或推理 |
GoogleMapsTool | Gemini Google 地图接地 | 地点、路线和本地上下文 |
GeminiCodeExecutionTool | Gemini 原生代码执行 | 服务器端 Python 执行 |
WebSearchTool | Anthropic 原生网络搜索 | Claude 服务器端网络搜索 |
OpenAIWebSearchTool | OpenAI 响应网络搜索 | OpenAI 托管检索 |
AgentTool | 将代理封装为可调用工具 | 代理组合与委派 |
ExitLoopTool | 循环终止 | 控制 LoopAgent 迭代 |
LoadArtifactsTool | 工件加载 | 访问存储的二进制数据 |
GoogleSearchTool
GoogleSearchTool 支持代理使用 Google Search 搜索网络。此工具由 Gemini 模型通过 grounding 功能在内部处理,这意味着搜索由模型本身在服务器端执行。
基本用法
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-3.7-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(())
}
工作原理
与常规函数工具不同,GoogleSearchTool 的运行方式有所不同:
- 服务器端执行:搜索由 Gemini 的 grounding 功能执行,而不是在本地执行
- 自动调用:模型根据查询内容决定何时进行搜索
- 结果集成:搜索结果会直接整合到模型的响应中
如果直接调用该工具,其实现会返回错误,因为实际搜索发生在 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 模型确定 |
| 执行 | 服务器端(Gemini grounding) |
使用场景
- 时事:“今天新闻里发生了什么?”
- 事实查询:“东京的人口是多少?”
- 最新信息:“人工智能领域有哪些最新进展?”
- 研究任务:“查找有关可再生能源趋势的信息”
示例查询
// 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 将任何代理封装为可调用工具,从而实现委托后返回的组合:调用方调用子代理、接收其结果,然后继续执行。子代理发出的状态和工件增量会合并到父工具事件中。子会话还会立即应用每个事件,因此委托工作流中的后续步骤可以看到之前的状态/历史记录变更。
旧版默认行为仍保持隔离并向后兼容。可移植团队可以选择启用父级历史记录/状态快照、记忆转发、失败传播、有限委托深度、精确的状态/历史记录投影,以及对已注册子代理交接的内部执行。已消费的子代理交接仍会作为事件保留,但其传输操作会在转发前被清除,因此父 Runner 不会重复执行该交接。请求元数据、取消操作、作用域、密钥、工件和并行共享状态均遵循配置的转发策略。AgentTool 本身不会运行 Runner 的全局交接循环;编译后的 TeamSpec 会为混合拓扑提供精确的嵌套交接注册表。已编译的团队还会选择启用嵌套事件转发,使委托活动在父事件流中保持可见;独立的 AgentTool 会保留旧版事件输出,除非选择了 forward_events(true)。
对于受控回写,请独立于输入 state_keys 投影使用 output_state_keys。state_merge_policy(RejectConflicts) 会将当前父级值与委托开始时获取的快照进行比较,并以原子方式拒绝冲突写入。artifact_prefixes 将相同的允许列表原则应用于工件名称。为保持向后兼容性,独立默认值仍采用最后写入者获胜策略,并允许不受限制的输出;编译后的团队可以选择其精确的边策略。
基本用法
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()?;
工作原理
- 父代理决定将包装后的代理作为工具调用
AgentTool使用StreamingMode::None创建调用上下文- 子代理运行至完成,并累积其完整响应
- 响应文本返回给父代理
- 状态增量和工件增量转发到父上下文
工具详细信息
| 属性 | 值 |
|---|---|
| 名称 | 与被包装 agent 的名称相同 |
| 描述 | 与被包装 agent 的描述相同 |
| 参数 | request:字符串(要发送给子代理的输入) |
| 返回值 | {"response": "..."},包含子代理的文本输出 |
关键行为
- 子代理在内部以非流式模式运行,以可靠地捕获响应
- 子代理的状态更改(
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-3.7-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(())
}
工作原理
- 代理评估是继续运行还是退出
- 准备退出时,代理调用
exit_loop - 工具设置
actions.escalate = true和actions.skip_summarization = true LoopAgent检测到升级标志并停止迭代
工具详情
| 属性 | 值 |
|---|---|
| 名称 | exit_loop |
| 描述 | "退出循环。仅在收到指示时调用此函数。" |
| 参数 | 无 |
| 返回 | 空对象 {} |
最佳实践
- 明确的退出条件:在 agent 的指令中定义具体条件
- 始终设置 max_iterations:将无限循环作为安全措施加以防止
- 有意义的指令:帮助 agent 理解何时退出
// 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 允许 agent 按名称检索已存储的工件。当 agent 需要访问之前保存的文件、图像或其他二进制数据时,这非常有用。
基本用法
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-3.7-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_names:字符串数组 |
| 返回值 | 包含 artifacts 数组的对象 |
参数
该工具需要一个 JSON 对象,其中包含一个 artifact_names 数组:
{
"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 正常工作,需要:
- 在运行器中配置
ArtifactService - 之前已保存到服务中的构件
- 将该工具添加到 agent
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);
组合内置工具
你可以将多个内置工具组合使用:
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-3.7-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 trait,按照与内置工具相同的模式创建自己的工具:
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;
}
相关内容
- 函数工具 - 创建自定义函数工具
- MCP 工具 - 使用 MCP 服务器作为工具提供方
- 工作流 agent - 使用 ExitLoopTool 和 LoopAgent
- 构件 - 使用构件管理二进制数据