L'IA : en parler et l'intégrer
En 2026, la question sur l'IA arrive dans presque tous les entretiens. Elle teste moins votre maîtrise des outils que votre jugement : respectez-vous les règles du client, restez-vous responsable du code livré, savez-vous travailler sans assistant ? Ce chapitre prépare d'abord ce discours, puis couvre les pratiques professionnelles et l'intégration de fonctionnalités d'IA dans une app Flutter.
Objectifs
- Répondre en 90 secondes à « Utilisez-vous l'IA ? » avec un discours en trois temps : règle, usage, responsabilité.
- Raconter deux exemples concrets et chiffrés, dont un où l'assistant s'est trompé.
- Décrire un workflow assisté sain et la revue d'un code produit par un assistant.
- Expliquer le Dart and Flutter MCP server et les fichiers de règles de projet.
- Concevoir une fonctionnalité d'IA dans une app sans clé d'API dans le binaire, avec streaming, gestion d'erreurs et maîtrise des coûts.
- Situer Flutter AI Toolkit, GenUI et A2UI, Genkit Dart et l'inférence on-device.
Partie 1 · Ce que craint un client grand compte
Avant de préparer une réponse, comprenez la question. Un responsable d'équipe dans une banque, un opérateur télécom ou une administration ne vous demande pas si vous êtes à la mode. Il évalue un risque. Ses craintes sont concrètes :
- Fuite de code et de données : du code source, des schémas d'API, des jeux de données de test ou des logs contenant des données clients envoyés à un service externe non autorisé. Pour une banque, c'est un incident de sécurité, parfois un manquement réglementaire (secret bancaire, protection des données personnelles, exigences du régulateur).
- Propriété intellectuelle : du code généré dont l'origine et la licence sont incertaines, ou du code du client réutilisé ailleurs.
- Qualité : du code qui compile mais que personne ne comprend, des tests qui ne testent rien, des failles introduites par une suggestion plausible.
- Dépendance : un consultant facturé comme senior qui ne sait plus avancer quand l'outil est indisponible ou interdit.
- Conformité : la politique de sécurité de l'entreprise, souvent stricte. Beaucoup de banques bloquent les assistants publics au niveau du proxy, autorisent seulement un outil validé (hébergé en interne ou sous contrat), ou interdisent tout.
En régie, vous travaillez dans le système d'information du client, avec ses règles. Votre habitude personnelle n'a aucun poids face à sa politique de sécurité. Le recruteur veut entendre que vous le savez sans qu'il ait à le dire.
Le discours en trois temps
Une bonne réponse tient en trois blocs, toujours dans cet ordre. Commencer par la règle rassure immédiatement ; commencer par l'usage inquiète.
| Temps | Message | Ce que le recruteur entend |
|---|---|---|
| 1. La règle | J'applique la politique du client. Je n'envoie jamais de code ni de données client vers un outil non validé. | Pas de risque de fuite, il connaît le contexte |
| 2. L'usage | Quand c'est autorisé, je m'en sers comme accélérateur : code répétitif, tests, migrations, documentation, exploration d'un code inconnu, première relecture. | Il est productif, sur des tâches à faible risque |
| 3. La responsabilité | Je relis et je comprends tout ce qui est fusionné. L'architecture, la sécurité et les règles métier restent des décisions humaines. | C'est lui qui signe, pas l'outil |
« Ma première règle, c'est la politique du client : je n'envoie ni code ni donnée client vers un outil qui n'a pas été validé, et si rien n'est autorisé, je travaille sans. Quand un outil est autorisé, je l'utilise pour accélérer ce qui est répétitif : tests, migrations, documentation, exploration d'un module que je découvre. En revanche, tout ce que je fusionne, je l'ai relu et compris, et je peux l'expliquer en revue. L'architecture, la sécurité et les règles métier, je les décide moi-même. »
Préparer deux exemples concrets
Une affirmation générale ne convainc personne. Préparez deux histoires courtes, vraies, avec un chiffre. Ne les inventez pas : un recruteur expérimenté pose deux questions de relance et une histoire fabriquée s'effondre. Canevas à remplir :
| Élément | Exemple 1 : un gain | Exemple 2 : une erreur détectée |
|---|---|---|
| Contexte | Projet, taille, contrainte (en une phrase) | Projet et tâche confiée à l'assistant |
| Tâche | Ex. migrer N écrans, écrire les tests d'un module, générer des modèles depuis un contrat OpenAPI | Ex. générer un intercepteur, une requête SQL, un parseur de dates |
| Ce que vous avez fait | Spécification, découpage, relecture, ce que vous avez réécrit | Comment l'erreur a été vue : test qui échoue, revue, analyse statique, comportement en recette |
| Chiffre | Durée estimée contre durée réelle, nombre de tests, couverture | Ce que l'erreur aurait coûté en production |
| Leçon | Ce que vous ne déléguez pas | Le garde-fou que vous avez ajouté depuis |
Erreurs typiques qui font de bons exemples 2 : une API Flutter dépréciée proposée avec assurance (WillPopScope, withOpacity, StateNotifier), un package inexistant ou une méthode inventée, une gestion de refresh token qui déclenche des appels concurrents, un calcul monétaire en double, un test qui vérifie le mock au lieu du comportement, une comparaison de dates sans fuseau horaire.
« Racontez une fois où l'IA s'est trompée. » Le candidat qui n'a pas d'exemple laisse entendre qu'il ne relit pas. Le candidat qui en a un, avec la manière dont il l'a détecté (un test, une revue, la doc officielle), démontre exactement la compétence recherchée.
Ce qu'il ne faut pas dire
- « L'IA code pour moi » ou « je ne tape presque plus de code » : vous venez de dire que votre valeur est celle d'un abonnement.
- Vanter la vitesse en régie : « je vais trois fois plus vite » se traduit chez un acheteur par « le TJM devrait être divisé par trois », et chez un responsable technique par « il produit trois fois plus de code à relire ». Parlez de qualité, de tests, de délais tenus, pas de multiplicateur.
- Citer un outil interdit comme une évidence, ou expliquer comment contourner un blocage du proxy.
- Dénigrer l'IA par principe : vous passeriez pour quelqu'un qui refuse les outils de l'équipe.
- Mentionner du code client collé dans un outil grand public chez un ancien client, même pour illustrer un gain.
Réponses modèles
« Utilisez-vous l'IA dans votre travail ? »
« Oui, quand le client l'autorise et avec l'outil qu'il a validé. Je l'utilise pour les tâches répétitives : squelettes de tests, migrations d'API, documentation, exploration d'un code que je découvre. Je relis tout ce que je fusionne et je dois pouvoir l'expliquer. L'architecture, la sécurité et les règles métier restent de ma responsabilité. Si la politique l'interdit, je travaille sans, et ça ne change pas ma capacité à livrer. »
« Et si c'est interdit chez nous ? »
« Alors je n'en utilise pas, ni sur le poste fourni ni ailleurs avec votre code. J'ai appris Flutter et le mobile avant ces outils ; je m'entraîne régulièrement sans assistant justement pour garder ce niveau. Mon efficacité repose surtout sur la connaissance du framework, les snippets de l'IDE, la génération de code classique (build_runner, OpenAPI) et de bons tests. Si un jour vous évaluez un outil validé, je peux aider à définir les règles d'usage. »
« Comment garantissez-vous la qualité du code généré ? »
« Exactement comme pour le code d'un collègue : je ne fusionne rien que je ne comprends pas. Je génère par petits morceaux sur une spécification précise, je vérifie les API dans la documentation officielle, je fais passer l'analyse statique avec des lints stricts, et chaque comportement est couvert par un test que j'ai relu, idéalement écrit avant. La revue de code de l'équipe s'applique sans exception. »
« L'IA va-t-elle remplacer les développeurs mobiles ? »
« Elle remplace une partie de la frappe, pas le travail. Sur un projet bancaire, l'essentiel est ailleurs : comprendre le besoin métier, arbitrer entre sécurité et ergonomie, concevoir une architecture qui tiendra cinq ans, gérer la publication sur les stores, diagnostiquer un crash en production. Le métier se déplace vers plus de conception, de revue et de responsabilité. Les développeurs qui savent faire tout cela restent nécessaires. »
« Comment l'utilisez-vous pour les tests ? »
« Je décide moi-même des cas à tester : nominal, limites, erreurs, concurrence. Ensuite, l'assistant peut écrire le squelette, les fixtures et les variantes répétitives. Je relis chaque assertion : le piège classique est un test qui vérifie le mock ou qui passe toujours. Je vérifie qu'un test échoue quand je casse volontairement le code, sinon il ne protège rien. »
« Quel est le risque principal selon vous ? »
« La confiance excessive. Un code plausible, bien formaté, qui utilise une API dépréciée ou introduit une faille subtile, par exemple un certificat non vérifié ou un token journalisé. Le second risque est la fuite de données vers un service non autorisé. Les deux se traitent par des règles claires et une revue systématique. »
« Pourriez-vous coder cet exercice sans assistant ? »
« Oui, c'est d'ailleurs comme ça que je préfère être évalué. Je vais reformuler, poser mes hypothèses, puis coder la version simple d'abord. »
« Vous avez dit l'utiliser pour explorer du code : concrètement ? »
« Sur un dépôt que je découvre, je lui demande de résumer un module, de retracer un flux (d'un bouton à l'appel réseau) ou de lister les endroits qui utilisent un service. Je vérifie ensuite en lisant le code moi-même. C'est un accélérateur de lecture, pas une source de vérité. Évidemment, uniquement avec un outil autorisé sur ce code. »
Version courte en anglais
Une partie de l'entretien peut se dérouler en anglais. Deux réponses à savoir dire sans lire :
Do you use AI tools? « Yes, when the client allows it and only with approved tools. I never send client code or data to an unapproved service. I use it for repetitive work: test scaffolding, migrations, documentation, exploring unfamiliar code. I review and understand everything I merge, and architecture, security and business rules stay my decisions. »
What if it's not allowed here? « Then I don't use it, full stop. I learned mobile development before these tools existed and I regularly practice without them. My productivity comes from knowing the framework, good tooling and solid tests. »
Partie 2 · Un workflow assisté sain
Les entretiens techniques posent de plus en plus la question « montrez-moi comment vous travaillez avec ». La bonne réponse décrit une boucle courte où l'humain garde la main :
Fichiers d'instructions de projet. La plupart des assistants lisent un fichier de règles à la racine du dépôt (le nom dépend de l'outil ; AGENTS.md est une convention partagée par plusieurs d'entre eux). On y décrit la stack (Riverpod 3 avec Notifier, go_router, freezed), les conventions (feature-first, Result/Failure), les interdits (pas de double pour l'argent, pas de print, pas de nouvelle dépendance sans accord) et les commandes de vérification. L'équipe Flutter publie des règles officielles pour Flutter et Dart à adapter : elles poussent l'assistant vers les API actuelles et les bonnes pratiques du framework.
Revue d'une sortie d'IA. Points à vérifier systématiquement :
- Hallucinations d'API : méthode, paramètre nommé ou package qui n'existe pas. Le compilateur attrape une partie, pas les packages au nom plausible mais malveillants (typosquatting). Vérifiez chaque nouvelle dépendance sur pub.dev : éditeur vérifié, popularité, maintenance.
- Versions obsolètes : les modèles ont une date de coupure. Ils proposent souvent
StateNotifier,WillPopScope,withOpacity, l'ancienne syntaxe Gradle Groovy ou des API Riverpod 2. - Sécurité :
badCertificateCallbackqui renvoietrue, secrets en dur, tokens dans les logs, stockage en clair dansSharedPreferences, désactivation de lints. - Tests complaisants : assertions sur le mock,
expect(true, isTrue)déguisé, tests réécrits pour passer au lieu de corriger le code. - Sur-ingénierie : abstractions inutiles, fichiers en trop, gestion d'erreur générique qui avale les exceptions.
// Proposé avec assurance : API dépréciée, double pour l'argent, erreur avalée.
final balanceProvider = StateNotifierProvider<BalanceNotifier, double>(
(ref) => BalanceNotifier(),
);
import 'package:flutter_riverpod/flutter_riverpod.dart';
// Riverpod 3 : AsyncNotifier, montant en centimes (int), erreurs exposées via AsyncValue.
class BalanceNotifier extends AsyncNotifier<int> {
@override
Future<int> build() async => ref.watch(walletRepositoryProvider).fetchBalanceMinor();
}
final balanceProvider = AsyncNotifierProvider<BalanceNotifier, int>(BalanceNotifier.new);
abstract interface class WalletRepository {
Future<int> fetchBalanceMinor();
}
final walletRepositoryProvider = Provider<WalletRepository>(
(ref) => throw UnimplementedError('Surchargé dans main()'),
);
Le Dart and Flutter MCP server
MCP (Model Context Protocol) est un protocole ouvert qui permet à un assistant d'appeler des outils exposés par un serveur : lire un état, lancer une commande, interroger un service. Au lieu de deviner, l'assistant consulte la réalité du projet.
Le Dart and Flutter MCP server est fourni par le SDK Dart (lancé par la commande dart mcp-server, que l'assistant configure comme serveur MCP). Il expose notamment :
- l'analyse du projet (erreurs et avertissements de l'analyzer),
dart fixetdart format; - la résolution de symboles et la documentation via le language server ;
- l'exécution des tests et des commandes
pub, la recherche sur pub.dev ; - la connexion à une app en cours d'exécution via le Dart Tooling Daemon : hot reload, hot restart, erreurs d'exécution, logs ;
- l'inspection de l'arbre de widgets et des commandes Flutter Driver pour interagir avec l'UI.
Depuis Flutter 3.44, le serveur découvre automatiquement les apps lancées et un agent peut déclencher lui-même le hot reload après une modification (agentic hot reload), puis lire les erreurs d'exécution. L'équipe publie aussi des Agent Skills pour Dart et Flutter : des guides procéduraux chargés à la demande par l'assistant (mise en page responsive, tests de widgets, FFI, migrations).
« Un agent qui exécute des commandes sur votre poste, c'est un problème de sécurité ? » Oui, potentiellement : il lance des processus, lit des fichiers, installe des dépendances. Réponse attendue : outils validés par le client, permissions limitées (confirmation avant les commandes), pas d'accès aux secrets, dépôt de travail isolé, et toujours une revue humaine avant fusion.
Garder ses compétences sans IA
Beaucoup d'entretiens techniques se déroulent sans assistant : live coding en partage d'écran, exercice sur papier, revue de code orale. Le client veut voir votre raisonnement, pas celui de l'outil, et il sait que certaines de ses missions interdiront ces outils. Après des mois de travail assisté, la perte est réelle : on oublie des signatures, on hésite sur la syntaxe, on perd l'habitude de lire une stack trace jusqu'au bout.
- Désactivez l'assistant pendant les exercices chronométrés de ce site.
- Réécrivez de mémoire les briques fréquentes :
AsyncNotifier, intercepteur Dio,ListView.builderpaginé, test de widget avec override. - Lisez la documentation officielle plutôt que de demander : vous retiendrez aussi le contexte.
- Expliquez votre code à voix haute : c'est exactement ce qu'on vous demandera.
Partie 3 · Intégrer de l'IA dans une app Flutter
Les clients demandent désormais des fonctionnalités d'IA : assistant de support, résumé de relevé, catégorisation de dépenses, saisie assistée. Les principes d'architecture comptent plus que le fournisseur de modèle.
Jamais de clé d'API dans le binaire
Une clé embarquée (en dur, dans --dart-define ou dans un fichier d'assets) se récupère en quelques minutes sur un APK ou une IPA. Conséquence : facture illimitée à vos frais et quota épuisé. Deux architectures acceptables :
Firebase AI Logic (nom actuel, package firebase_ai) permet d'appeler des modèles depuis l'app sans exposer de clé de modèle, à condition d'activer Firebase App Check, qui atteste que la requête provient de votre app authentique (Play Integrity sur Android, App Attest sur iOS). Pour une banque, l'option A reste la plus probable : les données transitent par un service que l'entreprise contrôle, qui peut retirer les données personnelles, appliquer des quotas et journaliser.
import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
// Nom de modèle : consulter la documentation, les noms évoluent souvent.
const modelName = 'nom-du-modele';
Future<void> initAi() async {
await Firebase.initializeApp();
await FirebaseAppCheck.instance.activate(
providerAndroid: const AndroidPlayIntegrityProvider(),
providerApple: const AppleAppAttestProvider(),
);
}
Stream<String> askModel(String prompt) async* {
final model = FirebaseAI.googleAI().generativeModel(model: modelName);
await for (final chunk in model.generateContentStream([Content.text(prompt)])) {
final text = chunk.text;
if (text != null) yield text;
}
}
Cette syntaxe correspond à firebase_app_check 0.5 (octobre 2026). Les anciens paramètres androidProvider et appleProvider, encore présents dans certaines pages de documentation et dans beaucoup de sorties d'assistants, n'existent plus : bon exemple d'API qui bouge vite.
Streaming de la réponse dans l'UI
Un modèle met plusieurs secondes à produire une réponse complète. Afficher le texte au fil de l'eau réduit la latence perçue. Côté backend maison, la réponse arrive souvent en Server-Sent Events (lignes data: ...). On l'expose comme un Stream<String> derrière une interface, puis un Notifier Riverpod accumule les morceaux.
import 'dart:convert';
import 'package:dio/dio.dart';
abstract interface class AssistantApi {
Stream<String> ask(String question);
}
class HttpAssistantApi implements AssistantApi {
HttpAssistantApi(this._dio);
final Dio _dio;
@override
Stream<String> ask(String question) async* {
final response = await _dio.post<ResponseBody>(
'/assistant/ask',
data: {'question': question},
options: Options(responseType: ResponseType.stream),
);
final lines = response.data!.stream
.cast<List<int>>()
.transform(utf8.decoder)
.transform(const LineSplitter());
await for (final line in lines) {
if (line.startsWith('data: ')) yield line.substring(6);
}
}
}
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
sealed class AssistantState {
const AssistantState();
}
final class AssistantIdle extends AssistantState {
const AssistantIdle();
}
final class AssistantStreaming extends AssistantState {
const AssistantStreaming(this.text);
final String text;
}
final class AssistantDone extends AssistantState {
const AssistantDone(this.text);
final String text;
}
final class AssistantFailed extends AssistantState {
const AssistantFailed(this.message, {this.partial = ''});
final String message;
final String partial;
}
final assistantApiProvider = Provider<AssistantApi>(
(ref) => throw UnimplementedError('Surchargé dans main()'),
);
class AssistantController extends Notifier<AssistantState> {
StreamSubscription<String>? _subscription;
final _buffer = StringBuffer();
@override
AssistantState build() {
ref.onDispose(() => _subscription?.cancel());
return const AssistantIdle();
}
void ask(String question) {
_subscription?.cancel(); // une seule réponse en cours à la fois
_buffer.clear();
state = const AssistantStreaming('');
_subscription = ref
.read(assistantApiProvider)
.ask(question)
.timeout(const Duration(seconds: 20)) // délai maximal entre deux morceaux
.listen(
(chunk) {
_buffer.write(chunk);
state = AssistantStreaming(_buffer.toString());
},
onError: (Object error) {
state = AssistantFailed(
'La réponse n\'a pas pu être obtenue. Réessayez.',
partial: _buffer.toString(),
);
},
onDone: () => state = AssistantDone(_buffer.toString()),
cancelOnError: true,
);
}
void stop() {
_subscription?.cancel();
_subscription = null;
state = AssistantDone(_buffer.toString());
}
}
final assistantControllerProvider =
NotifierProvider<AssistantController, AssistantState>(AssistantController.new);
Dans le widget, un switch sur ref.watch(assistantControllerProvider) affiche le texte partiel, un bouton « Arrêter » pendant le streaming et un message d'erreur qui conserve la partie déjà reçue. L'interface AssistantApi se remplace par un faux dans les tests (un Stream.fromIterable de morceaux).
Coûts, erreurs, quotas, latence
- Coûts : facturation au nombre de tokens en entrée et en sortie. Limiter la taille du contexte envoyé, plafonner la longueur de réponse, mettre en cache les réponses à des questions identiques côté serveur, choisir un modèle léger pour les tâches simples (classification).
- Quotas : par utilisateur et global, appliqués côté serveur. Côté app, gérer le
429avec un message clair et un délai, pas une boucle de retry. - Erreurs : réseau coupé en plein streaming, réponse tronquée, contenu refusé par le filtre de sécurité, JSON invalide quand on attend une sortie structurée. Toujours valider la sortie avant de l'utiliser.
- Latence : streaming, indicateur de progression, annulation possible, et une alternative sans IA (formulaire classique) si le service est indisponible.
- Modération : filtres du fournisseur, plus des règles métier côté serveur. L'app ne doit jamais exécuter une action sensible (virement, changement de bénéficiaire) sur la seule base d'une sortie de modèle sans confirmation explicite de l'utilisateur.
- Confidentialité : informer l'utilisateur, minimiser les données envoyées (pas de numéro de compte complet, pas d'identité), vérifier les conditions de conservation et d'entraînement du fournisseur, et la localisation des données. Mettre à jour le privacy manifest iOS et la section Data safety de Google Play.
« Pour une fonctionnalité d'IA, je pars du principe que la sortie du modèle est une donnée non fiable, comme une saisie utilisateur. La clé reste côté serveur, les données envoyées sont minimisées, la sortie est validée avant usage, et aucune action financière ne part sans confirmation explicite. Côté app, je gère le streaming, l'annulation, le 429 et un mode dégradé sans IA. »
Inférence on-device
Faire tourner un petit modèle sur le téléphone supprime l'envoi de données et fonctionne hors ligne, au prix de la taille de l'app (téléchargement du modèle, souvent plusieurs centaines de Mo), de la batterie et d'une qualité moindre. Le package communautaire historique flutter_gemma a été renommé flutter_edge_ai en 2026 ; il s'appuie de préférence sur le runtime LiteRT-LM de Google (MediaPipe passant en maintenance). Le moteur et les noms de packages évoluent vite : vérifiez l'état sur pub.dev avant de le proposer à un client.
Flutter AI Toolkit, GenUI et Genkit
Flutter AI Toolkit (flutter_ai_toolkit, publié par labs.flutter.dev) fournit des widgets de chat prêts à l'emploi : LlmChatView, avec saisie texte, pièces jointes et voix. Il repose sur une interface de fournisseur abstraite ; un fournisseur Firebase AI est inclus, et l'on peut écrire le sien pour viser un backend maison.
GenUI SDK (package genui) va plus loin : au lieu de répondre par du texte, l'agent compose une interface à partir d'un catalogue de vos propres widgets (carrousel de produits, formulaire avec sélecteur de date), et les interactions de l'utilisateur lui sont renvoyées. Le format échangé suit le protocole ouvert A2UI (Agent to UI) : des messages JSON qui créent, mettent à jour ou suppriment des surfaces et des données, sans jamais envoyer de code exécutable. En Flutter 3.47, genui est en version 0.10 et s'appuie sur a2ui_core ; la documentation le présente comme expérimental (alpha) et susceptible de changer.
Genkit Dart est le portage Dart du framework Genkit : définir des flows typés (entrée, sortie, appels de modèles, outils), les tracer, les tester et les exposer en HTTP, côté serveur Dart ou dans une app. Annoncé en preview en 2026, le package genkit est passé en 1.0 sur pub.dev, avec certaines parties (agents, flux bidirectionnels) encore marquées expérimentales.
| Outil | Rôle | Maturité (oct. 2026) |
|---|---|---|
| Firebase AI Logic | Appeler un modèle depuis l'app sans clé exposée | Produit Firebase |
| Flutter AI Toolkit | Widgets de chat | 1.0 |
| GenUI + A2UI | UI générée à partir d'un catalogue de widgets | Alpha (0.10) |
| Genkit Dart | Flows d'IA typés côté serveur ou client | 1.0, parties expérimentales |
| flutter_edge_ai | Inférence on-device | Communautaire, évolue vite |
« Proposeriez-vous GenUI pour notre app bancaire ? » Répondre oui avec enthousiasme est une erreur. Réponse mesurée : intéressant pour un parcours d'assistance non critique, à condition de limiter le catalogue à des widgets sûrs et de ne jamais déclencher d'opération sans confirmation ; mais le package est en alpha, donc à réserver à un prototype tant que l'API n'est pas stabilisée.
Questions d'entretien
Pourquoi ne jamais embarquer une clé d'API de modèle dans l'app ?
Tout ce qui est dans le binaire est extractible, même obfusqué. Une clé volée permet de consommer le quota à vos frais et d'accéder au service sous votre identité. On passe par un backend qui détient la clé, ou par un service conçu pour mobile avec attestation de l'app (Firebase AI Logic et App Check).
À quoi sert App Check ?
À attester que la requête provient d'une instance authentique de votre app sur un appareil non compromis (Play Integrity, App Attest, reCAPTCHA sur le web). Cela réduit les abus des services backend. Ce n'est pas une authentification utilisateur : il faut toujours des quotas et une identité.
Comment afficheriez-vous une réponse de modèle en streaming avec Riverpod ?
Une source qui expose un Stream<String>, un Notifier qui s'abonne, accumule dans un buffer et publie un état scellé (en cours, terminé, échec avec texte partiel), annule l'abonnement dans ref.onDispose et lors d'une nouvelle question. Le widget fait un switch sur l'état. Un StreamProvider suffit si l'on n'a pas besoin d'annulation ni d'accumulation.
Comment maîtrisez-vous le coût d'une fonctionnalité d'IA ?
Quotas par utilisateur côté serveur, contexte et longueur de réponse limités, modèle léger pour les tâches simples, cache des réponses répétées, métriques de consommation et alertes. Côté app, éviter les appels déclenchés à chaque frappe (debounce, bouton explicite).
Qu'est-ce que le Dart and Flutter MCP server ?
Un serveur MCP fourni par le SDK Dart qui donne à un assistant l'accès à l'analyse statique, aux tests, à pub et pub.dev, et à l'app en cours d'exécution (hot reload, erreurs, inspection des widgets). L'assistant consulte l'état réel du projet au lieu de deviner. Depuis 3.44, il découvre les apps automatiquement et peut déclencher le hot reload.
Qu'est-ce que GenUI et A2UI ?
GenUI est un SDK Flutter qui laisse un agent composer l'interface à partir d'un catalogue de widgets fourni par l'app, et lui renvoie les interactions. A2UI est le protocole JSON déclaratif utilisé pour décrire ces surfaces et leurs données, sans code exécutable. Le package genui est en alpha (0.10 en 3.47).
Quand choisir l'inférence on-device ?
Quand les données ne doivent pas quitter l'appareil, quand l'usage hors ligne est nécessaire ou quand la latence réseau est gênante, pour des tâches à la portée d'un petit modèle (classification, extraction, résumé court). Contreparties : taille du modèle à télécharger, batterie, appareils anciens exclus, qualité inférieure.
Comment relisez-vous du code produit par un assistant ?
Comme un code de collègue, avec une attention particulière aux API inventées ou dépréciées, aux dépendances ajoutées, à la sécurité (certificats, secrets, logs), aux cas d'erreur avalés et aux tests complaisants. Analyse statique stricte, tests que j'ai vus échouer, et je dois pouvoir expliquer chaque ligne.
Un utilisateur demande à l'assistant intégré de faire un virement. Que faites-vous ?
Le modèle peut au mieux préremplir l'écran de virement existant. L'opération passe par le parcours normal : validation des champs, écran de confirmation, authentification forte, contrôles serveur. Une sortie de modèle n'est jamais une autorisation, et une injection de prompt ne doit pas pouvoir déclencher d'action.
Exercices
Rédigez vos deux exemples avec le canevas du chapitre : un gain mesuré, une erreur détectée. Critères : chacun tient en 60 à 90 secondes à l'oral, contient un chiffre vérifiable, ne cite aucun client par son nom, ne mentionne pas de code client envoyé vers un outil grand public, et se termine par une leçon.
Enregistrez-vous (audio ou vidéo) en répondant à « Utilisez-vous l'IA ? », « Et si c'est interdit chez nous ? » et « L'IA va-t-elle remplacer les développeurs mobiles ? ». Réécoutez. Critères : la règle vient en premier, aucune promesse de vitesse, pas de « euh » sur les trois premières phrases, moins de 90 secondes par réponse. Refaites la première en anglais.
Écrivez de mémoire le AssistantController et son test : un faux AssistantApi qui émet trois morceaux puis une erreur ; vérifiez la séquence d'états (en cours avec texte croissant, puis échec avec le texte partiel). Critères : ProviderContainer.test avec override, aucun appel réseau, abonnement annulé à la destruction du conteneur.
Demandez à un collègue ou reprenez un ancien extrait généré par un assistant. Listez au moins cinq points de revue avec la grille du chapitre (API, versions, sécurité, tests, sur-ingénierie). Critère : chaque point cite la documentation officielle qui le justifie.
Pas d'étape obligatoire pour ce chapitre. Si vous voulez aller plus loin dans l'app Wallet (voir le projet) : ajoutez au backend un endpoint qui catégorise une transaction (courses, transport, factures...) en appelant un service d'IA côté serveur, avec une catégorie par défaut si le service échoue. Côté app, affichez la catégorie dans le détail d'une transaction et permettez à l'utilisateur de la corriger. Critères : aucune clé dans l'app, aucune donnée d'identité envoyée au modèle (seulement libellé et montant), sortie validée contre une liste fermée de catégories, mode dégradé testé.
Quiz
12 questions. Corrigez, relisez les explications, refaites-le 48 h plus tard.
Pour aller plus loin
- Créer avec l'IA (documentation Flutter)
- Dart and Flutter MCP server
- Règles d'IA pour Flutter et Dart
- Firebase AI Logic et Firebase App Check
- firebase_ai sur pub.dev
- Flutter AI Toolkit
- GenUI SDK, genui, a2ui_core, protocole A2UI
- Genkit et genkit sur pub.dev
- flutter_edge_ai (ex flutter_gemma)
- OWASP MAS pour l'angle sécurité mobile