23 Déploiement de l'agent
Le déploiement d'un agent transforme l'agent en application hébergée.
Vous pouvez déployer un agent dans le même calcul d'IA attaché à son terrain de jeu ou à un autre calcul d'IA. Lorsque vous déployez les dernières modifications apportées à votre agent sur le calcul AI attaché, l'agent déployé représente un cliché de l'agent au moment du déploiement. Pour mettre à jour l'agent déployé vers la dernière version, vous devez redéployer l'agent.
Chaque agent dispose d'une URL de déploiement stable qui dépend de la clé d'agent unique. Le redéploiement multiple de l'agent écrase l'agent derrière l'URL de déploiement.
- Un agent ne peut être déployé que sur un seul cluster de calcul AI à un moment donné.
- Le déploiement du même agent plusieurs fois sur le même cluster de calcul AI écrase l'itération précédemment déployée de l'agent.
Une fois que vous avez déployé un agent, vous pouvez extraire l'URI de discussion pour émettre des requêtes par programmation et extraire les réponses de l'agent à partir de l'onglet Détails de l'agent.

L'URL endpoint est stable et est liée à chaque agent. L'URL inclut l'ID d'agent unique affecté à chaque agent. En d'autres termes, si vous annulez le déploiement d'un agent et que vous le déployez à nouveau, l'URL reste identique. L'avantage est que vous n'avez pas à modifier le code client appelant l'adresse, l'inconvénient est que vous pouvez écraser un agent en production.
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/{protocol}oci-regioncorrespond à la région d'instance AI Data Platform ;agentIdest l'ID unique associé à l'agent.protocolest le protocole de communication :chatqui suit le format de l'API des réponses OpenAI eta2aqui suit le protocole de communication agent-agent. Les deux protocoles sont disponibles pour chaque adresse d'agent. Pour plus d'informations, reportez-vous à Déploiement d'agent A2A.
Remarques :
Deux calculs AI sont répertoriés dans l'onglet Détails. L'option Attaché à AI Compute permet de tester l'agent dans le playground de test. L'option Déployé sur AI Compute héberge l'agent déployé.Le champ URL endpoint est renseigné après le déploiement de l'agent. Vous pouvez appeler cette URL d'adresse à partir de l'application de production.
Déployer un agent
Vous déployez les agents que vous avez créés et configurés afin que les autres utilisateurs puissent les voir et les utiliser dans votre instance AI Data Platform.
Déployer un agent avec OAuth2
Vous pouvez déployer des agents que vous avez créés et configurés pour utiliser l'authentification OAuth2 afin de vous connecter à des fournisseurs d'identités externes.
Annuler le déploiement d'un agent
Vous pouvez choisir d'annuler le déploiement des agents pour lesquels vous disposez des droits d'accès MANAGE, ce qui les rend indisponibles.
Déploiement d'agent A2A
Le protocole Agent2Agent (A2A) est une norme ouverte pour la communication entre les agents d'IA indépendants, y compris les agents construits avec différentes structures, hébergés par différents fournisseurs ou exécutés en tant que systèmes distants opaques.
Son but est de donner à ces agents un modèle d'interaction partagé afin qu'ils puissent découvrir les capacités de l'autre, négocier les formats d'entrée/sortie pris en charge, déléguer ou collaborer sur des tâches et échanger des informations en toute sécurité sans exposer la mémoire interne, les outils ou les détails d'implémentation. Pour plus d'informations, reportez-vous à la section Agent2Agent (A2A) Protocol.
A2A est destiné à résoudre l'interopérabilité des agents : au lieu que chaque intégration d'agent soit personnalisée, un client ou un autre agent peut interagir avec n'importe quel agent distant compatible A2A en utilisant un ensemble commun de concepts et d'opérations. La spécification se concentre sur les messages, les tâches, les pièces, les artefacts, les mises à jour en continu et les notifications push. Elle prend en charge les réponses synchrones, le travail asynchrone à longue durée d'exécution, la diffusion en continu et les modèles d'authentification/sécurité de type entreprise.
Dans Oracle AI Data Platform, tous les agents déployés disposent d'un chemin d'appel /A2A qui peut être appelé par les applications client A2A.
Qu'est-ce qu'une carte agent ?
Une carte d'agent est un document de métadonnées JSON publié par un serveur A2A. Dans AIDP, le serveur A2A est le calcul AI qui héberge votre déploiement d'agent.
La carte décrit l'identité de l'agent, l'adresse de service, les protocoles/transports pris en charge, les capacités, les compétences, les modes d'entrée/sortie pris en charge et les exigences d'authentification. Les clients l'utilisent pour déterminer si l'agent convient et comment l'appeler. Une carte d'agent correctement documentée est une exigence du protocole A2A.
Les cartes d'agent dans AI Data Platform Workbench sont à l'état Brouillon, ce qui signifie que l'agent n'a pas été déployé ou Publié, ce qui signifie que la carte a été déployée avec l'agent.
Actions de carte d'agent
Pendant le développement d'un agent, la carte est disponible dans le menu Actions de l'agent.
- Le projet de carte reflète l'état actuel de l'agent en développement.
- La carte publiée correspond à un instantané de la carte prise lors du déploiement de l'agent. La carte publiée reflète l'état de l'agent déployé.
Champs de carte d'agent
AI Data Platform Workbench prend en charge un sous-ensemble des champs de carte d'agent de protocole A2A actuels, disponibles ici : Protocole A2A - Carte d'agent.
| Champ | Obligatoire | Description |
|---|---|---|
name |
Oui | Nom lisible par l'utilisateur pour l'agent. Exemple : "Agent recette" |
description |
Oui | Description lisible par l'homme de l'agent, qui aide les utilisateurs et autres agents à comprendre son but. Exemple : "Agent qui aide les utilisateurs avec des recettes et de la cuisine." |
Agent Version |
Oui | Version de l'agent. Exemple : "1.0.0" |
Documentation URL |
No | URL fournissant une documentation supplémentaire sur l'agent. |
Provider - Organization |
No | Fournisseur de services de l'agent. |
Provider - URL |
No | URL du fournisseur de services. |
Capabilities |
Oui | Jeu de fonctionnalités A2A pris en charge par l'agent.
Seul |
Skills
|
Oui | Les compétences représentent les capacités d'un agent. Il s'agit en grande partie d'un concept descriptif, mais il représente un ensemble de comportements plus ciblés que l'agent est susceptible de réussir. Les compétences représentent un éventail de compétences d'agent. |
Chaque AgentSkill est constitué de plusieurs champs documentant les capacités de l'agent. La définition des compétences de l'agent dans la carte d'agent est l'opération la plus longue et un processus itératif. Les compétences peuvent être modifiées (ainsi que le reste de la carte d'agent) dans la carte d'agent provisoire avant le déploiement.
Remarques :
inputModes, outputModes et securityRequirements sont fournis par AI Data Platform Workbench et ne peuvent pas être modifiés.
| Champ | Obligatoire | Description |
|---|---|---|
Skill ID |
Oui | Identificateur unique de la brique de l'agent. |
Skill Name |
Oui | Nom lisible par l'utilisateur pour la brique. |
Description |
Oui | Description détaillée de la brique. |
Tags |
Oui | Ensemble de mots-clés décrivant les capacités de la brique. |
Examples |
No | Exemples d'invites ou de scénarios que cette brique peut gérer. |
Chemin A2A de l'adresse de déploiement d'agent
Un chemin /a2a est exposé dans l'URL d'un agent déployé en plus de /chat.
Par exemple, un agent exposera ces chemins aux clients externes :
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/chathttps://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a
Les deux chemins (/chat, /a2a) peuvent être utilisés par des clients distincts.
Variables de session dans A2A
Les valeurs des variables de session peuvent être transmises à un agent A2A dans le champ de message metadata. Le fragment de code JSON ci-dessous affiche la charge utile d'un message utilisateur envoyé à l'agent a2a avec trois variables de session : userName, geoLocation et os :
{
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"contextId": "session_12345",
"taskId": "task_67890",
"message": {
"role": "user",
"parts": [
{
"text": "What is the current status of my order?",
}
],
"metadata": {
"sessionvariables.userName": "George",
"sessionvariables.geoLocation": “Dallas, TX”,
"sessionvariables.os": "mobile_ios"
}
}
},
"id": "rpc-99821"
}
Exemple : appel d'un agent A2A avec l'interface de ligne de commande OCI (non-streaming)
oci raw-request \
--http-method POST \
--auth security_token \
--request-body '{
"id": "<your-request-id>",
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"configuration": {
"acceptedOutputModes": [
"text/plain",
"text"
]
},
"message": {
"contextId": "<your-context-id>",
"kind": "message",
"messageId": "<your-message-id>",
"parts": [
{
"kind": "text",
"text": "What is the capital of India?"
}
],
"role": "user"
}
}
}' \
--request-headers '{
"x-session-id": "<your-session-id>",
"dh-user-principal": "<your-user-principal>"
}' \
--target-uri " <your-a2a-agent-endpoint-url>"
Exemple : appel d'un agent A2A avec l'interface de ligne de commande OCI (Streaming)
oci raw-request \
--http-method POST \
--auth security_token \
--request-body '{
"id": "<your-request-id>",
"jsonrpc": "2.0",
"method": "message/stream",
"params": {
"configuration": {
"acceptedOutputModes": [
"text/plain",
"text"
]
},
"message": {
"contextId": "<your-context-id>",
"kind": "message",
"messageId": " <your-message-id>",
"parts": [
{
"kind": "text",
"text": "What is the capital of India?"
}
],
"role": "user"
}
}
}' \
--request-headers '{
"x-session-id": "<your-session-id>",
"dh-user-principal": "<user-principal>"
}' \
--target-uri "<your-a2a-agent-endpoint-url>"
Exemple : SDK client A2A
import asyncio
import json
import logging
import typing
from collections.abc import Iterator
import uuid
import httpx
import oci
from a2a.client import A2AClient, ClientFactory
from a2a.types import (
AgentCard,
Message,
Part,
Role,
TextPart,
SendMessageRequest,
MessageSendParams,
MessageSendConfiguration,
Task, SendMessageSuccessResponse, SendStreamingMessageRequest,
)
class OCIAuth(httpx.Auth):
"""httpx auth implementation using OCI signer via requests auth adapter."""
def __init__(self, signer: oci.signer.AbstractBaseSigner):
self._requests_auth = _OCIRequestsAuth(signer)
def auth_flow(self, request: httpx.Request) -> Iterator[httpx.Request]:
req = RequestsRequest(
method=request.method,
url=str(request.url),
headers=dict(request.headers),
data=request.content,
)
prepared: RequestsPreparedRequest = req.prepare()
prepared = self._requests_auth(prepared)
request.headers.update(dict(prepared.headers))
yield request
def getOCIAuth():
conf = oci.config.from_file(profile_name="DEFAULT")
token_file = conf['security_token_file']
token = None
with open(token_file, 'r') as f:
token = f.read()
private_key = oci.signer.load_private_key_from_file(conf['key_file'])
signer = oci.auth.signers.SecurityTokenSigner(token, private_key)
auth = OCIAuth(signer=signer)
return auth
async def _call_agent_with_a2a(agent_url: str, query: str, context_id: str,auth:OCIAuth) -> str:
"""Call an agent using the A2A protocol."""
try:
# Initialize OCI signer
#headers = {"dh-user-principal": "dh-user"}
headers = {"Accept": "*/*",
"dh-user-principal": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
async with httpx.AsyncClient(timeout=60.0, auth=auth,headers=headers) as hc:
agent_card = await _get_agent_card(agent_url,auth)
print(f"Agent card is {agent_card}")
client = A2AClient(httpx_client=hc, agent_card=agent_card)
# Create message
message = Message(
message_id=str(uuid.uuid4()),
context_id=context_id,
role=Role.user,
parts=[Part(root=TextPart(text=query))],
metadata={"sessionvariables.cred.mcp.weatherReportMCP.bearer": "valid-123"}
)
request = SendMessageRequest(
id=str(uuid.uuid4()), # Add the required id field
params=MessageSendParams(
message=message,
configuration=MessageSendConfiguration(acceptedOutputModes=["text/plain", "text"]),
),
)
#json_string = json.dumps(message, indent=4)
print(f"Send request : {request}")
response = await client.send_message(request)
logging.info("Received response from A2A server: %s", response.root.result)
# Extract response
result = response.root.result
# Handle different response types
if isinstance(result, Task):
# Task response
if result.artifacts:
# Extract text from artifacts
texts = []
for artifact in result.artifacts:
for part in artifact.parts:
if hasattr(part, "root") and hasattr(part.root, "text"):
texts.append(part.root.text)
return "\n".join(texts) if texts else "Task completed with no text response"
elif result.status and result.status.message:
logging.info(f"Received Task status {result.status.state} from A2A server and status message is {result.status.message}", result.status.message)
if result.status.state== "failed":
print("Failure observed in Task invocation")
for m_part in result.status.message.parts:
print(f"Error message { m_part.root.text}")
return get_message_text(result.status.message)
else:
return f"Task {result.id} status: {result.status.state if result.status else 'unknown'}"
elif isinstance(result, Message):
return get_message_text(result)
else:
logging.warning(f"Unexpected response type: {type(result)}")
return "Received response but unable to extract text"
except Exception as ex:
logging.error(f"Error calling agent at {agent_url}: {ex}", exc_info=True)
return f"Error communicating with agent: {str(ex)}"
async def _call_agent_with_a2a_with_stream(agent_url: str, query: str, context_id: str, auth: OCIAuth) -> str:
"""Call an agent using the A2A protocol with streaming (SSE) and return the final artifact text."""
try:
async with httpx.AsyncClient(timeout=60.0, auth=auth) as hc:
agent_card = await _get_agent_card(agent_url)
if not agent_card:
return "No Agent Card Found"
print(f"Agent card is {agent_card}")
client = A2AClient(httpx_client=hc, agent_card=agent_card)
message = Message(
message_id=str(uuid.uuid4()),
context_id=context_id,
role=Role.user,
parts=[Part(root=TextPart(text=query))],
)
request = SendStreamingMessageRequest(
id=str(uuid.uuid4()),
params=MessageSendParams(
message=message,
configuration=MessageSendConfiguration(acceptedOutputModes=["text/plain", "text"]),
),
)
print("Invoking Remote Agent request (beautified JSON):")
print(json.dumps(request.model_dump(), indent=2, ensure_ascii=False))
# Expected event types:
# - TaskStatusUpdateEvent (working/in-progress)
# - TaskArtifactUpdateEvent (contains Artifact.parts[].root.text) -> final output
final_artifact_text_parts: list[str] = []
async for event in client.send_message_streaming(request):
# Print each SSE event as-is (SDK object)
print(f"[A2A stream event] {event}")
try:
result = getattr(event.root, "result", None)
if not result:
continue
# TaskArtifactUpdateEvent and TaskStatusUpdateEvent are SDK types; to avoid tight coupling,
# extract by attribute presence.
artifact = getattr(result, "artifact", None)
if artifact and getattr(artifact, "parts", None):
for part in artifact.parts:
root = getattr(part, "root", None)
txt = getattr(root, "text", None)
if txt:
final_artifact_text_parts.append(txt)
except Exception:
# Keep streaming even if an event can't be parsed
continue
return "\n".join([t for t in final_artifact_text_parts if t]).strip() or "Stream completed (no artifact text)."
except Exception as ex:
logging.error(f"Error calling agent at {agent_url}: {ex}", exc_info=True)
return f"Error communicating with agent: {str(ex)}"Modifier une carte d'agent provisoire
Vous pouvez modifier la carte d'agent d'un agent qui n'est pas encore déployé.
Modifier une carte d'agent publiée
Vous pouvez modifier une carte d'agent publiée sans avoir à annuler le déploiement ou à redéployer un agent.
Remarques :
Les modifications apportées à une carte publiée sont immédiatement répercutées dans le fichier agent-card.json accessible aux clients A2A.https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a/agent-card.json







