Aller au contenu

Choisir sa solution

Point de théorie · semaine 2 · à appliquer sur votre projet 2 avant la revue d'avancement n°1

Slides du cours

Le chapitre précédent a posé les mots. Reste à choisir quoi installer dans votre projet, cette semaine, sans y passer trois soirées. Ce chapitre classe les solutions en trois familles, vous donne deux options par stack, dit où ranger les conversations, et règle les quelques détails d'OpenRouter qui font varier votre facture.

À la fin de ce chapitre, vous serez capables de :

  1. classer une solution d'agent dans l'une des trois familles ;
  2. choisir une solution adaptée à votre stack, et lister ce qu'il vous restera à écrire ;
  3. régler un appel à OpenRouter : modèle, fournisseur, raisonnement, plafond de jetons ;
  4. éviter les six pièges les plus courants d'une application IA.

Le paysage bouge chaque semaine. Les versions citées sont celles du 4 novembre 2026 : vérifiez la dernière au moment d'installer.

1. Trois familles de solutions

Trois familles : les harness utilisables depuis votre code, les SDK d'agents, les harness des grands laboratoires d'IA

Famille Ce qu'elle apporte Pour le projet 2
Les harness utilisables depuis votre code (pi, OpenCode) Un agent complet, boucle, sessions et skills compris, que votre serveur appelle comme une bibliothèque Une voie possible pour un groupe à l'aise en JavaScript
Les SDK d'agents (laravel/ai, Vercel AI SDK, OpenAI Agents SDK, PydanticAI) Une bibliothèque dans votre code : boucle d'outils, sortie structurée, approbation, parfois les conversations en base et un faux fournisseur Le choix conseillé
Les harness des grands laboratoires (Claude Code, Codex) Les agents les plus capables, pilotables en ligne de commande En démonstration seulement

Famille 1 : les harness utilisables depuis votre code

Un harness de programmation se lance d'habitude dans un terminal. Certains proposent aussi un usage programmatique : votre serveur les importe comme une bibliothèque, par un SDK, ou les pilote comme un service, par une API HTTP. Vous leur retirez alors leurs outils de lecture, d'écriture et de shell, vous remplacez leur prompt système d'agent de code par le vôtre, et vous leur donnez vos outils.

pi (licence MIT, TypeScript) offre un tel SDK. Il tourne dans votre processus Node et accepte vos outils et votre prompt. Le jeu présenté en cours est construit ainsi, dans un serveur Nuxt. OpenCode et Hermes Agent se pilotent par HTTP, mais restent centrés sur un dossier de code. Goose et OpenClaw sont à connaître, pas à intégrer dans une application web d'étudiants.

Famille 2 : les SDK d'agents

Un SDK d'agent est une bibliothèque que vous importez dans votre serveur. C'est la famille faite pour votre cas.

  • laravel/ai (le Laravel AI SDK, pour Laravel 12 ou 13) est le plus complet : classe d'agent, outils, sortie structurée validée, conversations enregistrées en base sans code, approbation des outils, et Agent::fake() pour les tests. OpenRouter est un fournisseur natif.
  • Vercel AI SDK (paquet ai, version 7) : boucle d'outils, sortie structurée, approbation, et useChat pour Vue. OpenRouter passe par le paquet @openrouter/ai-sdk-provider. Les conversations sont à stocker vous-même.
  • En Python : OpenAI Agents SDK, PydanticAI (la sortie structurée est son cœur) ou Google ADK. Vérifiez la connexion à OpenRouter dans la documentation avant de choisir.
  • En PHP sans Laravel : Prism, sans persistance, ou Neuron AI.

OpenRouter a sorti son propre SDK d'agent la veille de ce chapitre : trop neuf pour y bâtir un projet. Le Claude Agent SDK exige une clé Anthropic et sort du budget OpenRouter.

Famille 3 : les harness des grands laboratoires

Claude Code et Codex s'appellent sans interface, en ligne de commande, et savent rendre un JSON. C'est spectaculaire en démonstration, et le professeur vous le montrera. Comme architecture de produit, c'est une mauvaise idée : un processus lancé à chaque requête, un agent qui a par défaut le shell et les fichiers de votre serveur, une facture que vous plafonnez mal. Surtout, l'usage derrière un produit se paie à l'API : jamais votre abonnement personnel, Anthropic l'interdit et OpenAI le déconseille. Dans le projet 2, ces harness servent à programmer votre application, au cours du 17 novembre.

Les frontières entre les familles s'effacent déjà. Retenez la question à poser à chaque solution : qui fait tourner la boucle, et où vivent les conversations ?

2. Choisir selon votre stack

Votre stack est déjà validée par le professeur. Voici deux options pour chacune, et ce qu'il vous restera à écrire.

Stack Option 1 Option 2 Ce que vous écrivez vous-même
PHP, Laravel laravel/ai Prism Le journal (O4) et les quotas. Avec Prism, aussi les tables de conversation
JavaScript ou TypeScript (Nuxt, Next, Express) Vercel AI SDK et @openrouter/ai-sdk-provider pi par son SDK, sans ses outils de code Les tables de conversation, le journal, les quotas
Python (Django, FastAPI) OpenAI Agents SDK PydanticAI ou Google ADK Le journal et les quotas, et la persistance selon le SDK

L'API brute reste permise. Si votre fonctionnalité IA est un seul appel qui rend un JSON, sans outil ni conversation, un client HTTP et un schéma suffisent, et vous écrivez la validation, le journal et le faux fournisseur vous-même. Pour une autre stack, parlez-en au professeur sur Teams avant d'installer quoi que ce soit. Et un seul SDK par projet : deux bibliothèques d'agent, c'est deux façons de stocker les messages et deux journaux à réconcilier.

3. Deux applications montrées en cours

Le professeur a préparé deux POC (proof of concept, une petite application qui montre qu'une idée marche), un par famille conseillée. Le chapitre suivant les détaille, code et journal à l'appui.

L'expédition Le gîte
Famille Harness utilisé depuis le code (pi par son SDK) SDK d'agent (laravel/ai)
Stack Nuxt, SQLite Laravel, SQLite
Ce que fait le modèle Écrit le scénario, les événements et les répliques d'un personnage Rédige une réponse à un voyageur et en extrait une demande de réservation
Ce que fait le code Applique les règles du jeu, borne les effets, plafonne la dépense Recalcule prix et disponibilité, attend le clic du propriétaire avant d'envoyer

4. La persistance

Un seul fichier SQLite dans un volume persistant : conversations, messages, journal, entités métier

Pour un binôme, un serveur et quelques dizaines d'utilisateurs, SQLite suffit : un fichier, aucun service en plus, des transactions, et une sauvegarde par copie du fichier. Si votre projet tourne déjà sur MySQL ou PostgreSQL, gardez-les. Les tables sont les mêmes.

Avec laravel/ai, deux commandes créent les tables de conversations et de messages, et un trait recharge l'historique avant chaque prompt. Avec les autres SDK, vous les écrivez vous-même : une table de conversations liée à l'utilisateur, une table de messages, et votre journal des appels. Supprimer un compte supprime ses conversations (O7). Le journal garde ses lignes sans l'utilisateur, pour vos totaux.

Attention

Trois pièges de persistance. Un volume oublié dans Coolify, et toutes les conversations disparaissent au déploiement suivant. SQLite suppose un seul serveur. Et l'identifiant d'une conversation ne vient jamais de l'URL ni du prompt : il est en base, lié à l'utilisateur, et le serveur vérifie l'appartenance (O3).

5. OpenRouter en pratique

Les deux modèles conseillés

DeepSeek V4.1 Flash GPT-6 Luna
Identifiant deepseek/deepseek-v4.1-flash openai/gpt-6-luna
Prix catalogue, en $ par million de jetons 0,045 en entrée, 0,50 en sortie 0,10 en entrée, 0,50 en sortie
Entrées texte, image texte, image, fichier
Outils et sortie structurée dans la même requête non : en laboratoire, le modèle n'a jamais appelé son outil oui
Raisonnement réglable oui oui

Au catalogue, DeepSeek V4.1 Flash est le moins cher. À l'usage, ce n'est pas sûr : il compte deux fois plus de jetons que Luna pour la même requête, et trois événements du jeu ont coûté moins cher avec Luna. Mesurez avec votre propre prompt avant de choisir. Les variantes gratuites :free d'autres modèles ont une limite partagée entre toutes les clés du professeur, et beaucoup refusent les sorties structurées : bien pour un essai, jamais en démonstration (énoncé, § 5).

Le fournisseur change le prix et la conservation des données

Derrière un même identifiant de modèle, OpenRouter choisit un fournisseur, et le prix peut tripler de l'un à l'autre. Le champ provider de la requête restreint ce choix.

Il sert aussi à autre chose. Certains fournisseurs gardent vos prompts quelques jours pour détecter les abus, d'autres s'en servent pour entraîner leurs modèles, d'autres ne conservent rien une fois la réponse renvoyée. Cette dernière garantie s'appelle la ZDR (zero data retention). Avec "zdr": true, OpenRouter n'envoie votre requête qu'à un fournisseur qui s'y engage, et "data_collection": "deny" écarte en plus ceux qui exploitent les données. Ces options servent quand vos utilisateurs écrivent des données personnelles, des messages de clients ou des documents. Votre politique de confidentialité peut alors dire que les fournisseurs ne gardent rien. En contrepartie, la liste des fournisseurs se réduit, ce qui peut changer le prix, la vitesse ou la prise en charge des sorties structurées, et certains modèles n'ont aucun fournisseur ZDR.

Rien ne vous oblige à l'activer. Un jeu qui ne reçoit que des répliques inventées peut s'en passer. Une application qui reçoit les messages de vrais clients a de bonnes raisons de la choisir. Chaque groupe décide pour son projet, écrit son choix et sa raison dans le rapport, et compare le coût par appel dans son journal avant et après.

Une requête réglée

Voici le corps d'une requête à chat/completions, schématique. Les … sont à remplir, les noms de champs sont ceux de la documentation d'OpenRouter.

{
  "model": "openai/gpt-6-luna",
  "messages": [ … ],
  "tools": [ … ],
  "response_format": { "type": "json_schema", "json_schema": { … } },
  "reasoning_effort": "low",
  "max_tokens": 800,
  "provider": { "zdr": true, "data_collection": "deny" }
}
  • model : GPT-6 Luna, parce que la requête combine des outils et une sortie structurée.
  • reasoning_effort bas : le raisonnement est facturé comme de la sortie, et un devis n'en demande pas beaucoup.
  • max_tokens : un plafond par appel, votre première protection contre une réponse qui s'emballe.
  • provider : seulement si vous avez choisi la ZDR.

Votre SDK expose ces réglages sous ses propres noms : cherchez-les dans sa documentation. Dans la réponse, le champ usage donne les jetons et le coût facturé.

Pour l'ordre de grandeur, une conversation du garagiste coûte 0,000567 $ avec Luna, soit plus de 1 700 conversations pour un dollar, développement compris. Avec le fournisseur courant de DeepSeek, trois fois plus cher que le catalogue, le même dollar paie trois fois moins d'appels.

6. Six pièges, six parades

Piège Ce qui arrive La parade
Laisser le modèle calculer Un total faux une fois sur cent, un quota contourné, une date inventée Le modèle propose des valeurs. Votre code calcule, compare, arrondit, avec les données de la base
Un prompt système trop long Il est renvoyé à chaque appel : 2 000 jetons de consignes, c'est 2 000 jetons payés à chaque tour Des consignes courtes et stables, que le cache du fournisseur rend moins chères
Une boucle d'outils sans limite Le modèle rappelle le même outil en boucle et vide le crédit du groupe en une soirée Un plafond d'étapes, un plafond de jetons, un quota par utilisateur
Pas de délai Un fournisseur lent bloque la requête, l'utilisateur recharge, et vous payez deux fois Un délai par appel, un message clair, la saisie conservée (O5)
Pas de faux fournisseur Chaque test coûte, et les quatre cas d'erreur de O5 sont impossibles à montrer Agent::fake() dans laravel/ai, une fausse session pi, ou un faux client derrière une interface dans votre code
Des secrets dans le dépôt La clé OpenRouter est publiée sur GitHub et utilisée par d'autres Une variable d'environnement, un .env.example sans valeur, et la clé révoquée au moindre doute

Astuce

Le faux fournisseur est aussi votre meilleur outil de démonstration pour O5 : un réglage de l'administrateur le branche à la place du vrai, et les quatre cas (délai dépassé, panne, crédit épuisé, réponse inexploitable) se montrent à la demande.

7. Décider en quinze minutes

Complétez cette liste en binôme et notez vos réponses dans votre cahier des charges. Elle reprend aussi les trois étapes de la semaine du chapitre précédent.

  • Phrase O1 : ce que le modèle produit (Y) et ce que votre code en fait (Z) sont séparés
  • Famille et solution : le nom du paquet, sa version du jour, et la page de sa documentation qui explique la connexion à OpenRouter
  • Outils : la liste, et pour chacun : lit-il ou agit-il ? Ceux qui agissent passent par un brouillon ou une approbation
  • Persistance : où vivent les conversations, et dans quel volume
  • Modèle : DeepSeek V4.1 Flash ou GPT-6 Luna, ou un autre que vous justifiez, testé avec votre combinaison d'outils et de sortie structurée
  • Fournisseur : ZDR ou non, et pourquoi
  • Secrets : la clé OpenRouter dans une variable d'environnement, jamais dans le dépôt ni dans le navigateur
  • Journal : la table de O4 existe, et chaque requête au modèle, réussie ou ratée, y écrit une ligne avec le coût facturé
  • Budget et tests : le coût estimé d'une action type, le plafond d'étapes et de jetons, et comment vous remplacez le vrai modèle dans vos tests

Le livrable avant la revue n°1

Un appel réel au modèle, depuis votre serveur en production, journalisé. Une route de votre application appelle OpenRouter avec la solution choisie, affiche une sortie validée, et écrit une ligne dans le journal avec les jetons, le coût, la durée et le succès. Une capture du journal entre dans votre rapport d'avancement. Le 24 novembre, le professeur vous demandera de déclencher l'appel en direct et d'ouvrir le journal juste après.

En résumé

  • Trois familles. Les SDK d'agents sont le choix conseillé. Certains harness, comme pi, s'utilisent depuis votre code par leur SDK. Claude Code et Codex restent en démonstration.
  • Votre stack décide. Laravel : laravel/ai. JavaScript : le Vercel AI SDK, ou pi. Python : OpenAI Agents SDK, PydanticAI ou ADK.
  • SQLite suffit pour les conversations, les messages et le journal, dans un volume persistant.
  • Le fournisseur compte autant que le modèle : il change le prix, la conservation des données et la prise en charge des sorties structurées. La ZDR est un choix de votre groupe.
  • Plafonnez tout : étapes, jetons, durée, quotas. Et gardez un faux fournisseur pour vos tests et vos démonstrations d'erreur.

Quelle famille de solutions est conseillée pour le projet 2 ?

Les SDK d'agents : une bibliothèque dans votre serveur, qui fournit la boucle d'outils, la sortie structurée et souvent l'approbation et le faux fournisseur.

Un harness de programmation peut-il servir dans votre application ?

Oui, quand il offre un usage programmatique, comme le SDK de pi : votre serveur l'appelle comme une bibliothèque, avec votre prompt et vos outils.

Pourquoi ne pas faire tourner Claude Code ou Codex derrière votre produit ?

Un processus par requête, des outils shell à enfermer, un coût difficile à plafonner, et jamais un abonnement personnel derrière un produit.

Qu'est-ce que la ZDR ?

La garantie qu'un fournisseur ne conserve rien après avoir renvoyé la réponse. Elle s'active par le champ provider, réduit le choix des fournisseurs, et chaque groupe décide s'il en a besoin.

Pourquoi tester un outil et une sortie structurée ensemble, dès le premier jour ?

Parce que chaque capacité peut marcher seule et échouer combinée : en laboratoire, DeepSeek V4.1 Flash n'a jamais appelé son outil sous sortie structurée, GPT-6 Luna oui.

Quel est le livrable attendu avant la revue n°1 ?

Un appel réel au modèle, depuis votre serveur en production, avec une ligne dans le journal des appels.

Pour aller plus loin

Sources des versions, des prix et des mesures

Dépôts, registres de paquets, documentation des éditeurs et API publique d'OpenRouter consultés le 4 novembre 2026. Coûts et comportements mesurés le même jour en laboratoire. Vérifiez les versions et les prix avant d'installer et avant de calculer vos tarifs.