SwiftClaude 是一个用于 Anthropic Claude API 的 Swift 客户端。
CLAUDE 和 ANTHROPIC 是 Anthropic, PBC 的商标。本项目与 Anthropic 无关联,亦未获得其赞助。
此软件包非常新,且未经充分测试。SwiftClaude 处于 1.0 版本之前,这意味着 API 可能会根据社区的反馈而更改。
以下是 SwiftClaude 的快速入门介绍。更多详情,请查看 .xcode/SwiftClaudeAppPackage
中定义的示例项目,特别是 HaikuGenerator
。
以下示例假设您已创建了一个值 let claude: Claude
。有关如何创建 Claude
,请参阅 身份验证。
SwiftClaude 的核心抽象是 Conversation
,这是一个您需要在项目中实现的协议
import SwiftClaude
struct Conversation: Claude.Conversation {
var messages: [Message]
}
var conversation = Conversation(
messages: [
.user("Write me a haiku about a really well-made tool.")
]
)
一旦您拥有了对话,您可以要求 Claude 提供下一条消息
let message = claude.nextMessage(in: conversation)
消息有一个简单的异步 API,您可以等待完整文本或分块处理它
/// Print the full text
print(try await message.text())
/// Print the text as segments come in
for try await segment in message.textSegments {
print(segment, terminator: "")
fflush(stdout)
}
print()
消息也是 Observable
的,这意味着您可以直接在 SwiftUI 中使用它们
Text(message.currentText)
对于大多数属性,SwiftClaude 提供了异步版本和 Observable
版本。Observable
版本通常以 current
为前缀。
如果您想实现对话的多个轮次,只需将新消息添加到对话中,然后添加响应并请求一条新消息。
conversation.messages += [
.assistant(message),
.user("That was great! Can you write me one more, this time about track saws?")
]
let nextMessage = claude.nextMessage(in: conversation)
SwiftClaude 对通过 @Tool
宏实现的工具使用提供了出色的支持。
定义工具就像创建一个带有 invoke
方法并附加 @Tool
宏的类型一样简单。以下是 HaikuGenerator
中的一个示例
@Tool
struct EmojiTool {
/// Displays an emoji
/// Great for spicing up a haiku!
func invoke(
_ emoji: String
) -> String {
emoji
}
}
invoke
函数上的注释在这里尤为重要,SwiftClaude 实际上会将其发送给 Claude,以帮助 Claude 理解如何最好地调用您定义的函数。有关如何最好地记录您的工具的信息,请查阅 Anthropic 的文档。
如果您希望工具的输入更复杂,您可以使用 @ToolInput
宏来定义自定义结构体或枚举。例如,这里有一个 Command
工具,它可以使 Claude 能够向前、向后导航或导航到指定的 URL
@ToolInput
enum Command {
case goBack
case goForward
case navigate(to: String)
}
您可以通过简单地将其作为参数添加到 invoke
函数中,在工具中使用它
@Tool
struct Browser {
/// Controls a browser
func invoke(
_ command: Command
) -> String {
/// Execute `command`
}
}
要在对话中使用它,您需要指定您想要用于 ToolOutput
的类型
private struct Conversation: Claude.Conversation {
var messages: [Message] = []
typealias ToolOutput = String
}
String
是用于工具输出的最简单类型,但如果您想利用更复杂的功能(如 视觉),您也可以使用 ToolInvocationResultContent
,甚至自定义类型。有关工作示例,请查阅 .xcode/SwiftClaudeAppPackage
中的 ComputerUseDemo
。
您还需要向 Claude 提供它可以访问的工具列表
let message = claude.nextMessage(
in: conversation,
tools: Tools {
CatEmojiTool()
EmojiTool()
}
)
当 Claude 请求工具调用时,这些工具默认情况下不会被调用,并且需要显式地在特定工具上调用 requestInvocation
,或在消息上调用 requestToolInvocations
。我们建议在调用工具之前提示用户,以确保 Claude 的请求与用户的意图一致。对于仅提供上下文或显示 UI 的简单工具,您可以指定一个 ToolInvocationStrategy
,使此过程更简单。例如,whenToolInputAvailable
将在成功解码输入时自动调用工具
let message = claude.nextMessage(
in: conversation,
tools: Tools {
CatEmojiTool()
EmojiTool()
},
invokeTools: .whenInputAvailable
)
使用工具的对话需要处理一些额外的用例,因为它们可能包含的不仅仅是文本。您现在需要处理内容块,而不是仅仅处理文本或文本段落。文本内容块具有与纯文本消息类似的 API,工具使用块可以通过多种方式处理。异步 API 看起来像这样
for try await block in message.contentBlocks {
switch block {
case .textBlock(let textBlock):
for try await textFragment in textBlock.textFragments {
print(textFragment, terminator: "")
fflush(stdout)
}
case .toolUseBlock(let toolUseBlock):
print("[Using \(toolUseBlock.toolName): \(try await toolUseBlock.output())]")
}
}
print()
与纯文本消息一样,带有工具调用的消息也是 Observable
的,并且可以在构建于 Observation
之上的框架(如 SwiftUI
)中使用(通过以 current
为前缀的属性)。这是一个 SwiftUI 示例
ForEach(assistant.currentContentBlocks) { block in
switch block {
case .textBlock(let textBlock):
Text(textBlock.currentText)
case .toolUseBlock(let toolUseBlock):
if let output = toolUseBlock.toolUse.currentOutput {
Text("[Using \(toolUseBlock.toolUse.toolName): \(output)]")
} else {
Text("[Using \(toolUseBlock.toolUse.toolName)]")
}
}
}
注意:消息和内容块也都符合 Identifiable
协议,以便更轻松地与 SwiftUI
一起使用。
工具结果需要发送回 Claude 才能继续对话。最简单的方法是像这样检查 conversation.nextStep()
repeat {
let message = claude.nextMessage(
in: conversation,
tools: Tools { … }
)
conversation.append(message)
} while try await conversation.nextStep() == .toolUseResult
SwiftClaude 支持视觉。在 Apple 平台上,您可以直接在用户消息中包含 UIImage
和 NSImage
conversation.messages.append(
.user("Describe this image: \(image)")
)
默认情况下,SwiftClaude 会按照 Anthropic 的建议 调整图像大小。您可以通过指定 imagePreprocessingMode: .disabled
来禁用此行为。
SwiftClaude 支持提示缓存。您可以将 Claude.Beta.CacheBreakpoint
添加到大多数结果构建器 API。您还可以将 cacheBreakpoint: Claude.Beta.CacheBreakpoint()
参数添加到字符串插值或 append
API。
通过 SwiftClaude 使用 Claude API 进行身份验证需要使用 Claude.Authenticator
。在 Apple 平台上,我们鼓励您使用 KeychainAuthenticator
,它将 API 密钥安全地存储在钥匙串中。
let authenticator = Claude.KeychainAuthenticator(
namespace: "com.codebygeorge.SwiftClaude.HaikuGenerator",
identifier: "api-key"
)
/// Call `authenticator.save(…)` with your API key
一旦您拥有了身份验证器,您就可以创建一个 Claude
let claude = Claude(authenticator: authenticator)
SwiftClaude 需要 Swift 6 和 macOS 15 或 iOS 18。
SwiftClaude
是使用 Swift Package Manager 构建的。要包含它,请在您的 Package.swift
中添加以下内容
let package = Package(
…
dependencies: [
.package(url: "git@github.com:GeorgeLyon/SwiftClaude", branch: "main")
],
…
)
然后,将 SwiftClaude
作为依赖项添加到您的目标
.target(
…
dependencies: [
"SwiftClaude"
],
…
),
您还可以参考 .xcode/SwiftClaudeAppPackage
中的项目以获取更多详细信息。