Token导航 LogoToken导航

Agent Skill · 研究检索

axiom-foundation-models-ref(Axiom 基础模型参考)

axiom-foundation-models-ref 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

axiom-foundation-models-ref 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 23,059。

总安装 4,375周安装 186GitHub Stars 873下载 1,533核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:axiom-foundation-models-ref(Axiom 基础模型参考)
来源仓库:https://github.com/charleswiltgen/axiom
仓库路径:skills/axiom-foundation-models-ref
安装命令:
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-foundation-models-ref
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-foundation-models-ref

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。提供 Foundation Models 框架的完整 API 参考,包括 3B 参数模型规格、4096 token 上下文窗口及 Swift 调用示例。

通过 GitHub 仓库安装,使用 npx skills add 命令添加指定技能,需结合原始 README 进一步确认具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。

axiom-foundation-models-ref 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/axiom-foundation-models-ref

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/charleswiltgen/axiom --skill axiom-foundation-…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

axiom-foundation-models-ref 怎么安装?

在终端执行 npx skills add https://github.com/charleswiltgen/axiom --skill axiom-foundation-models-ref。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

axiom-foundation-models-ref 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

axiom-foundation-models-ref 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

axiom-foundation-models-ref 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

axiom-foundation-models-ref 用的人多吗?

公开数据是累计安装 4,375 次,近一周安装 186 次,下载 1,533 次,GitHub 873 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

axiom-foundation-models-ref 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
axiom-foundation-models-ref

Axiom 基础模型参考 · 本页

4,375873需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Foundation Models Framework — Complete API Reference

Overview

The Foundation Models framework provides access to Apple's on-device Large Language Model (3 billion parameters, 2-bit quantized) with a Swift API. This reference covers every API, all WWDC 2025 code examples, and comprehensive implementation patterns.

Model Specifications

3B parameter model, 2-bit quantized, 4096 token context (input + output combined). Optimized for on-device summarization, extraction, classification, and generation. NOT suited for world knowledge, complex reasoning, math, or translation. Runs entirely on-device — no network, no cost, no data leaves device.


When to Use This Reference

Use this reference when:

  • Implementing Foundation Models features
  • Understanding API capabilities
  • Looking up specific code examples
  • Planning architecture with Foundation Models
  • Migrating from prototype to production
  • Debugging implementation issues

Related Skills:

  • axiom-foundation-models — Discipline skill with anti-patterns, pressure scenarios, decision trees
  • axiom-foundation-models-diag — Diagnostic skill for troubleshooting issues

LanguageModelSession

Overview

LanguageModelSession is the core class for interacting with the model. It maintains conversation history (transcript), handles multi-turn interactions, and manages model state.

Creating a Session

Basic Creation:

import FoundationModels

let session = LanguageModelSession()

With Custom Instructions:

let session = LanguageModelSession(instructions: """
    You are a friendly barista in a pixel art coffee shop.
    Respond to the player's question concisely.
    """
)
From WWDC 301:1:05

With Tools:

let session = LanguageModelSession(
    tools: [GetWeatherTool()],
    instructions: "Help user with weather forecasts."
)
From WWDC 286:15:03

With Specific Model/Use Case:

let session = LanguageModelSession(
    model: SystemLanguageModel(useCase: .contentTagging)
)
From WWDC 286:18:39

Instructions vs Prompts

Instructions:

  • Come from developer
  • Define model's role, style, constraints
  • Mostly static
  • First entry in transcript
  • Model trained to obey instructions over prompts (security feature)

Prompts:

  • Come from user (or dynamic app state)
  • Specific requests for generation
  • Dynamic input
  • Each call to respond(to:) adds prompt to transcript

Security Consideration:

  • NEVER interpolate untrusted user input into instructions
  • User input should go in prompts only
  • Prevents prompt injection attacks

respond(to:) Method

Basic Text Generation:

func respond(userInput: String) async throws -> String {
    let session = LanguageModelSession(instructions: """
        You are a friendly barista in a world full of pixels.
        Respond to the player's question.
        """
    )
    let response = try await session.respond(to: userInput)
    return response.content
}
From WWDC 301:1:05

Return Type: Response<String> with .content property

respond(to:generating:) Method

Structured Output with @Generable:

@Generable
struct SearchSuggestions {
    @Guide(description: "A list of suggested search terms", .count(4))
    var searchTerms: [String]
}

let prompt = """
    Generate a list of suggested search terms for an app about visiting famous landmarks.
    """

let response = try await session.respond(
    to: prompt,
    generating: SearchSuggestions.self
)

print(response.content) // SearchSuggestions instance
From WWDC 286:5:51

Return Type: Response<SearchSuggestions> with .content property

Generation Options

See Sampling & Generation Options for GenerationOptions including sampling:, temperature:, and includeSchemaInPrompt:.


Multi-Turn Interactions

Retaining Context

let session = LanguageModelSession()

// First turn
let firstHaiku = try await session.respond(to: "Write a haiku about fishing")
print(firstHaiku.content)
// Silent waters gleam,
// Casting lines in morning mist—
// Hope in every cast.

// Second turn - model remembers context
let secondHaiku = try await session.respond(to: "Do another one about golf")
print(secondHaiku.content)
// Silent morning dew,
// Caddies guide with gentle words—
// Paths of patience tread.

print(session.transcript) // Shows full history
From WWDC 286:17:46

How it works:

  • Each respond() call adds entry to transcript
  • Model uses entire transcript for context
  • Enables conversational interactions

Transcript Property

let transcript = session.transcript

for entry in transcript.entries {
    print("Entry: \(entry.content)")
}

Use cases:

  • Debugging generation issues
  • Displaying conversation history in UI
  • Exporting chat logs
  • Condensing for context management

isResponding Property

Gate UI on session.isResponding to prevent concurrent requests:

Button("Go!") {
    Task { haiku = try await session.respond(to: prompt).content }
}
.disabled(session.isResponding)
From WWDC 286:18:22

@Generable Macro

Overview

@Generable enables structured output from the model using Swift types. The macro generates a schema at compile-time and uses constrained decoding to guarantee structural correctness.

Basic Usage

On Structs:

@Generable
struct Person {
    let name: String
    let age: Int
}

let response = try await session.respond(
    to: "Generate a person",
    generating: Person.self
)

let person = response.content // Type-safe Person instance
From WWDC 301:8:14

On Enums:

@Generable
struct NPC {
    let name: String
    let encounter: Encounter

    @Generable
    enum Encounter {
        case orderCoffee(String)
        case wantToTalkToManager(complaint: String)
    }
}
From WWDC 301:10:49

Supported Types

Primitives:

  • String
  • Int, Float, Double, Decimal
  • Bool

Collections:

  • [ElementType] (arrays)

Composed Types:

@Generable
struct Itinerary {
    var destination: String
    var days: Int
    var budget: Float
    var rating: Double
    var requiresVisa: Bool
    var activities: [String]
    var emergencyContact: Person
    var relatedItineraries: [Itinerary] // Recursive!
}
From WWDC 286:6:18

@Guide Constraints

@Guide constrains generated properties. Supports description: (natural language), .range() (numeric bounds), .count() / .maximumCount() (array length), and Regex (pattern matching).

@Generable
struct NPC {
    @Guide(description: "A full name")
    let name: String

    @Guide(.range(1...10))
    let level: Int

    @Guide(.count(3))
    let attributes: [String]
}
From WWDC 301:11:20

Constrained Decoding

How it works:

  1. @Generable macro generates schema at compile-time
  2. Schema defines valid token sequences
  3. During generation, model creates probability distribution for next token
  4. Framework masks out invalid tokens based on schema
  5. Model can only pick tokens valid according to schema
  6. Guarantees structural correctness - no hallucinated keys, no invalid JSON

From WWDC 286: "Constrained decoding prevents structural mistakes. Model is prevented from generating invalid field names or wrong types."

Benefits:

  • Zero parsing code needed
  • No runtime parsing errors
  • Type-safe Swift objects
  • Compile-time safety (changes to struct caught by compiler)

Property Declaration Order

Properties generated in order declared:

@Generable
struct Itinerary {
    var name: String        // Generated FIRST
    var days: [DayPlan]     // Generated SECOND
    var summary: String     // Generated LAST
}

Why it matters:

  • Later properties can reference earlier ones
  • Better model quality: Summaries after content
  • Better streaming UX: Important properties first
From WWDC 286:11:00

Streaming

Overview

Foundation Models uses snapshot streaming (not delta streaming). Instead of raw deltas, the framework streams PartiallyGenerated types with optional properties that fill in progressively.

PartiallyGenerated Type

The @Generable macro automatically creates a PartiallyGenerated nested type:

@Generable
struct Itinerary {
    var name: String
    var days: [DayPlan]
}

// Compiler generates:
extension Itinerary {
    struct PartiallyGenerated {
        var name: String?        // All properties optional!
        var days: [DayPlan]?
    }
}
From WWDC 286:9:20

streamResponse Method

@Generable
struct Itinerary {
    var name: String
    var days: [Day]
}

let stream = session.streamResponse(
    to: "Craft a 3-day itinerary to Mt. Fuji.",
    generating: Itinerary.self
)

for try await partial in stream {
    print(partial) // Incrementally updated Itinerary.PartiallyGenerated
}
From WWDC 286:9:40

Return Type: AsyncSequence<Itinerary.PartiallyGenerated>

SwiftUI Integration

struct ItineraryView: View {
    let session: LanguageModelSession
    let dayCount: Int
    let landmarkName: String

    @State
    private var itinerary: Itinerary.PartiallyGenerated?

    var body: some View {
        VStack {
            if let name = itinerary?.name {
                Text(name).font(.title)
            }

            if let days = itinerary?.days {
                ForEach(days, id: \.self) { day in
                    DayView(day: day)
                }
            }

            Button("Start") {
                Task {
                    do {
                        let prompt = """
                            Generate a \(dayCount) itinerary \
                            to \(landmarkName).
                            """

                        let stream = session.streamResponse(
                            to: prompt,
                            generating: Itinerary.self
                        )

                        for try await partial in stream {
                            self.itinerary = partial
                        }
                    } catch {
                        print(error)
                    }
                }
            }
        }
    }
}
From WWDC 286:10:05

Best Practices

1. Use SwiftUI animations:

if let name = itinerary?.name {
    Text(name)
        .transition(.opacity)
}

2. View identity for arrays:

// ✅ GOOD - Stable identity
ForEach(days, id: \.id) { day in
    DayView(day: day)
}

// ❌ BAD - Identity changes
ForEach(days.indices, id: \.self) { index in
    DayView(day: days[index])
}

3. Property order optimization:

// ✅ GOOD - Title first for streaming
@Generable
struct Article {
    var title: String      // Shows immediately
    var summary: String    // Shows second
    var fullText: String   // Shows last
}
From WWDC 286:11:00

Tool Protocol

Overview

Tools let the model autonomously execute your custom code to fetch external data or perform actions. Tools integrate with MapKit, WeatherKit, Contacts, EventKit, or any custom API.

Protocol Definition

protocol Tool {
    var name: String { get }
    var description: String { get }

    associatedtype Arguments: Generable

    func call(arguments: Arguments) async throws -> ToolOutput
}

Example: GetWeatherTool

import FoundationModels
import WeatherKit
import CoreLocation

struct GetWeatherTool: Tool {
    let name = "getWeather"
    let description = "Retrieve the latest weather information for a city"

    @Generable
    struct Arguments {
        @Guide(description: "The city to fetch the weather for")
        var city: String
    }

    func call(arguments: Arguments) async throws -> ToolOutput {
        let places = try await CLGeocoder().geocodeAddressString(arguments.city)
        let weather = try await WeatherService.shared.weather(for: places.first!.location!)
        let temperature = weather.currentWeather.temperature.value

        let content = GeneratedContent(properties: ["temperature": temperature])
        let output = ToolOutput(content)

        // Or if your tool's output is natural language:
        // let output = ToolOutput("\(arguments.city)'s temperature is \(temperature) degrees.")

        return output
    }
}
From WWDC 286:13:42

Attaching Tools to Session

let session = LanguageModelSession(
    tools: [GetWeatherTool()],
    instructions: "Help the user with weather forecasts."
)

let response = try await session.respond(
    to: "What is the temperature in Cupertino?"
)

print(response.content)
// It's 71˚F in Cupertino!
From WWDC 286:15:03

How it works:

  1. Session initialized with tools
  2. User prompt: "What's Tokyo's weather?"
  3. Model analyzes prompt, decides weather data needed
  4. Model generates tool call: getWeather(city: "Tokyo")
  5. Framework calls call() method
  6. Your code fetches real data from API
  7. Tool output inserted into transcript
  8. Model generates final response using tool output

From WWDC 301: "Model autonomously decides when and how often to call tools. Can call multiple tools per request, even in parallel."

Stateful Tools

Use class instead of struct to maintain state across tool calls. The tool instance persists for the session lifetime, enabling patterns like tracking previously returned results:

class FindContactTool: Tool {
    let name = "findContact"
    let description = "Finds a contact from a specified age generation."
    var pickedContacts = Set<String>()

    @Generable
    struct Arguments {
        let generation: Generation
        @Generable
        enum Generation { case babyBoomers, genX, millennial, genZ }
    }

    func call(arguments: Arguments) async throws -> ToolOutput {
        // Fetch, filter out already-picked, return new contact
        pickedContacts.insert(pickedContact.givenName)
        return ToolOutput(pickedContact.givenName)
    }
}
From WWDC 301:18:47, 301:21:55

ToolOutput

Two forms:

  1. Natural language (String):
return ToolOutput("Temperature is 71°F")
  1. Structured (GeneratedContent):
let content = GeneratedContent(properties: ["temperature": 71])
return ToolOutput(content)

Tool Naming Best Practices

DO:

  • Short, readable names: getWeather, findContact
  • Use verbs: get, find, fetch, create
  • One sentence descriptions
  • Keep descriptions concise (they're in prompt)

DON'T:

  • Abbreviations: gtWthr
  • Implementation details in description
  • Long descriptions (increases token count)

From WWDC 301: "Tool name and description put verbatim in prompt. Longer strings mean more tokens, which increases latency."

Multiple Tools

let session = LanguageModelSession(
    tools: [
        GetWeatherTool(),
        FindRestaurantTool(),
        FindHotelTool()
    ],
    instructions: "Plan travel itineraries."
)

// Model autonomously decides which tools to call and when

Tool Calling Behavior

Key facts:

  • Tool can be called multiple times per request
  • Multiple tools can be called in parallel
  • Model decides when to call (not guaranteed to call)
  • Arguments guaranteed valid via @Generable

From WWDC 301: "When tools called in parallel, your call method may execute concurrently. Keep this in mind when accessing data."


Dynamic Schemas

Overview

DynamicGenerationSchema enables creating schemas at runtime instead of compile-time. Useful for user-defined structures, level creators, or dynamic forms.

Creating and Using Dynamic Schemas

Build properties with DynamicGenerationSchema.Property, compose into schemas, then validate with GenerationSchema:

// Build schema at runtime
let questionProp = DynamicGenerationSchema.Property(
    name: "question", schema: DynamicGenerationSchema(type: String.self)
)
let answersProp = DynamicGenerationSchema.Property(
    name: "answers", schema: DynamicGenerationSchema(
        arrayOf: DynamicGenerationSchema(referenceTo: "Answer")
    )
)

let riddleSchema = DynamicGenerationSchema(name: "Riddle", properties: [questionProp, answersProp])
let answerSchema = DynamicGenerationSchema(name: "Answer", properties: [/* text, isCorrect */])

// Validate and use
let schema = try GenerationSchema(root: riddleSchema, dependencies: [answerSchema])
let response = try await session.respond(to: "Generate a riddle", schema: schema)

let question = try response.content.value(String.self, forProperty: "question")
From WWDC 301:14:50, 301:15:10

Dynamic vs Static @Generable

Use @Generable when:

  • Structure known at compile-time
  • Want type safety
  • Want automatic parsing

Use Dynamic Schemas when:

  • Structure only known at runtime
  • User-defined schemas
  • Maximum flexibility

From WWDC 301: "Compile-time @Generable gives type safety. Dynamic schemas give runtime flexibility. Both use same constrained decoding guarantees."


Sampling & Generation Options

Greedy (deterministic) — use for tests and demos. Only deterministic within same model version:

let response = try await session.respond(
    to: prompt,
    options: GenerationOptions(sampling: .greedy)
)

Temperature — controls variance. 0.1-0.5 focused, 1.0 default, 1.5-2.0 creative:

let response = try await session.respond(
    to: prompt,
    options: GenerationOptions(temperature: 0.5)
)
From WWDC 301:6:14

Built-in Use Cases

Content Tagging Adapter

Specialized adapter for:

  • Tag generation
  • Entity extraction
  • Topic detection
@Generable
struct Result {
    let topics: [String]
}

let session = LanguageModelSession(
    model: SystemLanguageModel(useCase: .contentTagging)
)

let response = try await session.respond(
    to: articleText,
    generating: Result.self
)
From WWDC 286:19:19

Custom Use Cases

With custom instructions:

@Generable
struct Top3ActionEmotionResult {
    @Guide(.maximumCount(3))
    let actions: [String]
    @Guide(.maximumCount(3))
    let emotions: [String]
}

let session = LanguageModelSession(
    model: SystemLanguageModel(useCase: .contentTagging),
    instructions: "Tag the 3 most important actions and emotions in the given input text."
)

let response = try await session.respond(
    to: text,
    generating: Top3ActionEmotionResult.self
)
From WWDC 286:19:35

Error Handling

GenerationError Types

Catch LanguageModelSession.GenerationError cases:

  • .exceededContextWindowSize — Context limit (4096 tokens) exceeded. Condense transcript or create new session.
  • .guardrailViolation — Content policy triggered. Show graceful message.
  • .unsupportedLanguageOrLocale — Language not supported. Check supportedLanguages.
From WWDC 301:3:37, 301:7:06

Context Window Management

Strategy 1: Fresh Session
var session = LanguageModelSession()

do {
    let response = try await session.respond(to: prompt)
    print(response.content)
} catch LanguageModelSession.GenerationError.exceededContextWindowSize {
    // New session, no history
    session = LanguageModelSession()
}
From WWDC 301:3:37
Strategy 2: Condensed Session
do {
    let response = try await session.respond(to: prompt)
} catch LanguageModelSession.GenerationError.exceededContextWindowSize {
    // New session with some history
    session = newSession(previousSession: session)
}

private func newSession(previousSession: LanguageModelSession) -> LanguageModelSession {
    let allEntries = previousSession.transcript.entries
    var condensedEntries = [Transcript.Entry]()

    if let firstEntry = allEntries.first {
        condensedEntries.append(firstEntry) // Instructions

        if allEntries.count > 1, let lastEntry = allEntries.last {
            condensedEntries.append(lastEntry) // Recent context
        }
    }

    let condensedTranscript = Transcript(entries: condensedEntries)
    // Note: transcript includes instructions
    return LanguageModelSession(transcript: condensedTranscript)
}
From WWDC 301:3:55

Fallback Architecture

When Foundation Models is unavailable (older device, user opted out, unsupported region), provide graceful degradation:

func summarize(_ text: String) async throws -> String {
    let model = SystemLanguageModel.default
    switch model.availability {
    case .available:
        let session = LanguageModelSession()
        let response = try await session.respond(to: "Summarize: \(text)")
        return response.content
    case .unavailable:
        // Fallback: truncate with ellipsis, or call server API
        return String(text.prefix(200)) + "..."
    }
}

Architecture pattern: Wrap Foundation Models behind a protocol so you can swap implementations:

protocol TextSummarizer {
    func summarize(_ text: String) async throws -> String
}

struct OnDeviceSummarizer: TextSummarizer { /* Foundation Models */ }
struct ServerSummarizer: TextSummarizer { /* Server API fallback */ }
struct TruncationSummarizer: TextSummarizer { /* Simple truncation */ }

Nested @Generable Troubleshooting

Nested @Generable types must each independently conform to @Generable:

// ✅ Both types marked @Generable
@Generable struct Itinerary {
    var days: [DayPlan]
}

@Generable struct DayPlan {
    var activities: [String]
}

// ❌ Will fail — nested type not @Generable
@Generable struct Itinerary {
    var days: [DayPlan]  // DayPlan must also be @Generable
}
struct DayPlan { var activities: [String] }

Common issue: Arrays of non-Generable types compile but fail at runtime. Check all types in the graph.


Availability

Checking Availability

struct AvailabilityExample: View {
    private let model = SystemLanguageModel.default

    var body: some View {
        switch model.availability {
        case .available:
            Text("Model is available").foregroundStyle(.green)
        case .unavailable(let reason):
            Text("Model is unavailable").foregroundStyle(.red)
            Text("Reason: \(reason)")
        }
    }
}
From WWDC 286:19:56

Supported Languages

let supportedLanguages = SystemLanguageModel.default.supportedLanguages
guard supportedLanguages.contains(Locale.current.language) else {
    // Show message
    return
}
From WWDC 301:7:06

Requirements

Device Requirements:

  • Apple Intelligence-enabled device
  • iPhone 15 Pro or later
  • iPad with M1+ chip
  • Mac with Apple silicon

Region Requirements:

  • Supported region (check Apple Intelligence availability)

User Requirements:

  • User opted in to Apple Intelligence in Settings

Performance & Profiling

Foundation Models Instrument

Access: Instruments app → Foundation Models template

Metrics:

  • Initial model load time
  • Token counts (input/output)
  • Generation time per request
  • Latency breakdown
  • Optimization opportunities

From WWDC 286: "New Instruments profiling template lets you observe areas of optimization and quantify improvements."

Optimization: Prewarming

Problem: First request takes 1-2s to load model

Solution: Create session before user interaction

class ViewModel: ObservableObject {
    private var session: LanguageModelSession?

    init() {
        // Prewarm on init
        Task {
            self.session = LanguageModelSession(instructions: "...")
        }
    }

    func generate(prompt: String) async throws -> String {
        let response = try await session!.respond(to: prompt)
        return response.content
    }
}

From WWDC 259: "Prewarming session before user interaction reduces initial latency."

Time saved: 1-2 seconds off first generation

Optimization: includeSchemaInPrompt

Problem: Large @Generable schemas increase token count

Solution: Skip schema insertion for subsequent requests

// First request - schema inserted
let first = try await session.respond(
    to: "Generate first person",
    generating: Person.self
)

// Subsequent requests - skip schema
let second = try await session.respond(
    to: "Generate another person",
    generating: Person.self,
    options: GenerationOptions(includeSchemaInPrompt: false)
)

From WWDC 259: "Setting includeSchemaInPrompt to false decreases token count and latency for subsequent requests."

Time saved: 10-20% per request

Optimization: Property Order

Declare important properties first in @Generable structs. With streaming, perceived latency drops from 2.5s to 0.2s when title appears before full text. See Streaming Best Practices for examples.


Feedback & Analytics

LanguageModelFeedbackAttachment lets you report model quality issues to Apple via Feedback Assistant. Create with input, output, sentiment (.positive/.negative), issues (category + explanation), and desiredOutputExamples. Encode as JSON and attach to a Feedback Assistant report.

From WWDC 286:22:13

Xcode Playgrounds

Overview

Xcode Playgrounds enable rapid iteration on prompts without rebuilding entire app.

Basic Usage

import FoundationModels
import Playgrounds

#Playground {
    let session = LanguageModelSession()
    let response = try await session.respond(
        to: "What's a good name for a trip to Japan? Respond only with a title"
    )
}
From WWDC 286:2:28

Playgrounds can also access types defined in your app (like @Generable structs).


API Quick Reference

  • LanguageModelSession — Main interface: respond(to:) → Response<String>, respond(to:generating:) → Response<T>, streamResponse(to:generating:) → AsyncSequence<T.PartiallyGenerated>. Properties: transcript, isResponding.
  • SystemLanguageModel — default.availability (.available/.unavailable(reason)), default.supportedLanguages, init(useCase:)
  • GenerationOptions — sampling (.greedy/.random), temperature, includeSchemaInPrompt
  • @Generable — Macro enabling structured output with constrained decoding
  • @Guide — Property constraints: description:, .range(), .count(), .maximumCount(), Regex
  • Tool protocol — name, description, Arguments: Generable, call(arguments:) → ToolOutput
  • DynamicGenerationSchema — Runtime schema definition with GeneratedContent output
  • GenerationError — .exceededContextWindowSize, .guardrailViolation, .unsupportedLanguageOrLocale

Migration Strategies

From Server LLMs

  • Migrate when: Privacy required, offline needed, per-request costs are a concern, and use case fits (summarization/extraction/classification)
  • Stay on server when: Need world knowledge, complex reasoning, or >4096 token context

From Manual JSON Parsing

Use @Generable with respond(to:generating:) instead of prompting for JSON and parsing manually. See axiom-foundation-models Scenario 2 for the complete migration pattern.


Resources

WWDC: 286, 259, 301

Skills: axiom-foundation-models, axiom-foundation-models-diag


Last Updated: 2025-12-03 Version: 1.0.0 Skill Type: Reference Content: All WWDC 2025 code examples included

平台分布

Claude Code

29.49%
按下载量换算452

Codex

23.81%
按下载量换算365

OpenCode

18.69%
按下载量换算287

Antigravity

12.1%
按下载量换算185

Cursor

7.88%
按下载量换算121

Gemini CLI

3.25%
按下载量换算50

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills