Aller au contenu principal

ai-diagram : d'une phrase (ou d'un compose.yaml) à un diagramme Mermaid

Une fonction zsh qui transforme une description en langage naturel, ou un fichier de config existant comme un docker-compose.yaml, en diagramme Mermaid — affiché sous forme de bloc de code prêt à coller. Là où docker-python-mermaid exige un script écrit pour chaque format d'entrée, ai-diagram prend ce que vous avez sous la main.

· 10 minutes de lecture
Voir la source
Christophe
Amoureux de Markdown, WSL et Docker ~ Curieux insatiable.
Claude Code
Assistant IA
Cet article existe aussi en anglais — lire la version originale.

Traduction automatique

Cette traduction a été produite par une IA. Elle peut contenir des contresens ou des maladresses, en particulier sur les termes techniques. En cas de doute, consultez l'article de référence en anglais — c'est lui qui fait foi.

ai-diagram : d'une phrase (ou d'un compose.yaml) à un diagramme Mermaid

⚡
TL;DR

Cet article ajoute ai-diagram à la série « Ollama daily use » : donnez-lui la description d'un processus en langage naturel, ou pointez-le vers un fichier comme un docker-compose.yaml, et il renvoie un diagramme Mermaid — un bloc de code, prêt à coller directement dans un fichier Markdown. C'est un pont volontaire entre cette série et mes articles doc-as-code : docker-compose-viz et docker-python-mermaid transforment tous deux des données structurées en diagrammes avec de vrais parsers ; ai-diagram couvre le cas qu'ils ne savent pas traiter — une description sans le moindre schéma, ou un fichier pour lequel vous n'avez pas envie d'écrire un parser juste pour esquisser un diagramme.

J'ai écrit plus d'articles « transformer X en diagramme » que je ne le croyais : Diagrams as code, un graphe à partir de compose.yaml, la documentation as code avec Python et Mermaid. Tous partagent la même forme : un vrai parser lit une entrée structurée et une librairie dessine l'image. Ça fonctionne très bien — jusqu'au moment où ce que je veux représenter est un paragraphe que je viens de taper, ou un fichier de config ponctuel qui ne mérite pas qu'on lui écrive un parser.

Démo — une description en langage naturel​

>user@machine: ~/yourproject

Pas de YAML, pas de schéma, juste une phrase — et un flowchart qui se ramifie sur la validation, la seule étape de cette phrase dont l'issue décide de la suite, tandis que l'enregistrement et l'envoi restent de simples étapes. Collé dans cette page, le bloc s'affiche ainsi :

Démo — un fichier de config existant​

>user@machine: ~/yourproject

Trois services, leurs liens de dépendance et le volume nommé — lus directement dans la structure du fichier compose, avec chaque image et chaque port publié intégrés au label de son service :

Relisez le Mermaid avant de lui faire confiance

Pour tout ce qui part dans de la vraie documentation — un document d'onboarding, un architecture decision record — traitez ça comme la sortie de docker-compose-viz : un bon premier jet. Le modèle peut rater un cas limite (un depends_on: condition: service_healthy, un alias réseau moins évident) qu'un vrai parser comme celui de docker-python-mermaid n'aurait pas manqué.

D'autres phrases à essayer​

Trois descriptions de plus, chacune prête à copier dans votre propre terminal. Chaque lien ouvre le diagramme produit par ai-diagram, dans le Mermaid Live Editor.

Tri des tickets de support​

ai-diagram "When a customer submits a support ticket, check if it is urgent. If it is urgent, assign it directly to a senior agent. If it is not urgent, place it in the standard queue and send an automated confirmation email to the customer."

Voir le diagramme obtenu sur mermaid.live

Connexion avec verrouillage de compte​

ai-diagram "To log into the system, the user enters their username and password. If the credentials are correct, grant access and display the main dashboard. If the credentials are incorrect, check if the attempt count is less than three. If it is less than three, increment the counter and ask the user to try again. Otherwise, lock the account and send a password reset link to the user's email."

Voir le diagramme obtenu sur mermaid.live

Une commande e-commerce​

ai-diagram "When receiving an e-commerce order, first verify if the requested item is in stock. If it is out of stock, notify the customer and ask if they want to backorder or cancel. If they cancel, process a full refund. If the item is in stock, check if the payment is processed successfully. If payment fails, prompt the user to update their payment method. If payment succeeds, pack the order, generate a shipping label, ship the item, and send a tracking number to the customer."

Voir le diagramme obtenu sur mermaid.live

Sa place réelle à côté de docker-python-mermaid​

Pas un remplaçant — un autre métier

docker-python-mermaid parse lui aussi un compose.yaml, et c'est le bon outil pour un diagramme qui vit dans la documentation : un script écrit une fois pour ce format d'entrée, déterministe, régénéré à chaque changement. ai-diagram sert à l'autre moitié du travail : une description de la taille d'un message Slack, ou un format pour lequel vous n'avez aucun script — un nginx.conf, un workflow CI, un schéma SQL. Moins de précision, aucune installation — j'utilise les deux, selon que le diagramme doit rester synchronisé ou simplement exister cet après-midi.

La fonction ai-diagram​

Pas besoin de copier quoi que ce soit pour l'instant : les fichiers .zsh montrés dans cet article sont là pour être lus, et L'installer à la fin les crée tous dans ~/.zsh/fns/ pour vous.

# ai-diagram <description>|<file> — turn a plain-English description, or an
# existing config/structure file, into a Mermaid diagram. Prints a fenced
# ```mermaid code block, ready to paste into a Markdown file (this blog
# already renders Mermaid natively).
AI_COMMANDS[diagram]="ai-diagram <description>|<file> — turn a description or a config file into a Mermaid diagram"
AI_PARAMS[diagram]="text"
ai-diagram() {
if [[ -z "$1" ]]; then
echo 'Usage: ai-diagram "plain-English description" or ai-diagram <file>' >&2
return 1
fi
local input hint
if [[ -f "$1" ]]; then
input=$(cat "$1")
# Without these rules, a model turns every value it reads into a node of
# its own: "postgres:16" or "8080:80" end up as boxes next to the services.
hint="The input below is the file '$1'. Infer the most natural Mermaid diagram type from its content — a docker-compose.yaml suggests a graph of services and their links, a folder listing suggests a flowchart or tree, an OpenAPI spec suggests a sequence diagram. Follow these rules:
- one node per entity the file declares (a service, a table, a class, a job), labelled with its name and its key attributes, e.g. app[\"app · build · :8080\"];
- one edge per relationship the file states (depends_on, a foreign key, needs), from the entity to what it relies on;
- storage (a named volume, a database file) is a cylinder node, e.g. db_data[(\"db-data\")], linked from the entity that uses it;
- attributes (an image, a port, a type) appear only inside labels, never as nodes of their own;
- node ids use letters, digits and underscores only."
else
input="$*"
hint="The input below is a plain-English description. Pick whichever Mermaid diagram type (flowchart, sequence, ER, class, state) best fits what is being described. Draw every branch the description states. Add a failure branch on your own only where a step is itself a check whose outcome decides what happens next (a validation, a login, a payment) — never for a plain action such as saving, sending or assigning something."
fi
local prompt="You are a Mermaid diagram expert. $hint
Output ONLY a fenced Mermaid code block — no explanation before or after it, no extra commentary, nothing outside the \`\`\`mermaid ... \`\`\` fence.
--- INPUT ---
$input"
local diagram
diagram=$(_ollama_query "$prompt") || return 1
if [[ -z "$diagram" ]]; then
echo "ai-diagram: the model returned an empty answer" >&2
return 1
fi
# The prompt asks for the fence, but a model still adds a sentence before it
# now and then. Keeping only the fenced lines and re-wrapping them makes the
# output paste-ready every time, whatever the model wrapped around it.
local code
code=$(_ai_strip_fences "$diagram")
print -r -- '```mermaid'
print -r -- "$code"
print -r -- '```'
# A Ctrl+click preview on mermaid.live. "base64:" is one of the two formats
# the editor reads from the URL hash — the JSON state, base64url-encoded — so
# jq and coreutils are enough, no compression library. It goes to stderr:
# stdout stays the bare Markdown block, even redirected to a file.
local state
state=$(jq -jcn --arg code "$code" '{code: $code}' | base64 | tr -d '\n=' | tr '+/' '-_')
print -r -- "Preview: https://mermaid.live/edit#base64:${state}" >&2
}

Cette fonction transforme une description en anglais simple ou un fichier de configuration existant en diagramme Mermaid. Elle envoie l'entrée à un modèle d'IA avec des instructions spécifiques sur la façon de structurer le diagramme, nettoie la réponse, puis affiche le résultat au format Markdown avec un lien d'aperçu.

Deux modes d'entrée, distingués par un seul test — si le premier argument est un fichier existant, c'est un fichier :

  1. Un fichier — lu tel quel, et le prompt demande au modèle de déduire le type de diagramme du contexte (un compose.yaml implique un graphe de services, un listing de dossier implique un arbre, une spec OpenAPI implique un diagramme de séquence). Une courte liste de règles garde le graphe honnête : un nœud par entité, une arête par relation, les attributs comme une image ou un port dans les labels, le stockage dessiné comme un cylindre.
  2. Du texte libre — tout ce qui suit la commande est traité comme la description, et le modèle choisit lui-même le type de diagramme Mermaid le plus adapté, en ajoutant une branche d'échec uniquement là où une étape est elle-même une vérification (une validation, une connexion, un paiement) — jamais un « email envoyé ? » inventé sur une action simple.

Dans les deux cas, la sortie est un bloc ```mermaid et rien d'autre. Le prompt demande exactement ça, et _ai_strip_fences ne conserve ensuite que les lignes du bloc avant que la fonction ne les réencadre elle-même — de sorte que même une réponse qui commence par « Here is your diagram: » ressort prête à coller dans un article, où ce blog la rend nativement.

Avant de la coller quelque part, vous voudrez la voir. La dernière ligne, Preview: https://mermaid.live/edit#base64:…, ouvre le diagramme dans le Mermaid Live Editor avec un Ctrl+clic depuis le terminal — rendu, et modifiable si le modèle s'est trompé sur un label. L'éditeur lit tout son état dans la partie de l'URL après le # : le JSON {"code": "…"}, encodé en base64url, donc jq et base64 suffisent à le construire. Ce fragment n'est jamais envoyé au serveur dans la requête ; le diagramme est décodé et dessiné par la page, dans votre navigateur. Le lien part sur stderr, donc ai-diagram compose.yaml > docs/services.md n'écrit toujours rien d'autre que le bloc Mermaid.

Enregistrée dans le menu ai​

Deux lignes — AI_COMMANDS[diagram]=... et AI_PARAMS[diagram]="text" — la rendent accessible via ai diagram <input> ou directement via ai-diagram, aux côtés de toutes les autres fonctions de la série. Choisie depuis le menu ai seul, elle demande son entrée : tapez une description, ou un nom de fichier.

_ollama_query, _ai_strip_fences et le registre AI_COMMANDS vivent tous dans la fondation partagée _ollama.zsh présentée dans ai-test. Si vous avez déjà suivi un article précédent de cette série, elle se trouve déjà dans ~/.zsh/fns/ et est sourcée par votre autoloader — rien de plus à faire. Vous commencez ici ? C'est l'un des fichiers créés dans L'installer plus bas.

À retenir​

ai-diagram en bref

  • Deux modes d'entrée — un fichier existant, ou une description en texte libre, détectés automatiquement
  • Le type de diagramme est déduit — flowchart, séquence, ER, classe, état — le modèle choisit selon le contexte
  • La sortie n'est qu'un bloc — un bloc `mermaid brut, réencadré par la fonction elle-même, destiné à être collé directement
  • Ctrl+clic pour prévisualiser — un lien mermaid.live sur stderr ouvre le diagramme rendu, stdout reste prêt à coller
  • Complète, ne remplace pas, docker-python-mermaid — un script pour les diagrammes qui doivent rester synchronisés ; ceci pour tout le reste
  • S'enregistre dans ai — accessible via ai diagram

L'installer​

Tout tourne sur votre machine : zsh, curl et jq (qui construit la requête envoyée à Ollama), et un serveur Ollama accessible — voyez installing Ollama si vous n'en avez pas encore.

1. Créez les fichiers. Chaque fonction de cette série vit dans son propre fichier dans ~/.zsh/fns/. La ligne de commande ci-dessous crée ce dossier et les deux fichiers d'un coup — sinon téléchargez le ZIP, ou créez chaque fichier à la main et collez son contenu. _ollama.zsh est la fondation partagée par toute la série : si un article précédent vous l'a déjà donnée, la copie ici est le même fichier.

📦 Mise en place du projet : ~/.zsh/fns
Aide

Besoin d'aide ? Cliquez sur le bouton « Aide » ci-dessus pour les instructions de mise en place.

2. Chargez le dossier depuis ~/.zshrc. Déjà fait si vous avez suivi un article précédent de cette série. Sinon, ajoutez ces lignes à la fin de ~/.zshrc — elles sourcent chaque fichier .zsh du dossier, donc la prochaine fonction que vous ajouterez ne nécessitera aucun changement ici :

~/.zshrc
for fn_file in ~/.zsh/fns/*.zsh; do
source "$fn_file"
done

3. Ouvrez un nouveau terminal (ou lancez exec zsh dans celui en cours), et vérifiez que le shell connaît la nouvelle fonction :

type ai-diagram

ai-diagram is a shell function from …/ai-diagram.zsh signifie que vous êtes prêt. ai-diagram not found signifie que l'étape 2 manque.

Conclusion​

Mes articles doc-as-code ont toujours supposé que j'avais déjà quelque chose de structuré à donner à un parser. ai-diagram comble le vide en amont — la phrase que je viens de taper, le fichier que j'ai mais pour lequel je n'ai pas écrit de parser. Il ne remplacera pas Diagrams as code ni docker-python-mermaid pour ce qui doit être exact et reproductible, mais pour le cas « laisse-moi juste esquisser ça vite fait » qui signifiait avant d'ouvrir un outil de whiteboard, c'est devenu une commande et un collage.


Cet article vous a-t-il été utile ?
Avez-vous suivi les étapes de cet article ?