huggingface/AnyLanguageModel

An API-compatible, drop-in replacement for Apple's Foundation Models framework with support for custom language model providers.

AnyLanguageModel – 面向多种 LLM 后端的 Swift 首选抽象层

是什么

  • 一个 Swift 包,它用一个统一的 Apple 风格 API 替代 Apple 的 FoundationModels 导入,支持众多 LLM 提供商(Apple、Core ML、MLX、llama.cpp、Ollama、Anthropic、OpenAI、Gemini 等)。
  • 你只需将导入语句从 import FoundationModels 改为 import AnyLanguageModel,其余代码保持不变即可使用。

核心概念

  • LanguageModelSession – 持有模型实例和可选的 工具(模型可调用的函数)列表的对象。所有交互都通过 session.respond { … } 进行。
  • 引导生成 – 使用 @Generable@Guide 属性包装器,让模型生成强类型的 Swift 结构体,而非解析原始文本。
  • 工具调用 – 定义一个符合 Tool 协议的类型(例如天气查询),让模型自行决定何时调用。可通过 ToolExecutionDelegate 观察或批准每次调用。
  • 特性(Traits) – Swift Package Manager 的 特性 允许你仅启用所需的重型后端(CoreML、MLX、Llama),从而保持二进制文件体积小。

支持的提供方(README 中的复选框表示已实现)

  • Apple Foundation Models(iOS 26/macOS 26+ 上的系统模型)
  • Core ML(设备端的 .mlmodelc 文件)
  • MLX(通过 mlx-swift 实现 Apple Silicon 加速模型)
  • llama.cpp(GGUF 量化模型)
  • Ollama HTTP API(本地或远程 Ollama 服务器)
  • Anthropic Messages API
  • Google Gemini API
  • OpenAI Chat Completions & Responses API
  • Open Responses(任何与 OpenAI 响应格式兼容的端点)

安装

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

如果需要特定后端,启用其特性:

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

使用特性时,还需添加底层包(CoreML → huggingface/swift-transformers,MLX → ml-explore/mlx-swift-lm,Llama → mattt/llama.swift)。README 提供了无法直接声明特性的项目所用的完整 Xcode 模拟工作流。

典型用法

import AnyLanguageModel

let model = SystemLanguageModel.default          // 或 CoreMLLanguageModel(...), MLXLanguageModel(...), 等
let session = LanguageModelSession(model: model)

// 简单提示
let resp = try await session.respond { Prompt("用一句话解释量子计算") }
print(resp.content)

引导生成示例

@Generable(description: "关于一只猫的基本信息")
struct CatProfile {
    var name: String
    @Guide(description: "猫的年龄", .range(0...20))
    var age: Int
    @Guide(description: "一句话的性格描述")
    var profile: String
}

let profile = try await session.respond(
    to: "生成一只可爱的救援猫的资料",
    generating: CatProfile.self
).content

模型直接返回一个 CatProfile 实例。

工具调用

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

    @Generable
    struct Arguments { @Guide var city: String }

    func call(arguments: Arguments) async throws -> String {
        "The weather in \(arguments.city) is sunny and 72°F"
    }
}

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

可附加代理以观察或批准工具调用。

图像输入 许多云提供方(OpenAI、Anthropic、Gemini、Open Responses)和部分本地后端(MLX、Ollama)支持图像输入:

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

README 中的表格列出了哪些提供方支持图像。

安全建议 README 强调 切勿硬编码 API 密钥。推荐两种生产环境模式:

  1. 自带密钥(Bring-Your-Own-Key) – 将用户提供的密钥存储在系统 Keychain 中,并直接发送给提供方。
  2. 代理服务器 – 将提供方密钥保留在你控制的后端,向 App 公开一个短期令牌,并转发请求。 两种方法均附有优缺点说明。

为何要使用它

  • 一次编写,处处运行:相同的 Swift 代码可在设备端(Core ML、MLX、llama.cpp)和云端(OpenAI、Anthropic、Gemini、Ollama)运行。
  • 通过引导生成实现强类型输出,减少脆弱的字符串解析。
  • 内置工具调用支持,可构建代理式应用(如能获取天气、查询数据或运行自定义代码的助手)。
  • 基于特性的依赖管理,使最终应用轻量化。

当前限制

  • Apple Foundation Models 需要 iOS/macOS 26,写作时仍为未来操作系统版本。
  • llama.cpp 不支持工具调用。
  • v0.11 版本因构建问题移除了 LiteRT 后端。

进一步学习

  • README 提供了 Apple 的 Guided Generation 文档、各提供方 API 以及示例 Xcode 项目(chat-ui-swift)的链接。
  • 问题 #15 和 #135 讨论了已知的 Xcode/SwiftPM 问题及变通方案。

总结AnyLanguageModel 是一个真正的、生产就绪的 Swift 库,抽象了广泛的语言模型提供方,增加了第一类工具调用和类型化生成功能,并利用 Swift Package Manager 特性保持二进制文件小巧。它面向希望在设备端和云端 LLM 上使用统一 API 的 iOS/macOS/visionOS 开发者。

相关

  • Dispatch
  • 项目
  • 项目
  • 项目
  • 项目