Rust的Claude代理SDK
 
Rust SDK用于使用Claude构建生产就绪的AI代理。使用惯用的Rust模式复制Python Claude Agent SDK的完整功能集。
概述
Claude Agent SDK使您能够使用Claude Code的代理工具构建强大的AI代理。此SDK封装了Claude Code CLI,提供对以下内容的类型安全访问:
- 自动上下文管理和压缩
- 20+内置工具(文件操作、代码执行、网络搜索)
- 自定义MCP(模型上下文协议)工具
- 细粒度权限控制
- 确定性行为的钩子系统
- 交互式双向对话
- 使用情况跟踪和配额监控(最大计划)
重要说明
结构化输出需要超过1圈。 使用时output_format对于JSON模式,CLI可能需要在内部进行额外的转换以生成结构化的JSON。集max_turns至少2-3(或完全省略)-使用max_turns(1)可能会导致error_max_turns没有结构化输出。
max_budget_usd 是一顶软帽。 预算限制是在每一轮之间检查的,而不是在中期。当前回合将始终在预算评估之前完成,因此实际支出可能会略微超过配置的限制。没有嵌套的Claude Code实例。 截至 CLI v2.1.41,Claude Code防止生成自身的嵌套实例。CLI设置CLAUDECODE=1在环境中;任何试图启动另一个Claude Code实例的子进程都会检测到这一点并拒绝启动。这意味着您无法在Claude Code会话中测试SDK示例(例如,从Claude Code的Bash工具中)。请从常规终端运行它们。如果需要绕过此设置,请取消设置CLAUDECODE生成之前先env-var,但要注意递归代理循环和共享资源(文件、会话、API配额)上的争用问题。
先决条件
- 锈:1.85或更高(2024年版)
- Claude 代码命令行界面:2.0.0或更高版本
- 认证:Claude订阅(Pro、Max、Team或Enterprise)或Anthropic API密钥
安装
1.安装Claude Code命令行界面
本机安装程序(推荐):
# macOS / Linux
curl -fsSL https://claude.ai/install.sh | bash
# Windows (PowerShell)
irm https://claude.ai/install.ps1 | iex替代方案(npm):
npm install -g @anthropic-ai/claude-code验证安装:
claude -v
# Should output: 2.0.0 or higher2.将SDK添加到您的项目中
[dependencies]
claude-agent-sdk-rust = "1"
tokio = { version = "1", features = ["full"] }
futures = "0.3"身份验证设置
Claude Code支持多种身份验证方法:
选项1:克劳德订阅(推荐)
如果您有Claude Pro、Team或Enterprise订阅:
claude setup-token这将使用您的Claude订阅进行身份验证。无需额外配置!
选项2:API密钥
如果您正在使用Anthropic API密钥:
- 从获取API密钥https://console.anthropic.com/account/keys
- 设置环境变量:
Linux/macOS:
export ANTHROPIC_API_KEY="sk-ant-..."Windows(PowerShell):
$env:ANTHROPIC_API_KEY="sk-ant-..."Windows(命令提示符):
set ANTHROPIC_API_KEY=sk-ant-...验证身份验证是否有效:
claude --print "Hello, Claude!"快速开始
简单查询
use claude_agent_sdk_rust::{query, Message};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result> {
let mut messages = query("What is 2 + 2?", None).await?;
while let Some(msg) = messages.next().await {
match msg? {
Message::Assistant(assistant) => {
for block in &assistant.message.content {
if let Some(text) = block.as_text() {
println!("Claude: {}", text.text);
}
}
}
Message::Result(result) => {
println!("Cost: ${:.4}", result.total_cost_usd.unwrap_or(0.0));
}
_ => {}
}
}
Ok(())
}通过配置
use claude_agent_sdk_rust::{query, ClaudeAgentOptions, PermissionMode, SystemPrompt};
#[tokio::main]
async fn main() -> Result> {
let options = ClaudeAgentOptions::builder()
.allowed_tools(vec!["Read".into(), "Write".into()])
.permission_mode(PermissionMode::AcceptEdits)
.system_prompt(SystemPrompt::Text(
"You are a helpful file assistant".to_string()
))
.build();
let mut messages = query("Create a hello.txt file", Some(options)).await?;
// Process messages...
Ok(())
}互动对话
use claude_agent_sdk_rust::{ClaudeSDKClient, ClaudeAgentOptions, Message};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result> {
let options = ClaudeAgentOptions::builder()
.allowed_tools(vec!["Read".into(), "Bash".into()])
.build();
let mut client = ClaudeSDKClient::new(options);
client.connect(None).await?;
// First query
client.query("List files in current directory").await?;
let mut response = client.receive_response()?;
while let Some(msg) = response.next().await {
if let Ok(Message::Result(_)) = msg {
break;
}
}
drop(response);
// Follow-up query
client.query("Read the first file").await?;
let mut response = client.receive_response()?;
while let Some(msg) = response.next().await {
println!("{:?}", msg?);
}
drop(response);
client.disconnect().await?;
Ok(())
}主要特点
工具控制
let options = ClaudeAgentOptions::builder()
.allowed_tools(vec!["Read", "Write", "Bash"])
.disallowed_tools(vec!["WebSearch"]) // Block specific tools
.build();权限模式
- 默认:危险操作提示
- 接受编辑:自动接受文件编辑
- 计划:计划模式(不执行)
- 旁路权限:允许使用所有工具(小心使用!)
.permission_mode(PermissionMode::AcceptEdits)系统提示
// Text prompt
.system_prompt(SystemPrompt::Text(
"You are an expert Rust developer".to_string()
))
// Or use Claude Code preset
.system_prompt(SystemPrompt::Preset(SystemPromptPreset {
preset_type: "preset".to_string(),
preset: "claude_code".to_string(),
append: Some("Focus on Rust best practices".to_string())
}))工作目录
.cwd("/path/to/your/project")模型选择
.model(Some("claude-opus-4-20250514".to_string()))思考与努力
控制克劳德的推理深度:
use claude_agent_sdk_rust::{query, ClaudeAgentOptions, ThinkingConfig, Effort};
let options = ClaudeAgentOptions::builder()
.thinking(Some(ThinkingConfig::Adaptive)) // Let Claude decide when to think
.effort(Some(Effort::High)) // More thorough responses
.build();
let messages = query("Solve this complex problem...", Some(options)).await?;ThinkingConfig变体:
Adaptive--克劳德决定什么时候扩展思维有用Enabled { budget_tokens }--始终以象征性的预算思考Disabled--没有深入思考
努力程度: Low, Medium, High, Max
结构化输出
获取与模式匹配的经过验证的JSON响应:
use claude_agent_sdk_rust::{query, ClaudeAgentOptions, Message};
let schema = serde_json::json!({
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"capital": { "type": "string" },
"population": { "type": "string" }
},
"required": ["capital", "population"]
}
});
let options = ClaudeAgentOptions::builder()
.output_format(Some(schema))
.max_turns(3u32) // Structured output needs >1 turn
.build();
let mut messages = query("What is the capital and population of Japan?", Some(options)).await?;
while let Some(msg) = messages.next().await {
if let Ok(Message::Result(result)) = msg {
if let Some(output) = &result.structured_output {
println!("{}", output);
// {"capital": "Tokyo", "population": "approximately 125 million"}
}
}
}预算限额
为每个查询设置软支出上限:
let options = ClaudeAgentOptions::builder()
.max_budget_usd(Some(0.05)) // Soft cap — see Important Notes above
.build();回退模型
如果主模型不可用,请指定回退模型:
let options = ClaudeAgentOptions::builder()
.model(Some("claude-opus-4-20250514".into()))
.fallback_model(Some("claude-sonnet-4-5-20250929".into()))
.build();高级功能
权限回调
通过编程控制工具的使用 PermissionCallback 特质:
use claude_agent_sdk_rust::callbacks::{PermissionCallback, permissions};
use claude_agent_sdk_rust::types::{PermissionResult, ToolPermissionContext};
use async_trait::async_trait;
use serde_json::Value;
struct SafetyChecker;
#[async_trait]
impl PermissionCallback for SafetyChecker {
async fn call(
&self,
tool_name: String,
input: Value,
_context: ToolPermissionContext,
) -> claude_agent_sdk_rust::Result
{
if tool_name == "Bash" {
if let Some(cmd) = input.get("command").and_then(|v| v.as_str()) {
if cmd.contains("rm -rf") {
return Ok(permissions::deny("Dangerous command blocked"));
}
}
}
Ok(permissions::allow())
}
}
// Use with client
let mut client = ClaudeSDKClient::new(options);
client.set_permission_callback(SafetyChecker);
client.connect(None).await?;钉钩系统
在代理循环的特定点执行自定义代码:
use claude_agent_sdk_rust::callbacks::{HookCallback, hooks};
use claude_agent_sdk_rust::types::{HookInput, HookOutput, HookContext, HookEvent};
use async_trait::async_trait;
struct ValidationHook;
#[async_trait]
impl HookCallback for ValidationHook {
async fn call(
&self,
input: HookInput,
_tool_use_id: Option,
_context: HookContext,
) -> claude_agent_sdk_rust::Result {
if let HookInput::PreToolUse(pre) = input {
if pre.tool_name == "Bash" {
if let Some(cmd) = pre.tool_input.get("command")
.and_then(|v| v.as_str()) {
if cmd.contains("dangerous") {
return Ok(hooks::block("Blocked dangerous command"));
}
}
}
}
Ok(hooks::allow())
}
}
// Register hook
let mut client = ClaudeSDKClient::new(options);
client.register_hook(HookEvent::PreToolUse, None, ValidationHook);
client.connect(None).await?;MCP服务器配置
使用外部MCP服务器进行自定义工具:
use std::collections::HashMap;
use claude_agent_sdk_rust::types::{McpServerConfig, McpStdioConfig};
let mut mcp_servers = HashMap::new();
mcp_servers.insert("calculator".into(), McpServerConfig::Stdio(
McpStdioConfig {
command: "python".into(),
args: Some(vec!["-m".into(), "calculator_server".into()]),
env: None
}
));
let options = ClaudeAgentOptions::builder()
.mcp_servers(mcp_servers)
.allowed_tools(vec!["mcp__calculator__add", "mcp__calculator__multiply"])
.build();可用工具
Claude Code包括20多个内置工具:
- 文件操作:阅读、写作、编辑、环球
- 代码执行:Bash,笔记本编辑
- 搜索:Grep、WebSearch、WebFetch
- 沟通:任务(子代理),SlashCommand
- 还有更多:参见 Claude代码文档
错误处理
use claude_agent_sdk_rust::ClaudeSDKError;
match query("test", None).await {
Ok(messages) => { /* process */ }
Err(ClaudeSDKError::CLINotFound { path }) => {
eprintln!("Claude CLI not found at: {:?}", path);
eprintln!("Install from: https://claude.ai/download");
}
Err(ClaudeSDKError::Process { exit_code, message, stderr }) => {
eprintln!("Process failed (exit {}): {}", exit_code, message);
if let Some(err) = stderr {
eprintln!("Details: {}", err);
}
}
Err(ClaudeSDKError::ControlTimeout { timeout_secs, request_type }) => {
eprintln!("Timeout after {}s waiting for: {}", timeout_secs, request_type);
}
Err(e) => {
eprintln!("Error: {}", e);
}
}会话管理
SDK为管理对话会话提供了全面支持,允许您:
- 从对话中捕获会话ID
- 以完整的上下文恢复之前的对话
- 从最近的对话继续
捕获会话ID
会话ID会自动从消息中捕获:
use claude_agent_sdk_rust::{ClaudeSDKClient, ClaudeAgentOptions, Message};
use futures::StreamExt;
let mut client = ClaudeSDKClient::new(ClaudeAgentOptions::default());
client.connect(Some("Hello!".to_string())).await?;
// Process messages
let mut messages = client.receive_messages()?;
while let Some(msg) = messages.next().await {
match msg? {
Message::Result(result) => {
// Session ID is available from result message
let session_id = result.session_id;
println!("Session: {}", session_id);
}
_ => {}
}
}
// Or get it directly from the client
if let Some(session_id) = client.get_session_id() {
println!("Current session: {}", session_id);
}续会
按会话ID恢复特定对话:
let options = ClaudeAgentOptions::builder()
.resume("session-id-here".to_string())
.build();
let mut client = ClaudeSDKClient::new(options);
client.connect(Some("Continue our conversation...".to_string())).await?;继续最近
继续最近的对话:
let options = ClaudeAgentOptions::builder()
.continue_conversation(true)
.build();
let mut client = ClaudeSDKClient::new(options);
client.connect(Some("As we were discussing...".to_string())).await?;分叉会话
恢复时创建新的会话ID(用于实验):
let options = ClaudeAgentOptions::builder()
.resume("original-session-id".to_string())
.fork_session(true) // Creates new ID instead of reusing
.build();会话存储在 ~/.claude/projects/ /.jsonl 并保留完整的对话上下文,包括:
- 所有消息
- 工具使用历史
- 背景和状态
看 examples/session_resume.rs 一个完整的工作示例。
例子
请参阅 examples/ 完整工作示例目录:
basic.rs-简单的一次性查询with_options.rs-配置示例interactive.rs-双向对话with_callbacks.rs-钩子和权限回调session_resume.rs-会话管理和恢复对话usage_tracking.rs-监控Claude代码使用情况和配额(最大计划)new_features.rs-思维、努力、预算限制、结构化产出、MCP状态
运行示例:
cargo run --example basic
cargo run --example interactive
cargo run --example with_callbacks
cargo run --example session_resume
cargo run --example usage_tracking
cargo run --example new_features文档
API指南
看 docs/API_GUIDE.md文件 以获取全面的文档。
Rust API文档
已发布文档: docs.rs/claude-agent-sdk-rust
或者在本地生成:
cargo doc --open故障排除
未找到CLI
Error: Claude Code CLI not found解决方案:安装CLI并确保其位于PATH中:
# Native installer (recommended)
curl -fsSL https://claude.ai/install.sh | bash
# Or via npm
npm install -g @anthropic-ai/claude-code
which claude # Unix/macOS
where claude # Windows或设置自定义路径:
.cli_path(Some("/path/to/claude".into()))认证失败
Error: Authentication failed解决方案:
- 如果使用Claude订阅:运行
claude setup-token - 如果使用API键:设置
ANTHROPIC_API_KEY环境变量 - 验证:运行
claude --print "test"检查身份验证
版本不匹配
Warning: Claude Code version 1.x.x < minimum 2.0.0解决方案:更新克劳德代码:
npm update -g @anthropic-ai/claude-code流程超时
如果初始化或控制请求出现超时错误:
// The SDK uses 60s timeouts by default for control protocol messages
// If your queries need more time, consider using streaming mode with
// the ClaudeSDKClient instead of the one-shot query() function发展
构建项目:
cargo build运行测试:
# Unit tests
cargo test --lib
# Integration tests (requires authentication)
cargo test --test integration_test -- --ignored --test-threads=1格式和lint:
cargo fmt
cargo clippy资源
- API指南 -全面的API文件
- Claude代码文档
- 拟人控制台
许可证
麻省理工学院
支持
- GitHub问题:用于错误报告和功能请求
- 文档:
cargo doc --open供API参考 - Claude代码帮助:https://docs.claude.com/en/docs/claude-code
______________________________________________________________________
备注:此SDK封装了Claude Code CLI。使用前请确保已安装并经过身份验证。
