Un agent Utility-based qui transforme n'importe quel texte source en 4 formats plateforme optimisés (Facebook, LinkedIn, Instagram, YouTube) avec évaluation par fonction d'utilité, suggestions d'images, et dashboard temps réel.
Formats d'intégration : API REST (SSE streaming), CLI, Dashboard web temps réel.
flowchart TD
subgraph "Entrée"
TEXT[Texte source<br/>ou URL]
BRAND[Profil de marque]
end
subgraph "Supervisor Agent"
ANALYSE[Analyse source<br/>Gemini]
FORK[Spawn 4 agents]
end
subgraph "Format Agents"
FB[Agent Facebook]
LI[Agent LinkedIn]
IG[Agent Instagram]
YT[Agent YouTube]
end
subgraph "Évaluation"
UTIL[Fonction d'utilité<br/>calculerUtilite]
EVAL[Évaluateur<br/>Gemini]
end
subgraph "Sortie"
SSE[SSE streaming<br/>temps réel]
CLI[Terminal]
DASH[Dashboard React]
end
TEXT --> ANALYSE
BRAND --> ANALYSE
ANALYSE --> FORK
FORK --> FB & LI & IG & YT
FB & LI & IG & YT --> EVAL
EVAL --> UTIL
UTIL --> SSE
SSE --> DASH
UTIL --> CLI
# CLI
npx tsx src/index.ts --text-file article.txt --profile brand.json
# API (SSE streaming)
curl -X POST http://localhost:3001/api/pipeline \
-H "Content-Type: application/json" \
-d '{"text": "Notre startup a développé...", "profile": {...}}'Le Supervisor Agent appelle Gemini 2.5 Flash pour extraire du texte source :
- Sujet : le thème central
- Concepts clés : les idées principales
- Ton : le registre (informatif, passionné, expert...)
- Arguments : les points de discussion
- Public cible : l'audience visée
Chaque agent spécialisé reçoit l'analyse et le profil de marque, puis génère un contenu optimisé pour sa plateforme :
| Agent | Format | Cible | Ton |
|---|---|---|---|
| Post conversationnel (≤150 mots) | Grand public | Émotionnel, engagement | |
| Post professionnel (≤250 mots) | Décideurs | Expert, crédible | |
| Légende courte (≤100 mots) | Visuel | Percutant, hashtags | |
| YouTube | Script structuré (hook + body + CTA) | Abonnés | Dynamique, rythmé |
Chaque contenu est noté par Gemini sur 3 critères spécifiques à son format (poids selon format) :
U = Σ(w_i × f_i(x))
facebook = 0.35×accroche + 0.35×ton + 0.30×concision
linkedin = 0.35×crédibilité + 0.35×structure + 0.30×valeur
instagram = 0.35×concision + 0.30×hashtags + 0.35×viral
youtube = 0.35×hook + 0.30×structure + 0.35×rythme
Le score final intègre :
- Moyenne pondérée des critères
- Bonus angle (+0.5 si le profil de marque a un angle défini)
- Capping à 10
Si une clé OpenAI est configurée, l'image-suggester propose une description d'image pertinente pour chaque format. Sinon, suggestion vide.
Le pipeline envoie des événements temps réel :
event: analysis → analyse source (sujet, concepts, ton)
event: progress → statut par format (generating / evaluating / done)
event: complete → tous les résultats + analyse
event: error → erreur avec message
| Couche | Technologie | Usage |
|---|---|---|
| Runtime | Node.js 22 + tsx | Serveur API zéro dépendance |
| Provider analyse | Gemini 2.5 Flash | Extraction source + évaluation qualité |
| Provider génération | OpenAI GPT-4o Mini | Génération contenu + suggestions image |
| Scoring | Fonction d'utilité maison | U = Σ(w × f(x)) avec bonus angle |
| API | node:http (zéro framework) | REST + SSE streaming |
| Dashboard | React 19 + Vite + TypeScript 6 | Interface temps réel amber/teal |
| Tests | Vitest 4 (12 tests) | Utility, extractJson, constants |
| Infrastructure | Docker + Docker Compose | Build multi-stage, conteneur API |
| CI/CD | GitHub Actions | Build → Test → Docker |
# 1. Cloner le projet
git clone https://github.com/lewenbach228/MAS---MultiAgent-ContentPipeline.git
cd MAS---MultiAgent-ContentPipeline/agents/p4-content
# 2. Variables d'environnement
cp .env.example .env
# Éditer .env avec vos clés :
# GEMINI_KEY=... (obligatoire — analyse + évaluation)
# OPENAI_KEY=... (optionnel — génération + images)
# 3. Démarrer l'API
npm start
# 4. Tester
curl http://localhost:3001/api/health
# → {"status": "ok", "version": "1.3"}
# 5. Lancer le pipeline
curl -X POST http://localhost:3001/api/pipeline \
-H "Content-Type: application/json" \
-d '{"text": "Notre startup a développé une IA qui..."}'
# 6. Dashboard (dans un autre terminal)
cd dashboard && npm run dev
# → http://localhost:5173# CLI alternative
npx tsx src/index.ts --text-file texte-exemple.txt --profile brand.example.json| Compétence | Comment |
|---|---|
| Utility function formelle | U = Σ(w × f(x)) avec 3 critères par format, bonus angle, capping |
| Multi-agent supervisor | 1 supervisor décompose → 4 agents spécialisés exécutent en parallèle |
| Multi-provider IA | Gemini (analyse + évaluation) + OpenAI (génération + images) |
| Format-specific scoring | Chaque plateforme a ses propres critères et poids |
| SSE streaming temps réel | Événements analysis/progress/complete au fur et à mesure |
| API node:http zéro dépendance | Pas de framework, SSE + CORS + JSON natifs |
| Agent avec feedback loop | Évaluation → utility score → le score pilote le tri |
| Dashboard React temps réel | EventSource client, barre de progression live |
| Walking Skeleton | Script zéro infra validé avant toute infrastructure |
- TypeScript 6, Node.js 22, React 19, Vite
- Gemini 2.5 Flash API, OpenAI GPT-4o Mini API
- node:http (SSE, REST), Vitest
- Docker, Docker Compose, GitHub Actions
- Programmation asynchrone, Stream I/O
| Pattern | Où |
|---|---|
| Utility-based agent | Fonction calculerUtilite + evaluerContenu |
| Supervisor / Workers | supervisor.ts → 4 agents format |
| Multi-provider routing | Gemini pour analyse/éval, OpenAI pour génération |
| Event-driven streaming | SSE events : analysis → progress → complete |
| Zero-dep server | 100% Node.js stdlib, pas de framework |
| Pipeline parallèle | Promise.all sur les 4 agents |
| Feedback loop | Génération → évaluation → utility score |
npm test # 12 tests (vitest)
npm test -- --watch # mode watch| Fichier | Tests | Couvre |
|---|---|---|
tests/utility.test.ts |
5 | Calcul utility, bonus angle, capping, edge cases |
tests/extract-json.test.ts |
6 | Extraction JSON, markdown, malformed, braces |
tests/constants.test.ts |
10 | Formats, critères, poids, labels, UTILITY_WEIGHTS |
Lance le pipeline complet. Retourne un flux SSE.
Body :
{
"text": "string (obligatoire)",
"profile": "BrandProfile (optionnel, défaut: brand.example.json)"
}Événements SSE :
event: analysis
data: {"sujet": "...", "concepts_cles": [...], "ton": "...", ...}
event: progress
data: {"format": "facebook", "status": "generating"|"evaluating"|"done", "moyenne": 8.5}
event: complete
data: {"analyse": {...}, "results": [{format, contenu, moyenne, scores, ...}]}
event: error
data: {"message": "..."}
{"status": "ok", "version": "1.3"}{"profiles": [{...brand profile}]}