Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
See how MongoDB 9.0 delivers up to 2x higher throughput.
MongoDB Branding Shape
Register now >
Docs Menu

Utilice la comunicación de agente a agente.

La comunicación entre agentes (A2A) permite que un agente descubra e invoque a otros agentes en el mismo proyecto en tiempo de ejecución. El motor de orquestación (OE) gestiona cada llamada realizando las siguientes acciones:

  • Valida el acceso

  • Crea una ejecución secundaria

  • Envía la solicitud al agente de destino.

  • Devuelve el resultado

Las garantías de intervención humana (HITL, por sus siglas en inglés) se aplican de extremo a extremo. Un agente de destino que suspende la llamada para su revisión humana la pausa en lugar de devolver un error.

A2A sigue esta secuencia cuando lo habilitas:

  1. Se añade un bloque a2a: al archivo agent.yaml. En su primera ejecución, la plataforma registra la configuración del agente en el OE, lo que permite que otros agentes del mismo proyecto puedan descubrir y llamar al agente.

  2. Cuando el OE envía una ejecución a su agente, inyecta un token de corta duración en el contexto de ejecución. Su agente utiliza ese token de forma transparente al llamar a otros agentes.

  3. Desde el código de su agente, expone A2A como herramientas LLM con app.a2a_tools() (recomendado) o llama al cliente A2A directamente a través de app._runtime.a2a para un enrutamiento determinista.

  4. El OE aplica el control de acceso, vincula la ejecución secundaria con la principal, la envía al destino y devuelve el resultado.

Agregue una sección a2a: a su archivo agent.yaml para que su agente sea detectable y se pueda invocar. Si omite esta sección o establece a2a.enabled en false, su agente permanecerá invisible para las llamadas A2A y será totalmente compatible con versiones anteriores de las implementaciones existentes.

Nota

Para probar A2A localmente, establezca la variable de entorno A2A_JWT_SECRET con el mismo valor en el archivo .env de cada agente que llame o sea llamado a través de A2A.

El siguiente ejemplo muestra una sección a2a: completamente configurada:

name: insurance-agent
entrypoint: insurance_agent.main:app
a2a:
enabled: true
allowed_callers:
- "ws-router-002"
skills:
- name: policy-lookup
description: Look up insurance policy details
example_input: '{"policy_id": "POL-123"}'
example_output: '{"status": "active", "premium": 240}'
- name: get-quote
description: Generate an insurance quote
input_modes:
- "text/plain"
output_modes:
- "text/plain"

La siguiente tabla describe los campos de la sección a2a: del archivo agent.yaml:

Campo
Tipo
predeterminado
Descripción

a2a.enabled

bool

false

Hace que el agente sea detectable y llamable a través de A2A. Cuando false, todos los demás campos a2a se ignoran.

a2a.allowed_callers

list[str]

[]

Los ID de espacio de trabajo tienen permiso para invocar a este agente. Una lista vacía permite cualquier agente habilitado para A2A en el mismo proyecto. Una lista no vacía actúa como una lista de permitidos.

a2a.skills

list[object]

[]

Habilidades que el agente anuncia para su descubrimiento. Cada entrada requiere un campo name y un campo description. Los campos example_input y example_output son opcionales. Las descripciones claras y específicas ayudan a otros agentes a decidir si este agente se ajusta a sus necesidades.

a2a.input_modes

list[str]

[]

Tipos de extensiones de correo de Internet multipropósito (MIME) que acepta el agente, por ejemplo text/plain o application/json. Se utiliza como filtro de detección.

a2a.output_modes

list[str]

[]

Tipos MIME que produce el agente. Se utiliza como filtro de detección.

Nota

Los identificadores name, skills, input_modes, output_modes y allowed_callers del agente se envían automáticamente al OE al iniciar. La descripción de texto libre y las etiquetas de capacidades que aparecen en los resultados de detección provienen de la tarjeta de agente del espacio de trabajo que se configura a través de los puntos finales del espacio de trabajo de API Gateway, no de agent.yaml.

Puedes llamar a otros agentes desde tu código de agente de dos maneras: exponiendo A2A como herramientas LLM (recomendado) o usando el cliente A2A directamente. Ambos métodos utilizan el mismo cliente subyacente. Elige el enfoque que prefieras según si deseas que LLM gestione la decisión de enrutamiento o si necesitas un control determinista.

El método app.a2a_tools() devuelve dos objetos LangChain StructuredTool: discover_available_agents y invoke_a2a_agent. Estos objetos permiten que el LLM descubra y llame a otros agentes de forma autónoma. Intégrelos con sus herramientas existentes para que el modelo pueda enrutar a otros agentes por sí mismo.

El método app.a2a_tools() devuelve una lista vacía cuando a2a.enabled es false en su archivo agent.yaml, por lo que es seguro incluirlo en todos los agentes.

El siguiente ejemplo vincula las herramientas A2A con las herramientas existentes:

from agent_engine_sdk_langgraph import App
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph
from langgraph.prebuilt import ToolNode
app = App(app_name="router-agent")
@app.entrypoint
def build_agent():
llm = app.llm(ChatOpenAI(model="gpt-5.4"))
a2a = app.a2a_tools()
llm_with_tools = llm.bind_tools(
app.get_tool_schemas() + a2a
)
tool_node = ToolNode(app.get_tools() + a2a)
graph = StateGraph(...)
return graph.compile(checkpointer=app.checkpointer())

Cuando se vincula al LLM, el modelo llama a las dos herramientas por su nombre. Las herramientas exponen las siguientes firmas de función:

  • discover_available_agents() Devuelve una lista JSON de agentes visibles para el agente que realiza la llamada. Cada entrada incluye agent_id, name, description, skills y capabilities. El agente que realiza la llamada se filtra a partir de sus propios resultados.

  • invoke_a2a_agent(agent_id, message, custom_headers="") Invoca al agente de destino y devuelve el resultado como JSON. Si proporciona custom_headers, páselo como una cadena JSON, por ejemplo '{"x-tenant": "acme"}'.

Cuando quieras utilizar el enrutamiento determinista, puedes acceder al cliente AgentToAgent directamente a través de runtime.a2a, un atributo que expone el cliente.

El siguiente ejemplo descubre agentes por habilidad e invoca la primera coincidencia:

agents = app._runtime.a2a.discover_agents(
skills=["policy-lookup"],
limit=10,
)
if agents:
resp = app._runtime.a2a.invoke_agent(
agent_id=agents[0].agent_id,
message="Look up policy POL-123",
skill="policy-lookup",
timeout=120,
)
if resp.status == "completed":
print(resp.result)

El atributo runtime.a2a devuelve None cuando A2A no está disponible. Para saber cuándo ocurre esto, consulte Consideraciones. Compruebe siempre este caso antes de llamar a los métodos del cliente, como se muestra en el siguiente ejemplo:

a2a = app._runtime.a2a
if a2a is None:
...

Nota

Acceda a runtime.a2a en el código del agente a través de app._runtime.a2a. No existe ningún accesor público app.a2a ni app.runtime. Para la mayoría de los casos de uso, app.a2a_tools() es la alternativa recomendada, ya que no depende de un atributo privado.

En esta sección, podrá obtener información sobre el SDK del cliente A2A, que proporciona métodos para descubrir e invocar agentes mediante programación desde el código de su agente.

Para utilizar el SDK del cliente, importe los tipos A2A desde agent_engine_runner_shared.a2a, como se muestra en el siguiente ejemplo:

from agent_engine_runner_shared.a2a import (
AgentToAgent,
DiscoveredAgent,
AgentSkill,
AgentResponse,
)

AgentToAgent Es un cliente HTTP que se comunica con los puntos finales /a2a/discover y /a2a/invoke de OE. En el código del agente, utilice la instancia preautenticada de runtime.a2a en lugar de construir esta clase directamente.

El siguiente ejemplo muestra el constructor y sus parámetros:

AgentToAgent(oe_url: str, auth_token: str = "")

La siguiente tabla describe los parámetros del constructor AgentToAgent:

Argument
Descripción

oe_url

URL base HTTP de OE, por ejemplo http://localhost:8000.

auth_token

A2A JSON Web Token (JWT) sent as Authorization: Bearer <token>. Provided automatically when you use runtime.a2a.

El método discover_agents() devuelve los agentes que el usuario tiene permiso para ver. Al pasar varios valores en un único parámetro de filtro, un agente coincide si cumple con alguno de esos valores. Por ejemplo, skills=["a", "b"] devuelve los agentes que anuncian cualquiera de las habilidades. Al pasar varios parámetros de filtro, un agente debe cumplir con todos ellos. Los agentes que no tienen la función A2A habilitada y excluyen al usuario mediante allowed_callers nunca se devuelven.

El siguiente ejemplo muestra este método y sus parámetros:

discover_agents(
project_id: str = "",
skills: list[str] | None = None,
capabilities: list[str] | None = None,
input_modes: list[str] | None = None,
limit: int = 50,
) -> list[DiscoveredAgent]

La siguiente tabla describe los parámetros para el método discover_agents():

Parameter
Tipo
Descripción

project_id

str

Proyecto a buscar. Una cadena vacía utiliza el proyecto del llamador.

skills

list[str]

Filtrar por nombre de habilidad. Devuelve los agentes que poseen alguna de las habilidades listadas.

capabilities

list[str]

Filtrar por etiqueta de capacidad. Devuelve los agentes que tienen alguna de las capacidades enumeradas.

input_modes

list[str]

Filtra por tipo MIME aceptado. Devuelve los agentes que aceptan cualquiera de los tipos MIME listados.

limit

Int

Número máximo de resultados a devolver. El valor predeterminado es 50.

El método invoke_agent() invoca a un agente objetivo y espera el resultado. El OE valida el token, comprueba el control de acceso, crea una ejecución secundaria y realiza sondeos hasta que el agente finaliza, se suspende para revisión humana o se agota el tiempo de espera.

El siguiente ejemplo muestra este método y sus parámetros:

invoke_agent(
agent_id: str,
message: str,
skill: str = "",
timeout: float | None = None,
custom_headers: dict[str, str] | None = None,
) -> AgentResponse

La siguiente tabla describe los parámetros para el método invoke_agent():

Parameter
Tipo
Descripción

agent_id

str

ID del espacio de trabajo de destino. Obtener de discover_agents().

message

str

Mensaje o indicación que se enviará al agente de destino.

skill

str

Sugerencia de habilidad opcional para agentes que anuncian muchas habilidades.

timeout

flotar | Ninguno

Segundos de espera antes de que se agote el tiempo de espera. None utiliza el valor predeterminado de OE de 300 segundos. 300 segundos es el tiempo de espera máximo.

custom_headers

dict[str, str] | None

Encabezados clave-valor reenviados al contexto de ejecución del agente de destino. Las claves no deben usar el prefijo reservado a2a-. Para obtener más información, consulte Reenvío de encabezados personalizados.

La siguiente tabla enumera los tipos de respuesta, que son todos clases de datos inmutables:

clase
Campos

DiscoveredAgent

agent_id, name, description, project_id, skills: list[AgentSkill], capabilities: list[str], input_modes: list[str], output_modes: list[str]

AgentSkill

namedescription, example_input (opcional), example_output (opcional)

AgentResponse

status, result (opcional), error (opcional), execution_id

La siguiente tabla describe cada valor posible para el campo AgentResponse.status:

Estado
Significado
¿Qué hacer?

completed

El agente objetivo finalizó con éxito.

Leer result.

failed

El agente de destino devolvió un error.

Leer error.

input-required

El agente objetivo ha sido suspendido para su revisión humana.

Muestra la pausa a tu usuario o flujo. No la consideres un fallo.

Los errores de red y de nivel HTTP, como los tiempos de espera o las respuestas 4xx y 5xx del OE, generan un httpx.HTTPError desde los métodos discover_agents() y invoke_agent(). Un AgentResponse con un valor status de failed indica que la llamada llegó al OE, pero el agente de destino falló. Para gestionar tanto los errores de red como los fallos del agente, envuelva las llamadas en bloques try/except y compruebe el valor status.

El siguiente ejemplo maneja los tres valores de estado:

resp = app._runtime.a2a.invoke_agent(
agent_id="ws-billing-001",
message="Process the payment",
)
if resp.status == "completed":
handle(resp.result)
elif resp.status == "input-required":
notify_user(
"The billing agent needs human approval before continuing."
)
else:
log.error("A2A call failed: %s", resp.error)

Puede utilizar A2A para adjuntar encabezados de clave-valor arbitrarios a una invocación de agente para propagar el contexto del ámbito de la solicitud, como un ID de inquilino, una etiqueta de seguimiento o un token OAuth delegado.

Para adjuntar encabezados a un agente llamado, pase un dict usando el parámetro custom_headers de invoke_agent(). Cuando use la herramienta LLM invoke_a2a_agent, pase los encabezados como una cadena JSON.

El siguiente ejemplo pasa encabezados personalizados mediante el uso del cliente directo:

app._runtime.a2a.invoke_agent(
agent_id="ws-billing-001",
message="Charge the customer",
custom_headers={
"x-tenant": "acme",
"oauth-token": "<delegated-token>",
},
)

El siguiente ejemplo pasa encabezados personalizados mediante la herramienta LLM:

invoke_a2a_agent(
agent_id="ws-billing-001",
message="Charge the customer",
custom_headers='{"x-tenant": "acme"}',
)

Las claves de encabezado no deben usar el prefijo reservado a2a- que no distingue entre mayúsculas y minúsculas. El OE rechaza las solicitudes con una respuesta 400 Bad Request si alguna clave comienza con a2a-. El prefijo a2a- está reservado para el enrutamiento de la plataforma y los encabezados de identidad, como a2a-token y a2a-caller-workspace.

Para leer los encabezados personalizados reenviados por un agente que realiza la llamada, utilice el método get_current_custom_headers() de la clase agent_engine_runner_shared.context. El siguiente ejemplo llama a este método:

from agent_engine_runner_shared.context import get_current_custom_headers
headers = get_current_custom_headers()
tenant = headers.get("x-tenant")

get_current_custom_headers() Devuelve un dict[str, str]. El método elimina todos los encabezados de plataforma a2a- antes de devolverlo, por lo que el código de su agente nunca ve tokens A2A ni metadatos de enrutamiento. Si quien realiza la llamada no envía encabezados personalizados, el método devuelve un diccionario vacío.

El campo a2a.allowed_callers en su archivo agent.yaml controla qué agentes pueden descubrir el suyo a través del siguiente comportamiento:

  • Lista vacía (predeterminado): Cualquier agente habilitado para A2A en el mismo proyecto puede invocar a su agente y verlo en los resultados de detección.

  • Lista no vacía: Solo los ID de espacio de trabajo listados pueden invocar a su agente. Todos los demás agentes reciben una respuesta 403 y no pueden ver a su agente en los resultados de detección.

El OE verifica la identidad del agente que realiza la llamada con respecto a su lista allowed_callers antes de realizar el envío. No se requieren cambios de código en su agente. El siguiente ejemplo restringe la invocación a un único agente de enrutador:

a2a:
enabled: true
allowed_callers:
- "ws-router-002"

Cada llamada A2A aparece automáticamente en el panel de seguimiento de la sesión. No se requiere instrumentación. La actividad del agente de destino aparece integrada en el mismo seguimiento de la sesión, lo que permite seguir todo el árbol de llamadas entre agentes en un solo lugar.

Cada invocación se representa como un nodo de subagente etiquetado como A2A: <target agent name>, utilizando el ID del espacio de trabajo del objetivo cuando no tiene nombre para mostrar. El nodo muestra el estado y la duración de la llamada. El estado comienza como running y cambia a done si la operación es exitosa o a error si falla. Al seleccionar un nodo, se abre un panel de detalles que muestra el nombre, el estado, la duración, la descripción de la operación, la salida transmitida y cualquier error.

Las llamadas a herramientas, los pasos LLM y las operaciones de memoria del propio agente objetivo aparecen anidados bajo el nodo del subagente, reconstruyendo el árbol de llamadas completo a través de los agentes.

runtime.a2a Devuelve un cliente solo cuando se cumplen todas las siguientes condiciones:

  1. El código del agente se está ejecutando en el entorno aislado del agente. A2A no está disponible desde el código que se ejecuta en el entorno aislado de la herramienta.

  2. En el contexto de ejecución hay una URL de OE presente.

  3. En los encabezados entrantes se encuentra presente un a2a-token. El OE inyecta este token automáticamente en cada envío cuando se configura A2A.

Cuando no se cumple alguna condición, runtime.a2a devuelve None. Al usar app.a2a_tools(), las herramientas devuelven un JSON de error estructurado en lugar de generar una excepción.

El token A2A caduca después de 5 minutos por defecto. Para flujos típicos de solicitud y respuesta, esto es suficiente. Los agentes que se ejecutan durante más tiempo que la vida útil del token pueden recibir una respuesta 401 en llamadas A2A. La actualización automática del token aún no está implementada. Considere una respuesta 401 de una llamada de larga duración como un fallo transitorio.

La herramienta LLM discover_available_agents filtra el espacio de trabajo del agente que realiza la llamada para evitar que el modelo se llame a sí mismo. Si utiliza el método de cliente discover_agents() sin procesar, el OE podría incluir su propio agente en los resultados. Filtre este espacio manualmente si es necesario.

En la versión actual, el descubrimiento y la invocación de A2A están limitados a agentes del mismo proyecto. El enrutamiento entre proyectos aún no está implementado.

La plataforma registra y vincula automáticamente cada llamada A2A. No es necesario añadir instrumentación. El objetivo se ejecuta como una ejecución secundaria vinculada al emisor a través de parent_execution_id. Un root_session_id compartido agrupa todo el árbol de llamadas entre agentes bajo la sesión del usuario de origen.

El siguiente ejemplo muestra un agente de enrutador que utiliza LLM para encontrar y delegar en un agente especializado. El archivo agent.yaml habilita A2A y declara una habilidad route:

agent.yaml
name: router-agent
entrypoint: router_agent.main:app
a2a:
enabled: true
skills:
- name: route
description: Route a user request to the best specialist agent

El siguiente código de agente vincula las herramientas A2A junto con sus propias herramientas y permite que el LLM gestione el enrutamiento:

main.py
from agent_engine_sdk_langgraph import App
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
app = App(app_name="router-agent")
@app.entrypoint
def build_agent():
llm = app.llm(ChatOpenAI(model="gpt-5.4"))
a2a = app.a2a_tools()
llm_with_tools = llm.bind_tools(
app.get_tool_schemas() + a2a
)
def call_model(state: MessagesState):
return {
"messages": [llm_with_tools.invoke(state["messages"])]
}
graph = StateGraph(MessagesState)
graph.add_node("model", call_model)
graph.add_node("tools", ToolNode(app.get_tools() + a2a))
graph.set_entry_point("model")
graph.add_conditional_edges(
"model",
lambda s: (
"tools"
if s["messages"][-1].tool_calls
else "__end__"
),
)
graph.add_edge("tools", "model")
return graph.compile(checkpointer=app.checkpointer())

En tiempo de ejecución, el LLM descubre un agente especializado que anuncia una habilidad coincidente, lo llama a través de invoke_a2a_agent y el OE intermedia la llamada al tiempo que aplica el control de acceso y registra ambos lados de la invocación.

Para enrutar de forma determinista en lugar de depender del LLM, llame al cliente directamente dentro de un nodo del grafo:

def delegate(state):
a2a = app._runtime.a2a
if a2a is None:
return {"messages": [("ai", "A2A is unavailable.")]}
resp = a2a.invoke_agent(
agent_id="ws-insurance-001",
message=state["messages"][-1].content,
skill="policy-lookup",
custom_headers={"x-request-source": "router-agent"},
)
text = (
resp.result
if resp.status == "completed"
else f"({resp.status}) {resp.error}"
)
return {"messages": [("ai", text)]}

Tras habilitar la comunicación entre agentes, puede consultar las siguientes guías para obtener más información sobre las tareas relacionadas: