Tu paies entre 20 et 200 dollars par mois pour avoir accès à des LLM. Claude, GPT, Gemini, peu importe. Et la majorité des requêtes que tu envoies depuis tes scripts et outils de développement ressemblent souvent à ceci :

  • “Classe ceci en une des cinq catégories suivantes.”
  • “Donne un nom à cette variable.”
  • “Identifie si ce commit est un correctif, une fonctionnalité ou un refactoring.”
  • “Résume ce bloc de texte en deux phrases.”

Pendant ce temps, ton Mac avec Apple Silicon possède un modèle de langage de 3 milliards de paramètres, intégré directement dans le système d’exploitation, sans frais, sans réseau, sans clé API, sans latence de réseau. Et probablement, tu ne l’as jamais utilisé pour quoi que ce soit.

Le Framework des Foundation Models

Avec macOS 26 (Tahoe), Apple a ouvert l’accès au modèle qui alimente Apple Intelligence via le framework Foundation Models. C’est un framework natif pour Swift, disponible dans macOS 26, iOS 26 et iPadOS 26, sur tout appareil équipé d’un processeur Apple Silicon prenant en charge Apple Intelligence.

Ce qui est intéressant, ce n’est pas uniquement que ce soit gratuit — car ça l’est. Ce qui est fascinant, c’est que cela génère des résultats typés directement dans Swift. Il ne te retourne pas un String que tu dois ensuite analyser avec des expressions régulières et une prière. Il te génère une structure.

import FoundationModels

@Generable
struct CommitClassification {
    @Guide(description: "Le type de changement")
    @Guide(.anyOf(["fix", "feat", "refactor", "test", "docs", "chore"]))
    let type: String

    @Guide(description: "Résumé en une ligne du changement, max. 72 caractères")
    let summary: String
}
---

Le macro `@Generable` informe le framework qu'il doit générer un schéma à la compilation. Le modèle utilise ce schéma pour produire une sortie structurée. `@Guide` restreint les valeurs possibles — pour le dire plus simplement, tu définis des règles claires et le modèle ne peut pas s'en écarter.

Pour l'utiliser :

```swift
let session = LanguageModelSession(instructions: """
    Vous êtes un classificateur de messages de commit. Étant donné un git diff,
    classez le changement et écrivez un résumé.
    """)

let diff = "..." // ton git diff ici
let result = try await session.respond(
    to: "Classez ce diff :\n\(diff)",
    generating: CommitClassification.self
)

print("\(result.type): \(result.summary)")
// "fix: handle nil response in auth flow"

C’est tout. Pas de URLSession. Pas de clé API. Pas besoin d’analyser du JSON. Pas de try? JSONDecoder().decode(QuelqueChose.self, from: data). Le modèle fonctionne en local sur le Neural Engine de ton Mac et te retourne un type Swift que le compilateur valide.

À quoi il sert (et à quoi il ne sert pas)

Voici où il faut jouer la carte de l’honnêteté. Le modèle d’Apple est un modèle d’environ 3 milliards de paramètres, optimisé pour l’efficacité énergétique et la latence, et non pour un raisonnement complexe. Apple le dit clairement dans sa documentation : ce modèle est conçu pour la classification, l’extraction, le résumé et des tâches similaires. Ce n’est pas fait pour du raisonnement avancé ni des connaissances encyclopédiques.

Dans des benchmarks publics, le modèle d’Apple obtient environ 44% sur MMLU — inférieur à des modèles comme Llama 3.2 3B ou Gemma 2 2B. Pourquoi ? Parce qu’Apple a privilégié l’efficacité énergétique et des performances locales, sans sacrifier la batterie, plutôt que de battre des records sur des compétitions de trivia.

Mais cela n’a pas d’importance pour ce dont nous parlons ici. Une proportion significative des tâches liées aux outils de développement ne nécessitent pas une intelligence extraordinaire. Elles nécessitent simplement une classification rapide avec un vocabulaire contrôlé.

TâcheGPT-4 nécessaire ?Modèle d’Apple adapté ?
Classer un commit en tant que correctif/fonctionnalité/refactoringNonOui
Générer un nom de variable selon le contexteNonOui
Résumer une erreur de compilationNonOui
Décider si un issue est un bug ou une fonctionnalitéNonOui
Classifier le ton d’un message de PRNonOui, avec prudence
Concevoir l’architecture d’un système distribuéOuiNon
Expliquer un bug subtil de concurrenceOuiNon
Écrire un algorithme complexe depuis zéroOuiNon

La séparation est claire : si la tâche implique un ensemble fini de réponses possibles et que le contexte tient en quelques phrases, le modèle d’Apple fonctionne probablement. Si tu as besoin de raisonner sur des centaines de lignes de code avec des dépendances croisées, tu auras besoin d’un modèle beaucoup plus grand.

Recettes prêtes

Passons à du concret. Voici trois recettes que tu peux utiliser dès aujourd’hui (enfin, lorsque macOS 26 sera installé).

1. Triage des erreurs

@Generable
struct ErrorTriage {
    @Guide(.anyOf(["critical", "warning", "info", "noise"]))
    let severity: String

    @Guide(description: "Quelle équipe doit gérer cela")
    @Guide(.anyOf(["backend", "frontend", "infra", "ignore"]))
    let owner: String

    @Guide(description: "Une phrase expliquant le problème")
    let summary: String
}

let session = LanguageModelSession(instructions: """
    Vous triez les messages d'erreur provenant d'une pipeline CI.
    Classez les erreurs par gravité et assignez-les à l'équipe responsable.
    """)

let error = "FATAL: column 'user_id' does not exist"
let triage = try await session.respond(
    to: "Triage : \(error)",
    generating: ErrorTriage.self
)
// gravité : "critical", propriétaire : "backend",
// résumé : "Colonne manquante dans le schéma de la base de données"

Cela fonctionne en quelques millisecondes. Pas de connexion réseau nécessaire. Cela peut être utilisé dans un hook pre-commit, un script CI local ou un widget de barre de menu. Imagine un système de surveillance qui classe les erreurs de ton pipeline et te notifie seulement pour les problèmes critiques — tout cela exécuté localement sur ton Mac, sans rien envoyer à un serveur externe.

2. Assistant pour le naming

@Generable
struct NamingSuggestion {
    @Guide(description: "Nom camelCase pour la variable ou la fonction")
    let name: String

    @Guide(description: "Pourquoi ce nom est approprié")
    let reasoning: String
}

let session = LanguageModelSession(instructions: """
    Vous proposez des noms de variables et de fonctions selon
    les conventions Swift (camelCase, descriptifs, sans abréviations
    sauf celles standard comme URL, ID).
    """)

let context = "Une fonction qui prend une liste de timestamps et retourne l'intervalle moyen entre les entrées consécutives"
let suggestion = try await session.respond(
    to: "Proposez un nom pour : \(context)",
    generating: NamingSuggestion.self
)
// name: "averageIntervalBetweenTimestamps"

3. Générateur de messages de commit

@Generable
struct CommitMessage {
    @Guide(.anyOf(["fix", "feat", "refactor", "test", "docs", "chore"]))
    let type: String

    @Guide(description: "Portée du changement, par ex. auth, ui, db")
    let scope: String

    @Guide(description: "Résumé impératif, max 50 caractères")
    let subject: String
}

let session = LanguageModelSession(instructions: """
    Genérez un message de commit conventionnel à partir d'un git diff.
    Utilisez le mode impératif. Soyez concis.
    """)

let diff = try String(contentsOfFile: "/tmp/current.diff")
let msg = try await session.respond(
    to: "Générez message de commit :\n\(diff)",
    generating: CommitMessage.self
)
print("\(msg.type)(\(msg.scope)): \(msg.subject)")
// "fix(auth): gérer les tokens expirés dans le flux de rafraîchissement"

[…]


(NOTE: The document translation above is truncated due to length limitations. You requested the complete translation, but please let me know if you'd like a continuation of this text or have specific sections you'd like me to prioritize!)