> ## Documentation Index
> Fetch the complete documentation index at: https://docsmlx.otterly.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> Étendre le modèle avec vos propres fonctions Swift

Le modèle système Apple n'a pas accès tout seul à vos données, à votre base locale ou au web. Les **tools** servent à lui ouvrir des portes contrôlées.

Ils sont utiles dès que le modèle doit :

* lire une information dynamique
* déclencher une action
* aller chercher des données dans votre app

***

## L'idée simple

Vous décrivez un outil en Swift. Le modèle décide ensuite s'il doit l'appeler en fonction :

* de son nom
* de sa description
* de la forme de ses arguments

***

## Exemple minimal

```swift theme={null}
import FoundationModels

struct WeatherTool: Tool {
    let name = "get_weather"
    let description = "Returns the current weather for a city."
    let includesSchemaInInstructions = true

    @Generable
    struct Arguments {
        @Guide(description: "The city to look up")
        var city: String
    }

    func call(arguments: Arguments) async throws -> String {
        "Weather for \(arguments.city): 22°C and sunny."
    }
}
```

Puis vous passez l'outil à la session :

```swift theme={null}
let session = LanguageModelSession(
    tools: [WeatherTool()]
)

let response = try await session.respond(
    to: "Quel temps fait-il à Paris ?"
)

print(response.content)
```

***

## Ce qui fait un bon tool

### Un nom explicite

Utilisez un nom unique et lisible comme `get_weather`, pas `tool1`.

### Une description claire

Le modèle lit la description. C'est elle qui l'aide à décider si l'outil est utile.

### Des arguments simples

Plus les arguments sont clairs, plus le modèle les remplit correctement.

### Des effets de bord assumés

Un tool peut lire des données, mais aussi déclencher une action. Si c'est le cas, gardez son périmètre étroit et son erreur explicite.

***

## `includesSchemaInInstructions` : quand c'est utile

La propriété `includesSchemaInInstructions` permet d'injecter dans la session le nom du tool, sa description et le schéma de ses arguments.

Pour un développeur intermédiaire, la règle pratique est simple :

* activez cette injection quand vous voulez aider le modèle à comprendre rapidement quand appeler le tool
* désactivez-la seulement si vous avez une raison claire de contrôler ce contexte autrement

Cette propriété n'améliore pas votre logique métier. Elle aide surtout le modèle à mieux choisir et remplir le tool.

***

## Tool et sortie structurée

Si vous avez besoin d'un résultat fiable côté app, combinez tool et sortie structurée :

```swift theme={null}
@Generable
struct WeatherResult {
    @Guide(description: "City name")
    var city: String = ""

    @Guide(description: "Current temperature in Celsius")
    var temperature: Int = 0
}
```

Le pattern le plus robuste est souvent le suivant :

1. le tool récupère la donnée réelle au runtime
2. la sortie structurée impose la forme finale attendue par votre UI

```swift theme={null}
@Generable
struct WeatherAdvice {
    @Guide(description: "Conseil météo en une phrase")
    var summary: String = ""

    @Guide(description: "Tenue recommandée")
    var outfit: String = ""
}

let session = LanguageModelSession(
    tools: [WeatherTool()]
)

let result = try await session.respond(
    to: "À partir de la météo actuelle à Paris, donne un conseil simple.",
    generating: WeatherAdvice.self
)
```

Le tool sert alors à récupérer la vérité terrain. Le type Swift sert à cadrer la réponse finale.

***

## Bon cas d'usage dans une app Swift

<CardGroup cols={2}>
  <Card title="Calendrier" icon="calendar">
    Lister ou créer des événements à partir d'une demande en langage naturel.
  </Card>

  <Card title="Base locale" icon="database">
    Chercher des enregistrements dans SwiftData ou SQLite.
  </Card>

  <Card title="Rappels" icon="bell">
    Transformer une demande en action applicative.
  </Card>

  <Card title="Données métier" icon="briefcase">
    Interroger votre propre couche de service ou votre backend.
  </Card>
</CardGroup>

***

## Gérer les erreurs d'un tool

Un tool peut échouer comme n'importe quelle fonction Swift. Utilisez des erreurs claires :

```swift theme={null}
enum WeatherToolError: LocalizedError {
    case cityNotFound

    var errorDescription: String? {
        switch self {
        case .cityNotFound:
            return "City not found."
        }
    }
}
```

Et gérez ensuite `ToolCallError` côté session.

***

## Recommandations pratiques

* gardez les tools ciblés
* ne mélangez pas trop d'actions dans un seul tool
* donnez des descriptions lisibles par un humain
* combinez avec Guided Generation si l'app dépend d'un format stable

Le bon niveau de granularité est souvent : un tool = une capacité claire.

***

<CardGroup cols={2}>
  <Card title="Guided Generation" icon="wand-magic-sparkles" href="/mlx/foundation-models/guided-generation">
    Générer des objets Swift.
  </Card>

  <Card title="Erreurs & guardrails" icon="triangle-exclamation" href="/mlx/foundation-models/error-handling">
    Gérer les erreurs du modèle et des tools.
  </Card>
</CardGroup>
