返回市场
克劳德代理软件开发工具包锈语版

克劳德代理软件开发工具包锈语版

作者:Wally8697 星标更新:2025-10-24

项目介绍

Claude Agent SDK for Rust

用于使用Claude构建生产级AI代理的Rust SDK。通过使用符合Rust习惯用法的模式,复制Python Claude Agent SDK的所有功能。

概述

Claude Agent SDK使您能够使用Claude Code的代理框架构建强大的AI代理。此SDK封装了Claude Code CLI,提供了类型安全的访问:

  • 自动上下文管理和压缩
  • 20多个内置工具(文件操作、代码执行、网络搜索)
  • 自定义MCP(模型上下文协议)工具
  • 细粒度权限控制
  • 确定性行为的钩子系统
  • 交互式双向对话
  • 使用跟踪和配额监控(Max Plan)

预备条件

  • Rust: 1.70或更高版本
  • Claude Code CLI: 2.0.0或更高版本
  • Node.js: 安装Claude Code所需的
  • 身份验证: Claude订阅(Pro、Team或Enterprise)或Anthropic API密钥

安装

1. 安装Claude Code CLI

npm install -g @anthropic-ai/claude-code

验证安装:

claude -v
# 应该输出:2.0.0或更高版本

2. 将SDK添加到您的项目中

[dependencies]
claude-agent-sdk = "0.1"
tokio = { version = "1", features = ["full"] }
futures = "0.3"

身份验证设置

Claude Code支持多种身份验证方法:

选项1:Claude订阅(推荐)

如果您有Claude Pro、Team或Enterprise订阅:

claude setup-token

这将使用您的Claude订阅进行身份验证。无需额外配置!

选项2:API密钥

如果您正在使用Anthropic API密钥:

  1. https://console.anthropic.com/account/keys 获取您的API密钥
  2. 设置环境变量:

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::{query, Message};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut messages = query("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!("费用: ${:.4}", result.total_cost_usd.unwrap_or(0.0));
            }
            _ => {}
        }
    }

    Ok(())
}

带配置

use claude_agent_sdk::{query, ClaudeAgentOptions, PermissionMode, SystemPrompt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = ClaudeAgentOptions::builder()
        .allowed_tools(vec!["Read".into(), "Write".into()])
        .permission_mode(PermissionMode::AcceptEdits)
        .system_prompt(SystemPrompt::Text(
            "您是一个有用的文件助手".to_string()
        ))
        .build();

    let mut messages = query("创建一个hello.txt文件", Some(options)).await?;

    // 处理消息...

    Ok(())
}

交互式对话

use claude_agent_sdk::{ClaudeSDKClient, ClaudeAgentOptions, Message};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = ClaudeAgentOptions::builder()
        .allowed_tools(vec!["Read".into(), "Bash".into()])
        .build();

    let mut client = ClaudeSDKClient::new(options);
    client.connect(None).await?;

    // 第一次查询
    client.query("列出当前目录中的文件").await?;
    let mut response = client.receive_response()?;
    while let Some(msg) = response.next().await {
        if let Ok(Message::Result(_)) = msg {
            break;
        }
    }
    drop(response);

    // 跟随查询
    client.query("读取第一个文件").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"])  // 阻止特定工具
    .build();

权限模式

  • 默认: 对危险操作进行提示
  • AcceptEdits: 自动接受文件编辑
  • Plan: 计划模式(不执行)
  • BypassPermissions: 允许所有工具(谨慎使用!)
.permission_mode(PermissionMode::AcceptEdits)

系统提示

// 文本提示
.system_prompt(SystemPrompt::Text(
    "您是一位经验丰富的Rust开发者".to_string()
))

// 或使用Claude Code预设
.system_prompt(SystemPrompt::Preset(SystemPromptPreset {
    preset_type: "preset".to_string(),
    preset: "claude_code".to_string(),
    append: Some("专注于Rust最佳实践".to_string())
}))

工作目录

.cwd("/path/to/your/project")

模型选择

.model(Some("claude-opus-4-20250514".to_string()))

高级特性

权限回调

通过实现PermissionCallback特质来程序化地控制工具使用:

use claude_agent_sdk::callbacks::{PermissionCallback, permissions};
use claude_agent_sdk::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::Result<PermissionResult> {
        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("阻止危险命令"));
                }
            }
        }
        Ok(permissions::allow())
    }
}

// 与客户端一起使用
let mut client = ClaudeSDKClient::new(options);
client.set_permission_callback(SafetyChecker);
client.connect(None).await?;

钩子系统

在代理循环的特定点执行自定义代码:

use claude_agent_sdk::callbacks::{HookCallback, hooks};
use claude_agent_sdk::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<String>,
        _context: HookContext,
    ) -> claude_agent_sdk::Result<HookOutput> {
        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("阻止危险命令"));
                    }
                }
            }
        }
        Ok(hooks::allow())
    }
}

// 注册钩子
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::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多个内置工具:

  • 文件操作: 读取、写入、编辑、Glob
  • 代码执行: Bash、NotebookEdit
  • 搜索: Grep、WebSearch、WebFetch
  • 通信: Task(子代理)、SlashCommand
  • 更多: 详见Claude Code文档

错误处理

use claude_agent_sdk::ClaudeSDKError;

match query("测试", None).await {
    Ok(messages) => { /* 处理 */ }
    Err(ClaudeSDKError::CLINotFound { path }) => {
        eprintln!("未找到Claude CLI于: {:?}", path);
        eprintln!("安装方式: npm install -g @anthropic-ai/claude-code");
    }
    Err(ClaudeSDKError::Process { exit_code, message, stderr }) => {
        eprintln!("进程失败(退出{}): {}", exit_code, message);
        if let Some(err) = stderr {
            eprintln!("详情: {}", err);
        }
    }
    Err(ClaudeSDKError::ControlTimeout { timeout_secs, request_type }) => {
        eprintln!("超时后等待{}秒: {}", timeout_secs, request_type);
    }
    Err(e) => {
        eprintln!("错误: {}", e);
    }
}

会话管理

SDK完全支持会话管理,允许您:

  • 从对话中捕获会话ID
  • 使用完整上下文恢复之前的对话
  • 从最近的对话继续

捕获会话ID

会话ID自动从消息中捕获:

use claude_agent_sdk::{ClaudeSDKClient, ClaudeAgentOptions, Message};
use futures::StreamExt;

let mut client = ClaudeSDKClient::new(ClaudeAgentOptions::default());
client.connect(Some("你好!".to_string())).await?;

// 处理消息
let mut messages = client.receive_messages()?;
while let Some(msg) = messages.next().await {
    match msg? {
        Message::Result(result) => {
            // 会话ID可以从结果消息中获得
            let session_id = result.session_id;
            println!("会话: {}", session_id);
        }
        _ => {}
    }
}

// 或者直接从客户端获取
if let Some(session_id) = client.get_session_id() {
    println!("当前会话: {}", session_id);
}

恢复会话

通过会话ID恢复特定对话:

let options = ClaudeAgentOptions::builder()
    .resume("session-id-here".to_string())
    .build();

let mut client = ClaudeSDKClient::new(options);
client.connect(Some("继续我们的对话...".to_string())).await?;

继续最近的

继续最近的对话:

let options = ClaudeAgentOptions::builder()
    .continue_conversation(true)
    .build();

let mut client = ClaudeSDKClient::new(options);
client.connect(Some("正如我们讨论的那样...".to_string())).await?;

分支会话

恢复时创建新的会话ID(用于实验):

let options = ClaudeAgentOptions::builder()
    .resume("原始会话ID".to_string())
    .fork_session(true)  // 创建新ID而不是重用
    .build();

会话存储在~/.claude/projects/<项目>/<会话ID>.jsonl中,并保留完整的对话上下文,包括:

  • 所有消息
  • 工具使用历史
  • 上下文和状态

参见examples/session_resume.rs以获取完整的工作示例。

示例

查看examples/目录以获取完整的工作示例:

  • basic.rs - 简单的一次性查询
  • with_options.rs - 配置示例
  • interactive.rs - 双向对话
  • with_callbacks.rs - 钩子和权限回调
  • session_resume.rs - 会话管理和恢复对话
  • usage_tracking.rs - 监控Claude Code使用情况和配额(Max Plan)

运行示例:

cargo run --example basic
cargo run --example interactive
cargo run --example with_callbacks
cargo run --example session_resume
cargo run --example usage_tracking

文档

API指南

参见docs/API_GUIDE.md以获取全面的文档。

Rust API文档

生成并查看完整的API文档:

cargo doc --open

故障排除

CLI未找到

错误: 未找到Claude Code CLI

解决方案: 安装CLI并确保它在PATH中:

npm install -g @anthropic-ai/claude-code
which claude  # Unix/macOS
where claude  # Windows

或者设置自定义路径:

.cli_path(Some("/path/to/claude".into()))

身份验证失败

错误: 身份验证失败

解决方案

  1. 如果使用Claude订阅:运行claude setup-token
  2. 如果使用API密钥:设置ANTHROPIC_API_KEY环境变量
  3. 验证:运行claude --print "test"检查身份验证

版本不匹配

警告: Claude Code版本1.x.x <最低要求2.0.0

解决方案: 更新Claude Code:

npm update -g @anthropic-ai/claude-code

进程超时

如果您遇到初始化或控制请求的超时错误:

// SDK默认使用60秒超时时间来控制协议消息
// 如果您的查询需要更多时间,请考虑使用流模式
// 使用ClaudeSDKClient而不是一次性query()函数

开发

构建项目:

cargo build

运行测试:

# 单元测试
cargo test --lib

# 集成测试(需要身份验证)
cargo test --test integration_test -- --ignored --test-threads=1

格式化和检查:

cargo fmt
cargo clippy

资源

许可

MIT

支持


注意: 此SDK封装了Claude Code CLI。使用前请确保已安装并完成身份验证。