Back to Home

Macros @Generable @Guide FoundationModels Swift

Macros @Generable and @Guide in FoundationModels automate Swift structure generation from language models. Support for streaming sessions, property instructions and SwiftUI integration ensures type safety and responsive UI. Code examples demonstrate practical application.

Swift model generation with @Generable and @Guide
Advertisement 728x90

@Generable and @Guide Macros in FoundationModels: Automating Model Generation

The @Generable and @Guide macros in the FoundationModels framework enable the generation of Swift structure instances based on language model outputs. The compiler synthesizes protocols and methods for streaming responses from LanguageModelSession. This reduces boilerplate code and ensures type safety when working with structured data from LLMs.

Applying @Generable to a structure makes it compatible with generation mechanisms. The structure must conform to Identifiable for proper object identification.

@Generable
struct ShoppingItem: Identifiable {
    let id: String
    let value: String
}

The optional description parameter clarifies the generation context, guiding the LLM toward relevant results.

Google AdInline article slot
@Generable(description: "Generate items for a shopping list")
struct ShoppingItem: Identifiable {
    let id: String
    let value: String
}

Detailing Properties with @Guide

The @Guide macro is applied to individual properties to provide instructions to the LLM. This offers precise control over field content without altering the model generation logic.

@Generable(description: "Generate items for a shopping list")
struct ShoppingItem: Identifiable {
    let id: String

    @Guide(description: "The name of the product to purchase")
    let value: String
}

@Guide annotations are passed to the language model session as directives, influencing the parsing and validation of outputs. This is useful for complex structures with nested types or specific data formats.

Integration with LanguageModelSession

Generated models integrate into asynchronous tasks via streamResponse. The method accepts a result type and prompt, returning a stream of chunks.

Google AdInline article slot
private func generateShoppingList() {
    let prompt = "Create 15 shopping list items"
    Task {
        do {
            let session = LanguageModelSession()

            let response = session.streamResponse(
                generating: [ShoppingItem].self
            ) {
                prompt
            }

            isGenerating = true

            for try await chunk in response {
                self.shoppingList = chunk.compactMap {
                    guard let id = $0.id, let task = $0.value else {
                        return nil
                    }

                    return ShoppingItem(id: id, value: task)
                }
            }

            isGenerating = false
        } catch {
            print(error.localizedDescription)
            isGenerating = false
        }
    }
}

Chunk processing includes filtering nil values and updating the UI state. This ensures interface responsiveness during generation.

  • Streaming Processing: Chunks arrive asynchronously, minimizing delays.
  • Type Safety: The compiler verifies the structure's protocol conformance.
  • Validation: Guard expressions filter out incomplete objects.
  • Error Handling: Try-catch captures session failures.

SwiftUI Integration for Streamed Generation

In SwiftUI views, models are bound to @State. A button triggers generation, becoming disabled during execution.

struct ContentView: View {
    @State private var shoppingList: [ShoppingItem] = []
    @State private var isGenerating: Bool = false

    var body: some View {
        List(shoppingList) { item in
            Text(item.value)
        }
        .toolbar {
            ToolbarItem(placement: .bottomBar) {
                Button(
                    "Generate Shopping List",
                    systemImage: "cart.fill.badge.plus"
                ) {
                    generateShoppingList()
                }
                .disabled(isGenerating)
            }
        }
    }

    private func generateShoppingList() {
        // ...
    }
}

The UI updates reactively as data arrives. This demonstrates real-world application for dynamic content in apps.

Google AdInline article slot

Key Takeaways

  • @Generable synthesizes protocols for streaming generation from LLMs into Swift structures.
  • @Guide provides property-level instructions for precise parsing of outputs.
  • Integration with LanguageModelSession supports asynchronous streaming with type safety.
  • Suitable for generating lists, forms, and dynamic data in SwiftUI applications.
  • Reduces boilerplate code while maintaining control over generated object structure.

— Editorial Team

Advertisement 728x90

Read Next