┌─────────────────────────────────────────────────────────────────────┐
│ │
│ ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██████╗ ███╗ ██╗ │
│ ██╔══██╗╚██╗ ██╔╝██╔══██╗██╔══██╗██║ ██║██╔═══██╗████╗ ██║ │
│ ██████╔╝ ╚████╔╝ ██████╔╝██████╔╝███████║██║ ██║██╔██╗ ██║ │
│ ██╔═══╝ ╚██╔╝ ██╔══██╗██╔══██╗██╔══██║██║ ██║██║╚██╗██║ │
│ ██║ ██║ ██║ ██║██║ ██║██║ ██║╚██████╔╝██║ ╚████║ │
│ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ │
│ │
│ Un agent IA qui observe, choisit, et écrit. │
│ │
│ by Patrick DARBEAU │
└─────────────────────────────────────────────────────────────────────┘
Pyrrhon d'Élis suspendait son jugement face à toute certitude. Cet agent, lui, s'y plonge — et en tire quelque chose à écrire.
Pyrrhon est un agent IA autonome doté d'une personnalité configurable. Il navigue sur le Web, sélectionne les sujets qui l'intéressent, rédige des commentaires dans sa propre voix, et les soumet à relecture avant publication sur Substack.
Deux modes de fonctionnement :
- Mode validation (défaut) — l'humain reste le dernier filtre avant toute publication.
- Mode autonome — génération et publication entièrement automatiques, sans intervention.
[Scheduler]
│
▼
[Web Explorer] ──── trouve 3–5 sujets récents
│
▼
[Topic Selector] ── l'IA choisit ce qui l'intéresse le plus
│
▼
[Writer Agent] ───── rédige (300–800 mots) dans sa voix
│
▼
├─── Mode validation ──→ [Editorial Queue] → notification → validation humaine
│ │
│ ▼ (si approuvé)
└─── Mode autonome ───→ [Substack Publisher] ←─────┘
git clone https://github.com/vous/pyrrhon.git
cd pyrrhon
python -m venv .venv
source .venv/bin/activate # Linux / macOS
.venv\Scripts\activate # Windows
pip install -r requirements.txtRenseignez vos clés API dans .env (voir .env.example).
Les profils de configuration sont déjà inclus dans config/ :
config/
├── pyrrhon_default.yaml # Profil littéraire (mardi + vendredi)
├── pyrrhon_tech.yaml # Profil technique (lundi + jeudi)
└── pyrrhon.example.yaml # Template vierge commenté
Pour créer un profil personnalisé :
cp config/pyrrhon_default.yaml config/pyrrhon_monprofil.yaml
# Éditer selon vos besoins, puis : pyrrhon run --profile monprofilChaque profil est un fichier config/pyrrhon_<nom>.yaml qui couple une configuration éditoriale à un template de prompt. Les deux profils livrés :
| Profil | Fichier config | Template prompt | Jours | Longueur |
|---|---|---|---|---|
default |
pyrrhon_default.yaml |
writer_default |
mar + ven | 500–1000 mots |
tech |
pyrrhon_tech.yaml |
writer_tech |
lun + jeu | 700–1200 mots |
Chaque profil définit la personnalité de l'agent dans son fichier config/pyrrhon_<nom>.yaml :
identity:
name: "Pyrrhon"
provider: "anthropic" # anthropic | zhipu
model: "claude-opus-4-6"
tagline: "Un modèle qui observe et commente."
personality:
tone: "analytique, légèrement ironique, jamais condescendant"
values:
- "rigueur factuelle"
- "curiosité ouverte"
avoid:
- "enthousiasme performatif"
- "listes à puces systématiques"
reference_authors:
- "Joan Didion"
- "David Foster Wallace"
editorial:
theme: "intelligence artificielle et société"
keywords: ["LLM", "agents IA", "régulation IA"]
language: "fr"
length_words: [300, 800]
post_format: "commentaire court avec titre accrocheur"
schedule:
frequency: "2x per week"
days: ["tuesday", "friday"]
time: "09:00"
timezone: "Europe/Paris"Les prompts LLM sont stockés dans des fichiers YAML indépendants du code, dans prompts/. Les équipes éditoriales peuvent les modifier ou en créer de nouveaux sans toucher au code Python.
# Dans pyrrhon.yaml
prompts:
writer: writer_default # Voix littéraire (Didion / Foster Wallace)
selector: selector_defaultTemplates disponibles :
| Fichier | Style | Usage |
|---|---|---|
prompts/writer_default.yaml |
Littéraire, analytique, 1ère personne | Commentaires éditoriaux |
prompts/writer_tech.yaml |
Technique, didactique, rigoureux | Décryptage de systèmes IA |
prompts/selector_default.yaml |
Sélection éditoriale | Choix du meilleur sujet |
Créer un nouveau template :
cp prompts/writer_default.yaml prompts/writer_mon_style.yaml
# Éditer le fichier — les variables sont en syntaxe Jinja2 : {{ name }}, {{ tone }}, etc.Puis dans le fichier de profil correspondant :
prompts:
writer: writer_mon_styleVariables disponibles dans les templates :
| Variable | Valeur |
|---|---|
{{ name }}, {{ tagline }} |
Identité de l'agent |
{{ tone }}, {{ authors }} |
Personnalité |
{{ values }}, {{ avoid }} |
Listes Jinja2 itérables |
{{ theme }}, {{ language }} |
Ligne éditoriale |
{{ length_min }}, {{ length_max }} |
Contraintes de longueur |
{{ topic_title }}, {{ topic_url }}, {{ topic_source }} |
Sujet du jour |
{{ topic_excerpt }} |
Extrait de l'article source |
{{ recent_posts }} |
Liste des posts récents (mémoire) |
{{ draft_title }}, {{ draft_body }}, {{ feedback }} |
Prompt de révision |
publishing:
platform: "substack"
publication_id: "123456" # ID numérique interne
publication_slug: "pdarbeau" # Sous-domaine substack.com
auto_publish_after_approval: true # Publier dès qu'un humain approuve
send_newsletter: false # Envoyer aux abonnés après publication
skip_approval: false # true = mode entièrement autonomeCombinaisons possibles :
skip_approval |
auto_publish_after_approval |
Comportement |
|---|---|---|
false |
true |
Humain approuve → publication immédiate sur Substack |
false |
false |
Humain approuve → draft marqué APPROVED, publication manuelle |
true |
true |
Génération → publication directe, aucune intervention humaine |
true |
false |
Génération → approuvé automatiquement, sans publication Substack |
Recommandation : Laisser
skip_approval: falsele temps de valider la qualité de l'agent sur plusieurs cycles, puis passer en mode autonome si les résultats sont satisfaisants.
Sur Windows sans installation globale, préfixer chaque commande par
.venv\Scripts\python cli.py. Avecpip install -e ., utiliser directementpyrrhon.
# Générer un article (profil littéraire, immédiatement)
python cli.py run --profile default --now
# Générer un article technique
python cli.py run --profile tech --now
# Voir les drafts produits
python cli.py review
# Approuver et publier
python cli.py approve a1b2c3d4
# Lancer l'interface web de validation
python cli.py ui# ── Configuration ─────────────────────────────────────────────────────────────
python cli.py init # Configuration guidée interactive
# ── Cycle de génération ───────────────────────────────────────────────────────
python cli.py run # Profil default, schedule respecté
python cli.py run --now # Profil default, lancement immédiat
python cli.py run --profile tech # Profil technique
python cli.py run --profile tech --now # Profil technique, immédiat
python cli.py run --config path/to/config.yaml # Chemin de config explicite
# ── Validation éditoriale ─────────────────────────────────────────────────────
python cli.py review # Drafts en attente (statut PENDING)
python cli.py review --all # Tous les drafts (tous statuts)
python cli.py approve <id> # Approuve et publie (profil default)
python cli.py approve <id> --profile tech # Approuve avec config du profil tech
python cli.py revise <id> --feedback "..." # Révision IA avec feedback éditorial
python cli.py revise <id> --feedback "..." --profile tech
python cli.py reject <id> # Rejette définitivement un draft
python cli.py reject <id> --reason "..." # Rejet avec raison explicite
# ── Historique ────────────────────────────────────────────────────────────────
python cli.py history # 10 derniers posts publiés
python cli.py history --n 20 # N derniers posts
# ── Scheduler (cycles automatiques) ──────────────────────────────────────────
python cli.py start # Scheduler profil default
python cli.py start --profile tech # Scheduler profil tech
python cli.py stop # Arrête le scheduler actif
# ── Interface web ─────────────────────────────────────────────────────────────
python cli.py ui # http://localhost:8080
python cli.py ui --port 9090 # Port personnalisé
python cli.py ui --host 0.0.0.0 --port 8080 # Accessible sur le réseau local# 1. Générer un draft
python cli.py run --profile default --now
# 2. Consulter ce qui a été produit
python cli.py review
# 3a. Approuver et publier
python cli.py approve a1b2c3d4
# 3b. Ou demander une révision
python cli.py revise a1b2c3d4 --feedback "Trop technique, revenir à la voix personnelle"
# 3c. Ou rejeter
python cli.py reject a1b2c3d4 --reason "Sujet déjà traité récemment"Les profils default et tech ont des jours distincts et peuvent tourner en même temps :
# Lundi + jeudi à 09:00 : articles techniques
python cli.py start --profile tech
# Mardi + vendredi à 09:00 : articles littéraires
python cli.py start --profile default| Statut | Signification |
|---|---|
PENDING |
Généré, en attente de validation |
APPROVED |
Approuvé par un humain |
REVISION_REQUESTED |
Révision IA en cours ou demandée |
REJECTED |
Rejeté définitivement |
PUBLISHED |
Publié sur Substack |
# LLM (au moins un requis)
ANTHROPIC_API_KEY=sk-ant-...
ZHIPU_API_KEY=...
# Recherche web (au moins un requis)
BRAVE_SEARCH_API_KEY=...
TAVILY_API_KEY=...
# Publication
SUBSTACK_SESSION_TOKEN=...
# Notifications (optionnels)
TELEGRAM_BOT_TOKEN=...
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=user@gmail.com
SMTP_PASSWORD=...
NOTIFICATION_EMAIL=destinataire@example.compyrrhon/
├── config/
│ ├── pyrrhon_default.yaml # Profil littéraire (mardi + vendredi)
│ ├── pyrrhon_tech.yaml # Profil technique (lundi + jeudi)
│ └── pyrrhon.example.yaml # Template vierge commenté
│
├── prompts/ # Templates de prompts LLM (éditables sans code)
│ ├── writer_default.yaml # Voix littéraire par défaut
│ ├── writer_tech.yaml # Variante technique
│ └── selector_default.yaml # Sélection de sujets
│
├── tools/
│ ├── web_explorer.py # Navigation et curation Web
│ ├── topic_selector.py # Sélection éditoriale IA
│ ├── writer_agent.py # Rédaction dans la voix de l'agent
│ ├── prompt_loader.py # Chargeur de templates YAML (Jinja2)
│ ├── memory_engine.py # Contexte et mémoire des posts
│ ├── editorial_queue.py # File d'attente de validation
│ ├── substack_publisher.py # Publication Substack
│ └── notifier.py # Notifications email / Telegram
│
├── ui/
│ ├── review.html # Interface web de validation
│ └── app.py # Serveur FastAPI local
│
├── data/
│ ├── memory.json # Historique des posts publiés
│ ├── drafts/ # Drafts en attente (JSON)
│ └── published/ # Archive des posts publiés
│
├── conductor.py # Orchestrateur principal + resolve_config_path()
├── scheduler.py # Planification des cycles (multi-profil)
├── run_scheduler.py # Point d'entrée subprocess du scheduler
├── models.py # Modèles de données (Pydantic)
├── cli.py # Interface ligne de commande (Click)
└── requirements.txt
| Composant | Technologie |
|---|---|
| LLM principal | Claude Opus 4.6 / GLM-5 |
| LLM sélecteur | Claude Haiku 4.5 / GLM-5 |
| Recherche web | Brave Search API / Tavily API |
| Templates prompts | PyYAML + Jinja2 |
| Orchestration | Python asyncio |
| Scheduling | APScheduler |
| Mémoire | JSON local |
| Publication | Substack API |
| Notifications | SMTP + python-telegram-bot |
| UI review | FastAPI + HTML |
| Config | PyYAML + Pydantic v2 |
- Phase 1 — MVP : config YAML, web explorer, writer agent, queue CLI, publication Substack, conductor de bout en bout
- Phase 2 — Mémoire & Planification : memory engine, scheduler, notifications email
- Phase 3 — Interface & Confort : UI web, révision avec feedback IA, Telegram
- Phase 4 — Robustesse : migration SQLite, multi-personnalités, multi-plateformes, métriques
Inspiré du projet Archer AI de Marco Kotrotsos. Système Pyrrhon v1.0 — 2026