Rédaction IA dans Strapi : génération LLM et validation humaine
Découvrez pas à pas comment intégrer un LLM dans Strapi, stocker les brouillons IA, exploiter le plugin Revisionary pour le versioning et créer un pipeline de validation qui garantit la sécurité et la conformité du contenu.
Par l’équipe Revisionary · · 5 min de lecture
AI peut rédiger les premières ébauches en quelques secondes, mais la publication nécessite toujours l’œil humain. Dans Strapi, vous pouvez combiner un point d’accès LLM, le plugin Revisionary et les fonctionnalités de révision natives de Strapi pour créer un pipeline complet de rédaction : le LLM écrit un brouillon, Revisionary enregistre chaque modification, les éditeurs approuvent ou rejettent, et l’article final est publié avec une traçabilité totale.
Pourquoi un pipeline de rédaction assisté par IA est important
- Vitesse : générer des plans, des méta‑données ou des articles complets en quelques millisecondes.
- Cohérence : centraliser les modèles de prompts afin que la voix de la marque reste uniforme.
- Gouvernance : conserver chaque version IA dans le journal d’audit et permettre à un humain d’accepter ou de rejeter avant la mise en ligne.
- Conformité : la traçabilité satisfait les réglementations qui exigent une supervision humaine du contenu généré par IA.
Le guide suivant montre comment construire ce pipeline avec Strapi, Node.js et le plugin Revisionary.
1. Choisir un fournisseur de LLM et sécuriser la clé d’API
La première étape consiste à décider quel grand modèle de langage vous allez appeler. La plupart des fournisseurs exposent un simple point d’accès HTTP / JSON (OpenAI, Anthropic, Cohere, etc.). Stockez la clé secrète dans une variable d’environnement afin qu’elle n’apparaisse jamais dans le contrôle de version.
# fichier .env (ne jamais valider ce fichier)
LLM_API_KEY=sk‑your‑secret‑key
LLM_ENDPOINT=https://api.openai.com/v1/chat/completions2. Modéliser le type de contenu pour les brouillons IA
Créez un type de collection nommé ai‑draft (ou étendez votre type article existant). Les champs clés sont :
| Champ | Type | Description |
|---|---|---|
title | String | Le titre suggéré par le LLM. |
body | Rich Text | Contenu complet généré par le LLM. |
promptTemplate | JSON | Le prompt utilisé pour ce brouillon – stocké pour la reproductibilité. |
status | Enumeration (draft, review, published) | État du workflow. |
author | Relation → admin::user | Qui a déclenché la génération. |
Comme Revisionary suit toutes les versions d’une entrée, vous n’avez pas besoin de tables supplémentaires pour conserver les anciens brouillons – le plugin enregistre automatiquement les différences champ par champ.
3. Ajouter un contrôleur personnalisé pour appeler le LLM
Créez une nouvelle route API qui accepte un prompt, appelle le LLM et crée une entrée ai‑draft avec le résultat. Placez le code dans src/api/ai‑draft/controllers/generate.js.
// src/api/ai-draft/controllers/generate.js
'use strict';
const fetch = require('node-fetch');
module.exports = {
async createDraft(ctx) {
const { prompt, templateId } = ctx.request.body;
if (!prompt) return ctx.badRequest('Prompt is required');
// Construire le corps de la requête pour le LLM (exemple OpenAI)
const requestBody = {
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: prompt }],
temperature: 0.7,
};
const response = await fetch(process.env.LLM_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.LLM_API_KEY}`,
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const err = await response.text();
return ctx.internalServerError('LLM request failed: ' + err);
}
const data = await response.json();
const generated = data.choices?.[0]?.message?.content || '';
// Créer l’entrée du brouillon – Revisionary enregistrera automatiquement la version
const draft = await strapi.entityService.create('api::ai-draft.ai-draft', {
data: {
title: 'AI draft – ' + new Date().toISOString().slice(0, 10),
body: generated,
promptTemplate: { prompt, templateId },
status: 'draft',
author: ctx.state.user.id,
},
});
ctx.send({ draftId: draft.id, message: 'Draft created' });
},
};Définition de la route
Ajoutez la route dans src/api/ai-draft/routes/generate.js :
module.exports = {
routes: [
{
method: 'POST',
path: '/ai-draft/generate',
handler: 'generate.createDraft',
config: {
policies: [], // ajouter une politique d’authentification si nécessaire
middlewares: [],
},
},
],
};Une fois cela en place, un front‑end peut POST un prompt vers /api/ai-draft/generate et recevoir l’ID du brouillon créé.
4. Utiliser Revisionary pour conserver chaque version IA
Lorsque le LLM est rappelé pour le même article, vous pouvez mettre à jour l’entrée existante. Revisionary stockera la version précédente, le diff champ par champ, et l’utilisateur qui a effectué le changement. Vous obtenez ainsi une traçabilité complète sans code additionnel.
5. Construire un espace de révision pour les éditeurs
La fonctionnalité Review de Strapi (documentée à /docs/everyday-use/review) fournit une file d’attente des entrées dont le status est review. Créez un hook de cycle de vie simple qui déplace un brouillon vers la révision après sa génération :
// src/api/ai-draft/content-types/ai-draft/lifecycles.js
module.exports = {
async afterCreate(event) {
const { result } = event;
// Si le brouillon vient d’être généré, le placer dans la file de révision
await strapi.entityService.update('api::ai-draft.ai-draft', result.id, {
data: { status: 'review' },
});
},
};Les éditeurs ouvrent l’espace Review, voient le brouillon et peuvent :
- Accepter – changer le
statusenpublished(ou le transférer vers le typearticle). - Rejeter – laisser le brouillon en état
draft, ajouter des commentaires ou le supprimer.
Comme Revisionary enregistre chaque changement d’état, vous pouvez générer ultérieurement un rapport de conformité indiquant qui a approuvé chaque article généré par IA.
6. Publier le contenu final
Lorsqu’un éditeur clique sur Publish dans Strapi, le status de l’entrée devient published et le workflow de publication standard s’enclenche (webhooks, invalidation de cache, etc.). L’article apparaît alors dans l’API publique.
Si vous préférez garder le brouillon IA séparé de l’article final, vous pouvez copier les champs dans une nouvelle entrée article :
async function promoteToArticle(draftId) {
const draft = await strapi.entityService.findOne('api::ai-draft.ai-draft', draftId, {
populate: '*',
});
await strapi.entityService.create('api::article.article', {
data: {
title: draft.title,
body: draft.body,
author: draft.author,
// tout mappage supplémentaire …
},
});
// Marquer le brouillon comme archivé
await strapi.entityService.update('api::ai-draft.ai-draft', draftId, {
data: { status: 'archived' },
});
}7. Gouvernance : audit, traçabilité et conformité
Journal d’audit
Revisionary écrit chaque action — création, mise à jour, restauration, changement de statut — dans le journal d’audit de Strapi (/docs/reference/audit). Cela répond à de nombreuses exigences réglementaires demandant un enregistrement inviolable du contenu généré par IA.
Provenance du prompt
Stocker le prompt exact (promptTemplate) à côté du texte généré vous permet de reproduire le résultat ultérieurement, une bonne pratique pour le AI Act européen et les cadres similaires.
Politiques de rétention
Configurez la durée de conservation des sauvegardes automatiques et de l’historique des versions dans /docs/settings/retention. Pour des publications à haut risque, vous pouvez conserver les brouillons 90 jours ; pour des blogs à faible risque, 30 jours suffisent.
Permissions basées sur les rôles
Limitez qui peut déclencher la génération IA et qui peut l’approuver :
- Créateur de contenu – permission d’appeler
/ai-draft/generate. - Éditeur – permission de changer le
statusdereviewàpublished. - Responsable conformité – accès en lecture seule au journal d’audit.
Configurez ces permissions sous Settings → Roles → Plugins → Revisionary (
/docs/getting-started/permissions).
8. Astuces et bonnes pratiques
| Pratique | Raison |
|---|---|
| Versionner chaque prompt | Garantit la reproductibilité et aide à déboguer les sorties de mauvaise qualité. |
| Limiter le taux d’appels LLM | Évite les coûts incontrôlés et protège l’API contre les abus. |
| Ajouter un drapeau « human‑in‑the‑loop » | Stockez un booléen humanApproved qui doit être vrai avant la publication. |
| Sanitiser la sortie IA | Supprimez les balises HTML dangereuses ou les scripts avant d’enregistrer en base. |
| Surveiller la consommation de tokens | Journalisez le nombre de tokens consommés par requête pour suivre les dépenses. |
| Tester les prompts en isolation | Utilisez un petit script pour itérer sur les variations avant de les mettre en production. |
9. Conclusion
Intégrer un LLM dans Strapi est simple : exposez un point d’accès de génération, stockez le résultat dans un type de contenu versionné, et laissez Revisionary gérer la traçabilité. En connectant le brouillon à l’espace Review de Strapi et en appliquant des permissions basées sur les rôles, vous obtenez un pipeline sûr et conforme où l’IA booste la productivité sans sacrifier le contrôle éditorial.
Pour les équipes qui ont besoin d’un historique de versions garanti et d’une file de révision intégrée, le plugin Revisionary fournit les pièces manquantes d’un workflow de rédaction IA de niveau production.
L’équipe Revisionary
Les développeurs de Revisionary, un plugin d’historique des versions pour Strapi 5. Nous écrivons sur Strapi, le développement web, l’IA et la sécurité des applications.
Cet article a été rédigé avec l'aide d'une IA.