Environment setup
Use Xcode 27. Create a SwiftUI app for iOS 27 or macOS 27. Add Foundation Models. You will open more than one LanguageModelSession.
xcodebuild -version
# Xcode 27. New App, SwiftUI, deployment iOS 27 or macOS 27.
# Add FoundationModels. Confirm LanguageModelSession.DynamicProfile in the SDK docs.
One session can plan and call tools. That is fine for a draft. It is a poor fit for a refund, a delete, or a send that leaves the device. A single model call is a sample, not a decision. An Edge FDE puts a gate in front of the action.
Consensus means the app requires agreement, or a judge, before a tool with a side effect can run. The model can still draft. The app decides when the draft is allowed to execute.
Foundation Models has no vote API. You write the gate. Dynamic Profiles help you switch specialist instructions inside one session. Several sessions let those specialists speak at the same time. You will use both.
import FoundationModels
// One session can switch Profiles. Parallel agreement needs two sessions.
let planner = LanguageModelSession(profile: PlannerProfile())
let reviewer = LanguageModelSession(profile: ReviewerProfile())
let draft = try await planner.respond(to: request)
let vote = try await reviewer.respond(to: String(describing: draft))
// The app, not the model, decides whether the refund tool may run.
Read Pause and resume long AI jobs, Stop prompt attacks and leaks, and Talk to tools with MCP for long jobs, injection checks, and how tools get into a session.
Next, split Dynamic Profiles from multiple sessions so you pick the right one.
Key concepts
- A single session can plan and call tools. That is fine for drafts.
- One model reply is a sample, not consent to refund, delete, or send.
- There is no Foundation Models vote API. You write the gate.
- Parallel agreement needs two or more sessions.
Takeaways
- A reply is not consent to act.
- Side-effect tools stay closed until the gate passes.
- The app decides when a draft may execute.