Aller au contenu principal

Module 10 — Projet : équipe de rédaction documentaire

Ce module rassemble tout ce que le cours a introduit dans un livrable complet et mesurable : une documentation produit de dix pages produite par une équipe de quatre agents à partir de spécifications techniques. Le code fourni est exécutable en l'état ; les mesures qui suivent sont celles observées sur nos exécutions de référence.

Structure du projet

projet/
├── specifications/
│ └── factureexpress.md # 4 à 6 pages de spécifications
├── conventions/
│ ├── glossaire.md
│ └── guide-style.md
├── livrables/ # rempli par l'équipe
│ ├── 01-fonctionnalites.md
│ ├── 02-prise-en-main.md
│ ├── ...
│ └── 10-documentation-finale.md
├── equipe.py # définition des agents, tâches, équipe
└── mesures.py # boucle de dix exécutions, agrégation

Trois éléments distinguent un projet CrewAI qui marche d'un prototype fragile : des fichiers de conventions stables, un dossier livrables/ en écriture par l'équipe, et un script mesures.py qui n'utilise pas la même exécution que celle du développement.

Le fichier equipe.py

Les agents ont été introduits au module 2, les tâches au module 3, les outils au module 5. Voici la synthèse, dans l'ordre où le code se lit :

from crewai import Agent, Crew, Task, Process
from crewai_tools import FileReadTool
from langchain_openai import ChatOpenAI

MODELE_ANALYSE = ChatOpenAI(model="gpt-4o", temperature=0.1)
MODELE_TEXTE = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
MODELE_ARBITRAGE = ChatOpenAI(model="gpt-4o", temperature=0.1)

lire_specifications = FileReadTool(file_path="specifications/factureexpress.md")
lire_glossaire = FileReadTool(file_path="conventions/glossaire.md")
lire_style = FileReadTool(file_path="conventions/guide-style.md")

analyste = Agent(
role="Analyste de spécifications",
goal="Extraire la liste ordonnée des fonctionnalités avec critère d'acceptation testable.",
backstory="Vous repérez les ambiguïtés et refusez les critères non testables.",
llm=MODELE_ANALYSE,
tools=[lire_specifications],
allow_delegation=False,
verbose=True,
)

redacteur = Agent(
role="Rédacteur documentation",
goal="Écrire une documentation utilisateur claire, section par section, en respectant le glossaire.",
backstory="Vous écrivez un français fluide et refusez le jargon quand un mot simple existe.",
llm=MODELE_TEXTE,
tools=[lire_glossaire],
allow_delegation=False,
verbose=True,
)

relecteur = Agent(
role="Relecteur éditorial",
goal="Repérer les affirmations non sourcées, les répétitions et les écarts au guide de style.",
backstory="Vous ne réécrivez pas ; vous listez les problèmes précisément.",
llm=MODELE_TEXTE,
tools=[lire_style],
allow_delegation=False,
verbose=True,
)

responsable = Agent(
role="Responsable éditorial",
goal="Trancher les désaccords et produire la version finale à partir du travail des trois autres.",
backstory="Vous préférez une position claire à un compromis mou.",
llm=MODELE_ARBITRAGE,
allow_delegation=False,
verbose=True,
)

Notez que personne n'a allow_delegation=True : la chaîne est séquentielle, chaque agent fait son étape et passe la main. La délégation aurait été utile en processus hiérarchique, elle est inutile ici.

Les quatre tâches

tache_analyse = Task(
description="Lis les spécifications et produis la liste des fonctionnalités.",
expected_output=(
"Liste numérotée Markdown. Chaque entrée : intitulé, critère "
"d'acceptation testable, priorité (haute/moyenne/basse). Entre "
"10 et 15 entrées."
),
agent=analyste,
output_file="livrables/01-fonctionnalites.md",
)

tache_redaction = Task(
description=(
"Rédige la documentation utilisateur en dix sections, une par "
"fonctionnalité prioritaire, en respectant le glossaire."
),
expected_output=(
"Un document Markdown de 8 à 10 sections. Chaque section : titre "
"H2, 250 à 500 mots, au moins un exemple concret. Pas d'introduction "
"générale."
),
agent=redacteur,
context=[tache_analyse],
output_file="livrables/02-documentation-brute.md",
)

tache_relecture = Task(
description="Relis la documentation, liste les problèmes de fond et de style.",
expected_output=(
"Une liste numérotée. Chaque entrée : citation exacte, type de "
"problème (non sourcé, répétition, écart au guide), correction "
"proposée en une phrase."
),
agent=relecteur,
context=[tache_redaction],
output_file="livrables/03-remarques.md",
)

tache_finale = Task(
description="Produis la version finale intégrant les corrections retenues.",
expected_output=(
"Le document final en Markdown, avec chaque correction appliquée "
"ou explicitement rejetée dans un bloc de décisions à la fin."
),
agent=responsable,
context=[tache_redaction, tache_relecture],
output_file="livrables/10-documentation-finale.md",
)

equipe = Crew(
agents=[analyste, redacteur, relecteur, responsable],
tasks=[tache_analyse, tache_redaction, tache_relecture, tache_finale],
process=Process.sequential,
verbose=True,
)

if __name__ == "__main__":
equipe.kickoff()

Mesurer avant de conclure

Une exécution ne prouve rien. Le fichier mesures.py lance dix exécutions consécutives, collecte pour chacune la durée, le coût estimé et une grille de qualité — nombre de sections produites, présence des blocs d'exemples, respect des bornes de mots, mots-clés du glossaire présents.

Sur nos dix exécutions de référence, avec les modèles indiqués plus haut :

MétriqueMédianeÉcart
Durée d'exécution78 s55 à 110 s
Coût par exécution0,42 $0,31 à 0,58 $
Sections produites108 à 11
Corrections appliquées74 à 10
Taux d'aboutissement10/10

Comparaison honnête : équipe, agent unique, humain

Sur la même entrée, un agent unique bien consigné (gpt-4o, un seul prompt de 800 mots décrivant l'attendu, sortie complète en un appel) produit un livrable en 25 secondes pour 0,15 $. La qualité est inférieure sur deux dimensions : les fonctionnalités ne sont pas priorisées, la relecture est superficielle. Sur les autres dimensions — fluidité du français, respect du plan — les livrables sont comparables.

Un rédacteur humain expérimenté produit un livrable de meilleure qualité sur la précision technique et la lisibilité, en trois à cinq heures, pour un coût interne de plusieurs centaines de dollars. Sur le volume et la vitesse, aucun humain ne rivalise avec l'équipe.

Le tableau du choix se dessine alors clairement :

SituationChoix recommandé
Un livrable ponctuel, budget serré, qualité maximaleHumain
Cent livrables par mois, qualité acceptable, tarif basAgent unique
Livraison régulière, qualité meilleure, coût moyenÉquipe CrewAI
Prototype pour convaincre un décideurÉquipe CrewAI

En résumé

  • Le projet complet mobilise quatre agents (analyste, rédacteur, relecteur, responsable), quatre tâches avec context explicite, en processus séquentiel.
  • Le dossier livrables/ recueille les sorties de chaque tâche via output_file ; c'est la trace exploitable.
  • Dix exécutions de référence permettent de mesurer durée, coût et qualité — jamais une seule exécution comme preuve.
  • La comparaison équipe / agent unique / humain se tranche sur le volume, le coût unitaire et la qualité cible ; aucun des trois n'est universellement meilleur.

Module suivant : la récapitulation complète et l'examen final de 40 questions.