Claudia

Claudia

强类型非官方Anthropic Claude API .NET客户端

Claudia是一个非官方Anthropic Claude API的.NET客户端库,支持.NET Standard 2.1、.NET 6和.NET 8。该库提供类似官方SDK的强类型C# API,支持消息流处理、令牌计数和错误处理等核心功能。此外,Claudia还包含C#源生成器用于Function Calling,并支持文件上传、系统提示设置等高级特性。

ClaudiaAnthropic Claude APIC#SDKAIGithub开源项目

Claudia

非官方的 Anthropic Claude API .NET 客户端。

我们构建了一个类似于官方 Python SDKTypeScript SDK 的 C# API。它支持 netstandard2.1、net6.0 和 net8.0。

除了纯客户端 SDK 外,它还包含一个用于执行函数调用的 C# 源代码生成器。

安装

该库通过 NuGet 分发,支持 .NET Standard 2.1、.NET 6(.NET 7) 和 .NET 8 或更高版本。

PM> Install-Package Claudia

它还可以在 Unity 游戏引擎的运行时和编辑器中使用。有关使用说明,请参阅 Unity 部分

您还可以将其与 AWS Bedrock 一起使用。有关更多详细信息,请查看 AWS Bedrock 部分

使用方法

有关 API 的详细信息,请查看官方 API 参考

using Claudia; var anthropic = new Anthropic { ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") // 这是默认设置,可以省略 }; var message = await anthropic.Messages.CreateAsync(new() { Model = "claude-3-5-sonnet-20240620", // 您可以使用 Claudia.Models.Claude3_5Sonnet 字符串常量 MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); Console.WriteLine(message);

Claudia 的设计旨在与官方客户端具有相似的外观和感觉,特别是 TypeScript SDK。然而,它不使用 objectdynamicDictionary,所有内容都是强类型的。通过利用 C# 9.0 目标类型化 new 表达式C# 12 集合表达式,可以以简单的方式编写。

流式消息

我们提供使用服务器发送事件(SSE)的流式响应支持。

using Claudia; var anthropic = new Anthropic(); var stream = anthropic.Messages.CreateStreamAsync(new() { Model = "claude-3-opus-20240229", MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); await foreach (var messageStreamEvent in stream) { Console.WriteLine(messageStreamEvent); }

如果需要取消流,可以将 CancellationToken 传递给 CreateStreamAsync

流返回一个 IAsyncEnumerable<IMessageStreamEvent>,允许使用 await foreach 进行枚举。IMessageStreamEvent 的实现类型可以在 IMessageStreamEvent.cs 中找到。

例如,输出文本结果。

await foreach (var messageStreamEvent in stream) { if (messageStreamEvent is ContentBlockDelta content) { Console.WriteLine(content.Delta.Text); } }

请求和响应类型

该库包含所有请求参数和响应字段的 C# 定义。您可以像这样导入和使用它们:

using Claudia; var request = new MessageRequest() { Model = Models.Claude3Opus, MaxTokens = 1024, Messages = [new() { Role = Roles.User, Content = "你好,Claude" }] };

每个方法、请求参数和响应字段的文档都可以在文档字符串中找到,并且在大多数现代编辑器中悬停时会显示。

所有 MessageRequest 定义都在这里 MessageRequest.cs,MessageResponse 定义在这里 MessageResponse.cs

此外,还定义了常用常量。例如,Models.Claude3Opusclaude-3-opus-20240229,像 "user" 和 "assistant" 这样的角色使用 Roles.UserRoles.Assistant 等常量。请参阅 Constant.cs 了解所有常量。另外,Claude 官方聊天界面中使用的系统提示被定义为 SystemPrompts.Claude3

计算令牌

您可以通过使用响应属性查看给定请求的确切使用情况,例如:

var message = await anthropic.Messages.CreateAsync(...) // Usage { InputTokens = 11, OutputTokens = 18 } Console.WriteLine(message.Usage);

流式助手

通过与 R3(新的响应式扩展库)集成,可以以各种方式处理流式事件。

// 转换为数组 var array = await stream.ToObservable().ToArrayAsync(); // 过滤并执行 await stream.ToObservable() .OfType<IMessageStreamEvent, ContentBlockDelta>() .Where(x => x.Delta.Text != null) .ForEachAsync(x => { Console.WriteLine(x.Delta.Text); }); // 分支查询 var branch = stream.ToObservable().Publish(); var messageStartTask = branch.OfType<IMessageStreamEvent, MessageStart>().FirstAsync(); var messageDeltaTask = branch.OfType<IMessageStreamEvent, MessageDelta>().FirstAsync(); branch.Connect(); // 开始消费流 Console.WriteLine((await messageStartTask)); Console.WriteLine((await messageDeltaTask)); // 总计使用情况 var totalUsage = await stream.ToObservable() .Where(x => x is MessageStart or MessageDelta) .Select(x => x switch { MessageStart ms => ms.Message.Usage, MessageDelta delta => delta.Usage, _ => throw new ArgumentException() }) .AggregateAsync((x, y) => new Usage { InputTokens = x.InputTokens + y.InputTokens, OutputTokens = x.OutputTokens + y.OutputTokens }); Console.WriteLine(totalUsage);

错误处理

当库无法连接到 API,或 API 返回非成功状态码(即 4xx 或 5xx 响应)时,将抛出 ClaudiaException 的子类:

try { var msg = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Opus, MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); } catch (ClaudiaException ex) { Console.WriteLine((int)ex.Status); // 400(ErrorCode.InvalidRequestError) Console.WriteLine(ex.Name); // invalid_request_error Console.WriteLine(ex.Message); // Field required. Input:... }

错误代码如下:

public enum ErrorCode { /// <summary>请求的格式或内容有问题。</summary> InvalidRequestError = 400, /// <summary>API 密钥有问题。</summary> AuthenticationError = 401, /// <summary>您的 API 密钥没有权限使用指定的资源。</summary> PermissionError = 403, /// <summary>未找到请求的资源。</summary> NotFoundError = 404, /// <summary>您的账户已达到速率限制。</summary> RateLimitError = 429, /// <summary>Anthropic 系统内部发生了意外错误。</summary> ApiError = 500, /// <summary>Anthropic 的 API 暂时过载。</summary> OverloadedError = 529 }

重试

默认情况下,某些错误将自动重试 2 次,并使用短指数退避。连接错误(例如,由于网络连接问题)、408 请求超时、409 冲突、429 速率限制和 >=500 内部错误默认都会重试。

您可以使用 MaxRetries 选项来配置或禁用此功能:

// 为所有请求配置默认值: var anthropic = new Anthropic { MaxRetries = 0, // 默认为 2 }; // 或者,按请求配置: await anthropic.Messages.CreateAsync(new() { MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }], Model = "claude-3-opus-20240229" }, new() { MaxRetries = 5 });

超时

默认情况下,请求在 10 分钟后超时。您可以使用 Timeout 选项配置此设置:

// 为所有请求配置默认值: var anthropic = new Anthropic { Timeout = TimeSpan.FromSeconds(20) // 20 秒(默认为 10 分钟) };

// 覆盖每个请求: await anthropic.Messages.CreateAsync(new() { MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }], Model = "claude-3-opus-20240229" }, new() { Timeout = TimeSpan.FromSeconds(5) });


超时时会抛出 `TimeoutException`。

注意,超时的请求默认会[重试两次](#retries)。

默认标头
---
我们会自动发送 `anthropic-version` 标头,值设为 `2023-06-01`。

如果需要,你可以在每个请求的基础上覆盖它。

请注意,这样做可能会导致SDK中的类型不正确和其他意外或未定义的行为。

```csharp
await anthropic.Messages.CreateAsync(new()
{
    MaxTokens = 1024,
    Messages = [new() { Role = "user", Content = "你好,Claude" }],
    Model = "claude-3-opus-20240229"
}, new()
{
    Headers = new() { { "anthropic-version", "我的自定义值" } }
});

自定义HttpClient

Anthropic客户端默认使用标准的HttpClient进行通信。如果你想自定义HttpClient的行为,可以传入一个HttpMessageHandler。此外,如果你不想在处理Anthropic客户端时处理HttpClient,可以将disposeHandler标志设置为false。

public class Anthropic : IDisposable { public HttpClient HttpClient => httpClient; public Anthropic() : this(new HttpClientHandler(), true) { } public Anthropic(HttpMessageHandler handler) : this(handler, true) { } public Anthropic(HttpMessageHandler handler, bool disposeHandler) { this.httpClient = new HttpClient(handler, disposeHandler); this.httpClient.Timeout = System.Threading.Timeout.InfiniteTimeSpan; // 忽略超时,Anthropic客户端使用Timeout属性(或每个请求的覆盖)中的超时设置 } public void Dispose() { httpClient.Dispose(); } }

此外,你可以通过HttpClient属性检索用于请求的HttpClient。这允许你修改诸如DefaultRequestHeaders之类的设置。

// 禁用keep-alive anthropic.HttpClient.DefaultRequestHeaders.ConnectionClose = true;

你可以更改HttpClient.BaseAddress来更改API地址(例如,用于代理)。

// 请求发送到http://myproxy/messages而不是https://api.anthropic.com/v1/messages anthropic.HttpClient.BaseAddress = new Uri("http://myproxy/");

访问原始响应数据(例如,标头)

通过按照HttpClient约定定义DelegatingHandler,可以在请求之前和之后钩入请求管道。这允许进行日志记录、添加遥测和检查响应标头信息。观察标头时,你可以看到包含了与RateLimit相关的额外信息。

image

让我们创建一个DelegatingHandler,它检索此信息,并在发生RateLimit时抛出一个带有RateLimit信息的特殊异常。

public class RateLimitDetailsHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var response = await base.SendAsync(request, cancellationToken); if ((int)response.StatusCode == (int)ErrorCode.RateLimitError) { var requestLimit = int.Parse(response.Headers.GetValues("anthropic-ratelimit-requests-limit").First()); var requestRemaining = int.Parse(response.Headers.GetValues("anthropic-ratelimit-requests-remaining").First()); var requestReset = DateTime.Parse(response.Headers.GetValues("anthropic-ratelimit-requests-reset").First()); var tokenLimit = int.Parse(response.Headers.GetValues("anthropic-ratelimit-tokens-limit").First()); var tokenRemaining = int.Parse(response.Headers.GetValues("anthropic-ratelimit-tokens-remaining").First()); var tokenReset = DateTime.Parse(response.Headers.GetValues("anthropic-ratelimit-tokens-reset").First()); var error = await response.Content.ReadFromJsonAsync<ErrorResponseShape>(AnthropicJsonSerializerContext.Default.Options, cancellationToken); var message = error!.ErrorResponse.Message; throw new AnthropicRateLimitException(requestLimit, requestRemaining, requestReset, tokenLimit, tokenRemaining, tokenReset, message); } return response; } } public class AnthropicRateLimitException : Exception { public int RateLimitRequestsLimit { get; } public int RateLimitRequestsRemaining { get; } public DateTime RateLimitRequestsReset { get; } public int RateLimitTokensLimit { get; } public int RateLimitTokensRemaining { get; } public DateTime RateLimitTokensReset { get; } public AnthropicRateLimitException( int rateLimitRequestsLimit, int rateLimitRequestsRemaining, DateTime rateLimitRequestsReset, int rateLimitTokensLimit, int rateLimitTokensRemaining, DateTime rateLimitTokensReset, string message) : base(message) { RateLimitRequestsLimit = rateLimitRequestsLimit; RateLimitRequestsRemaining = rateLimitRequestsRemaining; RateLimitRequestsReset = rateLimitRequestsReset; RateLimitTokensLimit = rateLimitTokensLimit; RateLimitTokensRemaining = rateLimitTokensRemaining; RateLimitTokensReset = rateLimitTokensReset; } }

DelegatingHandler(HttpMessageHandler)可以传递给Anthropic的构造函数。

var anthropic = new Anthropic(new RateLimitDetailsHandler() { InnerHandler = new HttpClientHandler() });

上传文件

Message.Content接受多个Content对象。但是,如果传递单个字符串,它会自动转换为文本数组。

// 这段代码 Content = "你好,Claude" // 会转换为以下内容 Content = [new Content { Type = "text", Text = "你好,Claude" }]

传递图像时,在Content中同时设置图像和文本。

var imageBytes = File.ReadAllBytes(@"dish.jpg"); var anthropic = new Anthropic(); var message = await anthropic.Messages.CreateAsync(new() { Model = "claude-3-opus-20240229", MaxTokens = 1024, Messages = [new() { Role = "user", Content = [ new() { Type = "image", Source = new() { Type = "base64", MediaType = "image/jpeg", Data = imageBytes } }, new() { Type = "text", Text = "描述这张图片。" } ] }], }); Console.WriteLine(message);

上面的代码可以简化。如果将字符串传递给Content构造函数,它会被设置为文本,如果传递ReadOnlyMemory<byte>,它会被设置为图像。

var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Opus, MaxTokens = 1024, Messages = [new() { Role = Roles.User, Content = [ new(imageBytes, "image/jpeg"), "描述这张图片。" ] }], }); Console.WriteLine(message);

目前,有四种可上传的二进制类型:image/jpegimage/pngimage/gifimage/webp。例如,如果你想上传markdown文件,最好读取其内容并作为文本发送。如果你想上传PDF,你可以将其转换为文本或图像后再发送。像pptx这样的演示文件也可以作为图像发送,Claude会为你解释内容并提取文本。

系统提示和温度

MessageRequest的其他可选属性包括SystemMetadataStopSequencesTemperatureTopPTopK

var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = SystemPrompts.Claude3, Temperature = 0.4, Messages = [ new() { Role = Roles.User, Content = "你好,Claude" }, ], });

SystemPrompts.Claude3是官方聊天UI中使用的系统提示的字符串常量。当然,你也可以设置任意的系统提示。

保存 / 加载

所有请求和响应模型都可以使用System.Text.Json.JsonSerializer进行序列化。此外,AnthropicJsonSerializerContext通过Source Generator提供了预生成的序列化器,可以实现更高的性能。

List<Message> chatMessages; void Save() { var json = JsonSerializer.Serialize(chatMessages, AnthropicJsonSerializerContext.Default.Options); File.WriteAllText("chat.json", json); } void Load() { chatMessages = JsonSerializer.Deserialize<List<Message>>("chat.json", AnthropicJsonSerializerContext.Default.Options)!; }

函数调用

Claude支持函数调用。

工具使用

工具使用(函数调用)是函数调用的新形式。目前它处于测试阶段,需要在标头中添加anthropic-beta标志。

var anthropic = new Anthropic(); anthropic.HttpClient.DefaultRequestHeaders.Add("anthropic-beta", "tools-2024-04-04");

使用Claudia,你只需定义带有[ClaudiaFunction]注解的静态方法,C# Source Generator就会自动生成必要的代码。

public static partial class FunctionTools { /// <summary> /// 获取指定时区的当前时间,格式为时-分-秒。时区应以标准格式书写,如UTC、US/Pacific、Europe/London。 /// </summary> /// <param name="timeZone">要获取当前时间的时区,如UTC、US/Pacific、Europe/London。</param> [ClaudiaFunction] public static string TimeOfDay(string timeZone) { var time = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, timeZone); return time.ToString("HH:mm:ss"); } }

partial class包含生成的.AllTools.Tools.[Methods].InvokeToolAsync(MessageResponse)

函数调用需要向Claude发送两次请求。流程如下:"在系统提示中包含可用工具的初始请求 -> 根据包含必要工具的消息执行函数 -> 将结果包含在新消息中并向Claude发送另一个请求。"

var anthropic = new Anthropic(); anthropic.HttpClient.DefaultRequestHeaders.Add("anthropic-beta", "tools-2024-04-04"); var input = new Message { Role = Roles.User, Content = "洛杉矶现在几点了?" }; var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, Tools = FunctionTools.AllTools, // 使用生成的Tools Messages = [input], }); // 调用本地函数 var toolResult = await FunctionTools.InvokeToolAsync(message); var response = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, Tools = FunctionTools.AllTools, Messages = [ input, new() { Role = Roles.Assistant, Content = message.Content }, new() { Role = Roles.User, Content = toolResult! } ], }); // 洛杉矶现在的时间是上午10:45。 Console.WriteLine(response.Content.ToString());

ClaudiaFunction的返回类型也可以指定为Task<T>ValueTask<T>。这允许您执行各种任务,如HTTP请求或数据库请求。例如,可以如上所示定义一个获取指定网页内容的函数。

public static partial class FunctionTools { // ... /// <summary> /// 从指定URL获取HTML内容。 /// </summary> /// <param name="url">要获取HTML的URL。</param> [ClaudiaFunction] static async Task<string> GetHtmlFromWeb(string url) { // 在实际应用中,传递原始HTML可能会消耗太多令牌。 // 您可以使用像AngleSharp这样的库在本地解析HTML,并将其转换为紧凑的文本结构以节省令牌。 using var client = new HttpClient(); return await client.GetStringAsync(url); } }

请注意,允许的参数类型是boolsbytebyteshortushortintuintlongulongdecimalfloatdoublestringDateTimeDateTimeOffsetGuidTimeSpanEnum

返回值可以是任何类型,但它将使用ToString()转换为字符串。如果您想返回自定义字符串,请将返回类型设为string,并在函数内部格式化字符串。

旧版风格

Anthropic Cookbook提供了函数调用的示例。要实现这一点,需要复杂的XML生成和解析处理,以及基于解析结果的执行。

使用Claudia,您只需定义带有[ClaudiaFunction]注解的静态方法,C#源代码生成器就会自动生成必要的代码,包括解析器和系统消息。

public static partial class FunctionTools { /// <summary> /// 获取指定时区的当前时间,格式为时-分-秒。时区应以标准格式书写,如UTC、US/Pacific、Europe/London。 /// </summary> /// <param name="timeZone">要获取当前时间的时区,如UTC、US/Pacific、Europe/London。</param> [ClaudiaFunction] public static string TimeOfDay(string timeZone) { var time = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, timeZone); return time.ToString("HH:mm:ss"); } }

partial class包含生成的.SystemPrompt.InvokeAsync(MessageResponse)

函数调用需要向Claude发送两次请求。流程如下:"在系统提示中包含可用工具的初始请求 -> 根据包含必要工具的消息执行函数 -> 将结果包含在新消息中并向Claude发送另一个请求。"

// `FunctionTools.SystemPrompt`包含用于通知Claude可用工具的XML。 // 这个XML是从方法的XML文档注释生成的。 /* 在这个环境中,您可以使用一组工具来回答用户的问题。 ... 您可以这样调用它们: ... 以下是可用的工具: <tools> <tool_description> <tool_name>TimeOfDay</tool_name> <description>获取指定时区的当前时间,格式为时-分-秒。时区应以标准格式书写,如UTC、US/Pacific、Europe/London。</description> <parameters> <parameter> <name>timeZone</name> <type>string</type> <description>要获取当前时间的时区,如UTC、US/Pacific、Europe/London。</description> </parameter> </parameters> </tool_description> </tools> */ // Console.WriteLine(FunctionTools.SystemPrompt); var input = new Message { Role = Roles.User, Content = "洛杉矶现在几点了?" }; var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, // 设置生成的提示 StopSequences = [StopSequnces.CloseFunctionCalls], // 将</function_calls>设置为停止序列 Messages = [input], }); // Claude返回xml以调用工具 /* <function_calls> <invoke> <tool_name>TimeOfDay</tool_name> <parameters> <timeZone>US/Pacific</timeZone> </parameters> </invoke> */ // Console.WriteLine(message); // 自动生成的`FunctionTools.InvokeAsync`从`MessageResponse`中解析函数名和参数, // 执行相应的函数,并生成XML以通知Claude函数执行结果。 var partialAssistantMessage = await FunctionTools.InvokeAsync(message); // 通过将此消息作为Assistant响应的开头传递给Claude, // 它将提供一个考虑了函数执行结果的续写。 /* <function_calls> <invoke> <tool_name>TimeOfDay</tool_name> <parameters> <timeZone>US/Pacific</timeZone> </parameters> </invoke> </function_calls> <function_results> <result> <tool_name>TimeOfDay</tool_name> <stdout>03:27:03</stdout> </result> </function_results> */ // Console.WriteLine(partialAssistantMessage); var callResult = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, Messages = [ input, // 用户:"洛杉矶现在几点了?" new() { Role = Roles.Assistant, Content = partialAssistantMessage! } // 设置为Assistant ], }); // 洛杉矶(US/Pacific时区)的当前时间是03:36:04。 Console.WriteLine(callResult);

对于初始请求,指定StopSequences.CloseFunctionCalls是高效的。此外,如果您想包含自己的系统提示,最好将其与生成的SystemPrompt连接起来。

ClaudiaFunction的返回类型也可以指定为Task<T>ValueTask<T>。这允许您执行各种任务,如HTTP请求或数据库请求。例如,可以如上所示定义一个获取指定网页内容的函数。

public static partial class FunctionTools { // ... /// <summary> /// 从指定URL获取HTML内容。 /// </summary> /// <param name="url">要获取HTML的URL。</param> [ClaudiaFunction] static async Task<string> GetHtmlFromWeb(string url) { // 在实际应用中,传递原始HTML可能会消耗太多令牌。 // 您可以使用像AngleSharp这样的库在本地解析HTML,并将其转换为紧凑的文本结构以节省令牌。 using var client = new HttpClient(); return await client.GetStringAsync(url); } }
var input = new Message { Role = Roles.User, Content = """ 能用三行话总结这个页面吗? https://docs.anthropic.com/claude/docs/intro-to-claude """ }; var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, // 设置生成的提示 StopSequences = [StopSequnces.CloseFunctionCalls], // 将</function_calls>设置为停止序列 Messages = [input], }); var partialAssistantMessage = await FunctionTools.InvokeAsync(message);

var callResult = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, Messages = [ input, new() { Role = Roles.Assistant, Content = partialAssistantMessage! } // 设置为助手 ], });

// 该页面可以用三行概括: // 1. Claude是由Anthropic开发的一系列大型语言模型,旨在彻底改变您与AI交互的方式。 // 2. 本文档旨在帮助您充分利用Claude,提供清晰的解释、示例、最佳实践和额外资源的链接。 // 3. Claude在涉及语言、推理、分析、编码等广泛任务中表现出色,文档涵盖了关键功能、提示入门和API使用。 Console.WriteLine(callResult);


可以定义多个函数,它们可以在一个请求中多次执行。

```csharp
public static partial class FunctionTools
{
    [ClaudiaFunction]
    public static string TimeOfDay(string timeZone) //...

    // 示例来自 https://github.com/anthropics/anthropic-cookbook/blob/main/function_calling/function_calling.ipynb

    /// <summary>
    /// 用于进行基本算术的计算器函数。
    /// 支持加法、减法、乘法
    /// </summary>
    /// <param name="firstOperand">第一个操作数(运算符之前)</param>
    /// <param name="secondOperand">第二个操作数(运算符之后)</param>
    /// <param name="operator">要执行的操作。必须是 +, -, *, 或 / 之一</param>
    [ClaudiaFunction]
    static double DoPairwiseArithmetic(double firstOperand, double secondOperand, string @operator)
    {
        return @operator switch
        {
            "+" => firstOperand + secondOperand,
            "-" => firstOperand - secondOperand,
            "*" => firstOperand * secondOperand,
            "/" => firstOperand / secondOperand,
            _ => throw new ArgumentException("不支持的操作")
        };
    }
}
var input = new Message { Role = Roles.User, Content = """ 西雅图和东京现在几点了? 顺便把1,984,135乘以9,343,116""" }; var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, // 设置生成的提示 StopSequences = [StopSequnces.CloseFunctionCalls], // 设置</function_calls>作为停止序列 Messages = [input], }); var partialAssistantMessage = await FunctionTools.InvokeAsync(message); var callResult = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, Messages = [ input, new() { Role = Roles.Assistant, Content = partialAssistantMessage! } // 设置为助手 ], }); // 西雅图(美国太平洋时区)的时间是8:06:53。 // 东京(亚洲/东京时区)的时间是00:06:53。 // 1,984,135乘以9,343,116的结果是18,524,738,326,760。 Console.WriteLine(callResult);

注意,允许的参数类型为boolsbytebyteshortushortintuintlongulongdecimalfloatdoublestringDateTimeDateTimeOffsetGuidTimeSpanEnum

返回值可以是任何类型,但会使用ToString()转换为字符串。如果你想返回自定义字符串,请将返回类型设为string并在函数内格式化字符串。

Blazor示例

通过在Blazor中使用Claudia,你可以轻松创建如下所示的聊天界面。

blazorclauderec

所有代码可以在BlazorApp1中找到。

关键部分是Program.csHome.razor.cs中的设置。

// Program.cs // 从用户机密获取ANTHROPIC_API_KEY // https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets Environment.SetEnvironmentVariable("ANTHROPIC_API_KEY", builder.Configuration["ANTHROPIC_API_KEY"]); // 添加Anthropic客户端 builder.Services.AddSingleton<Anthropic>(); var app = builder.Build();
// Home.razor.cs using Claudia; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; namespace BlazorApp1.Components.Pages; public partial class Home { [Inject] public required Anthropic Anthropic { get; init; } double temperature = 1.0; string textInput = ""; string systemInput = SystemPrompts.Claude3; List<Message> chatMessages = new(); bool running = false; async Task SendClick() { if (running) return; if (string.IsNullOrWhiteSpace(textInput)) return; running = true; try { chatMessages.Add(new() { Role = Roles.User, Content = textInput }); var stream = Anthropic.Messages.CreateStreamAsync(new() { Model = Models.Claude3Opus, MaxTokens = 1024, Temperature = temperature, System = string.IsNullOrWhiteSpace(systemInput) ? null : systemInput, Messages = chatMessages.ToArray() }); var currentMessage = new Message { Role = Roles.Assistant, Content = "" }; chatMessages.Add(currentMessage); textInput = ""; // 清空输入 StateHasChanged(); await foreach (var messageStreamEvent in stream) { if (messageStreamEvent is ContentBlockDelta content) { currentMessage.Content[0].Text += content.Delta.Text; StateHasChanged(); } } } finally { running = false; } } }

如果需要存储聊天消息历史,可以将List<Message> chatMessages序列化为JSON并保存到文件或数据库中。

AWS Bedrock

我们通过一个单独的包提供对Anthropic Bedrock API的支持。

PM> Install-Package Claudia.Bedrock

要从AWS SDK创建AmazonBedrockRuntimeClient并使用UseAnthropic指定Bedrock模型ID,请将RequestMessage的Model属性设置为anthropic_version。其余部分与常规Anthropic客户端相同。

// credentials是你自己的 AWSConfigs.AWSProfileName = ""; var bedrock = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1); var anthropic = bedrock.UseAnthropic("anthropic.claude-3-haiku-20240307-v1:0"); // 模型ID var response = await anthropic.Messages.CreateAsync(new() { Model = "bedrock-2023-05-31", // anthropic_version MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); Console.WriteLine(response);

流式消息的工作方式相同。

var stream = anthropic.Messages.CreateStreamAsync(new() { Model = "bedrock-2023-05-31", // anthropic_version MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); await foreach (var item in stream) { Console.WriteLine(item); }

如果需要原始响应,请改为调用InvokeModelAsyncInvokeModelWithResponseStreamAsync。这允许你在使用GetMessageResponseGetMessageResponseAsync检索结果之前检查状态码和标头。

var bedrock = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1); // (string modelId, MessageRequest request) var response = await bedrock.InvokeModelAsync("anthropic.claude-3-haiku-20240307-v1:0", new() { Model = "bedrock-2023-05-31", // anthropic_version MaxTokens = 1024, Messages = [new() { Role = "user", Content = "你好,Claude" }] }); Console.WriteLine(response.ResponseMetadata.RequestId); var responseMessage = response.GetMessageResponse(); Console.WriteLine(responseMessage);

Unity

最低支持的Unity版本是2022.3.12f1。你需要从NuGet安装。我们建议使用NuGetForUnity

  1. 安装NuGetForUnity
  2. 从Window -> Manage NuGet Packages打开,搜索"Claudia"并点击安装。

这样,你就可以在编辑器和运行时使用Anthropic客户端了。

using Claudia; using System; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { async void Start() { var anthropic = new Anthropic() { ApiKey = "你的API密钥" }; Debug.Log("在Unity中开始简单调用"); var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Opus, MaxTokens = 1024, Messages = new Message[] { new() { Role = "user", Content = "你好,Claude" } } }); Debug.Log("用户:你好,Claude"); Debug.Log("助手:" + message); } }

image

函数调用的源代码生成器也受支持,但需要额外的工作。

  1. 为Unity设置C#编译器。

    • 在Assets/目录下添加一个名为csc.rsp的文本文件,内容如下:
      • -langVersion:10 -nullable
        
  2. 为您的IDE设置C#编译器。

    • 安装CsprojModifier
    • 添加一个名为LangVersion.props的文本文件,内容如下:
      • <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <LangVersion>10</LangVersion> <Nullable>enable</Nullable> </PropertyGroup> </Project>
    • 打开项目设置,在[编辑器]下找到[C# Project Modifier]部分。
    • 将刚刚创建的.props文件添加到[附加项目导入]列表中。
    • 注意:
      • 如果您使用的是程序集定义,请将您的附加csproj添加到[要添加导入的项目]列表中。

如果遇到"不支持在此版本的编译器中使用具有必需成员的类型的构造函数"错误,应将LangVersion更改为11

using Claudia; using System; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { async void Start() { var anthropic = new Anthropic() { ApiKey = "你的API密钥" }; Debug.Log("在Unity中开始函数调用演示"); var input = new Message { Role = Roles.User, Content = "将1,984,135乘以9,343,116" }; var message = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, StopSequences = new[] { StopSequnces.CloseFunctionCalls }, Messages = new[] { input }, }); var partialAssistantMessage = await FunctionTools.InvokeAsync(message); var callResult = await anthropic.Messages.CreateAsync(new() { Model = Models.Claude3Haiku, MaxTokens = 1024, System = FunctionTools.SystemPrompt, Messages = new[]{ input, new() { Role = Roles.Assistant, Content = partialAssistantMessage! } }, }); Debug.Log("用户:将1,984,135乘以9,343,116"); Debug.Log("助手:" + callResult.ToString().Trim()); } } public static partial class FunctionTools { /// <summary> /// 用于进行基本算术的计算器函数。 /// 支持加法、减法、乘法 /// </summary> /// <param name="firstOperand">第一个操作数(运算符之前)</param> /// <param name="secondOperand">第二个操作数(运算符之后)</param> /// <param name="operator">要执行的操作。必须是+、-、*或/之一</param> [ClaudiaFunction] static double DoPairwiseArithmetic(double firstOperand, double secondOperand, string @operator) { return @operator switch { "+" => firstOperand + secondOperand, "-" => firstOperand - secondOperand, "*" => firstOperand * secondOperand, "/" => firstOperand / secondOperand, _ => throw new ArgumentException("不支持的操作") }; } }

WebGL

在使用HttpClient进行通信失败的环境中,如WebGL,您需要通过使用这个UnityWebRequestHttpMessageHandler.cs来替换传输层。

// 将处理程序替换为UnityWebRequestHttpMessageHandler var anthropic = new Anthropic(new UnityWebRequestHttpMessageHandler()) { ApiKey = "你的API密钥", ConfigureAwait = true // 在使用UnityWebRequest的Unity环境中,建议设为true };

然而,要在浏览器环境中进行API调用,您需要设置代理或采取其他措施来支持CORS。

许可证

该库使用MIT许可证。

编辑推荐精选

Keevx

Keevx

AI数字人视频创作平台

Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。

即梦AI

即梦AI

一站式AI创作平台

提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作

扣子-AI办公

扣子-AI办公

AI办公助手,复杂任务高效处理

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

下拉加载更多