Quickstart Arclith¶
Ce guide montre comment démarrer un projet concret avec Arclith, puis comment le faire évoluer par adapter sans modifier le code métier.
Arclith doit rester une brique hexagonale stable:
- le domaine et les cas d'usage portent le métier;
- les adapters inbound exposent le métier via API, MCP, bus ou CLI;
- les adapters outbound branchent MongoDB, DuckDB, cache, LLM, tracing ou secrets;
- la CLI assemble ces briques et met a jour la configuration.
Prérequis¶
- Python 3.13
uvgit
Installer au préalable la CLI publiée sur PyPI :
Pour le parcours recommandé dans un terminal, lancer simplement le cockpit plein écran :
| Bash | |
|---|---|
La TUI demande le résultat attendu, montre le plan complet avant toute écriture, continue dans le nouveau projet et permet d'y démarrer l'API avec ses logs. Elle couvre le socle minimal, l'API REST CRUD ou ciblée, FastMCP, LangGraph et RabbitMQ, sans rendre implicite le choix du repository ou du transport. Voir le guide interactif Arclith CLI.
Les commandes ci-dessous restent l'équivalent direct pour les scripts et la CI.
Pour partir d'un projet vide de métier, utiliser init, puis ajouter explicitement les fichiers
du cœur:
init n'installe aucun transport. La commande add-adapter ci-dessus ajoute le
blueprint et l'extra FastAPI à la demande ; utiliser mcp/fastmcp de la même
manière uniquement si le service expose aussi MCP. Pour un CRUD, utiliser plutôt
ce parcours complet, en alternative au bloc précédent :
Le blueprint crée le cœur applicatif et copie les champs métier déclarés dans
les commandes validées ; expose-feature constitue la décision séparée qui
publie ses cinq opérations sur l'adapter déjà installé. Consulter le blueprint
CRUD pour le contrat HTTP et ses erreurs.
Pour enregistrer des faits immuables, choisir explicitement l'autre archétype :
| Bash | |
|---|---|
Ce parcours génère un ImmutableRecord et une feature d'append idempotent sans
transport, query ou CRUD. Le container exige un store explicite ; lire le
blueprint append-only pour l'identité stable des retries,
les deux timestamps et les limites du store mémoire.
Pour un agrégat qui évolue par verbes métier, fournir une spec puis choisir le blueprint paramétré :
Le champ d'état est typé et protégé contre l'affectation directe. Chaque transition devient un port et un use case explicites ; le projet doit fournir un adapter qui respecte réellement le compare-and-swap. Lire le blueprint state-machine pour la spec, les gardes, le manifeste V2 et l'évolution des états persistés.
Pour une unité de travail suivie, ajouter le blueprint job avec une spec :
| Bash | |
|---|---|
Le parcours job complet fournit la spec, l'installation
depuis les sources avant publication PyPI, les commandes de test et l'exécution
mémoire. Il génère cinq opérations et un handler à compléter, sans transport.
Le runner mémoire est non durable et ne lance aucune tâche lors de submit :
son propriétaire appelle explicitement await runner.run(job_id).
Pour réconcilier des données externes, créer une feature liée à une entité :
| Bash | |
|---|---|
Le guide synchronization fournit la spec complète, l'installation depuis les sources compatibles et un exemple exécutable. La feature utilise Job, distingue son état d'exécution du checkpoint de synchronisation et laisse les adapters et le mapper métier à implémenter. Le replay conserve les paramètres dans la recette, sans dépendre du YAML initial.
arclith-cli run api exécute uv run dans la racine détectée et conserve le
serveur en avant-plan jusqu'à Ctrl+C. Le port et le reload restent pilotés par
la configuration FastAPI générée.
Chaque commande mutante réussie enrichit arclith.recipe.yaml. Ce fichier
versionné conserve les décisions de scaffolding sans remplacer Git et sans
stocker de secret. Consulter la timeline avec arclith-cli history, puis lire
le guide Recettes Arclith CLI pour le dry-run et le replay.
Pour tester une branche de développement avant merge:
| Bash | |
|---|---|
Pour une orchestration en plusieurs étapes reprenables, ajouter un workflow :
| Bash | |
|---|---|
Le parcours workflow fournit la spec et l'installation compatible, les étapes à compléter et un exemple de panne/reprise. La génération installe un contrat indépendant des transports ; la mémoire reste non durable.
1. Comprendre le raccourci new¶
Pour compatibilité, new reste disponible. Il équivaut à init suivi de
add-entity; il ne télécharge plus un projet complet et n'ajoute aucun adapter.
Le mode interactif demande le profil applicatif après l'entité ; le mode direct
peut utiliser --profile crud, --profile append-only ou --profile
state-machine --spec <fichier>, sinon il reste minimal.
| Bash | |
|---|---|
L'option --port ne démarre et ne configure aucun serveur : elle sert uniquement
à afficher la commande FastAPI suggérée. Le transport reste une décision explicite
avec add-adapter.
Le projet généré suit le layout canonique:
| Text Only | |
|---|---|
Le premier uv sync crée uv.lock. Ensuite, ajouter les use cases et uniquement
les adapters nécessaires en suivant les parcours dédiés :
2. Changer ou ajouter un adapter outbound¶
Pour ajouter seulement du cœur métier, sans CRUD ni adapter automatique :
| Bash | |
|---|---|
Pour le cycle de vie CRUD classique, sans adapter automatique :
| Bash | |
|---|---|
Puis, uniquement si une API REST est voulue :
| Bash | |
|---|---|
add-entity ajoute un squelette guidé sans import inutilisé. add-usecase
propose les entités détectées en interactif ; en mode direct, --entity,
--new-entity et --no-entity rendent le choix explicite et sont mutuellement
exclusifs. Les fichiers générés montrent le pattern
Command/Query -> UseCase -> Entity/Result, mais les champs, invariants et
appels aux ports restent du code métier à écrire dans le projet. Lire le
deep dive scaffold CLI pour les exemples complets,
ou la vue d'ensemble des blueprints applicatifs pour comprendre
la séparation entre comportement, capability et adapter.
L'adapter actif est déclaré dans:
| Text Only | |
|---|---|
Exemple:
Pour ajouter ou remplacer un adapter de repository:
La sortie JSON expose les garanties de chaque adapter repository. Utiliser la matrice de choix repository pour comparer runtime, multi-processus, transactions, stratégie de schéma, usages et limites avant de modifier l'adapter actif.
Le wizard détecte les entités dans src/<package>/domain/models/, pose les questions nécessaires,
génère les fichiers de l'adapter et met à jour la configuration.
Le même flux peut être joué en mode direct:
MongoDB¶
Le wizard MongoDB doit produire une configuration scoped:
| Text Only | |
|---|---|
Exemple attendu:
L'URI reste un secret et ne doit pas être commitée. En local, utiliser secrets.yaml ou une variable
d'environnement selon la recette active.
DuckDB¶
Exemple:
MariaDB¶
La CLI ajoute elle-même l'extra arclith[mariadb] au projet.
Génération directe:
| Bash | |
|---|---|
Exemple de configuration générée:
| YAML | |
|---|---|
Le mot de passe ou l'URL complète doivent rester dans un resolver de secrets, par exemple
config/secrets.yaml, env ou Vault.
3. Ajouter un autre inbound sans toucher au métier¶
Le même service applicatif peut être exposé par plusieurs adapters:
- FastAPI pour HTTP;
- FastMCP pour les outils MCP;
command-bus/rabbitmqpour un worker RabbitMQ.
La règle à conserver: l'inbound transforme le protocole en appel de cas d'usage. Il ne contient pas le métier.
4. Cas agent IA¶
Pour un agent, le cœur doit rester testable sans LLM:
| Text Only | |
|---|---|
Le LLM est un adapter outbound derrière un port. Il traduit une demande naturelle en données structurées, mais n'exécute pas directement le métier.
Exemple de ports applicatifs cibles:
IntentInterpreterPort: transforme une phrase en commande structurée;RepositoryPort: persiste les entités;TracePort: envoie les traces LangSmith ou autre;EventBusPort: publie des événements si besoin.
LangGraph local comme banc de test¶
Arclith ne génère pas d'UI dédiée pour tester un agent. Le chemin standard est un adapter
agent/langgraph testé via l'Agent Server local. LangGraph Studio et LangSmith sont utiles pour
inspecter les conversations quand internet et la clé sont disponibles, mais ils ne sont pas requis
pour valider un run local:
| Bash | |
|---|---|
Ajouter LangSmith séparément uniquement lorsque les traces distantes sont souhaitées:
| Bash | |
|---|---|
Tester sans Studio:
| Bash | |
|---|---|
Pour les commandes complètes LM Studio, threads et inspection de state, lire Validation IA locale.
L'adapter agent/langgraph génère langgraph.json, config/adapters/inbound/langgraph.yaml et
src/<package>/adapters/inbound/langgraph/agent.py. Le projet n'a plus qu'à modifier ce fichier
pour définir l'état, les nœuds et les transitions de son agent. Comme fastapi et fastmcp,
LangGraph est configuré par son nom produit dans AppConfig.langgraph, sans clé générique
adapters.agent.
Le flux attendu est: utilisateur ou canal conversationnel -> LangGraph Agent Server -> agent.py ->
ports et use cases applicatifs. Les nodes peuvent utiliser un LLMPort configuré par llm/* et les
traces via observability/*, sans appeler les repositories directement.
L'adapter observability/langsmith génère config/adapters/outbound/langsmith.yaml, ajoute
langsmith à observability.enabled, ajoute l'extra optionnel correspondant et écrit uniquement
les valeurs non secrètes dans .env.example. La CLI ne demande et n'écrit jamais la clé API.
Définir LANGSMITH_API_KEY dans l'environnement runtime ou un secret manager avant de lancer un
service avec cet adapter activé. Sans LangSmith, ne pas l'ajouter à observability.enabled: aucun
client, buffer ou appel réseau n'est alors créé.
L'adapter llm/lmstudio génère config/adapters/outbound/lm.yaml, chargé dans
AppConfig.adapters.lm. L'interpréteur d'intention applicatif consomme ensuite un LLMPort;
LangGraph ne fait qu'orchestrer les nœuds et injecter l'adapter outbound.
Pour llm/openai, choisir explicitement le modèle et garder la clé hors du dépôt: la CLI mappe
adapters.lm.api_key vers OPENAI_API_KEY via config/secrets.yaml, puis la valeur réelle vient de
.env local gitignoré, de l'environnement runtime ou d'un resolver Vault.
Utiliser llm/anthropic pour Claude via le provider Anthropic; garder llm/openai pour OpenAI,
LM Studio ou tout endpoint OpenAI-compatible avec base_url.
Le langgraph.json généré pointe vers .env pour que le serveur local charge les variables LangSmith.
Les tests conversationnels et traces agent se font ensuite dans LangSmith Studio.
Pour un parcours complet depuis un projet vide, avec création d'entité, API FastAPI, adapter LangGraph, LangSmith et LLM local LM Studio, suivre:
5. Construire l'image runtime¶
init et new n'incluent aucun fichier Docker. Ajouter explicitement le runtime lorsque le service
doit être conteneurisé :
| Bash | |
|---|---|
La même image démarre les transports par argument:
| Bash | |
|---|---|
Pour bus, ajouter d'abord command-bus/rabbitmq et implémenter le runner MODE=bus dans
main.py. Pour agent, ajouter agent/langgraph; arclith-run agent utilise langgraph.json ou
ARCLITH_AGENT_COMMAND.
Les secrets restent hors image: utiliser l'environnement runtime, Docker secrets, Vault ou fichiers
montés. Le .dockerignore généré exclut .env, secrets.yaml et les clés privées.
6. Valider avant commit¶
| Bash | |
|---|---|
L'implémentation arclith-reference sert de banc de test pour les évolutions Arclith. Avant de publier
Arclith, vérifier aussi:
Terminal 1:
Terminal 2:
Reference¶
- Implémentation de référence: https://github.com/karned-agency/arclith-reference
- CLI:
cli/README.md - Capacités standardisées:
docs/capabilities.md - Tutoriel Docker:
docs/runtime-docker.md - Architecture:
arclith/docs/architecture.md - Decisions:
docs/decisions.md