درس 7 — Contrôler et publier

Kit LinkedIn, droits et mention IA

50 min

هذا المحتوى غير مترجم بعد. تُعرض النسخة الأصلية.

Le kit est prêt, approuvé, contrôlé. Avant de cliquer sur « Publier », la directrice juridique d'Ondée pose trois questions : à qui appartiennent ces images, faut-il dire qu'elles sont générées, et peut-on le prouver si un concurrent conteste ? Cette leçon assemble le kit LinkedIn, exécute la chaîne complète de bout en bout, répond à ces trois questions et nettoie tout.

Le mécanisme

flowchart LR
  A["Visuels et vidéo approuvés"] --> E["exporter_linkedin()"]
  E --> C1["carrousel-1.png<br/>fond Instagram + accroche"]
  E --> C2["carrousel-2 à 4.png<br/>bandeau photo + argument"]
  E --> C5["carrousel-5.png<br/>signature"]
  E --> P["post.md<br/>+ hashtags + mention IA"]
  E --> V["video.mp4<br/>Veo + logo"]
  subgraph Traces["Ce qui permet de répondre en cas de contestation"]
    M["manifest.json : versions, consignes, approbateur, coûts"]
    S["SynthID dans les pixels générés"]
  end

Le carrousel LinkedIn est publié comme un document : cinq images 1080x1350 de même format. La couverture reprend le fond Instagram validé avec l'accroche de la première diapositive ; les trois suivantes alternent les aplats de la palette sous un bandeau photo recadré différemment ; la dernière porte la signature.

La mise en œuvre

Le test de bout en bout enchaîne tout, avec les vrais modèles, puis approuve explicitement (approuve_par="e2e") et exporte :

make e2e          # ≈ 0,80 $, 2 à 3 minutes
ls sorties/e2e/linkedin/

La sortie réelle de la campagne Ondée est versionnée dans exemple-campagne-ondee/ : post.md, cinq PNG, video.mp4.

Carrousel LinkedIn exporté pour Ondée, 5 diapositives 1080x1350

Résultat obtenu

make test, puis make e2e du 2026-10-15 (extrait, Gemini API) :

20 passed in 5.81s

20:43:38 INFO studio.models kit gemini-3.5-flash-lite coût=0.0016 $
20:43:42 INFO studio.models textes gemini-3.5-flash-lite coût=0.0025 $
20:43:58 INFO studio.models image gemini-3-pro-image coût=0.1401 $
...
20:45:29 INFO studio.models video veo-3.1-lite-generate-preview coût=0.3000 $
20:45:39 INFO studio.pipeline kit LinkedIn exporté : ['carrousel-1.png', ..., 'carrousel-5.png', 'post.md', 'video.mp4']
linkedin              1200x627  v1  contraste  4.91:1  palette  10.5  texte parasite non  QC OK
instagram_portrait   1080x1350  v1  contraste  13.2:1  palette  10.0  texte parasite non  QC OK
story                1080x1920  v1  contraste 11.94:1  palette   9.4  texte parasite non  QC OK
banniere              1584x396  v1  contraste  6.01:1  palette  22.3  texte parasite non  QC OK
kit LinkedIn : carrousel-1.png (996 Ko), carrousel-2.png (916 Ko), carrousel-3.png (689 Ko),
               carrousel-4.png (768 Ko), carrousel-5.png (48 Ko), post.md (0 Ko), video.mp4 (1633 Ko)
images générées : 5  coût total : 0.7196 $  durée : 123 s

Le même parcours sur Vertex AI (make e2e-vertex, région global, sans vidéo) : quatre visuels QC OK, sonde concluante, 6 images, 423 s. Les coûts affichés sont calculés avec la grille de l'API Gemini ; vérifiez la grille Vertex AI de votre contrat avant d'en faire un budget.

Droits, mention IA et SynthID

À qui appartiennent les images. Les conditions de l'API Gemini indiquent que Google ne revendique pas la propriété du contenu généré, mais aussi que le service peut générer un contenu identique ou similaire pour d'autres. Vous avez donc l'usage, pas l'exclusivité. La protection par le droit d'auteur d'une image produite par un modèle est incertaine : en droit français, elle suppose une création originale portant l'empreinte de la personnalité d'un auteur humain, et l'Office américain du droit d'auteur a conclu en 2025 qu'un prompt seul ne suffit pas. Ce qui est clairement à vous : les choix humains (sélection, consignes, mise en page, textes) que le manifeste documente version par version.

Ce qui doit rester exact. Un visuel publicitaire montre le produit vendu. Si le flacon généré diffère du vrai (contenance, forme, couleur), le visuel peut constituer une pratique commerciale trompeuse. La parade est dans le flux : l'image de référence doit être validée contre le produit réel, et toutes les mentions chiffrées sont des calques exacts.

Le dire. L'article 50 du règlement européen sur l'IA, applicable depuis le 2 août 2026, impose aux fournisseurs de marquer les contenus générés de façon lisible par une machine, et aux utilisateurs professionnels de signaler les hypertrucages (contenus qui ressemblent à des personnes, objets ou lieux existants et peuvent passer pour authentiques). Une photo de produit photoréaliste s'en approche. La décision prise ici : la mention « Visuels créés avec l'IA (Gemini, Veo), sélectionnés et validés par notre équipe » est ajoutée par le code à chaque post, jamais laissée au modèle ni à la mémoire de quelqu'un.

Le prouver. Toutes les images générées par les modèles Gemini et toutes les vidéos Veo portent un filigrane invisible SynthID, d'après la documentation officielle. Deux limites à connaître :

  • les pixels dessinés par le code (aplats du carrousel, texte, logo) ne portent pas de filigrane : seule la partie photographique est marquée ;
  • SynthID est conçu pour résister aux transformations courantes (recadrage, compression), mais nous n'avons pas vérifié la détection après nos recadrages, voiles et réencodages JPEG et H.264. Ce point n'a pas été testé.

Nos fichiers ne portent pas non plus de manifeste C2PA (Pillow et ffmpeg réécrivent les fichiers) : la mention textuelle est la seule information visible pour le lecteur. Le manifeste JSON, conservé avec la campagne, est la preuve interne : quel modèle, quelle consigne, quelle version, qui a approuvé, quand.

Les polices. Inter et DM Serif Display sont sous SIL Open Font License 1.1, qui autorise leur usage dans des images commerciales ; les fichiers de licence sont dans fonts/.

Ce qui casse en production

SymptômeCauseParade
Le carrousel s'affiche en mosaïque au lieu de défilerles 5 PNG publiés comme post multi-images ; le format qui défile est le post « document », qui attend un PDFassembler les 5 PNG en un PDF (Image.save(..., save_all=True, append_images=...)) au moment de la publication
Vidéo refusée ou recompressée en bouilliedébit trop élevé ou profil exotiqueH.264, yuv420p, +faststart, 2,3 Mbit/s : 1,5 Mo pour 6 s
Mention IA oubliée sur un post republié à la mainmention ajoutée par une personnemention ajoutée par post_linkedin() ; un test vérifie qu'elle termine le post
make cloud-down dit « aucune ressource » alors que gcloud a échouéerreur de commande ignoréele Makefile échoue si cloud-status échoue (vérifié avec un identifiant de projet invalide : code de sortie 2)

Nettoyage

Exécuté le 2026-10-15 :

$ make cloud-down
Aucune ressource formation-lab=studio-contenu-de-marque dans le projet.
$ make clean
Artefacts supprimés.
$ make reset
Artefacts supprimés.
Environnement supprimé (.env conservé).

Le projet ne crée aucune ressource Google Cloud (Vertex AI est facturé à l'appel) : cloud-down vérifie qu'aucun bucket ni service Cloud Run étiqueté formation-lab=studio-contenu-de-marque n'existe, et échoue si la vérification elle-même échoue. Les vidéos Veo sont supprimées du serveur de l'API au bout de 2 jours.

La règle de décision

Publiez un contenu généré quand trois conditions sont réunies : un humain l'a approuvé et c'est tracé, la mention IA est posée par le code, et le produit montré correspond au produit vendu. Si l'un des trois manque, l'export doit échouer, pas avertir.

Pratique

Un concurrent publie un visuel presque identique au vôtre, généré lui aussi avec Gemini. Que pouvez-vous faire valoir ?

Le flacon réel d'Ondée a une étiquette imprimée. Le visuel généré montre un flacon sans étiquette. Quelle est la bonne décision avant publication ?

Exercice. Ajoutez à l'export un fichier provenance.json qui liste, pour chaque fichier du kit, le modèle qui a produit ses pixels, la version, l'approbateur et la date d'approbation.

Voir la solution
# pipeline.py, à la fin de exporter_linkedin()
prov = {
    "carrousel-1.png": {"source": self.manifest["assets"]["instagram_portrait"]["fond"],
                        "modele": self.s.image_model,
                        "approuve_par": self.manifest["assets"]["instagram_portrait"].get("approuve_par"),
                        "approuve_le": self.manifest["assets"]["instagram_portrait"].get("approuve_le")},
    "carrousel-2.png": {"source": "hero.jpg", "modele": self.s.image_model_final},
    "video.mp4": {"modele": self.manifest["video"]["modele"], "approuve_par": self.manifest["video"].get("approuve_par")}
                 if self.manifest.get("video") else None,
    "mention": MENTION_IA,
}
(cible / "provenance.json").write_text(json.dumps(prov, ensure_ascii=False, indent=2), encoding="utf-8")

Testez que chaque fichier image du kit a une entrée et que la mention correspond à MENTION_IA.

  • Je sais exporter un kit LinkedIn complet depuis des visuels approuvés
  • Je sais ce que les conditions de l'API disent de la propriété des contenus générés
  • Je sais ce que SynthID prouve et ce qu'il ne prouve pas
  • Je sais vérifier qu'aucune ressource du projet ne subsiste