Token导航 LogoToken导航TokenDH.com
Claude Agent SDK logo
开发工具未说明官方级别未说明来源级核验

Claude Agent SDK

MCP Server

用于构建Claude Code CLI代理的C# SDK,提供.NET接口以访问Claude Code的代理能力,适用于开发智能助手和自动化工具。

工具数

0

提示词数

0

GitHub Stars

2

资源数

0
智能代理C#Claude自然语言处理Claude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

AJGit

提供方

AJGit

最后核验

2026/5/17 20:20

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

克劳德。Agent SDK

用于使用Claude Code CLI构建代理的C#SDK。此SDK提供了一个。NET接口实现了与Claude Code相同的代理功能。

需求

  • .NET 8.0、9.0或10.0
  • 克劳德代码CLI 已安装并在PATH中可用

安装

安装Claude代码命令行界面

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

验证安装:

claude --version

将SDK添加到您的项目中

dotnet add package AJGit.Claude.AgentSdk

对于ASP。NET Core依赖注入支持:

dotnet add package AJGit.Claude.AgentSdk.Extensions.DependencyInjection

或者直接引用项目:

快速开始

简单查询

using Claude.AgentSdk;
using Claude.AgentSdk.Messages;

var client = new ClaudeAgentClient();

await foreach (var message in client.QueryAsync("What is the capital of France?"))
{
    if (message is AssistantMessage assistant)
    {
        foreach (var block in assistant.MessageContent.Content)
        {
            if (block is TextBlock text)
            {
                Console.Write(text.Text);
            }
        }
    }
}

带选项

var options = new ClaudeAgentOptions
{
    Model = "sonnet",                              // Model to use (string)
    MaxTurns = 10,                                 // Limit conversation turns
    SystemPrompt = "You are a helpful assistant.", // Custom system prompt (string)
    AllowedTools = ["Read", "Glob", "Grep"],       // Tools Claude can use
    WorkingDirectory = "/path/to/project"          // Working directory
};

var client = new ClaudeAgentClient(options);

强类型模型选择

使用 ModelIdentifier 对于具有IntelliSense支持的类型安全模型选择:

using Claude.AgentSdk.Types;

var options = new ClaudeAgentOptions
{
    // New: Strongly-typed model selection
    ModelId = ModelIdentifier.Sonnet,              // Use predefined model aliases
    FallbackModelId = ModelIdentifier.Haiku,       // Type-safe fallback

    // Specific versions also available
    // ModelId = ModelIdentifier.ClaudeOpus45,     // claude-opus-4-5-20251101
    // ModelId = ModelIdentifier.ClaudeSonnet4,    // claude-sonnet-4-20250514

    // Custom models supported
    // ModelId = ModelIdentifier.Custom("my-fine-tuned-model"),

    MaxTurns = 10,
    AllowedTools = ["Read", "Glob", "Grep"]
};

// Backward compatible: string Model property still works
var legacyOptions = new ClaudeAgentOptions { Model = "sonnet" };

可用模型标识符

标识符
ModelIdentifier.Sonnet"sonnet"
ModelIdentifier.Opus"opus"
ModelIdentifier.Haiku"haiku"
ModelIdentifier.ClaudeSonnet4"claude-sonnet-4-20250514"
ModelIdentifier.ClaudeOpus45"claude-opus-4-5-20251101"
ModelIdentifier.ClaudeHaiku35"claude-3-5-haiku-20241022"

强类型工具名称

使用 ToolName 对于具有IntelliSense支持的类型安全工具引用:

using Claude.AgentSdk.Types;

var options = new ClaudeAgentOptions
{
    // Strongly-typed tool names
    AllowedTools = [ToolName.Read, ToolName.Write, ToolName.Bash, ToolName.Grep],
    DisallowedTools = [ToolName.WebSearch, ToolName.WebFetch],

    // MCP tool names use factory method
    // AllowedTools = [ToolName.Mcp("email-tools", "search_inbox")]
};

// Backward compatible: string arrays still work
var legacyOptions = new ClaudeAgentOptions
{
    AllowedTools = ["Read", "Write", "Bash"]
};

可用的内置工具

工具名称描述
ToolName.Read从文件系统读取文件
ToolName.Write将文件写入文件系统
ToolName.Edit编辑现有文件
ToolName.MultiEdit一次操作中进行多次编辑
ToolName.Bash执行bash命令
ToolName.Grep搜索文件内容
ToolName.Glob按模式查找文件
ToolName.Task产卵子代
ToolName.WebFetch获取网络内容
ToolName.WebSearch搜索网页
ToolName.TodoRead阅读待办事项列表
ToolName.TodoWrite更新待办事项列表
ToolName.NotebookEdit编辑Jupyter笔记本
ToolName.AskUserQuestion向用户提问
ToolName.Skill调用技能
ToolName.TaskOutput获取后台任务输出
ToolName.KillShell终止后台shell

MCP工具名称

使用工厂方法创建MCP工具名称:

// Format: mcp____
var mcpTool = ToolName.Mcp("email-tools", "search_inbox");
// Result: "mcp__email-tools__search_inbox"

// Or use McpServerName for even more type safety
var server = McpServerName.Sdk("email-tools");
var tool = server.Tool("search_inbox");  // Returns ToolName

强类型MCP服务器名称

使用 McpServerName 对于类型安全的MCP服务器参考:

using Claude.AgentSdk.Types;

// Create server name
var server = McpServerName.Sdk("my-tools");

// Get tool names from server
var searchTool = server.Tool("search");       // ToolName: "mcp__my-tools__search"
var readTool = server.Tool("read_file");      // ToolName: "mcp__my-tools__read_file"

// Use with AllowedTools
var options = new ClaudeAgentOptions
{
    AllowedTools = [
        server.Tool("search"),
        server.Tool("read_file"),
        server.Tool("write_file")
    ]
};

使用CLAUDE.md文件

CLAUDE.md文件提供特定于项目的上下文和说明。要加载它们,您必须明确指定 SettingSources:

var options = new ClaudeAgentOptions
{
    // Use Claude Code's system prompt (includes tool instructions, code guidelines, etc.)
    SystemPrompt = SystemPromptConfig.ClaudeCode(),

    // IMPORTANT: You must specify SettingSources to load CLAUDE.md files
    // The claude_code preset alone does NOT load CLAUDE.md automatically
    SettingSources = [SettingSource.Project],  // Load project-level CLAUDE.md

    WorkingDirectory = "/path/to/project"
};

var client = new ClaudeAgentClient(options);

await foreach (var message in client.QueryAsync("Help me refactor this code"))
{
    // Claude now has access to your project guidelines from CLAUDE.md
}

系统提示选项

// Option 1: Custom string prompt (replaces default entirely)
SystemPrompt = "You are a Python specialist."

// Option 2: Use Claude Code's preset (includes tools, code guidelines, safety)
SystemPrompt = SystemPromptConfig.ClaudeCode()

// Option 3: Use preset with appended instructions
SystemPrompt = SystemPromptConfig.ClaudeCode(append: "Always use TypeScript strict mode.")

// Option 4: Explicit preset configuration
SystemPrompt = new PresetSystemPrompt
{
    Preset = "claude_code",
    Append = "Focus on performance optimization."
}

设置源

// Load only project-level CLAUDE.md (./CLAUDE.md or ./.claude/CLAUDE.md)
SettingSources = [SettingSource.Project]

// Load only user-level CLAUDE.md (~/.claude/CLAUDE.md)
SettingSources = [SettingSource.User]

// Load both project and user-level CLAUDE.md
SettingSources = [SettingSource.Project, SettingSource.User]

// Load project, user, and local settings (CLAUDE.local.md - gitignored)
SettingSources = [SettingSource.Project, SettingSource.User, SettingSource.Local]

CLAUDE.md位置:

  • 项目级别: CLAUDE.md.claude/CLAUDE.md 在您的工作目录中
  • 用户级别: ~/.claude/CLAUDE.md 获取所有项目的全局指令
  • 地方一级: CLAUDE.local.md.claude/CLAUDE.local.md (通常被忽略)

工具权限回调

控制Claude可以使用哪些工具:

var options = new ClaudeAgentOptions
{
    AllowedTools = ["Read", "Write", "Bash"],
    CanUseTool = async (request, ct) =>
    {
        Console.WriteLine($"Claude wants to use: {request.ToolName}");
        Console.WriteLine($"Input: {request.Input}");

        // Auto-allow read operations
        if (request.ToolName == "Read")
            return new PermissionResultAllow();

        // Deny dangerous operations
        if (request.ToolName == "Bash")
            return new PermissionResultDeny { Message = "Bash not allowed" };

        // Allow with modifications
        return new PermissionResultAllow();
    }
};

MCP服务器

模型上下文协议(MCP)服务器通过自定义工具和功能扩展了Claude。SDK支持四种传输类型。

运输类型

传输配置类型描述
标准McpStdioServerConfig通过stdin/stdout的外部进程
上海证券交易所McpSseServerConfig服务器通过HTTP发送事件
超文本传输协议McpHttpServerConfigHTTP请求/响应
软件开发工具包McpSdkServerConfig进程中的C#工具

stdio服务器(外部进程)

var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["filesystem"] = new McpStdioServerConfig
        {
            Command = "npx",
            Args = ["@modelcontextprotocol/server-filesystem"],
            Env = new Dictionary
            {
                ["ALLOWED_PATHS"] = "/Users/me/projects"
            }
        }
    },
    AllowedTools = ["mcp__filesystem__list_files", "mcp__filesystem__read_file"]
};

SSE服务器(远程)

var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["remote-api"] = new McpSseServerConfig
        {
            Url = "https://api.example.com/mcp/sse",
            Headers = new Dictionary
            {
                ["Authorization"] = "Bearer your-token"
            }
        }
    }
};

HTTP服务器(远程)

var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["http-service"] = new McpHttpServerConfig
        {
            Url = "https://api.example.com/mcp",
            Headers = new Dictionary
            {
                ["X-API-Key"] = "your-api-key"
            }
        }
    }
};

SDK服务器(进程中C#工具)

直接在C#中定义Claude可以调用的工具:

using Claude.AgentSdk.Attributes;
using Claude.AgentSdk.Tools;

// Create a tool server
var toolServer = new McpToolServer("my-tools", "1.0.0");

// Register a tool with typed input
toolServer.RegisterTool(
    "calculate",
    "Perform arithmetic operations",
    async (input, ct) =>
    {
        var result = input.Operation switch
        {
            "add" => input.A + input.B,
            "multiply" => input.A * input.B,
            _ => throw new ArgumentException("Unknown operation")
        };
        return ToolResult.Text($"Result: {result}");
    });

// Or use attributes with compile-time registration (recommended)
[GenerateToolRegistration]  // Generates RegisterToolsCompiled() extension
public class MyTools
{
    [ClaudeTool("get_weather", "Get weather for a location",
        Categories = ["weather"],
        TimeoutSeconds = 5)]
    public string GetWeather(
        [ToolParameter(Description = "City name", Example = "Tokyo")] string location,
        [ToolParameter(Description = "Unit: celsius or fahrenheit",
                       AllowedValues = ["celsius", "fahrenheit"])] string unit = "celsius")
    {
        return $"Weather in {location}: 72°F, sunny";
    }
}

var myTools = new MyTools();
toolServer.RegisterToolsCompiled(myTools);  // No reflection!

// Use with client
var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        ["my-tools"] = new McpSdkServerConfig
        {
            Name = "my-tools",
            Instance = toolServer
        }
    }
};

record CalculatorInput(double A, double B, string Operation);

编译时工具注册(推荐)

使用源代码生成器注册工具而不进行反射:

// Add generator reference to your project:
// 

[GenerateToolRegistration]  // Marker attribute for source generator
public class EmailTools
{
    [ClaudeTool("search_inbox", "Search emails with Gmail-like syntax",
        Categories = ["email"],
        TimeoutSeconds = 10)]
    public string SearchInbox(
        [ToolParameter(Description = "Gmail-style search query")] string query,
        [ToolParameter(Description = "Max results (1-100)", MinValue = 1, MaxValue = 100)] int? limit = 20)
    {
        // Implementation
    }

    [ClaudeTool("delete_email", "Delete an email by ID",
        Categories = ["email"],
        Dangerous = true)]  // Mark destructive operations
    public string DeleteEmail([ToolParameter(Description = "Email ID")] string id)
    {
        // Implementation
    }
}

// Generated extension method (no reflection)
var emailTools = new EmailTools();
toolServer.RegisterToolsCompiled(emailTools);

// Get tool names for AllowedTools configuration
var toolNames = emailTools.GetToolNamesCompiled();
// Returns: ["search_inbox", "delete_email", ...]

// Get MCP-prefixed tool names for a server
var mcpToolNames = emailTools.GetMcpToolNamesCompiled("email-tools");
// Returns: ["mcp__email-tools__search_inbox", "mcp__email-tools__delete_email", ...]

// Get AllowedTools array directly
var options = new ClaudeAgentOptions
{
    AllowedTools = emailTools.GetAllowedToolsCompiled("email-tools")
};

生成的工具名称方法:

方法说明
GetToolNamesCompiled()退货 IReadOnlyList 工具名称
GetMcpToolNamesCompiled(serverName)返回MCP前缀的工具名称
GetAllowedToolsCompiled(serverName)退货 string[] 为了 AllowedTools

编译时模式生成

在编译时为输入类型生成JSON模式:

[GenerateSchema]  // Generates static schema string
public record SearchInboxInput
{
    [ToolParameter(Description = "Gmail-style search query")]
    public required string Query { get; init; }

    [ToolParameter(Description = "Max results", MinValue = 1, MaxValue = 100)]
    public int? Limit { get; init; }
}

// Access generated schema
var schema = SearchInboxInputSchemaExtensions.GetSchema();

组合多个MCP服务器

var options = new ClaudeAgentOptions
{
    McpServers = new Dictionary
    {
        // External filesystem server
        ["filesystem"] = new McpStdioServerConfig
        {
            Command = "npx",
            Args = ["@modelcontextprotocol/server-filesystem"]
        },
        // Remote API via SSE
        ["remote-api"] = new McpSseServerConfig
        {
            Url = "https://api.example.com/mcp/sse"
        },
        // In-process custom tools
        ["custom"] = new McpSdkServerConfig
        {
            Name = "custom",
            Instance = myToolServer
        }
    },
    // Allow specific MCP tools (format: mcp____)
    AllowedTools = [
        "mcp__filesystem__list_files",
        "mcp__remote-api__query",
        "mcp__custom__calculate"
    ]
};

流畅的MCP服务器构建器

使用 McpServerBuilder 为了获得更符合人体工程学的配置体验:

using Claude.AgentSdk.Builders;

var servers = new McpServerBuilder()
    // Add stdio server with environment variables
    .AddStdio("file-tools", "python", "file_tools.py")
        .WithEnvironment("DEBUG", "true")
        .WithEnvironment("MAX_FILES", "100")

    // Add SSE server with authentication headers
    .AddSse("remote-api", "https://api.example.com/mcp/sse")
        .WithHeaders("Authorization", "Bearer your-token")
        .WithHeaders("X-API-Version", "2")

    // Add HTTP server
    .AddHttp("http-service", "https://api.example.com/mcp")
        .WithHeaders("X-API-Key", "your-api-key")

    // Add in-process SDK server
    .AddSdk("excel-tools", excelToolServer)

    .Build();

var options = new ClaudeAgentOptions
{
    McpServers = servers,
    AllowedTools = ["mcp__file-tools__read", "mcp__remote-api__query"]
};

建筑商提供:

  • 流畅的链接:在可读流中配置多个服务器
  • 上下文感知方法: WithEnvironment() 对于stdio, WithHeaders() 适用于SSE/HTTP
  • 类型安全性:配置编译时检查

流畅的选项生成器

使用 ClaudeAgentOptionsBuilder 获得全面流畅的配置体验:

using Claude.AgentSdk.Builders;
using Claude.AgentSdk.Types;

var options = new ClaudeAgentOptionsBuilder()
    // Model configuration
    .WithModel(ModelIdentifier.Sonnet)
    .WithFallbackModel(ModelIdentifier.Haiku)
    .WithMaxTurns(50)

    // System prompt options
    .WithSystemPrompt("You are a helpful assistant.")
    // Or: .UseClaudeCodePreset()
    // Or: .UseClaudeCodePreset(append: "Focus on C# code.")

    // Tool configuration with strongly-typed names
    .AllowTools(ToolName.Read, ToolName.Write, ToolName.Bash, ToolName.Task)
    .DisallowTools(ToolName.WebSearch)
    // Or: .AllowAllToolsExcept(ToolName.Bash)

    // MCP servers
    .AddMcpServer("my-tools", new McpSdkServerConfig
    {
        Name = "my-tools",
        Instance = toolServer
    })

    // Permission handling
    .WithPermissionMode(PermissionMode.AcceptEdits)
    .WithToolPermissionHandler(async (request, ct) =>
    {
        if (request.ToolName == "Bash")
            return new PermissionResultDeny { Message = "No shell access" };
        return new PermissionResultAllow();
    })

    // Hooks using builder
    .WithHooks(new HookConfigurationBuilder()
        .OnPreToolUse(handler, matcher: "Write|Edit")
        .OnSessionStart(sessionHandler)
        .Build())

    // Subagents using builder
    .AddAgent("reviewer", new AgentDefinitionBuilder()
        .WithDescription("Code review specialist")
        .WithPrompt("You review code for quality and security.")
        .WithTools(ToolName.Read, ToolName.Grep, ToolName.Glob)
        .WithModel(ModelIdentifier.Haiku)
        .Build())

    // Additional settings
    .WithWorkingDirectory("/path/to/project")
    .LoadSettingsFrom(SettingSource.Project, SettingSource.User)

    .Build();

var client = new ClaudeAgentClient(options);

ClaudeAgentOptionsBuilder 提供:

  • 完全智能感知支持:通过方法链发现所有选项
  • 类型安全性:模型、工具和设置的强类型标识符
  • 可组合性:与其他构建器(HookConfigurationBuilder、AgentDefinition Builder)结合使用
  • 验证:在生成时捕获配置错误

Fluent钩子配置生成器

使用 HookConfigurationBuilder 为了简化挂钩设置:

using Claude.AgentSdk.Builders;
using Claude.AgentSdk.Protocol;

var hooks = new HookConfigurationBuilder()
    // Pre-tool hooks with pattern matching
    .OnPreToolUse(ValidateBashCommand, matcher: "Bash")
    .OnPreToolUse(ValidateFileWrites, matcher: "Write|Edit|MultiEdit")

    // Post-tool hooks
    .OnPostToolUse(LogToolUsage)
    .OnPostToolUseFailure(HandleToolError)

    // Session lifecycle
    .OnSessionStart(InitializeTelemetry)
    .OnSessionEnd(CleanupResources)

    // Subagent tracking
    .OnSubagentStart(TrackSubagent)
    .OnSubagentStop(AggregateResults)

    // Other events
    .OnUserPromptSubmit(InjectContext)
    .OnNotification(SendToSlack)
    .OnPermissionRequest(CustomPermissionHandler)

    .Build();

var options = new ClaudeAgentOptions { Hooks = hooks };

流畅的代理定义生成器

使用 AgentDefinitionBuilder 对于子代理配置:

using Claude.AgentSdk.Builders;
using Claude.AgentSdk.Types;

// Basic agent definition
var codeReviewer = new AgentDefinitionBuilder()
    .WithDescription("Expert code reviewer for security and quality")
    .WithPrompt("""
        You are a code review specialist. Focus on:
        - Security vulnerabilities
        - Performance issues
        - Clean code principles
        """)
    .WithTools(ToolName.Read, ToolName.Grep, ToolName.Glob)
    .WithModel(ModelIdentifier.Haiku)
    .Build();

// Using convenience presets
var readOnlyAgent = new AgentDefinitionBuilder()
    .WithDescription("Read-only code analyzer")
    .WithPrompt("Analyze code without making changes.")
    .AsReadOnlyAnalyzer()  // Sets Read, Grep, Glob tools
    .Build();

var testRunner = new AgentDefinitionBuilder()
    .WithDescription("Test execution specialist")
    .WithPrompt("Run and analyze test suites.")
    .AsTestRunner()  // Sets Bash, Read, Grep tools
    .Build();

var fullAccessAgent = new AgentDefinitionBuilder()
    .WithDescription("Full-stack developer")
    .WithPrompt("Implement features with full file access.")
    .AsFullAccessDeveloper()  // Sets Read, Write, Edit, Bash, Grep, Glob
    .Build();

// Use with options
var options = new ClaudeAgentOptions
{
    AllowedTools = [ToolName.Task, ToolName.Read, ToolName.Write],
    Agents = new Dictionary
    {
        ["code-reviewer"] = codeReviewer,
        ["test-runner"] = testRunner
    }
};

子代理

子代理是处理集中子任务的独立代理实例。使用它们来隔离上下文,并行运行任务,并应用专门的指令。

定义子代理

var options = new ClaudeAgentOptions
{
    // Task tool is required for subagent invocation
    AllowedTools = ["Read", "Grep", "Glob", "Task"],

    Agents = new Dictionary
    {
        ["code-reviewer"] = new AgentDefinition
        {
            // Description tells Claude when to use this subagent
            Description = "Expert code review specialist. Use for quality, security, and maintainability reviews.",

            // Prompt defines the subagent's behavior
            Prompt = """
                You are a code review specialist with expertise in security and best practices.
                When reviewing code:
                - Identify security vulnerabilities
                - Check for performance issues
                - Suggest specific improvements
                Be thorough but concise.
                """,

            // Tools restricts what the subagent can do (read-only here)
            Tools = ["Read", "Grep", "Glob"],

            // Model overrides the default model for this subagent
            Model = "sonnet"
        },

        ["test-runner"] = new AgentDefinition
        {
            Description = "Runs and analyzes test suites. Use for test execution and coverage analysis.",
            Prompt = "You are a test execution specialist. Run tests and analyze results.",
            // Bash access lets this subagent run test commands
            Tools = ["Bash", "Read", "Grep"]
        }
    }
};

var client = new ClaudeAgentClient(options);
await foreach (var msg in client.QueryAsync("Review the authentication module for security issues"))
{
    // Claude will automatically delegate to code-reviewer based on the task
}

Agent定义属性

属性类型必填描述
Descriptionstring何时使用此代理(Claude使用此代理进行委托)
Promptstring系统提示定义代理的角色
ToolsIReadOnlyList?允许的工具(如果省略,则继承所有工具)
Modelstring?模型覆盖(“十四行诗”、“小品”、“俳句”)

常用工具组合

用例工具描述
只读分析["Read", "Grep", "Glob"]可以检查但不能修改
测试执行["Bash", "Read", "Grep"]可以运行命令
代码修改["Read", "Edit", "Write", "Grep", "Glob"]完全读/写
完全访问null (省略)从父级继承所有工具

显式调用

要保证Claude使用特定的子代理,请按名称提及它:

await foreach (var msg in client.QueryAsync("Use the code-reviewer agent to check the auth module"))
{
    // Directly invokes the named subagent
}
注: 子代理不能产生自己的子代理。不要在子代理的Tools数组中包含“Task”。

子代理工具配置

工具权限的工作原理:

主要代理人的 Tools 列表创建一个 基础工具池子代理可以使用:

  1. 主代理池中的工具(读、写等共享工具)
  2. 自己的工具 AgentDefinition.Tools 列表(即使不在main的池中)

工作模式:

var options = new ClaudeAgentOptions
{
    SystemPrompt = "You are a coordinator. Spawn subagents to do research.",

    // Main agent: Task for spawning + shared tools subagents need
    Tools = new ToolsList(["Task", "Read", "Write"]),

    Agents = new Dictionary
    {
        ["researcher"] = new AgentDefinition
        {
            Description = "Research specialist for web searches",
            // Subagent gets: WebSearch (own list) + Read, Write (from main's pool)
            Tools = ["WebSearch", "Write", "Read"],
            Prompt = "You research topics and save findings to files.",
            Model = "haiku"
        }
    }
};
工具主代理子代理配置子代理可以使用吗?
任务N/A(用于产卵)
阅读✓ (来自主泳池)
✓ (来自主泳池)
网络搜索✓ (来自子代理自己的列表)

要点:

  • 包含 Task 在主代理生成子代理的工具中
  • 包括共享文件工具(Read, Write)在主代理的工具中,子代理需要池中的这些工具
  • 子代理特定工具(如 WebSearch)只需要在子代理的 Tools 列表
  • 在文件操作提示中使用完整的绝对路径(相对路径可能解析不正确)
  • parent_tool_use_id 字段可能为空,但您可以通过检查 Model 场(例如,俳句vs十四行诗)

常见陷阱:

如果主要代理人有 Tools = ["Task"] 只有(没有读/写),即使写在他们的工具列表中,子代理也无法写入文件。共享工具必须在主代理的池中。

申报代理人注册

使用属性以声明方式定义代理:

using Claude.AgentSdk.Attributes;

[GenerateAgentRegistration]  // Generates GetAgentsCompiled() extension method
public class MyAgents
{
    [ClaudeAgent("code-reviewer",
        Description = "Expert code reviewer for quality, security, and maintainability")]
    [AgentTools("Read", "Grep", "Glob")]
    public static string CodeReviewerPrompt => """
        You are a code review specialist with expertise in:
        - Security vulnerability detection
        - Performance optimization
        - Clean code principles
        - SOLID design patterns

        When reviewing code:
        1. Identify potential security issues
        2. Check for performance bottlenecks
        3. Suggest specific improvements with code examples
        Be thorough but concise.
        """;

    [ClaudeAgent("test-runner",
        Description = "Test execution specialist for running and analyzing test suites",
        Model = "haiku")]  // Use faster model for test execution
    [AgentTools("Bash", "Read", "Grep")]
    public static string TestRunnerPrompt => """
        You are a test execution specialist. Your responsibilities:
        - Run test suites using appropriate commands
        - Analyze test results and failures
        - Provide clear summaries of test coverage
        """;

    [ClaudeAgent("documentation-writer",
        Description = "Technical writer for API docs, READMEs, and code comments")]
    [AgentTools("Read", "Write", "Edit", "Glob")]
    public static string DocumentationWriterPrompt => """
        You are a technical documentation specialist. Create clear, accurate documentation
        that helps developers understand and use the code effectively.
        """;
}

// Usage with generated extension method
var agents = new MyAgents();
var options = new ClaudeAgentOptions
{
    AllowedTools = ["Task", "Read", "Write", "Grep", "Glob", "Bash"],
    Agents = agents.GetAgentsCompiled()  // Returns IReadOnlyDictionary
};

属性参考:

属性目标描述
[GenerateAgentRegistration]启用 GetAgentsCompiled() 扩展
[ClaudeAgent(name)]属性使用名称和元数据定义代理
[AgentTools(...)]属性指定代理可用的工具

ClaudeAgent属性:

属性类型描述
Namestring必需。唯一代理标识符
Descriptionstring?克劳德什么时候应该使用这个代理
Modelstring?模型覆盖(例如,速度的“俳句”)

斜杠命令

Slash命令通过特殊方式控制Claude Code会话 / 前缀命令。

发现可用命令

var client = new ClaudeAgentClient();

await foreach (var msg in client.QueryAsync("Hello"))
{
    if (msg is SystemMessage sys && sys.IsInit)
    {
        Console.WriteLine("Available commands:");
        foreach (var cmd in sys.SlashCommands ?? [])
        {
            Console.WriteLine($"  {cmd}");
        }
        // Output: /compact, /clear, /help, /review, etc.
    }
}

发送Slash命令

以提示字符串形式发送命令:

// Compact conversation history
await foreach (var msg in client.QueryAsync("/compact"))
{
    if (msg is SystemMessage sys && sys.IsCompactBoundary)
    {
        Console.WriteLine($"Compacted: {sys.CompactMetadata?.PreTokens} → {sys.CompactMetadata?.PostTokens} tokens");
    }
}

// Clear conversation and start fresh
await foreach (var msg in client.QueryAsync("/clear"))
{
    if (msg is SystemMessage sys && sys.IsInit)
    {
        Console.WriteLine($"New session: {sys.SessionId}");
    }
}

带参数的命令

在命令后传递参数:

// Custom command with arguments (e.g., /fix-issue defined in .claude/commands/fix-issue.md)
await foreach (var msg in client.QueryAsync("/fix-issue 123 high"))
{
    // Arguments are passed as $1="123", $2="high" to the command
}

// Refactor a specific file
await foreach (var msg in client.QueryAsync("/refactor src/auth/login.cs"))
{
    // ...
}

自定义Slash命令

在中创建自定义命令作为markdown文件 .claude/commands/:

.claude/commands/security-check.md:

---
allowed-tools: Read, Grep, Glob
description: Run security vulnerability scan
model: claude-sonnet-4-5-20250929
---

Analyze the codebase for security vulnerabilities including:
- SQL injection risks
- XSS vulnerabilities
- Exposed credentials

.claude/commands/fix-issue.md:

---
argument-hint: [issue-number] [priority]
description: Fix a GitHub issue
---

Fix issue #$1 with priority $2.
Check the issue description and implement the necessary changes.

命令中的文件引用

参考文件使用 @ 命令定义中的前缀:

Review the following configuration:
- Package config: @package.json
- TypeScript config: @tsconfig.json

命令中的Bash输出

使用以下命令包含bash命令输出 !:

## Context
- Current status: !`git status`
- Recent changes: !`git diff HEAD~1`

系统消息属性

属性类型描述
Subtypestring消息子类型(“init”、“compact_boundary”等)
SessionIdstring?当前会话ID
SlashCommandsIReadOnlyList?可用的斜线命令
ToolsIReadOnlyList?可用工具
McpServersIReadOnlyList?MCP服务器连接状态
Modelstring?当前型号
CompactMetadataCompactMetadata?压实详图(压实边界)
IsInitbool如果子类型==“init”,则为True
IsCompactBoundarybool如果子类型==“compact_boundary”,则为True
SubtypeEnumSystemMessageSubtype子类型的强类型枚举访问器

强类型枚举访问器

SDK为类型安全的消息处理提供了强类型枚举访问器:

using Claude.AgentSdk.Types;

await foreach (var message in client.QueryAsync(prompt))
{
    switch (message)
    {
        case SystemMessage system:
            // Use SubtypeEnum instead of string comparison
            if (system.SubtypeEnum == SystemMessageSubtype.Init)
            {
                Console.WriteLine($"Session initialized: {system.SessionId}");

                // Check MCP server status with StatusEnum
                foreach (var server in system.McpServers ?? [])
                {
                    if (server.StatusEnum == McpServerStatusType.Connected)
                        Console.WriteLine($"  {server.Name}: Connected");
                    else if (server.StatusEnum == McpServerStatusType.Failed)
                        Console.WriteLine($"  {server.Name}: Failed - {server.Error}");
                }
            }
            break;

        case ResultMessage result:
            // Use SubtypeEnum for type-safe result checking
            var status = result.SubtypeEnum switch
            {
                ResultMessageSubtype.Success => "Completed",
                ResultMessageSubtype.Error => "Failed",
                ResultMessageSubtype.Partial => "Partial",
                _ => "Unknown"
            };
            var ctx = result.Usage is not null ? $"{result.Usage.TotalContextTokens / 1000.0:F0}k" : "?";
            Console.WriteLine($"[{result.DurationMs / 1000.0:F1}s | ${result.TotalCostUsd:F4} | {ctx}]");
            break;
    }
}

可用枚举类型

类型
MessageTypeUser, Assistant, System, Result, StreamEvent
ContentBlockTypeText, Thinking, ToolUse, ToolResult
SystemMessageSubtypeInit, CompactBoundary
ResultMessageSubtypeSuccess, Error, Partial
McpServerStatusTypeConnected, Failed, NeedsAuth, Pending
SessionStartSourceStartup, Resume, Clear, Compact
SessionEndReasonClear, Logout, PromptInputExit, BypassPermissionsDisabled
NotificationTypePermissionPrompt, IdlePrompt, AuthSuccess, ElicitationDialog

生成的枚举字符串映射

枚举与 [GenerateEnumStrings] 具有编译时生成的转换方法:

using Claude.AgentSdk.Types;

// Convert enum to JSON string
var jsonValue = MessageType.StreamEvent.ToJsonString();  // "stream_event"
var status = McpServerStatusType.NeedsAuth.ToJsonString();  // "needs-auth"

// Parse string to enum
var messageType = EnumStringMappings.ParseMessageType("assistant");  // MessageType.Assistant
var serverStatus = EnumStringMappings.ParseMcpServerStatusType("connected");  // McpServerStatusType.Connected

// Safe parsing with TryParse
if (EnumStringMappings.TryParseResultMessageSubtype("success", out var subtype))
{
    Console.WriteLine($"Parsed: {subtype}");  // ResultMessageSubtype.Success
}

好处超过 Enum.Parse:

  • 生成编译时间:无反射,性能更好
  • 类型安全:每个枚举都有专用的Parse/TTryParse方法
  • JSON兼容:处理snake_case和kebab case命名约定

功能匹配模式

SDK生成功能 Match 区分联合类型的扩展方法,如 MessageContentBlock。使用它们进行详尽的、类型安全的模式匹配:

using Claude.AgentSdk.Messages;

// Match with all cases (exhaustive)
var description = message.Match(
    userMessage: u => $"User: {u.MessageContent.Content}",
    assistantMessage: a => $"Assistant response with {a.MessageContent.Content.Count} blocks",
    systemMessage: s => $"System: {s.Subtype}",
    resultMessage: r => {
        var ctx = r.Usage is not null ? $"{r.Usage.TotalContextTokens / 1000.0:F0}k" : "?";
        return $"[{r.DurationMs/1000.0:F1}s | ${r.TotalCostUsd:F4} | {ctx}]";
    },
    streamEvent: e => $"Stream event: {e.Uuid}"
);

// Match with default for partial handling
var isFromClaude = message.Match(
    assistantMessage: _ => true,
    defaultCase: () => false
);

// Match on content blocks
foreach (var block in assistant.MessageContent.Content)
{
    var text = block.Match(
        textBlock: t => t.Text,
        thinkingBlock: t => $"[thinking: {t.Thinking.Length} chars]",
        toolUseBlock: t => $"[tool: {t.Name}]",
        toolResultBlock: t => t.Content?.ToString() ?? ""
    );
    Console.WriteLine(text);
}

// Action-based matching (void return)
message.Match(
    userMessage: u => Console.WriteLine($"User said: {u.MessageContent.Content}"),
    assistantMessage: a => ProcessAssistantResponse(a),
    systemMessage: s => LogSystemEvent(s),
    resultMessage: r => RecordCost(r),
    streamEvent: _ => { }  // Ignore stream events
);

优点:

  • 彻底检查:编译器确保所有情况都得到处理
  • 类型推断:每个处理程序都接收正确的派生类型
  • 默认支持:处理部分案件 defaultCase
  • 编译时生成:无运行时反射

消息处理扩展

SDK提供了扩展方法来简化常见的消息处理任务:

using Claude.AgentSdk.Extensions;
using Claude.AgentSdk.Messages;

await foreach (var message in client.QueryAsync(prompt))
{
    if (message is AssistantMessage assistant)
    {
        // Get all text content combined
        var fullText = assistant.GetText();
        Console.WriteLine(fullText);

        // Get all tool uses
        foreach (var toolUse in assistant.GetToolUses())
        {
            Console.WriteLine($"Tool: {toolUse.Name}");

            // Get typed input
            var input = toolUse.GetInput();
            if (input != null)
                Console.WriteLine($"Query: {input.Query}");
        }

        // Check if specific tool was used
        if (assistant.HasToolUse(ToolName.Bash))
            Console.WriteLine("Bash command executed");

        // Get thinking blocks (for extended thinking)
        foreach (var thinking in assistant.GetThinking())
        {
            Console.WriteLine($"[Thinking: {thinking.Thinking.Length} chars]");
        }
    }
}

record SearchInput(string Query, int? Limit);

内容块扩展

类型安全内容块处理的扩展方法:

using Claude.AgentSdk.Extensions;
using Claude.AgentSdk.Messages;

foreach (var block in assistant.MessageContent.Content)
{
    // Type checking
    if (block.IsText())
        Console.Write(block.AsText());

    if (block.IsToolUse())
    {
        var toolUse = block.AsToolUse()!;
        Console.WriteLine($"[{toolUse.Name}]");
    }

    if (block.IsThinking())
        Console.Write("[thinking...]");

    if (block.IsToolResult())
    {
        var result = block.AsToolResult()!;
        Console.WriteLine($"Result: {result.Content}");
    }
}

可用的扩展方法:

方法说明
GetText()连接所有文本块
GetToolUses()返回所有工具使用块
GetThinking()返回所有思维块
HasToolUse(ToolName)检查是否使用了特定工具
GetInput()将工具输入反序列化为类型
IsText() / AsText()文本的类型检查和转换
IsToolUse() / AsToolUse()工具使用的类型检查和转换
IsThinking() / AsThinking()类型检查和思维转换
IsToolResult() / AsToolResult()工具结果的类型检查和转换

钩子输入枚举访问器

[HookEvent.SessionStart] = new[]
{
    new HookMatcher
    {
        Hooks = new HookCallback[]
        {
            async (input, toolUseId, context, ct) =>
            {
                if (input is SessionStartHookInput start)
                {
                    // Use SourceEnum for type-safe source checking
                    if (start.SourceEnum == SessionStartSource.Resume)
                        Console.WriteLine("Resumed previous session");
                }
                return new SyncHookOutput { Continue = true };
            }
        }
    }
},
[HookEvent.Notification] = new[]
{
    new HookMatcher
    {
        Hooks = new HookCallback[]
        {
            async (input, toolUseId, context, ct) =>
            {
                if (input is NotificationHookInput notification)
                {
                    // Use NotificationTypeEnum for type-safe handling
                    if (notification.NotificationTypeEnum == NotificationType.PermissionPrompt)
                        await SendSlackNotification(notification.Message);
                }
                return new SyncHookOutput { Continue = true };
            }
        }
    }
}

技能

技能赋予了克劳德在相关情况下自主调用的专业能力。技能被定义为 SKILL.md 文件(非编程)。

赋能技能

var options = new ClaudeAgentOptions
{
    WorkingDirectory = "/path/to/project",  // Project with .claude/skills/

    // REQUIRED: Load skills from filesystem
    SettingSources = [SettingSource.Project, SettingSource.User],

    // REQUIRED: Enable the Skill tool
    AllowedTools = ["Skill", "Read", "Write", "Bash"]
};

var client = new ClaudeAgentClient(options);

// Claude automatically invokes relevant skills based on your request
await foreach (var msg in client.QueryAsync("Help me process this PDF document"))
{
    // If a PDF processing skill exists, Claude will use it
}

技能地点

位置路径加载时间
项目技能.claude/skills/*/SKILL.mdSettingSource.Project
用户技能~/.claude/skills/*/SKILL.mdSettingSource.User

创造技能

技能是包含以下内容的目录 SKILL.md 文件:

.claude/skills/pdf-processor/SKILL.md:

---
description: Extract and process text from PDF documents
---

# PDF Processing Skill

When the user needs to extract text from PDFs:

1. Use `pdftotext` or similar tools to extract content
2. Clean and format the extracted text
3. Return structured results

## Example Usage
- "Extract text from invoice.pdf"
- "Process all PDFs in the documents folder"

发现可用技能

// Ask Claude what skills are available
await foreach (var msg in client.QueryAsync("What Skills are available?"))
{
    if (msg is AssistantMessage assistant)
    {
        // Claude lists available skills based on current directory
    }
}

要点

  • 仅限文件系统:技能不能以编程方式定义(与子代理不同)
  • SettingSources 必需的:没有明确说明,技能将无法加载 SettingSources 配置
  • 自动调用:Claude根据自己的技能决定何时使用技能 description 领域
  • 工具限制:通过以下方式控制可用工具 AllowedTools 在你的选择中

插件

插件是Claude Code扩展的包,可以包括命令、代理、技能、钩子和MCP服务器。

加载插件

var options = new ClaudeAgentOptions
{
    Plugins = [
        new PluginConfig { Path = "./my-plugin" },
        new PluginConfig { Path = "/absolute/path/to/another-plugin" }
    ]
};

var client = new ClaudeAgentClient(options);

await foreach (var msg in client.QueryAsync("Hello"))
{
    if (msg is SystemMessage sys && sys.IsInit)
    {
        // Plugin commands, agents, and features are now available
        Console.WriteLine($"Commands: {string.Join(", ", sys.SlashCommands ?? [])}");
        // Example: /help, /compact, my-plugin:custom-command
    }
}

使用插件命令

插件命令的命名空间为 plugin-name:command-name:

// Use a plugin command
await foreach (var msg in client.QueryAsync("/my-plugin:greet"))
{
    // Claude executes the custom greeting command from the plugin
}

插件结构

插件是带有 .claude-plugin/plugin.json 显示:

my-plugin/
├── .claude-plugin/
│   └── plugin.json          # Required: plugin manifest
├── commands/                 # Custom slash commands
│   └── custom-cmd.md
├── agents/                   # Custom agents
│   └── specialist.md
├── skills/                   # Agent Skills
│   └── my-skill/
│       └── SKILL.md
├── hooks/                    # Event handlers
│   └── hooks.json
└── .mcp.json                # MCP server definitions

多个插件

var options = new ClaudeAgentOptions
{
    Plugins = [
        new PluginConfig { Path = "./local-plugin" },
        new PluginConfig { Path = "./project-plugins/team-workflows" },
        new PluginConfig { Path = "~/.claude/custom-plugins/shared-plugin" }
    ]
};

插件配置属性

属性类型描述
Typestring插件类型(默认:“本地”)
Pathstring插件目录的路径(相对或绝对)

结构化输出

获取特定JSON模式中的响应:

var options = new ClaudeAgentOptions
{
    OutputFormat = JsonDocument.Parse("""
    {
        "type": "json_schema",
        "json_schema": {
            "name": "analysis",
            "strict": true,
            "schema": {
                "type": "object",
                "properties": {
                    "summary": { "type": "string" },
                    "sentiment": {
                        "type": "string",
                        "enum": ["positive", "negative", "neutral"]
                    },
                    "score": { "type": "number" }
                },
                "required": ["summary", "sentiment", "score"],
                "additionalProperties": false
            }
        }
    }
    """).RootElement
};

var client = new ClaudeAgentClient(options);

await foreach (var msg in client.QueryAsync("Analyze: I love this product!"))
{
    if (msg is AssistantMessage assistant)
    {
        var text = assistant.MessageContent.Content.OfType().First();
        var result = JsonSerializer.Deserialize(text.Text);
        Console.WriteLine($"Sentiment: {result.Sentiment}, Score: {result.Score}");
    }
}

record AnalysisResult(string Summary, string Sentiment, double Score);

类型安全结构化输出(推荐)

使用 SchemaGenerator 从C#类型自动生成JSON模式:

using Claude.AgentSdk.Schema;

// Define your output type with descriptions
[Description("Analysis of text sentiment")]
public record SentimentAnalysis
{
    [SchemaDescription("Brief summary of the text")]
    public required string Summary { get; init; }

    [SchemaDescription("Overall sentiment of the text")]
    public required Sentiment Sentiment { get; init; }

    [SchemaDescription("Confidence score from 0-1")]
    public required double Confidence { get; init; }
}

public enum Sentiment { Positive, Negative, Neutral }

// Generate schema automatically
var schema = SchemaGenerator.Generate("sentiment_analysis");

// Or use the fluent extension method
var options = new ClaudeAgentOptions { Model = "sonnet" }
    .WithStructuredOutput();

var client = new ClaudeAgentClient(options);

await foreach (var msg in client.QueryAsync("Analyze: I love this product!"))
{
    if (msg is AssistantMessage assistant)
    {
        // Type-safe parsing
        var result = assistant.ParseStructuredOutput();
        Console.WriteLine($"Sentiment: {result?.Sentiment}, Confidence: {result?.Confidence}");
    }
}

钩子

钩子允许您在关键点拦截代理执行,以添加验证、日志记录、安全控制或自定义逻辑。

可用钩子事件

钩子事件描述用例
PreToolUse在工具执行之前(可以阻止/修改)阻止危险命令
PostToolUse工具成功执行后日志文件更改
PostToolUseFailure当工具执行失败时处理错误
UserPromptSubmit提交用户提示时注入上下文
Stop代理执行停止时保存会话状态
SubagentStart子代理初始化时跟踪并行任务
SubagentStop当子代理完成时聚合结果
PreCompact压缩对话前存档记录
PermissionRequest权限对话框何时显示自定义权限处理
SessionStart会话初始化时初始化遥测
SessionEnd会话终止时清理资源
Notification用于代理状态消息发送到Slack/PagerDuty

基本钩子示例

var options = new ClaudeAgentOptions
{
    Hooks = new Dictionary>
    {
        [HookEvent.PreToolUse] = new[]
        {
            new HookMatcher
            {
                Matcher = "Bash",  // Only for Bash tool (regex pattern)
                Hooks = new HookCallback[]
                {
                    async (input, toolUseId, context, ct) =>
                    {
                        if (input is PreToolUseHookInput pre)
                        {
                            Console.WriteLine($"About to run: {pre.ToolInput}");
                        }
                        return new SyncHookOutput { Continue = true };
                    }
                }
            }
        }
    }
};

阻止危险操作

var options = new ClaudeAgentOptions
{
    Hooks = new Dictionary>
    {
        [HookEvent.PreToolUse] = new[]
        {
            new HookMatcher
            {
                Matcher = "Write|Edit",  // Match file modification tools
                Hooks = new HookCallback[]
                {
                    async (input, toolUseId, context, ct) =>
                    {
                        if (input is PreToolUseHookInput pre)
                        {
                            var filePath = pre.ToolInput.GetProperty("file_path").GetString();
                            if (filePath?.EndsWith(".env") == true)
                            {
                                return new SyncHookOutput
                                {
                                    HookSpecificOutput = JsonSerializer.SerializeToElement(new
                                    {
                                        hookEventName = pre.HookEventName,
                                        permissionDecision = "deny",
                                        permissionDecisionReason = "Cannot modify .env files"
                                    })
                                };
                            }
                        }
                        return new SyncHookOutput { Continue = true };
                    }
                }
            }
        }
    }
};

会话生命周期挂钩

var options = new ClaudeAgentOptions
{
    Hooks = new Dictionary>
    {
        [HookEvent.SessionStart] = new[]
        {
            new HookMatcher
            {
                Hooks = new HookCallback[]
                {
                    async (input, toolUseId, context, ct) =>
                    {
                        if (input is SessionStartHookInput start)
                        {
                            Console.WriteLine($"Session started: {start.Source}");
                        }
                        return new SyncHookOutput { Continue = true };
                    }
                }
            }
        },
        [HookEvent.SessionEnd] = new[]
        {
            new HookMatcher
            {
                Hooks = new HookCallback[]
                {
                    async (input, toolUseId, context, ct) =>
                    {
                        if (input is SessionEndHookInput end)
                        {
                            Console.WriteLine($"Session ended: {end.Reason}");
                        }
                        return new SyncHookOutput { Continue = true };
                    }
                }
            }
        },
        [HookEvent.Notification] = new[]
        {
            new HookMatcher
            {
                Hooks = new HookCallback[]
                {
                    async (input, toolUseId, context, ct) =>
                    {
                        if (input is NotificationHookInput notification)
                        {
                            Console.WriteLine($"[{notification.NotificationType}] {notification.Message}");
                        }
                        return new SyncHookOutput { Continue = true };
                    }
                }
            }
        }
    }
};

挂钩输入类型

输入类型属性
PreToolUseHookInputToolName, ToolInput
PostToolUseHookInputToolName, ToolInput, ToolResponse
PostToolUseFailureHookInputToolName, ToolInput, Error, IsInterrupt
UserPromptSubmitHookInputPrompt
StopHookInputStopHookActive
SubagentStartHookInputAgentId, AgentType
SubagentStopHookInputStopHookActive, AgentId, AgentTranscriptPath
PreCompactHookInputTrigger, CustomInstructions
PermissionRequestHookInputToolName, ToolInput, PermissionSuggestions
SessionStartHookInputSource
SessionEndHookInputReason
NotificationHookInputMessage, NotificationType, Title

所有输入类型还包括公共字段: SessionId, TranscriptPath, Cwd, PermissionMode.

声明性钩子注册

使用属性以声明方式定义钩子,而不是手动构建字典:

using Claude.AgentSdk.Attributes;
using Claude.AgentSdk.Protocol;

[GenerateHookRegistration]  // Generates GetHooksCompiled() extension method
public class SecurityHooks
{
    [HookHandler(HookEvent.PreToolUse, Matcher = "Bash")]
    public Task ValidateBashCommand(HookInput input, string? toolUseId,
        HookContext ctx, CancellationToken ct)
    {
        if (input is PreToolUseHookInput pre)
        {
            var command = pre.ToolInput.GetProperty("command").GetString();
            if (command?.Contains("rm -rf") == true)
            {
                return Task.FromResult(new SyncHookOutput
                {
                    Continue = false,
                    Decision = "block",
                    StopReason = "Dangerous command blocked"
                });
            }
        }
        return Task.FromResult(new SyncHookOutput { Continue = true });
    }

    [HookHandler(HookEvent.PreToolUse, Matcher = "Write|Edit")]
    public Task ValidateFileWrites(HookInput input, string? toolUseId,
        HookContext ctx, CancellationToken ct)
    {
        if (input is PreToolUseHookInput pre)
        {
            var path = pre.ToolInput.GetProperty("file_path").GetString();
            if (path?.EndsWith(".env") == true)
            {
                return Task.FromResult(new SyncHookOutput
                {
                    Continue = false,
                    Decision = "block",
                    StopReason = "Cannot modify .env files"
                });
            }
        }
        return Task.FromResult(new SyncHookOutput { Continue = true });
    }

    [HookHandler(HookEvent.SessionStart)]
    public Task OnSessionStart(HookInput input, string? toolUseId,
        HookContext ctx, CancellationToken ct)
    {
        Console.WriteLine($"Session started: {ctx.SessionId}");
        return Task.FromResult(new SyncHookOutput { Continue = true });
    }
}

// Usage with generated extension method
var hooks = new SecurityHooks();
var options = new ClaudeAgentOptions
{
    Hooks = hooks.GetHooksCompiled(),  // No manual dictionary building!
    AllowedTools = ["Bash", "Write", "Edit", "Read"]
};

HookHandler属性属性:

属性类型描述
HookEventHookEvent必需。事件类型(构造函数参数)
Matcherstring?要匹配的正则表达式模式(例如,工具名称)
Timeoutdouble此挂钩超时(秒)

工具中的参数验证

[ToolParameter] 属性约束现在在运行时强制执行:

[GenerateToolRegistration]
public class ValidatedTools
{
    [ClaudeTool("search", "Search for items")]
    public string Search(
        [ToolParameter(Description = "Search query", MinLength = 1, MaxLength = 100)]
        string query,

        [ToolParameter(Description = "Results limit", MinValue = 1, MaxValue = 50)]
        int limit = 10,

        [ToolParameter(Description = "Filter pattern", Pattern = @"^[a-zA-Z0-9_-]+$")]
        string? filter = null)
    {
        // Implementation - validation happens before this code runs
        return $"Searching for: {query}";
    }
}

生成的验证:

  • 字符串长度检查(MinLength, MaxLength)
  • 数字范围检查(MinValue, MaxValue)
  • 通过正则表达式进行模式匹配(Pattern)
  • 数组长度检查集合参数

返回无效输入 ToolResult.Error() 在方法执行之前,使用描述性消息。

依赖注入(ASP.NET核心)

AJGit.Claude.AgentSdk.Extensions.DependencyInjection 该软件包提供了与Microsoft的集成。扩展。依赖注射。

安装

dotnet add package AJGit.Claude.AgentSdk.Extensions.DependencyInjection

基本注册

using Claude.AgentSdk.Extensions.DependencyInjection;

services.AddClaudeAgent(options =>
{
    options.Model = "sonnet";
    options.MaxTurns = 10;
    options.AllowedTools = ["Read", "Write", "Bash"];
});

通过应用程序配置

services.AddClaudeAgent(configuration.GetSection("Claude"));
{
  "Claude": {
    "Model": "sonnet",
    "MaxTurns": 10,
    "MaxBudgetUsd": 1.0,
    "AllowedTools": ["Read", "Write", "Bash"],
    "PermissionMode": "AcceptEdits"
  }
}

多代理场景的命名实例

// Register multiple agents with different configurations
services.AddClaudeAgent("analyzer", options =>
{
    options.Model = "sonnet";
    options.SystemPrompt = "You analyze code for issues.";
});

services.AddClaudeAgent("generator", options =>
{
    options.Model = "opus";
    options.SystemPrompt = "You generate high-quality code.";
});

// Resolve via factory
public class MyService
{
    private readonly IClaudeAgentClientFactory _factory;

    public MyService(IClaudeAgentClientFactory factory) => _factory = factory;

    public async Task AnalyzeAsync()
    {
        var analyzer = _factory.CreateClient("analyzer");
        // ...
    }
}

MCP工具服务器注册

services.AddClaudeAgent(options => options.Model = "sonnet")
    .AddMcpServer("tools", myToolServer)
    .AddMcpServer("custom");

健康检查

services.AddHealthChecks()
    .AddClaudeAgentCheck();

函数式编程

SDK包括函数类型,以实现更安全、更可组合的代码。

空安全选项\

using Claude.AgentSdk.Functional;

// Create options
Option some = Option.Some("hello");
Option none = Option.NoneOf();
Option fromNullable = Option.FromNullable(possiblyNull);

// Chain operations safely
var result = GetUserInput()
    .Map(s => s.Trim())
    .Where(s => !string.IsNullOrEmpty(s))
    .Bind(ParseCommand);

// Pattern match
result.Match(
    some: cmd => ProcessCommand(cmd),
    none: () => ShowHelp()
);

// Get value with defaults
var value = option.GetValueOrDefault("fallback");
var lazyValue = option.GetValueOrElse(() => ExpensiveComputation());

错误处理结果\

using Claude.AgentSdk.Functional;

// Create results
Result success = Result.Success(42);
Result failure = Result.Failure("Something went wrong");

// Wrap operations that can throw
var result = await Result.TryAsync(async () =>
{
    await using var client = new ClaudeAgentClient(options);
    await using var session = await client.CreateSessionAsync();
    return await ProcessAsync(session);
});

// Chain operations with automatic error propagation
var processed = result
    .Map(data => Transform(data))
    .Bind(data => Validate(data))
    .Ensure(data => data.IsValid, "Validation failed");

// Handle both cases
processed.Match(
    success: data => Console.WriteLine($"Success: {data}"),
    failure: error => Console.WriteLine($"Error: {error}")
);

用于可组合加工的管道\

using Claude.AgentSdk.Functional;

// Build a processing pipeline
var pipeline = Pipeline
    .StartWith(ProcessMessage);

// Or chain multiple steps
var pipeline = Pipeline
    .Start()
    .Then(ValidateInput)
    .ThenBind(ParseJson)
    .Then(TransformData)
    .ThenTap(LogSuccess);

// Run the pipeline
Result
 result = pipeline.Run(input);

累积误差的验证\

using Claude.AgentSdk.Functional;

// Validate multiple fields, accumulating all errors
var validation = Validation.Success(new User())
    .Ensure(u => !string.IsNullOrEmpty(u.Email), "Email is required")
    .Ensure(u => u.Email.Contains('@'), "Email must be valid")
    .Ensure(u => u.Age >= 18, "Must be 18 or older");

// Check all errors at once
if (validation.IsFailure)
{
    foreach (var error in validation.Errors)
        Console.WriteLine($"- {error}");
}

功能集合扩展

using Claude.AgentSdk.Functional;

// Choose: Filter and transform in one operation
var actions = blocks.Choose(block => block switch
{
    TextBlock text => Option.Some(() => Console.Write(text.Text)),
    ToolUseBlock tool => Option.Some(() => PrintTool(tool)),
    _ => Option.NoneOf()
});

// Sequence: Convert IEnumerable> to Option>
var allValues = options.Sequence();  // None if any is None

// Traverse: Map and sequence in one operation
var results = items.Traverse(item => TryParse(item));

v1行为契约

本节描述SDK在v1中的预期运行时行为。

一生

  • ClaudeAgentClient无状态它不拥有长期资源。
  • ClaudeAgentSession 拥有连接 发送到Claude CLI,完成后必须丢弃。

取消和处置

  • 处置a ClaudeAgentSession 取消会话的内部取消令牌,并启动底层传输的关闭。
  • 来自的任何活动消息枚举 ReceiveAsync() / ReceiveResponseAsync() 预期在会话结束时停止。

流和背压

  • 双向会话使用 有界内部缓冲器 用于消息。
  • 如果你这样做 枚举接收流,SDK可能会应用背压,消息处理可能会出现停滞。

对于交互式场景,始终运行接收循环(即使忽略消息)。

错误

  • 如果底层传输/协议失败,消息流通常会 故障 (投掷)期间 await foreach.
  • OperationCanceledException 当您取消/处理会话时,预计会出现。
  • 对于诊断, ClaudeAgentSession.TerminalException 可以在流结束后设置。

API 参考

ClaudeAgentClient

方法说明
QueryAsync(prompt, options?, ct)执行一次性查询,流式响应
QueryToCompletionAsync(prompt, options?, ct)执行并等待最终结果
CreateSessionAsync(ct)创建双向会话(返回 ClaudeAgentSession)

条款代理会议

方法说明
SendAsync(content, sessionId?)以双向模式发送消息
ReceiveAsync(ct)接收所有消息(连续)
ReceiveResponseAsync(ct)接收直到结果消息(典型)
InterruptAsync(ct)发送中断信号
CancelAsync(ct)取消会话
SetPermissionModeAsync(mode, ct)更改权限模式
SetModelAsync(model, ct)更改模型

ClaudeAgent选项

属性类型描述
Modelstring?模型使用(十四行诗、小品、俳句)
MaxTurnsint?最大对话次数
SystemPromptSystemPromptConfig?系统提示(字符串、预设或带附加的预设)
SettingSourcesIReadOnlyList?加载CLAUDE.md文件的源
ToolsIReadOnlyList?启用工具
AllowedToolsIReadOnlyList其他允许的工具
DisallowedToolsIReadOnlyList禁用工具
WorkingDirectorystring?代理工作目录
CliPathstring?Claude CLI的路径(默认:搜索Path)
CanUseToolFunc?权限回调
HooksIReadOnlyDictionary?吊钩配置
McpServersIReadOnlyDictionary?MCP服务器配置
OutputFormatJsonElement?结构化输出模式
PermissionModePermissionMode?权限模式
MaxThinkingTokensint?思考的最大代币
IncludePartialMessagesbool包括流式传输部分消息

SystemPromptConfig类型

类型描述
CustomSystemPrompt自定义字符串提示(完全替换默认值)
PresetSystemPrompt带有可选附加文本的预设配置

设置源值

描述
Project从项目目录加载CLAUDE.md
User加载~/.claude/claude.md(用户级)
Local从项目加载CLAUDE.local.md(gignored本地文件)

消息类型

类型描述
UserMessage用户输入消息
AssistantMessageClaude对内容块的回应
SystemMessage系统元数据消息
ResultMessage包含成本/使用信息的最终结果
StreamEvent部分流媒体更新

内容块

类型描述
TextBlock文本内容
ThinkingBlock延伸思维内容
ToolUseBlock工具调用请求
ToolResultBlock工具执行结果

建筑

┌─────────────────────────────────────────┐
│         ClaudeAgentClient               │
│  - QueryAsync() / CreateSessionAsync()  │
├─────────────────────────────────────────┤
│          ClaudeAgentSession             │
│  - SendAsync() / ReceiveAsync()         │
│  - Bidirectional communication          │
├─────────────────────────────────────────┤
│           QueryHandler                  │
│  - Control protocol routing             │
│  - Permission/hook handling             │
│  - MCP tool dispatch                    │
├─────────────────────────────────────────┤
│        SubprocessTransport              │
│  - CLI process management               │
│  - JSONL stdin/stdout I/O               │
├─────────────────────────────────────────┤
│         Claude Code CLI                 │
│  (external binary - handles API calls)  │
└─────────────────────────────────────────┘

例子

SDK包括几个演示不同功能和用例的示例项目。

快速入门示例

克劳德。代理商dk。例子 -带有13个SDK功能演示的交互式菜单:

cd examples/Claude.AgentSdk.Examples
dotnet run              # Shows interactive menu
dotnet run -- 1         # Run specific example by number

示例包括:

  1. 基本查询-简单的一次性查询
  2. 流式传输-在响应到达时进行流式传输
  3. 互动会话-双向对话
  4. 自定义工具-C中的MCP SDK工具#
  5. 挂钩-前置工具使用/后置工具使用挂钩
  6. 子代理-产卵专业子代理
  7. 结构化输出-JSON模式响应
  8. 权限处理程序-工具权限回调
  9. 系统提示-自定义和预设提示
  10. 设置源-加载CLAUDE.md文件
  11. MCP服务器-外部MCP服务器配置
  12. 沙盒-安全执行配置
  13. 功能模式-结果、选项、管道使用

独立示例

你好世界 -使用文件限制挂钩的基本查询:

cd examples/Claude.AgentSdk.HelloWorld
dotnet run                          # Default greeting
dotnet run -- "Your prompt here"    # Custom prompt

SimpleChatApp -多回合互动聊天:

cd examples/Claude.AgentSdk.SimpleChatApp
dotnet run    # Interactive REPL with /clear and /exit commands

功能聊天应用 -使用函数式编程模式的聊天应用程序:

cd examples/Claude.AgentSdk.FunctionalChatApp
dotnet run    # Demonstrates Result, Option, Pipeline, and immutable state

研究代理 -与研究人员和报告撰写子代理进行多代理协调:

cd examples/Claude.AgentSdk.ResearchAgent
dotnet run                    # Interactive mode
dotnet run -- --auto          # Auto-run with default prompt
dotnet run -- "Your topic"    # Research specific topic

简历生成器 -Web搜索和文档生成:

cd examples/Claude.AgentSdk.ResumeGenerator
dotnet run -- "Person Name"   # Generate resume for a person

错误 -用于电子邮件管理的自定义MCP工具(模拟收件箱):

cd examples/Claude.AgentSdk.EmailAgent
dotnet run    # Interactive email assistant

卓越 -用于创建Excel电子表格的自定义MCP工具:

cd examples/Claude.AgentSdk.ExcelAgent
dotnet run    # Interactive spreadsheet builder

信号 -ASP。NET Core web应用程序与实时Claude集成:

cd examples/Claude.AgentSdk.SignalR
dotnet run    # Starts server at http://localhost:5000

次级试剂测试 -用于测试子代理配置的诊断工具:

cd examples/Claude.AgentSdk.SubagentTest
dotnet run                    # Standard test
dotnet run -- --diagnostic    # Full diagnostic with hooks
dotnet run -- --cli-args      # Show CLI arguments

许可证

麻省理工学院

目录标签

目录标签

智能代理C#Claude自然语言处理本地部署C#SDK自动化工具多轮对话

支持客户端

Claude

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

api-key

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明api-key部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP