Les déploiements d’agents autonomes à grande échelle se heurtent à un mur d’efficacité économique. Un agent passe la majeure partie de son temps en attente d’entrées utilisateur, de retours d’API ou de réponses de modèles de langage. Conserver un pod Kubernetes dédié pour chaque instance inactive gaspille les ressources de calcul. J’observe cette friction chez de nombreuses équipes concevant des architectures d’agents connectés.
Agent Substrate résout ce défi d’infrastructure. Le projet propose un plan de contrôle couplé à un environnement d’exécution capable de suspendre et restaurer des états d’agents en une fraction de seconde. Le système projette un vaste registre d’« acteurs » logiciels sur un ensemble réduit de « workers » physiques prêts à l’emploi. Cette approche permet une sursouscription massive, atteignant un facteur de multiplexage de 30x sans sacrifier la persistance.
Ce projet n’est pas un produit officiel supporté par Google et ne participe pas au programme Google Open Source Software Vulnerability Rewards. Le code source est accessible sur le dépôt GitHub officiel.
Agent Substrate adopte une posture neutre vis-à-vis des frameworks applicatifs. La plateforme n’est pas un kit de développement (SDK) pour coder la logique interne d’un agent. Elle constitue le substrat d’exécution agnostique sous-jacent, gérant le cycle de vie, la mémoire vive volatile et le routage réseau des bacs à sable (sandboxes) microVM et gVisor.
Architecture Globale et Composants Internes
L’infrastructure s’articule autour de primitives Kubernetes standard pour la couche de calcul physique, tout en intégrant des mécanismes personnalisés pour l’ordonnancement fin à basse latence.
| Composant | Binaire / Commande | Rôle et Responsabilités |
|---|---|---|
| Control Plane API | cmd/ateapi | Expose l’API gRPC de gestion des acteurs et des workers. Maintient l’état dynamique hors etcd. |
| Node Supervisor | cmd/atelet | DaemonSet superviseur de nœud. Assemble les bundles OCI et gère le transfert des instantanés. |
| Resource Controller | cmd/atecontroller | Contrôleur Kubernetes réconciliant les Custom Resource Definitions (CRDs) WorkerPool et ActorTemplate. |
| Network Mesh | cmd/atenet | Fournit le serveur DNS unifié, le routage Envoy et la reprise d’activité à la demande. |
| In-Pod Sandboxing (gVisor) | cmd/ateom-gvisor | Agent interne exécutant les opérations de point de contrôle (checkpoint) et restauration via runsc. |
| In-Pod Sandboxing (MicroVM) | cmd/ateom-microvm | Homologue gVisor pilotant les acteurs sous forme de machines virtuelles Cloud Hypervisor. |
| Security Polyfill | cmd/podcertcontroller | Émetteur de certificats éphémères pour l’authentification mutuelle TLS inter-composants. |
| CLI Client | cmd/kubectl-ate | Plugin en ligne de commande pour manipuler les ressources et inspecter le système. |
| Charge Synthétique | cmd/benchmarking | Outils de test de charge comprenant le générateur glutton (consommation de RAM, disque, descripteurs de fichiers). |
| Infra Provisioner | tools/setup-gcp | Utilitaire d’automatisation des ressources cloud (GKE, Google Cloud Storage, IAM). |
Concepts Fondamentaux et Cycle de Vie
Pour exploiter Agent Substrate, la maîtrise des abstractions métier s’avère indispensable :
- Atespace : Périmètre d’isolation global délimitant l’identité des acteurs. Un acteur est identifié par le tuple
(atespace, name). L’atespace doit être créé avant toute instanciation d’acteurs et supprimé uniquement lorsqu’il est vide. - Actor : Instance logique dérivée d’un modèle d’acteur. C’est l’unité de calcul suspendue, reprise et migrée dynamiquement d’un worker à un autre.
- Worker : Pod physique au sein d’un WorkerPool hébergeant au maximum un acteur actif à un instant T.
- Golden Snapshot : Instantané initial complet capturé lors de la création d’un ActorTemplate après la phase de chauffe. Chaque nouvel acteur démarre à partir de cette image mémoire préchauffée.
- Pause vs Suspend : Une pause fige le processus et conserve l’instantané sur le stockage local du nœud physique pour une reprise immédiate. Une suspension transfère l’état complet vers un stockage objet externe (GCS/S3), libérant le worker.
Guide de Démarrage et Déploiement
L’installation locale nécessite Go, Docker et kubectl configurés sur votre poste.
Pour un cluster de développement local basé sur Kind :
# Création du cluster Kind et du registre local (IPv4 par défaut) hack/create-kind-cluster.shDéploiement du socle ate, valkey et rustfs hack/install-ate-kind.sh --deploy-ate-system Déploiement de l'application de démonstration hack/install-ate-kind.sh --deploy-demo-counter Installation de l'outil CLI go install ./cmd/kubectl-ate Création d'un espace d'isolation puis d'un acteur de comptage kubectl ate create atespace demo
kubectl ate create actor my-counter-1 -a demo --template=ate-demo-counter/counter Redirection de port pour joindre le routeur réseaukubectl port-forward -n ate-system svc/atenet-router 8000:80
Pour valider le fonctionnement et incrémenter l’état interne de l’acteur via le maillage DNS uniforme :
curl -X POST -H "Host: my-counter-1.demo.actors.resources.substrate.ate.dev" -i http://localhost:8000/
Pour un déploiement sur Google Kubernetes Engine (GKE) :
cp hack/ate-dev-env.sh.example .ate-dev-env.sh source .ate-dev-env.shAuthentification Google Cloud gcloud auth application-default login --project=${PROJECT_ID} Provisionnement des ressources d'infrastructure (GKE, Redis, GCS, IAM) go run ./tools/setup-gcp bootstrap Déploiement du système de base et de la démo./hack/install-ate.sh --deploy-ate-system
./hack/install-ate.sh --deploy-demo-counter
Le nettoyage s’effectue via des scripts dédiés :
# Suppression des ressources GCP ./hack/teardown.sh --allSuppression du cluster Kind local./hack/delete-kind-cluster.sh
Configuration de l’API Substrate : WorkerPool et ActorTemplate
Le système sépare la capacité physique de calcul de la définition logique des agents.
1. WorkerPool : Gestion de la Capacité Physique
Un WorkerPool définit une flotte de pods sentinelles (herders) prêts à recevoir des états d’acteurs. Les limites définies sur le pool établissent l’enveloppe maximale allouable à un acteur individuel.
apiVersion: ate.dev/v1alpha1
kind: WorkerPool
metadata:
name: agent-pool
namespace: ate-demo
labels:
workload: secret-agent
spec:
replicas: 10
ateomImage: ko://github.com/agent-substrate/substrate/cmd/ateom-gvisor
sandboxClass: gvisor
template:
labels:
project: agent-platform
annotations:
policy.example.com/exemption: sandbox-host
resources:
limits:
cpu: "2"
memory: 4Gi
Configuration des Accélérateurs GPU
Un pool GPU exige une allocation sur des nœuds compatibles ainsi qu’une requête explicite nvidia.com/gpu dans la section des ressources. Cette configuration active l’injection de périphériques via CDI et le proxy NVML/CUDA dans gVisor.
apiVersion: ate.dev/v1alpha1
kind: WorkerPool
metadata:
name: gpu-pool
namespace: ate-demo
spec:
replicas: 5
ateomImage: my-registry/ateom-gvisor-glibc@sha256:d8b2e5917482a6f8ec473180c4217be574ef210c4bc172fb6faef35650125867
template:
nodeSelector:
cloud.google.com/gke-accelerator: nvidia-tesla-t4
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
priorityClassName: substrate-workers
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: "1"
memory: 2Gi
nvidia.com/gpu: "1"
Prérequis et contraintes pour les pools GPU :
- Image
ateom-gvisorbasée sur glibc (ex: construite viaKO_DEFAULTBASEIMAGE=debian:stable-slim ko build ./cmd/ateom-gvisor) afin d’exécuternvidia-ctk. - Présence de
nvidia-ctksur l’hôte sous/usr/local/nvidia/toolkit. - Pilotes NVIDIA montés dans le conteneur sous
/usr/local/nvidia. - Exécution exclusive sous l’environnement
gvisoravec--nvproxy. - Limite majeure : La suspension échoue si un contexte CUDA reste ouvert en mémoire GPU. Les processus doivent libérer la carte avant la création d’un instantané.
2. ActorTemplate : Spécification des Agents
L’ActorTemplate spécifie le code, les variables d’environnement, les sondes de disponibilité et les règles de persistance.
apiVersion: ate.dev/v1alpha1
kind: ActorTemplate
metadata:
name: secret-agent
namespace: ate-demo
spec:
sandboxClass: gvisor
workerSelector:
matchLabels:
workload: secret-agent
snapshotsConfig:
location: gs://my-bucket/secret-agent
volumes:
- name: system-info
systemInfo:
dataSources:
- actorMetadata:
items:
- field: name
path: actor-name
- field: atespace
path: atespace
- field: uid
path: actor-uid
containers:
- name: agent
image: gcr.io/my-project/my-agent@sha256:5b328bcfa7f4a7c81d3f9b2d8e030248c8959d280e5b729e1d8be8d5d4d39f7a
readyz:
httpGet:
path: /readyz
port: 80
securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
volumeMounts:
- name: system-info
mountPath: /run/ate
Détails d’Exécution de la Sonde de Disponibilité (readyz)
La sonde readyz est interrogée directement par l’agent ateom à l’adresse IP interne du conteneur (actuellement 169.254.17.2). La boucle de scrutation émet des requêtes HTTP avec un intervalle de 500µs et un délai maximal de 30 secondes. Lorsque chaque conteneur définit cette sonde, le contrôleur ignore la temporisation standard de 20 secondes avant la prise du Golden Snapshot, réduisant ainsi le temps d’enregistrement initial.
3. SandboxConfig : Découplage des Runtimes
La ressource cluster SandboxConfig isole la version des binaires bas niveau (runsc ou hyperviseur) de la définition des templates applicatifs.
apiVersion: ate.dev/v1alpha1
kind: SandboxConfig
metadata:
name: gvisor-default
spec:
sandboxClass: gvisor
default: true
pauseImage: "registry.k8s.io/pause:3.10.2@sha256:f548e0e8e3dc1896ca956272154dde3314e8cc4fde0a57577ee9fa1c63f5baf4"
assets:
amd64:
gvisor:
url: "gs://gvisor/releases/release/20260803/x86_64/gvisor.tar.bz2"
sha256: "9e7a5fcc2cbd28c9cd4af910a9327abcf07a8efcce242c285b860d79010c2db5"
arm64:
gvisor:
url: "gs://gvisor/releases/release/20260803/aarch64/gvisor.tar.bz2"
sha256: "294d54dea2a18bcd2614a4b5072d6f32f0e8938f9e6e71c9e86b843c4a7b707b"
Organisation du Stockage et Isolation Multi-Tenant
Les données d’instantanés suivent une arborescence stricte basée sur la directive snapshotsConfig.location :
<location>/snapshots/<atespace>/<snapshot-name>
Cette hiérarchie permet d’appliquer des stratégies de contrôle d’accès granulaires au niveau du stockage objet :
# Stratégie IAM Google Cloud pour isoler les lectures au seul tenant 'team-a'
- members: ["serviceAccount:node-runtime@my-project.iam.gserviceaccount.com"]
role: roles/storage.objectViewer
condition:
title: team-a-snapshots
expression: >
resource.name.startsWith(
"projects/_/buckets/my-bucket/objects/secret-agent/snapshots/team-a/")
API de Contrôle gRPC et Gestion des Identités
Le serveur ate-api-server expose le service central de contrôle des flux d’exécution.
Méthodes du service ateapi.Control :
- CreateActor : Enregistre l’acteur logique à partir d’un
ActorTemplate. - UpdateActor : Modifie les champs éligibles (comme
worker_selector). Requiert les champsuid,versionet unupdate_maskexplicite pour garantir des écritures cohérentes en lecture-modification-écriture. - ResumeActor : Réactive l’acteur sur un worker disponible. Le paramètre optionnel
boot: trueforce un démarrage à froid. - SuspendActor : Capture la mémoire et l’état des disques vers le stockage durable.
- DeleteActor : Supprime l’acteur. Par défaut, seuls les acteurs suspendus ou crashés peuvent être purgés, sauf si
any_state: trueest spécifié. - GetActor / ListActors : Récupère l’état instantané des acteurs enregistrés.
- ListWorkers : Énumère les pods physiques et leurs assignations respectives.
Le service ateapi.ActorIdentity permet l’émission d’identités stables pour les agents migrant d’un nœud à un autre :
- MintJWT : Génère un jeton JWT compatible OIDC.
- MintCert : Signe une demande de certificat CSR pour l’établissement de sessions mTLS sous le schéma SPIFFE
spiffe://substrate-actor.local/atespace/${atespace}/actor/${actor_name}.
Ces méthodes exigent que l’appelant s’authentifie via le certificat de pod d’atelet, que l’acteur soit en cours d’exécution active, et que le worker associé réside sur le même nœud que le superviseur appelant.
Démonstrations et Intégrations dans l’Écosystème
Plusieurs modèles et applications types valident le comportement de la plateforme :
- Counter Demo : Serveur HTTP en Go illustrant la préservation d’état en mémoire vive au fil des cycles de veille.
- Sandbox Demo (Antigravity) : Environnement sous Alpine Linux autorisant l’exécution de commandes shell avec conservation des modifications du système de fichiers.
- Claude Code Multiplex : Multiplexage massif d’environnements de développement interactifs pour assistants de programmation.
- Request Parking : Rétention des requêtes entrantes au niveau du routeur lors des saturations temporaires de pools de workers, évitant les erreurs HTTP 503.
- Autoscaled WorkerPool : Dimensionnement automatique basé sur l’assignation réelle des workers via Prometheus Adapter et HPA.
- Frameworks compatibles : Intégration transparente avec LangChain, Model Context Protocol (MCP), Agent Development Kit (ADK) et Agent Executor.
Limitations Techniques, Risques et Communauté
Le projet se trouve à un stade précoce de son développement. Les interfaces de programmation restent sujettes à des ruptures de compatibilité ascendante. Le système prend en charge la version stable actuelle de Kubernetes ainsi que la version mineure précédente.
Pour participer aux échanges techniques :
- Groupe Google :
ate-dev - Canaux CNCF Slack :
#substrate-userset#substrate-dev - Réunion communautaire hebdomadaire le jeudi de 10h00 à 11h00 PST