Guide de développement d'agent
English version: ../../en/guides/agent-development.md
Ce guide montre comment écrire, valider, tester, enregistrer, exécuter, versionner et retirer un agent de la Navin
Platform. Il s'adresse aux développeurs qui ont le rôle developer ou tenant_admin ; suspendre ou arrêter
définitivement un agent demande tenant_admin ou security_officer. Comptez environ une heure pour un premier agent
à partir du modèle.
Concept
Un agent est un manifeste versionné de kind Agent accompagné de code exécuté par le moteur Navin. Le Control Plane
conserve chaque version du manifeste, démarre les exécutions (runs), applique les politiques et le budget, et
enregistre chaque étape. L'agent n'appelle jamais directement un fournisseur de modèle : chaque appel de modèle passe
par la passerelle IA, chaque appel d'outil par la passerelle d'outils, et chaque secret reste dans le Credential
Broker.
Le cycle de vie d'un agent est : active (nouveaux runs acceptés), suspended (kill switch réversible, nouveaux runs
refusés) et killed (définitif, ne peut jamais être repris).
Manifeste
Un agent est décrit par un manifeste de kind Agent (contracts/v1/agent-manifest.schema.json) : runtime (engine, entrypoint, limits), models (effort, max_output_tokens), memory, permissions (data_classification_max, scopes), autonomy (level, max_steps, max_subagents, max_depth, human_approval_for), evaluation et observability. Le modèle sdks/python/src/enterprise_ai/templates/agent-basic/agent.yaml en est un exemple valide.
enterprise-ai create agent invoice-agent --template rag-agent
enterprise-ai validate -f invoice-agent/agent.yaml
Champs du manifeste
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
apiVersion | chaîne | oui | Toujours enterprise-ai.io/v1. |
kind | chaîne | oui | Toujours Agent. |
metadata.name | chaîne | oui | Identifiant de style DNS, en minuscules, 128 caractères au plus. |
metadata.version | semver | oui | Version du manifeste ; une version publiée est immuable. |
metadata.owner | chaîne | oui | Équipe ou adresse responsable (3 à 200 caractères). |
metadata.description, metadata.labels | chaîne, table | non | Description libre et étiquettes (l'étiquette environment est posée par deploy). |
spec.description | chaîne | oui | Ce que fait l'agent. |
spec.purpose | chaîne | non | Finalité métier, transmise à la politique agent.run. |
spec.risk_level | énumération | non | minimal, limited, high ou unacceptable (refusé à l'enregistrement). |
spec.identity | objet | non | spiffe_id et service_account de la charge de travail. |
spec.runtime | objet | oui | engine (langgraph, temporal, custom), entrypoint, image, sandbox (none, gvisor, kata, wasm), limits. |
spec.models | tableau | oui | Chaque élément : model_id, role (primary, fallback, summarizer, embedding, judge, vision, speech), effort (de none à max), max_output_tokens. |
spec.tools | tableau | non | Chaque élément : ref (comme tool:crm-search@1.2.0), scopes, requires_approval. |
spec.mcp_servers, spec.skills, spec.connectors, spec.knowledge_bases, spec.channels | tableau | non | Références typées des objets que l'agent peut utiliser ; une skill absente de cette liste est refusée par le Skill Loader. |
spec.memory | objet | non | session, persistent, ttl_days. |
spec.permissions | objet | oui | data_classification_max (public < internal < confidential < restricted < secret), scopes, allowed_regions. |
spec.autonomy | objet | oui | level (assisted, supervised, autonomous), max_steps, max_subagents, max_depth, human_approval_for. |
spec.subagents | tableau | non | Références des agents auxquels il peut déléguer. |
spec.budgets | objet | non | max_cost, max_input_tokens, max_output_tokens, max_requests, max_tool_calls, max_duration_seconds, period. |
spec.schedules, spec.triggers | tableau | non | Démarrages planifiés et sur événement. |
spec.evaluation | objet | non | suites (références) et block_on_failure ; lu par le contrôle qualité de deploy. |
spec.observability | objet | non | trace_sampling (0 à 1) et log_prompts (none, hashed, redacted, full). |
Avant de commencer
- Le SDK Python et sa CLI sont installés et connectés :
enterprise-ai doctorne signale aucun FAIL. - Votre compte a le rôle
developerdans le tenant, et le droitagents:runpour démarrer des runs. - Le modèle référencé est approuvé dans le registre des modèles du tenant.
Étapes
-
Créer le projet à partir d'un modèle. Le modèle fournit un manifeste, le code, un prompt versionné, une politique OPA et des tests qui passent déjà ; partir de lui évite un premier manifeste invalide.
enterprise-ai create agent invoice-agent --template agent-basicLes modèles sont
agent-basic,rag-agentetsecure-agent(un alias deagent-basic).Résultat attendu : la commande liste les fichiers créés et se termine par le manifeste déclaré valide selon
agent-manifest.En cas d'échec : un code de sortie 1 avec « exists » signifie que le dossier existe déjà ; ajoutez
--forceou choisissez un autre nom. -
Modifier le manifeste. Renseignez
spec.description, le modèle, les droits et l'autonomie. Gardezpermissions.data_classification_maxetscopesaussi réduits que la tâche le permet : ils bornent chaque skill, outil et connecteur que l'agent peut charger. Vous pouvez aussi le modifier dans Agents > Registre > agent > Manifeste.Résultat attendu : le manifeste ne décrit que ce dont l'agent a besoin.
En cas d'échec : voyez la table des champs ci-dessus ; une skill ou un outil que l'agent appellera doit figurer dans
spec. -
Valider le manifeste. La CLI le vérifie selon le contrat v1, hors ligne, avant tout appel au Control Plane.
enterprise-ai validate -f invoice-agent/agent.yamlRésultat attendu : code de sortie 0, le document est valide.
En cas d'échec : le code de sortie 1 liste chaque champ invalide avec son chemin JSON ; corrigez-le et relancez la commande.
-
Tester en local. Lancez les tests unitaires et les tests OPA du projet, puis une suite d'évaluation sur le point d'entrée.
cd invoice-agentpython -m pytest -q testsenterprise-ai test authzenterprise-ai test -f suite.yaml --entrypoint agent:buildsuite.yaml: une suite d'évaluation du projet (cas et métriques). Voir le guide des tests.Résultat attendu : chaque test passe et la suite indique
passed.En cas d'échec :
enterprise-ai testrenvoie 1 quand l'évaluation est sous l'objectif, ou quandopaoufgan'est pas installé. -
Enregistrer l'agent. POST /v1/agents crée l'agent ou ajoute une version et la rend courante. L'appelant devient propriétaire ReBAC.
enterprise-ai apply -f agent.yamlRésultat attendu :
apply_statusvautcreated,version_addedouunchanged.En cas d'échec : 422
invalid_manifest(contrat), 422agent_risk_unacceptable(niveau de risque), 409version_immutable(même version, autre contenu : augmentezmetadata.version). -
Déployer après le contrôle qualité.
deployvalide, applique, lance le contrôle POST /v1/evaluations/gates/check sur les suites despec.evaluation, puis pose l'étiquetteenvironment.enterprise-ai deploy agent -f agent.yaml --env stagingRésultat attendu : l'agent est déployé en
staging.En cas d'échec : le code de sortie 1 signifie que le contrôle qualité a refusé la promotion ; son rapport est affiché.
-
Démarrer un run. POST /v1/agents/{agent_id}/runs crée un run et renvoie son Execution Contract. La politique
agent.runest d'abord évaluée et le budget du manifeste est appliqué. Dans le portail : Agents > Registre > agent > Démarrer une exécution.enterprise-ai run start invoice-agent --task '{"invoice_media_id": "med_01HZX3K9"}' --followenterprise-ai runs list --agent agt_ap --state runningRésultat attendu : le run passe par
pending,running, puissucceeded;--followaffiche ses événements.En cas d'échec : 409
agent_not_active, 403policy_denied, 422invalid_budget; avec--follow, le code de sortie 1 signifie que le run s'est terminé enfailed,cancelledoutimed_out. -
Publier une nouvelle version. Augmentez
metadata.version, validez, puis appliquez de nouveau. GET /v1/agents/{agent_id}/versions liste chaque version, de la plus récente à la plus ancienne, aveccurrentsur celle en service.Résultat attendu :
apply_statusvautversion_added; les nouveaux runs utilisent la nouvelle version.En cas d'échec : 409
version_immutablesignifie que le numéro de version n'a pas été augmenté. -
Suspendre, reprendre, arrêter définitivement ou supprimer. POST /v1/agents/{agent_id}/suspend passe l'agent et ses runs actifs en
suspended. POST /v1/agents/{agent_id}/resume ouvre une approbation (202pending_approval). POST /v1/agents/{agent_id}/kill annule chaque run actif et termine l'agent pour toujours. DELETE /v1/agents/{agent_id} supprime l'agent et ses versions. Dans le portail : Agents > Registre > agent > Suspendre, Reprendre ou Arrêter définitivement.client.agents.suspend("agt_ap", reason="incident INC-42")client.agents.resume("agt_ap")Résultat attendu : la réponse liste
affected_runs.En cas d'échec : 409
agent_killed(déjà arrêté), 409kill_switch_active(un confinement SOC retient l'agent), 409agent_has_active_runsà la suppression.
L'arrêt définitif (kill) est irréversible : un agent arrêté ne peut jamais être repris. Utilisez la suspension pour une investigation.
Enregistrer et exécuter
POST /v1/agents crée l'agent, GET /v1/agents/{agent_id}/versions liste ses versions, POST /v1/agents/{agent_id}/runs démarre un run, POST /v1/runs/{run_id}/heartbeat signale un run long (action stop : checkpoint puis sortie), POST /v1/agents/{agent_id}/suspend le suspend.
import yaml
agent = client.agents.create(yaml.safe_load(open("agent.yaml")))
run = client.agents.run("agt_ap", task={"invoice_media_id": "med_01HZX3K9"}, idempotency_key="inv-2291")
run = client.runs.get(run["id"])
Une Idempotency-Key répétée renvoie le premier run. Un run long envoie des heartbeats : la réponse action vaut
continue, ou stop avec une reason (run_cancelled, run_terminal, run_suspended, agent_killed,
agent_suspended). Sur stop, écrivez un checkpoint et sortez ; POST /v1/runs/{run_id}/resume le relance avec
from_last_checkpoint, restart_step ou restart_run.
Règles
Aucun appel direct à un fournisseur de modèle : tout passe par la passerelle. Aucun secret dans le code ni dans le manifeste. Un sous-agent reçoit toujours une délégation restreinte. Le moteur d'exécution Navin est AgentLoop, AgentRunner, SubagentManager, RunPlan et MessageBus ; LangGraph et Temporal sont des adaptateurs optionnels.
enterprise-ai deploy agent -f agent.yaml --env staging
enterprise-ai runs list --agent agt_ap --state running
Vérifier
enterprise-ai agent inspect invoice-agent affiche l'agent tel que le Control Plane le conserve : statut active, le
manifeste de la version courante et runs, le nombre de runs par état.
Dépannage
| Symptôme | Cause | Correction |
|---|---|---|
422 invalid_manifest | Le manifeste ne respecte pas contracts/v1/agent-manifest.schema.json. | Lancez enterprise-ai validate -f agent.yaml et corrigez les champs listés. |
422 agent_risk_unacceptable | spec.risk_level vaut unacceptable. | Un tel agent ne peut pas être enregistré ; réduisez son périmètre. |
409 version_immutable | La version existe avec un autre contenu. | Augmentez metadata.version. |
409 agent_not_active | L'agent est suspended ou killed. | Reprenez-le (approbation) ou enregistrez un nouvel agent. |
403 policy_denied | La politique agent.run a refusé le run. | Lisez la décision dans Sécurité et gouvernance ; vérifiez le risque, la finalité et la classification. |
422 invalid_budget | La requête tentait d'assouplir le budget du manifeste. | Une requête ne peut que resserrer budgets. |
409 idempotency_conflict | La même Idempotency-Key a servi pour un autre agent. | Utilisez une clé par requête logique. |
409 subagent_depth_exceeded, subagent_count_exceeded | Délégation au-delà de max_depth ou max_subagents. | Augmentez les limites d'autonomie ou réduisez la délégation. |
409 run_not_resumable | Le run a échoué sur budget_exceeded, max_steps_exceeded, killed ou approval_rejected. | Reprenez avec restart_run. |
409 no_checkpoint | Aucun checkpoint depuis lequel reprendre. | Utilisez restart_step ou restart_run. |