AnyLanguageModel

GitHub
835 67 简单 1 次阅读 今天Apache-2.0语言模型开发框架
AI 解读 由 AI 自动生成,仅供参考

AnyLanguageModel 是一款专为 Swift 开发者设计的开源库,旨在提供苹果官方 Foundation Models 框架的无缝替代方案。它解决了开发者在集成大语言模型时受限于单一后端或特定厂商 API 的痛点,允许通过仅修改一行导入代码(将 import FoundationModels 替换为 import AnyLanguageModel),即可灵活切换至多种自定义模型提供商。

该工具非常适合需要在 iOS、macOS 或 visionOS 应用中集成 AI 功能的 Swift 工程师使用。其核心亮点在于广泛的兼容性与模块化设计:不仅支持苹果原生模型,还无缝对接 Core ML、MLX、llama.cpp 等本地运行方案,以及 Ollama、Anthropic、Google Gemini 和 OpenAI 等主流云端 API。此外,AnyLanguageModel 利用 Swift 6.1 的包特性(Package Traits)机制,让开发者可按需启用特定后端依赖,从而有效减小应用体积并加快编译速度。配合完善的工具调用(Tool Calling)与执行监控接口,它能帮助开发者轻松构建具备复杂交互能力的智能应用,实现真正的“一次编写,多端部署”。

使用场景

某 iOS 开发团队正在为一款旅行助手 App 集成智能行程规划功能,需要灵活切换本地隐私模型与云端高性能模型以适配不同用户场景。

没有 AnyLanguageModel 时

  • 代码耦合严重:若需从苹果原生模型切换至 Ollama 或 Gemini,必须重写大量底层网络请求与解析逻辑,导致核心业务代码被特定厂商 SDK 绑定。
  • 多端适配困难:在 macOS、iOS 和 Linux 间移植项目时,因各平台支持的模型框架(如 Core ML 与 llama.cpp)差异巨大,需维护多套分支代码。
  • 功能扩展受限:想要添加“查询天气”等自定义工具调用能力,往往受限于单一框架的接口定义,难以统一处理不同后端的工具执行流程。
  • 包体积臃肿:为了兼容多种潜在需求,不得不引入所有可能的重型依赖库,导致应用安装包体积显著增加,影响用户下载意愿。

使用 AnyLanguageModel 后

  • 无缝切换后端:仅需将导入语句从 FoundationModels 改为 AnyLanguageModel,即可在苹果原生模型、Ollama、Anthropic 等十余种提供商间自由热切换,业务逻辑零改动。
  • 跨平台一致性:利用 Swift 包的特性条件编译,同一套代码可自动在 iOS 上调用 Core ML,在 Linux 服务器上运行 llama.cpp,极大降低了多端维护成本。
  • 统一工具链管理:通过标准化的 Tool 协议和 ToolExecutionDelegate,轻松实现跨模型的复杂工具调用(如实时天气查询),并支持在执行前拦截确认或记录日志。
  • 按需精简体积:借助 Package Traits 机制,开发者可按需勾选 CoreMLMLX 等特性,仅编译所需后端,显著减小二进制文件大小并加快构建速度。

AnyLanguageModel 通过屏蔽底层模型差异,让开发者能专注于业务创新,真正实现了“一次编写,随处运行”的敏捷 AI 开发体验。

运行环境要求

操作系统
  • macOS
  • iOS
  • visionOS
  • Linux
GPU

未说明 (取决于具体使用的后端模型,如 Core ML、MLX 或 llama.cpp 的硬件加速需求)

内存

未说明

依赖
notes该工具是一个 Swift 包,主要用于 Apple 生态系统及 Linux。不支持 Windows。需根据启用的特性(Traits)安装对应的底层依赖库。若在 macOS 15/iOS 18 或更早版本上构建且使用 Xcode 26,可能会遇到编译错误,建议使用 Xcode 16 作为变通方案。在 Xcode 项目中启用特性需要通过创建本地 Swift 包作为中间层来实现。严禁在客户端应用中硬编码第三方 API 密钥,建议使用用户自带密钥(存储于 Keychain)或代理服务器模式。
python不适用 (基于 Swift)
Swift 6.1+
huggingface/swift-transformers (CoreML 特性)
ml-explore/mlx-swift-lm (MLX 特性)
mattt/llama.swift (Llama 特性)
AnyLanguageModel hero image

快速开始

AnyLanguageModel

一个 Swift 软件包,为 Apple 的 Foundation Models 框架 提供即插即用的替代方案,并支持自定义语言模型提供商。你只需更改导入语句即可:

- import FoundationModels
+ import AnyLanguageModel
struct WeatherTool: Tool {
    let name = "getWeather"
    let description = "获取某个城市的最新天气信息"

    @Generable
    struct Arguments {
        @Guide(description: "要查询天气的城市")
        var city: String
    }

    func call(arguments: Arguments) async throws -> String {
        "\(arguments.city) 的天气是晴朗,温度为 72°F / 23°C"
    }
}

let model = SystemLanguageModel.default
let session = LanguageModelSession(model: model, tools: [WeatherTool()])

let response = try await session.respond {
    Prompt("库比蒂诺的天气怎么样?")
}
print(response.content)

要观察或控制工具执行,可以在会话上设置委托:

actor ToolExecutionObserver: ToolExecutionDelegate {
    func didGenerateToolCalls(_ toolCalls: [Transcript.ToolCall], in session: LanguageModelSession) async {
        print("生成的工具调用:\(toolCalls)")
    }

    func toolCallDecision(
        for toolCall: Transcript.ToolCall,
        in session: LanguageModelSession
    ) async -> ToolExecutionDecision {
        // 返回 .stop 以在工具调用后停止,或返回 .provideOutput(...) 以跳过执行。
        // 这里可以向用户请求确认(例如,在模态对话框中)。
        .execute
    }

    func didExecuteToolCall(
        _ toolCall: Transcript.ToolCall,
        output: Transcript.ToolOutput,
        in session: LanguageModelSession
    ) async {
        print("已执行的工具调用:\(toolCall)")
    }
}

let session = LanguageModelSession(model: model, tools: [WeatherTool()])
session.toolExecutionDelegate = ToolExecutionObserver()

功能特性

支持的提供商

系统要求

  • Swift 6.1+
  • iOS 17.0+ / macOS 14.0+ / visionOS 1.0+ / Linux

[!重要] Xcode 26 中的一个 bug 可能会导致在目标为 macOS 15 / iOS 18 或更早版本时出现构建错误 (例如 StringGenerable 的一致性仅在 macOS 26.0 或更高版本中可用)。 作为 workaround,请使用 Xcode 16 构建你的项目。 更多信息请参阅 issue #15

安装

将此软件包添加到你的 Package.swift 文件中:

dependencies: [
    .package(url: "https://github.com/huggingface/AnyLanguageModel", from: "0.8.0")
]

软件包特性

AnyLanguageModel 使用 Swift 6.1 特性 来有条件地包含重量级依赖项, 使你可以仅选择所需的语言模型后端。这有助于减小二进制文件大小并加快构建速度。

可用特性

  • CoreML:启用 Core ML 模型支持 (依赖于 huggingface/swift-transformers
  • MLX:启用 MLX 模型支持 (依赖于 ml-explore/mlx-swift-lm
  • Llama:启用 llama.cpp 支持 (需要 mattt/llama.swift

默认情况下,未启用任何特性。要启用特定特性,可在你的软件包依赖项中指定:

// 在你的 Package.swift 中
dependencies: [
    .package(
        url: "https://github.com/huggingface/AnyLanguageModel.git",
        from: "0.8.0",
        traits: ["CoreML", "MLX"] // 启用 Core ML 和 MLX 支持
    )
]

[!重要] 由于 Swift Package Manager 的一个 bug, 当你启用特性时,依赖解析可能会失败,并出现“已耗尽解析依赖关系图的尝试次数”的错误。 为了解决这个问题, 请将每个特性的底层依赖直接添加到你的软件包中:

dependencies: [
    .package(
        url: "https://github.com/huggingface/AnyLanguageModel.git",
        from: "0.8.0",
        traits: ["CoreML", "MLX", "Llama"]
    ),
    .package(url: "https://github.com/huggingface/swift-transformers", from: "1.0.0"), // CoreML
    .package(url: "https://github.com/ml-explore/mlx-swift-lm", from: "2.25.5"),       // MLX
    .package(url: "https://github.com/mattt/llama.swift", from: "2.0.0"),              // Llama
]

请仅包含与你启用的特性相对应的依赖项。 更多信息请参阅 issue #135

在 Xcode 项目中使用特性

Xcode 目前尚未提供内置方式来声明带有特性的包依赖项。 作为 workaround, 你可以创建一个内部 Swift 包作为桥接层, 导出启用了所需特性的 AnyLanguageModel 模块。 随后,你的 Xcode 项目可以将这个内部包添加为本地依赖。

例如, 要在 Xcode 应用项目中使用支持 MLX 的 AnyLanguageModel:

1. 创建本地 Swift 包 (在包含 Xcode 项目的根目录下):

mkdir -p Packages/MyAppKit
cd Packages/MyAppKit
swift package init

2. 指定 AnyLanguageModel 包依赖 (在 Packages/MyAppKit/Package.swift 中):

// swift-tools-version: 6.1
import PackageDescription

let package = Package(
    name: "MyAppKit",
    platforms: [
        .macOS(.v14),
        .iOS(.v17),
        .visionOS(.v1),
    ],
    products: [
        .library(
            name: "MyAppKit",
            targets: ["MyAppKit"]
        )
    ],
    dependencies: [
        .package(
            url: "https://github.com/huggingface/AnyLanguageModel",
            from: "0.4.0",
            traits: ["MLX"]
        )
    ],
    targets: [
        .target(
            name: "MyAppKit",
            dependencies: [
                .product(name: "AnyLanguageModel", package: "AnyLanguageModel")
            ]
        )
    ]
)

3. 导出 AnyLanguageModel 模块 (在 Sources/MyAppKit/Export.swift 中):

@_exported import AnyLanguageModel

4. 将本地包添加到你的 Xcode 项目

打开项目设置, 导航到“Package Dependencies”选项卡, 点击 “+” → “Add Local...” 来选择 Packages/MyAppKit 目录。

现在,你的应用就可以导入启用了 MLX 支持的 AnyLanguageModel 了。

[!TIP] 如需查看 Xcode 应用项目中包特性的实际示例, 请参阅 chat-ui-swift

API 凭证与安全

在使用 OpenAI、Anthropic 或 Google Gemini 等第三方语言模型提供商时, 必须安全地管理 API 凭证。

[!CAUTION] 切勿在应用中硬编码 API 凭证。 恶意行为者可以通过逆向工程你的应用程序二进制文件, 或通过观察传出的网络请求 (例如,在被攻陷的设备上或通过调试代理), 来提取嵌入的凭证。 已有记录显示,攻击者成功从移动应用中窃取 API 密钥, 并造成数千美元的费用。

以下是生产环境中管理 API 凭证的两种方法:

用户自备密钥 (BYO)

用户自行提供 API 密钥, 这些密钥会被安全地存储在系统的 Keychain 中, 并在 API 请求中直接发送给提供商。

安全考虑

  • Keychain 数据使用硬件支持的密钥加密, 受支持设备上的 Secure Enclave 保护;
  • 攻击者需要访问正在运行的进程才能拦截凭证;
  • TLS 加密可保护网络传输中的凭证;
  • 用户只能泄露自己的密钥,而不会影响其他用户的密钥。

权衡

  • Apple App Review 经常拒绝采用此模式的应用;
  • 审核人员可能无法测试功能——即使提供了凭证;
  • Apple 可能要求集成应用内购买以获取使用额度;
  • 部分用户可能会觉得获取和输入 API 密钥较为不便。

代理服务器

不直接连接到提供商, 而是将请求路由到你自己的经过身份验证的服务端点。 API 密钥安全地存储在你的服务器上, 绝不会出现在客户端应用中。

使用 OAuth 2.1 或类似协议对用户进行身份验证, 为客户端请求颁发短期且具有作用域限制的 Bearer 令牌。 如果攻击者从你的应用中提取了令牌, 这些令牌的作用范围有限,并会自动过期。

安全考虑

  • API 密钥永远不会离开你的服务器基础设施;
  • 客户端令牌可以设定作用域限制 (如速率限制、功能限制);
  • 客户端令牌可以独立撤销或失效;
  • 被攻陷的令牌造成的危害范围有限。

权衡

  • 需要额外的基础架构复杂性 (服务器、身份验证、监控);
  • 运营成本增加 (托管、维护、支持);
  • 因多一次跳转而导致的网络延迟。

幸运的是,有一些平台和服务可以简化代理实现, 为你处理身份验证、速率限制和计费等工作。

[!TIP] 在开发和测试阶段,可以从环境变量中使用 API 密钥即可。 但请确保生产版本采用上述安全的方法之一。

有关应用安全最佳实践的更多信息, 请参阅 OWASP 的 移动应用安全备忘录

使用方法

引导式生成

所有设备端模型——Apple Foundation Models、Core ML、MLX 和 llama.cpp—— 都支持引导式生成, 允许你使用 @Generable@Guide 来请求强类型输出,而无需解析原始字符串。 云提供商(OpenAI、Open Responses、Anthropic 和 Gemini) 也支持引导式生成。 更多详情,请参阅 使用引导式生成生成 Swift 数据结构

@Generable(description: "关于猫的基本个人资料信息")
struct CatProfile {
    // 对于基本字段,不需要指南。
    var name: String

    @Guide(description: "猫的年龄,范围为 0 到 20 岁")
    var age: Int

    @Guide(description: "一段描述猫性格的句子")
    var profile: String
}

let session = LanguageModelSession(model: model)
let response = try await session.respond(
    to: "生成一只可爱的救援猫",
    generating: CatProfile.self
)
print(response.content)

图像输入

许多提供商支持图像输入, 允许你在文本提示中加入图片。 在调用 respond 时,使用 images:image: 参数传递图像:

let response = try await session.respond(
    to: "描述你所看到的内容",
    images: [
        .init(url: URL(string: "https://example.com/photo.jpg")!),
        .init(url: URL(fileURLWithPath: "/path/to/local.png"))
    ]
)

不同提供商对图像的支持情况有所不同:

提供商 图像输入
Apple Foundation Models
Core ML
MLX 取决于模型
llama.cpp
Ollama 取决于模型
OpenAI
Open Responses
Anthropic
Google Gemini

对于 MLX 和 Ollama, 请使用具备视觉能力的模型 (例如 VLM 或 -vl 变体)。

工具调用

工具调用功能由所有提供商支持,除了 llama.cpp。 使用 Tool 协议定义工具,并在创建会话时传递它们:

struct WeatherTool: Tool {
    let name = "getWeather"
    let description = "获取某个城市的最新天气信息"

    @Generable
    struct Arguments {
        @Guide(description: "要查询天气的城市")
        var city: String
    }

    func call(arguments: Arguments) async throws -> String {
        "\(arguments.city) 的天气是晴朗的,温度为 72°F / 23°C"
    }
}

let session = LanguageModelSession(model: model, tools: [WeatherTool()])

let response = try await session.respond {
    Prompt("库比蒂诺的天气怎么样?")
}
print(response.content)

要观察或控制工具的执行,可以在会话上分配一个委托:

actor ToolExecutionObserver: ToolExecutionDelegate {
    func didGenerateToolCalls(_ toolCalls: [Transcript.ToolCall], in session: LanguageModelSession) async {
        print("生成的工具调用:\(toolCalls)")
    }

    func toolCallDecision(
        for toolCall: Transcript.ToolCall,
        in session: LanguageModelSession
    ) async -> ToolExecutionDecision {
        // 返回 .stop 以在工具调用后停止,或返回 .provideOutput(...) 以绕过执行。
        // 这是一个向用户请求确认的好地方(例如,在模态对话框中)。
        .execute
    }

    func didExecuteToolCall(
        _ toolCall: Transcript.ToolCall,
        output: Transcript.ToolOutput,
        in session: LanguageModelSession
    ) async {
        print("已执行的工具调用:\(toolCall)")
    }
}

session.toolExecutionDelegate = ToolExecutionObserver()

提供商

Apple 基础模型

使用 Apple 的 系统语言模型 (需要 macOS 26 / iOS 26 / visionOS 26 或更高版本)。

let model = SystemLanguageModel.default
let session = LanguageModelSession(model: model)

let response = try await session.respond {
    Prompt("用一句话解释量子计算")
}

Core ML

运行 Core ML 模型 (需要 CoreML 特性):

let model = CoreMLLanguageModel(url: URL(fileURLWithPath: "path/to/model.mlmodelc"))

let session = LanguageModelSession(model: model)
let response = try await session.respond {
    Prompt("总结这段文字")
}

在 Package.swift 中启用该特性:

.package(
    url: "https://github.com/huggingface/AnyLanguageModel.git",
    from: "0.8.0",
    traits: ["CoreML"]
)

MLX

在 Apple Silicon 上运行 MLX 模型 (需要 MLX 特性):

let model = MLXLanguageModel(modelId: "mlx-community/Qwen3-0.6B-4bit")

let session = LanguageModelSession(model: model)
let response = try await session.respond {
    Prompt("法国的首都是哪里?")
}

你可以通过特定于模型的选项来调整每次调用的 MLX 请求行为, 包括 KV 缓存设置和可选的媒体预处理:

var options = GenerationOptions(temperature: 0.7)
var mlxOptions = MLXLanguageModel.CustomGenerationOptions.default
mlxOptions.kvCache = .init(
    maxSize: 4096,
    bits: 4,
    groupSize: 64,
    quantizedStart: 128
)
// 对图像输入应用确定性的预处理步骤。
mlxOptions.userInputProcessing = .resize(to: CGSize(width: 512, height: 512))
// 注入额外的模板上下文,供特定于模型的聊天模板使用。
mlxOptions.additionalContext = [
    "user_name": .string("Alice"),
    "turn_count": .int(3),
    "verbose": .bool(true),
]
options[custom: MLXLanguageModel.self] = mlxOptions

let response = try await session.respond(
    to: "总结这份记录",
    options: options
)

你可以指定 userInputProcessing 来强制执行一致的图像预处理步骤 (例如,固定尺寸以获得可预测的延迟、内存使用和视觉行为)。 默认情况下,图像会直接传递,不会进行显式的大小调整(resize: nil), 因此 MLX 会应用其默认的媒体处理行为。

你还可以设置 additionalContext 来提供额外的 JSON 模板变量, 用于特定于模型的聊天模板。

GPU 缓存行为可以在创建模型时进行配置:

let model = MLXLanguageModel(
    modelId: "mlx-community/Qwen3-0.6B-4bit",
    gpuMemory: .automatic
)

视觉支持取决于你加载的具体 MLX 模型。 对于多模态提示,请使用具备视觉能力的模型 (例如,VLM 变体)。以下示例展示了从图像中提取文本:

let ocr = try await session.respond(
    to: "从这张收据中提取总金额",
    images: [
        .init(url: URL(fileURLWithPath: "/path/to/receipt_page1.png")),
        .init(url: URL(fileURLWithPath: "/path/to/receipt_page2.png"))
    ]
)
print(ocr.content)

在 Package.swift 中启用该特性:

.package(
    url: "https://github.com/huggingface/AnyLanguageModel.git",
    from: "0.8.0",
    traits: ["MLX"]
)

llama.cpp (GGUF)

通过 llama.cpp 运行 GGUF 量化模型 (需要 Llama 特性):

let model = LlamaLanguageModel(modelPath: "/path/to/model.gguf")

let session = LanguageModelSession(model: model)
let response = try await session.respond {
    Prompt("将 'hello world' 翻译成西班牙语")
}

在 Package.swift 中启用该特性:

.package(
    url: "https://github.com/huggingface/AnyLanguageModel.git",
    from: "0.8.0",
    traits: ["Llama"]
)

配置通过自定义生成选项完成, 允许你按每次请求控制运行时参数:

var options = GenerationOptions(temperature: 0.8)
options[custom: LlamaLanguageModel.self] = .init(
    contextSize: 4096,        // 上下文窗口大小
    batchSize: 512,           // 评估时的批次大小
    threads: 8,               // 线程数
    seed: 42,                 // 随机种子,用于生成确定性输出
    temperature: 0.7,         // 采样温度
    topK: 40,                 // Top-K 采样
    topP: 0.95,               // Top-P(核采样)
    repeatPenalty: 1.2,       // 重复标记的惩罚
    repeatLastN: 128,         // 考虑重复惩罚的标记数量
    frequencyPenalty: 0.1,    // 基于频率的惩罚
    presencePenalty: 0.1,     // 基于存在的惩罚
    mirostat: .v2(tau: 5.0, eta: 0.1)  // 自适应困惑度控制
)

let response = try await session.respond(
    to: "写一篇故事",
    options: options
)

Ollama

通过 Ollama 的 HTTP API 在本地运行模型:

// 默认:连接到 http://localhost:11434
let model = OllamaLanguageModel(model: "qwen3") // `ollama pull qwen3:8b`

// 自定义端点
let model = OllamaLanguageModel(
    endpoint: URL(string: "http://remote-server:11434")!,
    model: "llama3.2"
)

let session = LanguageModelSession(model: model)
let response = try await session.respond {
    Prompt("给我讲个笑话")
}

对于本地模型,请确保使用具备视觉能力的模型 (例如,-vl 变体)。您可以组合多张图片:

let model = OllamaLanguageModel(model: "qwen3-vl") // `ollama pull qwen3-vl:8b`
let session = LanguageModelSession(model: model)
let response = try await session.respond(
    to: "比较这两张海报并总结它们的区别",
    images: [
        .init(url: URL(string: "https://example.com/poster1.jpg")!),
        .init(url: URL(fileURLWithPath: "/path/to/poster2.jpg"))
    ]
)
print(response.content)

使用自定义生成选项传递任何特定于模型的参数:

var options = GenerationOptions(temperature: 0.8)
options[custom: OllamaLanguageModel.self] = [
    "seed": .int(42),
    "repeat_penalty": .double(1.2),
    "num_ctx": .int(4096),
    "stop": .array([.string("###")])
]

OpenAI

支持 聊天补全响应 API:

let model = OpenAILanguageModel(
    apiKey: ProcessInfo.processInfo.environment["OPENAI_API_KEY"]!,
    model: "gpt-4o-mini"
)

let session = LanguageModelSession(model: model)
let response = try await session.respond(
    to: "列出你看到的物体",
    images: [
        .init(url: URL(string: "https://example.com/desk.jpg")!),
        .init(
            data: try Data(contentsOf: URL(fileURLWithPath: "/path/to/closeup.png")),
            mimeType: "image/png"
        )
    ]
)
print(response.content)

对于使用较旧聊天补全 API 的 OpenAI 兼容端点:

let model = OpenAILanguageModel(
    baseURL: URL(string: "https://api.example.com")!,
    apiKey: apiKey,
    model: "gpt-4o-mini",
    apiVariant: .chatCompletions
)

使用自定义生成选项来设置高级参数,如采样控制、推理力度(针对 o 系列模型)以及厂商特定的扩展:

var options = GenerationOptions(temperature: 0.8)
options[custom: OpenAILanguageModel.self] = .init(
    topP: 0.9,
    frequencyPenalty: 0.5,
    presencePenalty: 0.3,
    stopSequences: ["END"],
    reasoningEffort: .high,        // 针对推理模型 (o3, o4-mini)
    serviceTier: .priority,
    extraBody: [                   // 厂商特定参数
        "custom_param": .string("value")
    ]
)

Open Responses

可连接到任何符合 Open Responses 规范的 API (例如 OpenAI、OpenRouter 或其他兼容提供商)。需要提供基础 URL——请使用您提供商的端点:

// 示例:OpenRouter (https://openrouter.ai/api/v1/)
let model = OpenResponsesLanguageModel(
    baseURL: URL(string: "https://openrouter.ai/api/v1/")!,
    apiKey: ProcessInfo.processInfo.environment["OPEN_RESPONSES_API_KEY"]!,
    model: "openai/gpt-4o-mini"
)

// 示例:OpenAI
let model = OpenResponsesLanguageModel(
    baseURL: URL(string: "https://api.openai.com/v1/")!,
    apiKey: ProcessInfo.processInfo.environment["OPEN_RESPONSES_API_KEY"]!,
    model: "gpt-4o-mini"
)

let session = LanguageModelSession(model: model)
let response = try await session.respond(to: "说声你好")

自定义选项支持 Open Responses 特定的字段, 例如 tool_choice(包括 allowed_tools)和 extraBody

var options = GenerationOptions(temperature: 0.8)
options[custom: OpenResponsesLanguageModel.self] = .init(
    toolChoice: .auto,
    allowedTools: ["getWeather"],
    reasoningEffort: .high,
    extraBody: ["custom_param": .string("value")]
)

Anthropic

使用 Messages API 与 Claude 模型配合:

let model = AnthropicLanguageModel(
    apiKey: ProcessInfo.processInfo.environment["ANTHROPIC_API_KEY"]!,
    model: "claude-sonnet-4-5-20250929"
)

let session = LanguageModelSession(model: model, tools: [WeatherTool()])
let response = try await session.respond {
    Prompt("旧金山的天气怎么样?")
}

您可以在提示中包含图片。可以指向远程 URL,也可以从图像数据构建:

let response = try await session.respond(
    to: "解释这张图的关键部分",
    image: .init(
        data: try Data(contentsOf: URL(fileURLWithPath: "/path/to/diagram.png")),
        mimeType: "image/png"
    )
)
print(response.content)

使用自定义生成选项来设置 Anthropic 特定的参数,如扩展思维、工具选择控制和采样参数:

var options = GenerationOptions(temperature: 0.7)
options[custom: AnthropicLanguageModel.self] = .init(
    topP: 0.9,
    topK: 40,
    stopSequences: ["END", "STOP"],
    thinking: .init(budgetTokens: 4096),  // 扩展思维
    toolChoice: .auto,                     // 工具选择控制
    serviceTier: .priority
)

Google Gemini

使用 Gemini API 和 Gemini 模型:

let model = GeminiLanguageModel(
    apiKey: ProcessInfo.processInfo.environment["GEMINI_API_KEY"]!,
    model: "gemini-2.5-flash"
)

let session = LanguageModelSession(model: model, tools: [WeatherTool()])
let response = try await session.respond {
    Prompt("东京的天气怎么样?")
}

通过远程或本地来源,在提示中发送图片:

let response = try await session.respond(
    to: "识别这张照片中的植物",
    image: .init(url: URL(string: "https://example.com/garden.jpg")!)
)
print(response.content)

Gemini 模型使用内部的“思考过程”(链接),可以提升推理能力和多步规划能力。可以通过自定义生成选项来配置思考模式:

var options = GenerationOptions()

// 启用动态预算分配的思考模式
options[custom: GeminiLanguageModel.self] = .init(thinking: .dynamic)

// 或者为思考预算设置一个明确的 token 数量
options[custom: GeminiLanguageModel.self] = .init(thinking: .budget(1024))

// 禁用思考模式(默认)
options[custom: GeminiLanguageModel.self] = .init(thinking: .disabled)

let response = try await session.respond(to: "解决这个问题", options: options)

Gemini 支持服务器端工具,这些工具会在 Google 的基础设施上透明地执行:

var options = GenerationOptions()
options[custom: GeminiLanguageModel.self] = .init(
    serverTools: [
        .googleSearch,
        .googleMaps(latitude: 35.6580, longitude: 139.7016)
    ]
)

let response = try await session.respond(
    to: "附近有哪些咖啡店?",
    options: options
)

可用的服务器工具

  • .googleSearch 根据实时网络信息提供回复
  • .googleMaps 提供基于位置的响应
  • .codeExecution 生成并运行 Python 代码以解决问题
  • .urlContext 从提示中提到的 URL 中获取并分析内容

[!TIP] Gemini 服务器工具不能作为客户端工具 (Tool) 用于其他模型。

测试

运行测试套件以验证一切是否正常工作:

swift test

针对不同语言模型后端的测试有不同的要求:

后端 特性 环境变量
CoreML CoreML HF_TOKEN
MLX MLX HF_TOKEN
Llama Llama LLAMA_MODEL_PATH
Anthropic ANTHROPIC_API_KEY
OpenAI OPENAI_API_KEY
Open Responses OPEN_RESPONSES_API_KEY, OPEN_RESPONSES_BASE_URL
Ollama

同时运行多个测试的示例设置:

export HF_TOKEN=your_huggingface_token
export LLAMA_MODEL_PATH=/path/to/model.gguf
export ANTHROPIC_API_KEY=your_anthropic_key
export OPENAI_API_KEY=your_openai_key
export OPEN_RESPONSES_API_KEY=your_open_responses_key
export OPEN_RESPONSES_BASE_URL=https://api.openai.com/v1/

swift test --traits CoreML,Llama

[!TIP] 在 CI 环境中(当设置了 CI 时),会跳过执行生成操作的测试。可以通过设置 ENABLE_COREML_TESTS=1ENABLE_MLX_TESTS=1 来覆盖此行为。

[!NOTE] 由于 Metal 库加载的要求,MLX 测试必须使用 xcodebuild 而不是 swift test 来运行。由于 xcodebuild 不支持直接指定包特性,您需要先更新 Package.swift 文件,将 MLX 特性设为默认启用。

- .default(enabledTraits: []),
+ .default(enabledTraits: ["MLX"]),

使用 TEST_RUNNER_ 前缀传递环境变量:

export TEST_RUNNER_HF_TOKEN=your_huggingface_token
xcodebuild test \
  -scheme AnyLanguageModel \
  -destination 'platform=macOS' \
  -only-testing:AnyLanguageModelTests/MLXLanguageModelTests

贡献

这是一个社区项目,我们欢迎各位的贡献。如果您正在寻找入门点,请查看标记为 good first issue 的问题:good-first-issues

在提交拉取请求之前,请确保您的代码能够通过构建和测试套件。

许可证

Apache 2

版本历史

0.8.02026/03/24
0.7.12026/02/17
0.7.02026/02/11
0.6.02026/02/04
0.5.42026/01/19
0.5.32026/01/05
0.5.22025/12/22
0.5.12025/12/17
0.5.02025/12/11
0.4.52025/11/25
0.4.42025/11/17
0.4.32025/11/14
0.4.22025/11/14
0.4.12025/11/11
0.4.02025/11/09
0.3.32025/11/09
0.3.22025/11/05
0.3.12025/11/03
0.3.02025/11/03
0.2.22025/10/31

常见问题

相似工具推荐

openclaw

OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你

349.3k|★★★☆☆|1周前
Agent开发框架图像

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|2周前
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

160.4k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

109.2k|★★☆☆☆|昨天
开发框架图像Agent

gemini-cli

gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。

100.8k|★★☆☆☆|1周前
插件Agent图像

markitdown

MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器

93.4k|★★☆☆☆|1周前
插件开发框架