L’intégration de l’IA dans une application Symfony ne se limite plus à appeler un modèle depuis un service PHP.
Aujourd’hui, le vrai sujet est ailleurs : comment garder une architecture lisible, testable, observable et gouvernable quand l’IA commence à qualifier une donnée, récupérer du contexte, appeler des outils ou déléguer une tâche à un agent spécialisé ?
Pour illustrer ce sujet, prenons un cas concret : un copilote d’incident Symfony.
L’objectif n’est pas de remplacer une équipe d’astreinte, mais d’aider l’application à transformer un signal bruité en information exploitable : résumé, sévérité, service impacté, contexte utile, prochaine action et trace partageable.
Le cas pratique : un copilote d’incident
Imaginons qu’une application Symfony reçoive une alerte de production :
- Erreur 500
- Latence anormale
- Saturation CPU
- Webhook APM
- Post Mortems.
Le copilote doit alors suivre une chaîne assez naturelle :
-
- Qualifier le signal ;
- Identifier une route de traitement ;
- Récupérer du contexte ;
- Proposer une décision ;
- Appeler éventuellement un outil ;
- Déléguer à un spécialiste si nécessaire.
Cette progression est intéressante, car elle montre qu’on ne parle pas d’un seul “prompt”. On parle de plusieurs design patterns IA, chacun adapté à une responsabilité précise.
Pour construire un copilote IA robuste dans Symfony, on avance par étapes avec six patterns complémentaires :
- Structured outputs pour cadrer la sortie ;
- Prompt chaining pour découper le raisonnement ;
- Routing pour orienter le traitement ;
- RAG pour récupérer le bon contexte ;
- Tool use pour agir via des capacités contrôlées ;
- Multi-agent orchestration pour déléguer quand un spécialiste doit reprendre la main.
1. Structured outputs : produire un objet métier exploitable
Rôle : contraindre la réponse du modèle dans un schéma attendu, par exemple un objet typé ou un JSON validable, afin d’éviter le parsing fragile de texte libre.
Le besoin ici n’est pas de générer un texte élégant, le premier besoin est de produire une sortie utilisable par le code.
Dans un copilote d’incident, on veut par exemple récupérer :
- une sévérité
- un service impacté
- une prochaine action
- un niveau de confiance.
Un exemple simplifié pourrait ressembler à ceci :
L’intérêt est simple : l’application Symfony manipule un objet métier, pas une chaîne de caractères à parser avec des conditions fragiles.
Ce pattern permet de poser un premier garde-fou entre le modèle et le code applicatif.
2. Prompt chaining : découper le raisonnement
Rôle : découpe une tâche complexe en plusieurs appels successifs, où la sortie d’une étape devient l’entrée de la suivante, avec la possibilité d’ajouter validation, seuils de confiance ou fallback entre deux appels
Quand une tâche contient plusieurs étapes connues à l’avance, il est souvent préférable de les séparer.
Dans notre cas :
-
- Qualifier l’incident
- Enrichir avec du contexte
- Proposer une décision.
Chaque étape peut être testée, tracée et remplacée indépendamment. Voici un exemple :
Le modèle ne pilote pas seul le workflow.
C’est l’application Symfony qui garde la main sur l’enchaînement.
3. Routing workflow : choisir le bon traitement
Rôle : classe une demande ou un signal en amont pour l’envoyer vers le bon traitement : prompt spécialisé, handler métier, outil dédié, modèle différent ou agent expert.
Tous les incidents ne doivent pas suivre le même chemin.
Un incident de base de données, un problème réseau et un signal de sécurité n’ont pas les mêmes règles, les mêmes outils, ni forcément le même niveau d’urgence.
On peut donc router l’incident avant de le traiter :
Le modèle aide à classifier, mais Symfony garde le contrôle de l’exécution via un routeur, un handler, un workflow ou Messenger.
4. RAG : récupérer le bon contexte avant de répondre
Rôle : interroge un corpus externe, souvent via embeddings et recherche vectorielle, pour récupérer quelques documents pertinents qui seront injectés dans le contexte avant la génération.
À partir d’ici, le copilote ne peut plus se contenter du contenu de l’alerte.
Il doit retrouver du contexte utile :
- Runbooks
- Incidents similaires
- Post-mortems
- Statut courant du service
- Documentation interne.
C’est le rôle du Retrieval-Augmented Generation.
L’idée n’est pas de donner “plus de texte” au modèle, c’est de lui fournir un contexte court, sourcé et exploitable.
Le copilote peut ensuite utiliser ce contexte pour proposer une réponse plus factuelle.
Le point important est que le contexte devient traçable.
On peut savoir quelles sources ont été utilisées pour produire une décision.
5. Tool use : donner des capacités contrôlées au modèle
Rôle : expose des fonctions ou services applicatifs au modèle sous forme d’outils appelables, avec des paramètres structurés, tout en laissant l’application exécuter réellement l’action et contrôler les droits, erreurs et logs.
Le modèle ne doit pas seulement “dire” quoi faire.
Dans certains cas, il doit pouvoir demander une capacité externe.
Par exemple :
- Chercher un runbook
- Consulter le statut d’un service
- Retrouver des incidents proches
- Préparer un ticket
- Notifier une équipe.
Mais l’exécution doit rester côté Symfony. Grace a l’annotation #AsTool apporté par Syfony AI, c’est relativement simple :
Un Tool doit rester un contrat applicatif clair : petit, explicite, testable et limité.
Le modèle choisit une capacité, Symfony l’exécute réellement.
6. Multi-agent orchestration : déléguer sans perdre la gouvernance
Rôle : organise plusieurs agents spécialisés selon une stratégie explicite, par exemple manager, handoff ou orchestrator-workers, pour répartir les responsabilités sans concentrer tout le raisonnement dans un seul agent généraliste.
L’orchestration multi-agent n’est pas forcément le point de départ.
Elle devient utile quand un domaine doit vraiment reprendre la main : infrastructure, base de données, sécurité, support, etc.
Il faut alors distinguer plusieurs approches :
- Un agent manager qui garde la conversation et appelle des spécialistes comme outils ;
- Un handoff où un agent spécialisé devient responsable de la suite ;
- Un orchestrator-workers quand le travail doit être découpé dynamiquement.
Un exemple de configuration simplifiée peut ressembler à ceci :
Cette configuration rend la délégation explicite.
L’agent orchestrator reçoit l’incident et décide s’il peut le traiter directement ou s’il doit le transmettre à un spécialiste.
Le bloc handoffs liste les domaines vers lesquels il peut déléguer :
infrapour les problèmes de latence, CPU, disque ou réseau ;databasepour les deadlocks, slow queries ou problèmes de réplication ;securitypour les signaux d’intrusion, d’identifiants ou d’abus.
Le fallback sert de filet de sécurité : si l’incident est ambigu ou si la confiance est trop faible, il revient vers triage.
L’intérêt est de spécialiser le traitement sans créer un agent généraliste trop large.
Les routes sont visibles, limitées et donc plus faciles à gouverner.
Le point essentiel n’est pas d’avoir “plus d’agents” mais de rendre la délégation explicite.
Pourquoi Symfony est bien adapté à ce type d’intégration ?
Symfony est intéressant pour intégrer l’IA parce qu’il sait déjà séparer les responsabilités.
Avant même d’ajouter un modèle, une application Symfony dispose déjà de briques utiles :
- Services : isoler les appels IA dans des classes testables et réutilisables ;
- Configuration : changer de modèle, provider ou stratégie sans disperser les réglages dans le code ;
- Validation : contrôler les entrées, sorties structurées et paramètres d’outils avant exécution ;
- Messenger : déléguer les traitements IA longs ou coûteux en asynchrone via AMQP ;
- Événements : réagir proprement aux étapes du copilote sans coupler tout le workflow ;
- Profiler : comprendre ce que l’IA a appelé, combien de temps cela a pris et où ça bloque ;
- Tests : sécuriser les prompts, les handlers, les tools et les fallbacks ;
- Logs : tracer les décisions, sources récupérées, erreurs et appels d’outils ;
- Workers : exécuter le retrieval, les appels modèle ou les actions longues hors requête HTTP.
Symfony AI s’inscrit dans cette logique.
Platform permet d’abstraire les fournisseurs et les modèles.
Agent apporte les tools, le RAG et les processors.
Store permet de travailler avec des vector stores et des retrievers.
AI Bundle ramène ces briques dans l’écosystème Symfony avec la configuration, le profiler et l’orchestration.
Le vrai intérêt est de garder une architecture Symfony quand tout en ajoutant de l’IA au sein de son application.
Conclusion
Un copilote d’incident est un bon exemple pour comprendre les design patterns IA dans Symfony.
On part d’un signal bruité.
On le qualifie.
On le route.
On récupère du contexte.
On appelle des capacités contrôlées.
On délègue uniquement quand le besoin le justifie.
La progression est ainsi volontaire :
-
-
- Structured Outputs
- Prompt Chaining
- Routing
- RAG
- Tool Use
- Multi-agent orchestration.
-
Ces patterns ne sont pas des mots à la mode.
Ce sont des niveaux de responsabilité dans l’architecture.
Le bon réflexe n’est donc pas de commencer par l’agent le plus ambitieux.
C’est de choisir le pattern minimal suffisant, au bon endroit du workflow.
Symfony ne rend pas l’IA magique, il la rend intégrable.
Sources
https://symfony.com/doc/current/ai/
https://symfony.com/doc/current/ai/components/platform.html
https://symfony.com/doc/current/ai/components/agent.html
https://symfony.com/doc/current/ai/components/store.html
https://symfony.com/doc/current/ai/bundles/ai-bundle.html
https://symfony.com/doc/current/messenger.html
https://symfony.com/doc/current/workflow.html
https://www.anthropic.com/engineering/building-effective-agents
https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/chain-prompts
https://platform.openai.com/docs/guides/structured-outputs
https://platform.openai.com/docs/guides/function-calling
https://openai.github.io/openai-agents-js/guides/multi-agent/
https://openai.github.io/openai-agents-js/guides/handoffs/
https://arxiv.org/abs/2005.11401
https://www.anthropic.com/engineering/contextual-retrieval
