23 Implantação do Agente
A implantação de um agente transforma seu agente em um aplicativo hospedado.
Você pode implantar um agente na mesma computação de IA anexada ao playground ou a outra computação de IA. Quando você implanta as alterações mais recentes no seu agente na computação de IA anexada, o agente implantado representa um snapshot do agente no momento da implantação. Para atualizar o agente implantado para a versão mais recente, você precisa reimplantar o agente.
Cada agente tem um URL de implantação estável que depende da chave de agente exclusiva. A reimplantação do agente várias vezes substitui o agente por trás do URL de implantação.
- Um agente só pode ser implantado em um cluster de computação de IA a qualquer momento.
- A implantação do mesmo agente várias vezes no mesmo cluster de computação AI substitui a iteração implantada anteriormente do agente.
Depois de implantar um agente, você poderá recuperar o URI do chat para emitir consultas de forma programática e recuperar respostas do agente na guia Detalhes do seu agente.

O URL do ponto final é estável e está vinculado a cada agente. O URL inclui o agentID exclusivo designado a cada agente. Em outras palavras, se você cancelar a implantação de um agente e implantá-lo novamente, o URL permanecerá o mesmo. O benefício é que você não precisa modificar o código do cliente que está chamando o ponto final. A desvantagem é que você pode substituir um agente na produção.
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/{protocol}oci-regioncorresponde à região da instância da AI Data Platform;agentIdé o id exclusivo associado ao agenteprotocolé o protocolo de comunicação:chatque segue o formato da API de Respostas do OpenAI ea2aque segue o protocolo de comunicação entre agentes. Ambos os protocolos estão disponíveis para cada ponto final do agente. Para obter mais informações, consulte Implantação do Agente A2A.
Observação:
Dois cálculos de IA são listados na guia Detalhes. O Anexado ao AI Compute é usado para testar o agente no playground. O serviço Implantado no AI Compute hospeda o agente implantado.O campo URL do ponto final é preenchido depois que você implanta seu agente. Você pode chamar esse URL de ponto final do seu aplicativo de produção.
Implantar um Agente
Você implanta agentes que criou e configurou para que outros usuários possam vê-los e usá-los em sua instância da AI Data Platform.
Implantar um Agente com o OAuth2
Você pode implantar agentes que criou e configurou para usar a autenticação OAuth2 para estabelecer conexão com provedores de identidades externos.
Cancelar Implantação de um Agente
Você pode optar por cancelar a implantação dos agentes para os quais tem permissões de GERENCIAMENTO, tornando-os indisponíveis para uso.
Implantação do Agente A2A
O protocolo Agent2Agent (A2A) é um padrão aberto para comunicação entre agentes independentes de IA, incluindo agentes criados com diferentes estruturas, hospedados por diferentes fornecedores ou executados como sistemas remotos opacos.
Seu objetivo é dar a esses agentes um modelo de interação compartilhada para que eles possam descobrir os recursos uns dos outros, negociar formatos de entrada/saída suportados, delegar ou colaborar em tarefas e trocar informações com segurança sem expor memória interna, ferramentas ou detalhes de implementação. Para obter mais informações, consulte Protocolo A2A (Agent2Agent).
A2A destina-se a resolver a interoperabilidade do agente: em vez de cada integração de agente ser personalizada, um cliente ou outro agente pode interagir com qualquer agente remoto compatível com A2A usando um conjunto comum de conceitos e operações. As especificações se concentram em mensagens, tarefas, peças, artefatos, atualizações de streaming e notificações push; ele oferece suporte a respostas síncronas, trabalho assíncrono de longa execução, streaming e padrões de segurança/autorização de estilo empresarial.
Na Oracle AI Data Platform, todos os agentes implantados recebem um caminho de chamada /A2A que pode ser chamado por aplicativos clientes A2A.
O que é um cartão de agente?
Um Cartão de Agente é um documento de metadados JSON publicado por um servidor A2A. No AIDP, o servidor A2A é a computação AI que hospeda a implantação do seu agente.
O cartão descreve a identidade do agente, o ponto final de serviço, protocolos/transportes suportados, recursos, habilidades, modos de entrada/saída suportados e requisitos de autenticação; os clientes o usam para descobrir se o agente é adequado e como chamá-lo. Um cartão de agente devidamente documentado é um requisito do protocolo A2A.
Os cartões de agente no AI Data Platform Workbench estão no estado Preliminar, o que significa que o agente não foi implantado ou Publicado, o que significa que o cartão foi implantado ao lado do agente.
Ações do Cartão do Agente
Durante o desenvolvimento de um agente, o cartão está disponível no menu Ações do agente.
- O rascunho do cartão reflete o estado atual do agente em desenvolvimento.
- O cartão publicado corresponde a um snapshot do cartão obtido quando o agente foi implantado. O cartão publicado reflete o estado do agente implantado.
Campos do cartão do agente
O AI Data Platform Workbench suporta um subconjunto dos campos atuais de cartão do agente de protocolo A2A, disponíveis aqui: Protocolo A2A - Cartão do Agente.
| Campo | Obrigatório | Descrição |
|---|---|---|
name |
Sim | Um nome legível para o agente. Exemplo: "Agente de Receita" |
description |
Sim | Uma descrição legível do agente, auxiliando os usuários e outros agentes na compreensão de seu propósito. Exemplo: "Agente que ajuda os usuários com receitas e culinária". |
Agent Version |
Sim | A versão do agente. Exemplo: "1.0.0" de |
Documentation URL |
No | Um URL que fornece documentação adicional sobre o agente. |
Provider - Organization |
No | O provedor de serviços do agente. |
Provider - URL |
No | O URL do provedor de serviços. |
Capabilities |
Sim | Conjunto de recursos A2A suportado pelo agente.
Somente |
Skills
|
Sim | Habilidades representam as habilidades de um agente. É em grande parte um conceito descritivo, mas representa um conjunto mais focado de comportamentos que o agente provavelmente terá sucesso. As habilidades representam uma matriz de AgentSkill. |
Cada AgentSkill é feito de vários campos que documentam os recursos do agente. Definir as habilidades do agente no cartão do agente é a operação mais demorada e é um processo iterativo. As habilidades podem ser editadas (juntamente com o restante do cartão de agente) no cartão de agente preliminar antes da implantação.
Observação:
inputModes, outputModes e securityRequirements são fornecidos pelo AI Data Platform Workbench e não podem ser modificados.
| Campo | Obrigatório | Descrição |
|---|---|---|
Skill ID |
Sim | Um identificador exclusivo para a habilidade do agente. |
Skill Name |
Sim | Um nome legível para a habilidade. |
Description |
Sim | Uma descrição detalhada da habilidade. |
Tags |
Sim | Um conjunto de palavras-chave que descreve os recursos da habilidade. |
Examples |
No | Exemplos de prompts ou cenários que essa habilidade pode tratar. |
Caminho A2A do Ponto Final de Implantação do Agente
Um caminho /a2a é exposto no URL de um agente implantado, além de /chat.
Por exemplo, um agente exporá esses caminhos para clientes externos:
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/chathttps://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a
Ambos os caminhos (/chat, /a2a) podem ser consumidos por clientes separados.
Variáveis de Sessão no A2A
Os valores de variáveis de sessão podem ser passados para um agente A2A no campo metadata da mensagem. O trecho de código JSON abaixo mostra o payload de uma mensagem do usuário emitida para o agente a2a com três variáveis de sessão: userName, geoLocation e 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"
}
Exemplo: Chamando um Agente A2A com a CLI do OCI (Não 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>"
Exemplo: Chamando um Agente A2A com a CLI do 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>"
Exemplo: A2A Client SDK
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)}"Editar um Rascunho de Cartão de Agente
Você pode editar o cartão de agente para um agente que ainda não foi implantado.
Editar um Cartão de Agente Publicado
Você pode modificar um cartão de agente publicado sem ter que cancelar a implantação ou reimplantar um agente.
Observação:
As alterações feitas em um cartão publicado são imediatamente refletidas no arquivo agent-card.json acessível aos clientes A2A.https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a/agent-card.json







