

# Menyebarkan server A2A di Runtime AgentCore
<a name="runtime-a2a"></a>

Amazon Bedrock AgentCore AgentCore Runtime memungkinkan Anda menerapkan dan menjalankan server Agent-to-Agent (A2A) di Runtime. AgentCore Panduan ini memandu Anda melalui pembuatan, pengujian, dan penerapan server A2A pertama Anda.

Di bagian ini, Anda belajar:
+ Bagaimana Amazon Bedrock AgentCore mendukung A2A
+ Cara membuat server A2A dengan kemampuan agen
+ Cara menguji server Anda secara lokal
+ Cara menyebarkan server Anda ke AWS 
+ Cara memanggil server yang Anda gunakan
+ Cara mengambil kartu agen untuk penemuan

Untuk informasi lebih lanjut tentang A2A, lihat kontrak protokol [A2A](runtime-a2a-protocol-contract.md).

**Topics**
+ [Bagaimana Amazon Bedrock AgentCore mendukung A2A](#runtime-a2a-how-agentcore-supports)
+ [Menggunakan A2A dengan Runtime AgentCore](#runtime-a2a-steps)
+ [Lampiran](#runtime-a2a-appendix)

## Bagaimana Amazon Bedrock AgentCore mendukung A2A
<a name="runtime-a2a-how-agentcore-supports"></a>

Dukungan protokol AgentCore A2A Amazon Bedrock memungkinkan integrasi tanpa batas dengan server A2A dengan bertindak sebagai lapisan proxy transparan. Saat dikonfigurasi untuk A2A, Amazon Bedrock AgentCore mengharapkan container untuk menjalankan server HTTP stateless dan streamable pada port `9000` di root path (`0.0.0.0:9000/`), yang sejajar dengan konfigurasi server A2A default.

Layanan ini menyediakan isolasi sesi tingkat perusahaan sambil mempertahankan transparansi protokol - JSON-RPC muatan dari [InvokeAgentRuntime](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_InvokeAgentRuntime.html)API diteruskan langsung ke wadah A2A tanpa modifikasi. Arsitektur ini mempertahankan fitur protokol A2A standar seperti penemuan agen bawaan melalui Kartu Agen `/.well-known/agent-card.json` dan JSON-RPC komunikasi, sambil menambahkan otentikasi perusahaan (SigV4/OAuth 2.0) dan skalabilitas.

Pembeda utama dari protokol lain adalah port (9000 vs 8080 untuk HTTP), jalur pemasangan (`/`vs`/invocations`), dan mekanisme penemuan agen standar, menjadikan Amazon Bedrock platform penyebaran yang AgentCore ideal untuk agen A2A di lingkungan produksi.

Perbedaan utama dari protokol lain:

 **Port**   
Server A2A berjalan pada port 9000 (vs 8080 untuk HTTP, 8000 untuk MCP)

 **Jalan**   
Server A2A dipasang di `/` (vs `/invocations` untuk HTTP, `/mcp` untuk MCP)

 **Kartu Agen**   
A2A menyediakan penemuan agen bawaan melalui Kartu Agen di `/.well-known/agent-card.json` 

 **Protokol**   
Penggunaan JSON-RPC untuk komunikasi agen-ke-agen

 **Autentikasi**   
Mendukung skema otentikasi SiGv4 dan OAuth 2.0

Untuk informasi selengkapnya, lihat [https://a2a-protocol.org/](https://a2a-protocol.org/).

## Menggunakan A2A dengan Runtime AgentCore
<a name="runtime-a2a-steps"></a>

Dalam tutorial ini Anda membuat, menguji, dan menyebarkan server A2A.

**Topics**
+ [Prasyarat](#runtime-a2a-prerequisites)
+ [Langkah 1: Buat proyek A2A Anda](#runtime-a2a-create-server)
+ [Langkah 2: Uji server A2A Anda secara lokal](#runtime-a2a-test-locally)
+ [Langkah 3: Terapkan server A2A Anda ke Bedrock Runtime AgentCore](#runtime-a2a-deploy)
+ [Langkah 4: Dapatkan kartu agen](#runtime-a2a-step-4)
+ [Langkah 5: Panggil server A2A yang Anda gunakan](#runtime-a2a-step-5)

### Prasyarat
<a name="runtime-a2a-prerequisites"></a>
+ Python 3.10 atau lebih tinggi diinstal dan pemahaman dasar Python
+ Node.js 18 atau lebih tinggi diinstal (diperlukan untuk AgentCore CLI)
+  AgentCore CLI diinstal: `npm install -g @aws/agentcore` 
+  AWS Akun dengan izin yang sesuai dan kredensi lokal yang dikonfigurasi
+ Memahami protokol A2A dan konsep komunikasi agen-ke-agen

### Langkah 1: Buat proyek A2A Anda
<a name="runtime-a2a-create-server"></a>

Contoh ini menggunakan Strands Agents, tetapi AgentCore CLI juga mendukung proyek A2A dengan LangChain/LangGraph dan Google ADK.

#### Perancah proyek
<a name="runtime-a2a-scaffold-project"></a>

Jalankan perintah berikut dan pilih *Strands* sebagai framework Anda saat diminta:

```
agentcore create --protocol A2A
```

CLI membuat proyek lengkap dengan semua dependensi dan konfigurasi yang diperlukan. Yang dihasilkan `main.py` berisi server A2A Anda:

```
from strands import Agent, tool
from strands.multiagent.a2a.executor import StrandsA2AExecutor
from bedrock_agentcore.runtime import serve_a2a
from model.load import load_model

@tool
def add_numbers(a: int, b: int) -> int:
    """Return the sum of two numbers."""
    return a + b

tools = [add_numbers]

agent = Agent(
    model=load_model(),
    system_prompt="You are a helpful assistant. Use tools when appropriate.",
    tools=tools,
)

if __name__ == "__main__":
    serve_a2a(StrandsA2AExecutor(agent))
```

#### Memahami kode
<a name="runtime-a2a-understanding-code"></a>

 **Agen Helai**   
Membuat agen dengan alat dan kemampuan khusus

 **Strandsa2AExecutor**   
Membungkus agen Strands untuk menyediakan kompatibilitas protokol A2A

 **serve\_a2a**   
Pembantu Amazon Bedrock AgentCore SDK yang memulai server A2A Bedrock-compatible . Ini menangani titik akhir `/ping` kesehatan, penyajian Kartu Agen, variabel `AGENTCORE_RUNTIME_URL` lingkungan, propagasi header Bedrock, dan berjalan pada port 9000 secara default.

 **Pelabuhan 9000**   
Server A2A berjalan pada port 9000 secara default di Runtime AgentCore 

Untuk menyesuaikan agen ini, ganti `add_numbers` alat dengan alat Anda sendiri dan perbarui prompt sistem.

### Langkah 2: Uji server A2A Anda secara lokal
<a name="runtime-a2a-test-locally"></a>

Jalankan dan uji server A2A Anda di lingkungan pengembangan lokal.

#### Mulai server A2A Anda
<a name="runtime-a2a-start-server"></a>

Mulai server A2A Anda secara lokal menggunakan CLI: AgentCore 

```
agentcore dev
```

Ini membuka inspektur AgentCore agen di browser web Anda. Untuk menggunakan TUI berbasis terminal sebagai gantinya, gunakan. `agentcore dev --no-browser`

Atau, Anda dapat menjalankan server secara langsung:

```
python main.py
```

Anda akan melihat output yang menunjukkan server berjalan pada port`9000`.

#### Memohon agen
<a name="runtime-a2a-invoke-agent"></a>

```
curl -X POST http://localhost:9000/ \
-H "Content-Type: application/json" \
-d '{
  "jsonrpc": "2.0",
  "id": "req-001",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "what is 101 * 11?"
        }
      ],
      "messageId": "12345678-1234-1234-1234-123456789012"
    }
  }
}' | jq .
```

#### Pengambilan kartu agen uji
<a name="runtime-a2a-test-agent-card"></a>

Anda dapat menguji titik akhir kartu agen secara lokal:

```
curl http://localhost:9000/.well-known/agent-card.json | jq.
```

Anda juga dapat menguji server yang digunakan menggunakan Inspector A2A seperti yang dijelaskan [dalam Pengujian jarak jauh](https://github.com/a2aproject/a2a-inspector) dengan inspektur A2A.

### Langkah 3: Terapkan server A2A Anda ke Bedrock Runtime AgentCore
<a name="runtime-a2a-deploy"></a>

#### Siapkan kumpulan pengguna Cognito untuk otentikasi
<a name="runtime-a2a-setup-cognito"></a>

Sebelum menerapkan, konfigurasikan otentikasi untuk akses aman ke server yang Anda gunakan. Untuk petunjuk penyiapan Cognito yang mendetail, lihat [Mengatur kumpulan pengguna Cognito](runtime-mcp.md#runtime-mcp-appendix-a) untuk autentikasi. Ini menyediakan token OAuth yang diperlukan untuk akses aman ke server yang Anda gunakan.

#### Menyebarkan ke AWS
<a name="runtime-a2a-deploy-aws"></a>

Menyebarkan agen Anda:

```
agentcore deploy
```

Perintah ini akan:

1. Package kode agen dan dependensi Anda

1. Unggah artefak penerapan ke Amazon S3

1. Buat runtime Amazon Bedrock AgentCore 

1. Menyebarkan agen Anda ke AWS 

Setelah penerapan, Anda akan menerima ARN runtime agen yang terlihat seperti:

```
arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/my_a2a_server-xyz123
```

### Langkah 4: Dapatkan kartu agen
<a name="runtime-a2a-step-4"></a>

Kartu Agen adalah dokumen metadata JSON yang menggambarkan identitas, kemampuan, keterampilan, titik akhir layanan, dan persyaratan otentikasi server A2A. Mereka memungkinkan penemuan agen otomatis di ekosistem A2A.

#### Mengatur variabel lingkungan
<a name="runtime-a2a-step-4-setup-environment-variables"></a>

Mengatur variabel lingkungan

1. Ekspor token pembawa sebagai variabel lingkungan. Untuk pengaturan token pembawa, lihat Pengaturan [token pembawa](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-mcp.html#runtime-mcp-appendix).

   ```
   export BEARER_TOKEN="<BEARER_TOKEN>"
   ```

1. Ekspor agen ARN.

   ```
   export AGENT_ARN="arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/my_a2a_server-xyz123"
   ```

#### Ambil kartu agen
<a name="retrieve-agent-card"></a>

```
import os
import json
import requests
from uuid import uuid4
from urllib.parse import quote

def fetch_agent_card():
    # Get environment variables
    agent_arn = os.environ.get('AGENT_ARN')
    bearer_token = os.environ.get('BEARER_TOKEN')

    if not agent_arn:
        print("Error: AGENT_ARN environment variable not set")
        return

    if not bearer_token:
        print("Error: BEARER_TOKEN environment variable not set")
        return

    # URL encode the agent ARN
    escaped_agent_arn = quote(agent_arn, safe='')

    # Construct the URL
    url = f"https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/{escaped_agent_arn}/invocations/.well-known/agent-card.json"

    # Generate a unique session ID
    session_id = str(uuid4())
    print(f"Generated session ID: {session_id}")

    # Set headers
    headers = {
        'Accept': '*/*',
        'Authorization': f'Bearer {bearer_token}',
        'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': session_id
    }

    try:
        # Make the request
        response = requests.get(url, headers=headers)
        response.raise_for_status()

        # Parse and pretty print JSON
        agent_card = response.json()
        print(json.dumps(agent_card, indent=2))

        return agent_card

    except requests.exceptions.RequestException as e:
        print(f"Error fetching agent card: {e}")
        return None

if __name__ == "__main__":
    fetch_agent_card()
```

Setelah Anda mendapatkan URL dari Kartu Agen, ekspor `AGENTCORE_RUNTIME_URL` sebagai variabel lingkungan:

```
export AGENTCORE_RUNTIME_URL="https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/<ARN>/invocations/"
```

### Langkah 5: Panggil server A2A yang Anda gunakan
<a name="runtime-a2a-step-5"></a>

Buat kode klien untuk memanggil server Amazon Bedrock AgentCore A2A yang Anda gunakan dan kirim pesan untuk menguji fungsionalitas.

Buat file baru `my_a2a_client_remote.py` untuk memanggil server A2A yang Anda gunakan:

```
import asyncio
import logging
import os
from uuid import uuid4

import httpx
from a2a.client import A2ACardResolver, ClientConfig, ClientFactory
from a2a.types import Message, Part, Role, TextPart

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

DEFAULT_TIMEOUT = 300  # set request timeout to 5 minutes

def create_message(*, role: Role = Role.user, text: str) -> Message:
    return Message(
        kind="message",
        role=role,
        parts=[Part(TextPart(kind="text", text=text))],
        message_id=uuid4().hex,
    )

async def send_sync_message(message: str):
    # Get runtime URL from environment variable
    runtime_url = os.environ.get('AGENTCORE_RUNTIME_URL')

    # Generate a unique session ID
    session_id = str(uuid4())
    print(f"Generated session ID: {session_id}")

    # Add authentication headers for Amazon Bedrock AgentCore
    headers = {"Authorization": f"Bearer {os.environ.get('BEARER_TOKEN')}",
        'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': session_id}

    async with httpx.AsyncClient(timeout=DEFAULT_TIMEOUT, headers=headers) as httpx_client:
        # Get agent card from the runtime URL
        resolver = A2ACardResolver(httpx_client=httpx_client, base_url=runtime_url)
        agent_card = await resolver.get_agent_card()

        # Agent card contains the correct URL (same as runtime_url in this case)
        # No manual override needed - this is the path-based mounting pattern

        # Create client using factory
        config = ClientConfig(
            httpx_client=httpx_client,
            streaming=False,  # Use non-streaming mode for sync response
        )
        factory = ClientFactory(config)
        client = factory.create(agent_card)

        # Create and send message
        msg = create_message(text=message)

        # With streaming=False, this will yield exactly one result
        async for event in client.send_message(msg):
            if isinstance(event, Message):
                logger.info(event.model_dump_json(exclude_none=True, indent=2))
                return event
            elif isinstance(event, tuple) and len(event) == 2:
                # (Task, UpdateEvent) tuple
                task, update_event = event
                logger.info(f"Task: {task.model_dump_json(exclude_none=True, indent=2)}")
                if update_event:
                    logger.info(f"Update: {update_event.model_dump_json(exclude_none=True, indent=2)}")
                return task
            else:
                # Fallback for other response types
                logger.info(f"Response: {str(event)}")
                return event

# Usage - Uses AGENTCORE_RUNTIME_URL environment variable
asyncio.run(send_sync_message("what is 101 * 11"))
```

## Lampiran
<a name="runtime-a2a-appendix"></a>

**Topics**
+ [Siapkan kumpulan pengguna Cognito untuk otentikasi](#runtime-a2a-setup-cognito-appendix)
+ [Pengujian jarak jauh dengan inspektur A2A](#runtime-a2a-remote-testing)
+ [Pemecahan masalah](#runtime-a2a-troubleshooting)

### Siapkan kumpulan pengguna Cognito untuk otentikasi
<a name="runtime-a2a-setup-cognito-appendix"></a>

Untuk petunjuk penyiapan Cognito yang mendetail, lihat Mengatur [kumpulan pengguna Cognito untuk autentikasi](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-mcp.html#set-up-cognito-user-pool-for-authentication) dalam dokumentasi MCP.

### Pengujian jarak jauh dengan inspektur A2A
<a name="runtime-a2a-remote-testing"></a>

Lihat [https://github.com/a2aproject/a2a-inspector](https://github.com/a2aproject/a2a-inspector).

### Pemecahan masalah
<a name="runtime-a2a-troubleshooting"></a>

 ** A2A-specific Masalah umum** 

Berikut ini adalah masalah umum yang mungkin Anda temui:

Konflik pelabuhan  
Server A2A harus berjalan pada port 9000 di lingkungan Runtime AgentCore 

JSON-RPC kesalahan  
Periksa apakah klien Anda mengirim pesan JSON-RPC 2.0 yang diformat dengan benar

Ketidakcocokan metode otorisasi  
Pastikan permintaan Anda menggunakan metode otentikasi yang sama (OAuth atau SigV4) yang dikonfigurasi agen

 **Penanganan pengecualian** 

Spesifikasi A2A untuk penanganan Kesalahan: [https://a2a-protocol.org/latest/specification/#81-standard-json-rpc-errors](https://a2a-protocol.org/latest/specification/#81-standard-json-rpc-errors) 

Server A2A mengembalikan kesalahan sebagai respons JSON-RPC kesalahan standar dengan kode status HTTP 200. Kesalahan Runtime internal secara otomatis diterjemahkan ke kesalahan JSON-RPC internal untuk mempertahankan kepatuhan protokol.

Layanan ini sekarang memberikan respons A2A-compliant kesalahan yang tepat dengan kode JSON-RPC kesalahan standar:


| JSON-RPC Kode Kesalahan | Pengecualian Runtime | Kode Kesalahan HTTP | JSON-RPC Pesan Kesalahan | 
| --- | --- | --- | --- | 
| N/A |  `AccessDeniedException`  | 403 | N/A | 
| -32501 |  `ResourceNotFoundException`  | 404 | Sumber daya tidak ditemukan — Sumber daya yang diminta tidak ada | 
| -32502 |  `ValidationException`  | 400 | Kesalahan validasi - Data permintaan tidak valid | 
| -32503 |  `ThrottlingException`  | 429 | Batas tarif terlampaui - Terlalu banyak permintaan | 
| -32503 |  `ServiceQuotaExceededException`  | 429 | Batas tarif terlampaui - Terlalu banyak permintaan | 
| -32504 |  `ResourceConflictException`  | 409 | Konflik sumber daya — Sumber daya sudah ada | 
| -32505 |  `RuntimeClientError`  | 424 | Kesalahan klien runtime - Periksa CloudWatch log Anda untuk informasi lebih lanjut. | 