Moteur de workflow LLM basé sur des graphes d'agents
Project description
llm-wf
Moteur de workflow LLM basé sur des graphes d'agents. Permet d'enchaîner des agents LLM connectés par leurs variables, avec parallélisation automatique des agents indépendants.
Principe
Un workflow est un graphe orienté acyclique (DAG) d'agents LLM. Chaque agent :
- reçoit des variables d'entrée injectées dans son prompt (template Jinja2) ;
- appelle un service LLM ;
- produit une ou plusieurs variables de sortie.
Les connexions entre agents sont déduites automatiquement : si l'agent A produit résumé et que l'agent B consomme résumé, l'arête A → B est créée. Les agents sans dépendance commune s'exécutent en parallèle.
entrée: document
│
▼
[agent_résumé] ──────────────────────────────────┐
│ résumé │
▼ ▼
[agent_mots_clés] [agent_sentiment]
│ mots_clés │ sentiment
└──────────────────────┬───────────────────────┘
▼
[agent_rapport]
│ rapport_final
▼
sortie
Installation
Disponible sur PyPI :
pip install llm-wf
Ou en mode développement :
pip install -e . # développement local
Usage CLI
llmwf -w workflow.yaml -v document="Mon texte à analyser"
llmwf -w workflow.yaml -f document=rapport.pdf --verbose
llmwf -w workflow.yaml -f doc=rapport.txt -v langue=français -o md
llmwf -w workflow.yaml --graph # diagramme seul
llmwf -w workflow.yaml --graph -f doc=texte.txt # diagramme + exécution
Options
| Option | Description |
|---|---|
-w, --workflow |
Fichier YAML du workflow (requis) |
-v var=valeur |
Variable directe (répétable) |
-f var=fichier |
Variable chargée depuis un fichier .txt, .md ou .pdf (répétable) |
-o text|md|html |
Format de sortie (défaut : text) |
-g [fichier], --graph [fichier] |
Génère le diagramme PlantUML du workflow (voir ci-dessous) |
--verbose |
Affiche le détail de l'exécution |
--version |
Affiche la version |
Génération de diagramme PlantUML
L'option -g/--graph produit une représentation visuelle du graphe d'agents au format PlantUML.
llmwf -w workflow.yaml --graph # → <Nom_du_workflow>.puml
llmwf -w workflow.yaml --graph mon_flow.puml # → mon_flow.puml
Le rendu en image (PNG) est tenté automatiquement selon la disponibilité :
- Binaire local
plantuml— rendu local si installé - Serveur public
plantuml.com— via le package Pythonplantumlsi le réseau est accessible - Fichier
.pumlseul — si aucune option de rendu n'est disponible
Utilisé sans variables d'entrée (-v/-f), le diagramme est généré puis la commande se termine (pas d'exécution du workflow).
Format du fichier workflow YAML
name: "Analyse de document"
system_prompt: prompts/system.md
agents:
- id: résumé
prompt: prompts/resume.md
service: ollama
model: gemma3:4b
inputs: [document]
outputs: [résumé]
- id: mots_clés
prompt: prompts/mots_cles.md
service: anthropic
model: claude-haiku-4-5-20251001
api_key: "None" # utilise QCANTHROPIC_API_KEY
inputs: [résumé]
outputs: [mots_clés]
- id: rapport
prompt: prompts/rapport.md
service: ollama
model: gemma3:4b
inputs: [résumé, mots_clés]
outputs: [rapport_final]
Champs d'un agent
| Champ | Requis | Description |
|---|---|---|
id |
oui | Identifiant unique de l'agent |
prompt |
oui | Chemin vers le fichier de prompt (relatif au YAML) |
service |
oui | Service LLM (voir ci-dessous) |
model |
oui | Nom du modèle |
inputs |
non | Variables d'entrée consommées |
outputs |
oui | Variables de sortie produites |
url |
non | URL personnalisée du service |
api_key |
non | Clé API (sinon variable d'environnement) |
Sorties multiples
Si un agent déclare plusieurs outputs, son prompt doit retourner un objet JSON :
{"var1": "valeur1", "var2": "valeur2"}
Le moteur extrait automatiquement un bloc ```json ``` ou le premier objet JSON nu dans la réponse.
Services LLM supportés
service |
Description | Variable d'env. |
|---|---|---|
ollama |
Ollama local (localhost:11434) ou distant si url fourni |
— |
ollama_cloud |
Ollama Cloud | OLLAMA_API_KEY |
lms |
LM Studio (local) | — |
openai |
OpenAI API | OPENAI_API_KEY |
anthropic |
Anthropic Claude | QCANTHROPIC_API_KEY |
google |
Google Gemini | GEMINI_API_KEY |
albert |
Albert (DINUM — service public) | ALBERT_API_KEY |
ragarenn |
Ragarenn (Eskemm Numérique) | RAG_API_KEY |
poe |
POE API | POE_API_KEY |
generic |
API compatible OpenAI (nécessite url et api_key) |
— |
Format des prompts
Les prompts sont des templates Jinja2. Les variables d'entrée déclarées dans inputs sont injectées automatiquement.
Voici le document à résumer :
{{ document }}
Produis un résumé en 3 phrases maximum.
Les caractères spéciaux Markdown et les balises Jinja2 présents dans les variables sont échappés automatiquement pour éviter les injections de prompt.
Usage programmatique
from llm_workflow import WorkflowConfig, WorkflowGraph, WorkflowExecutor
config = WorkflowConfig.from_yaml("workflow.yaml")
graph = WorkflowGraph.from_agents(config.agents)
errors = graph.validate({"document": "Mon texte..."})
if errors:
raise ValueError(errors)
executor = WorkflowExecutor(graph, config.load_system_prompt(), verbose=True)
results = executor.execute({"document": "Mon texte..."})
print(results["rapport_final"])
Callbacks d'exécution
WorkflowExecutor accepte trois callbacks optionnels pour suivre l'avancement (utilisés notamment par le visualiseur Streamlit) :
executor = WorkflowExecutor(
graph,
config.load_system_prompt(),
on_agent_start=lambda aid: print(f"▶ {aid}"),
on_agent_done=lambda aid: print(f"✓ {aid}"),
on_agent_error=lambda aid, exc: print(f"✗ {aid}: {exc}"),
)
Visualiseur Streamlit
Une interface web (app.py) permet de charger un workflow YAML, de saisir les variables d'entrée et de visualiser en temps réel l'état des agents (en attente / en cours / terminé / erreur) sur le DAG.
pip install -r requirements-app.txt
streamlit run app.py
Saisir alors le chemin du fichier workflow YAML dans l'interface, remplir les variables d'entrée, puis lancer l'exécution. Le DAG est affiché avec un code couleur mis à jour à chaque agent.
Variables d'environnement
export OPENAI_API_KEY="sk-..."
export QCANTHROPIC_API_KEY="sk-ant-..."
export GEMINI_API_KEY="AIza..."
export ALBERT_API_KEY="..."
export RAG_API_KEY="..."
export OLLAMA_API_KEY="..."
export POE_API_KEY="..."
Exemple complet
Le répertoire examples/analyse_document/ contient un workflow fonctionnel à 4 agents (résumé → mots-clés + sentiment en parallèle → rapport).
Prérequis : Ollama installé et démarré avec le modèle gemma3:4b.
# Avec un texte direct
llmwf -w examples/analyse_document/workflow.yaml \
-v document="L'intelligence artificielle transforme profondément nos sociétés." \
--verbose
# Avec un fichier texte
llmwf -w examples/analyse_document/workflow.yaml \
-f document=mon_document.txt \
-o md
Prérequis
- Python ≥ 3.11
- Dépendances : voir
requirements.txt
Auteur
Emmanuel Desmontils — emmanuel.desmontils@univ-nantes.fr
avec l'aide de Claude Code et POE/Sonnet-4.6
Licence
CeCILL-B — Licence libre française élaborée par le CEA, le CNRS et l'INRIA, compatible avec le droit français. Permet la réutilisation et la modification libres sous condition d'attribution.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llm_wf-0.2.0.tar.gz.
File metadata
- Download URL: llm_wf-0.2.0.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e77f075c93ac5b71c3a3e85cffeef64e3421aff918044cb89addd86fb5ac52f
|
|
| MD5 |
3b28b8cd6d0b66cc0fa69fd6ae4c87e3
|
|
| BLAKE2b-256 |
fce1ae73734e9829c2910b0b09c7a1b7f36f31aa3db7172923f3634242a4b56d
|
File details
Details for the file llm_wf-0.2.0-py3-none-any.whl.
File metadata
- Download URL: llm_wf-0.2.0-py3-none-any.whl
- Upload date:
- Size: 29.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0edf8145a79bb16de3e8b286a27fcbbc8fd651ab01f860a39c1837470a2a9aa
|
|
| MD5 |
0759849ad9b9f08f0623b77c6e46337b
|
|
| BLAKE2b-256 |
3d4cf35e61ef713f625d6f02c461d5717118884ce0fe58af8c9907c5aa7d6bf1
|