Lompat ke isi halaman
TechVerse X
AI AgentsDraf — belum diperiksa manusia

Agent2Agent (A2A) Protocol

Langkah belajar
12
Alat
4
Proyek mini
2
Sumber
15

Diperbarui 9 Oktober 2026

Overview

Bayangkan sebuah kantor tempat setiap orang ahli di bidangnya: ada yang mengurus tiket, ada yang mengurus hotel, ada yang paham kurs. Mereka tak perlu tahu isi kepala satu sama lain; cukup tahu siapa mengerjakan apa dan bagaimana menitipkan pekerjaan. Agent2Agent (A2A) adalah protokol terbuka yang memberi agen AI cara bekerja sama seperti itu, walaupun dibangun dengan framework berbeda, oleh tim atau organisasi berbeda, dan berjalan di server berbeda. Setiap agen menerbitkan Agent Card, semacam kartu nama berformat JSON yang menyebut identitas, keahlian (skill), alamat, dan cara autentikasinya. Pekerjaan yang dititipkan menjadi Task: punya ID, melewati siklus hidup (sedang dikerjakan, butuh masukan, selesai, gagal), dan menghasilkan Artifact. Setiap agen tetap menjadi kotak hitam bagi yang lain: memori, rencana, dan alatnya tidak dibuka. Versi 1.0 (Maret 2026) mendefinisikan satu model data dengan tiga binding, yaitu JSON-RPC 2.0, gRPC, dan HTTP+JSON, serta polling, streaming, dan push notification untuk tugas panjang. A2A melengkapi MCP: MCP menyambungkan satu agen ke alat dan datanya, sedangkan A2A menyambungkan agen dengan agen lain. Halaman ini mengajarkan A2A 1.0; banyak tutorial dan video masih memakai 0.3, yang nama metode dan bentuk pesannya berbeda.

Kenapa agen perlu bahasa bersama

Bayangkan asisten AI yang diminta merencanakan perjalanan ke luar negeri. Ia butuh bantuan agen tiket, agen hotel, agen tur, dan agen kurs, yang masing-masing dibangun tim berbeda dengan framework berbeda. Tanpa standar bersama, setiap pasangan agen butuh kode integrasi sendiri.

Ada jalan pintas yang menggoda: bungkus saja agen lain sebagai tool. Masalahnya, cara itu memangkas kemampuannya. Agen dibangun untuk bernegosiasi, bertanya balik, dan bekerja lama, bukan sekadar dipanggil sekali lalu selesai. Memperlakukannya sebagai tool ibarat memperlakukan seorang konsultan seperti kalkulator.

A2A memberi agen bahasa bersama. Agen menerbitkan Agent Card yang bisa dibaca agen lain, menerima Message, mengelola Task yang bisa berlangsung beberapa menit sampai berhari-hari, dan menyerahkan hasilnya sebagai Artifact, semuanya tanpa membuka memori, rencana, atau alat internalnya.

A2A dan MCP: ke samping dan ke dalam

Diagram: pengguna meminta kepada Agen A, yang berperan client. Agen A mendelegasikan lewat A2A kepada Agen B (tiket) dan Agen C (hotel), dua agen jarak jauh. Di dalam setiap agen jarak jauh ada wilayah buram bagi Agen A, berisi alat-alat yang disambungkan lewat MCP: API maskapai dan basis data harga di Agen B, sistem kamar dan pembayaran di Agen C.
MCP memberi satu agen alat-alatnya; A2A menyambung agen dengan agen lain. Diringkas dari perbandingan A2A dan MCP di dokumentasi resmi.Lisensi: Karya sendiri

Kalau kamu sudah membaca topik MCP, wajar bertanya: apa bedanya? Dokumentasi resmi membedakan keduanya menurut arah sambungannya.

  • MCP itu vertikal: ia memperdalam satu agen. Setiap server MCP yang disambungkan memberi agen itu satu alat, sumber data, atau kemampuan lagi.
  • A2A itu horizontal: ia menyambungkan agen lintas batas, ke tim lain, departemen lain, atau organisasi mitra.

Dalam praktik keduanya dipakai bersama: MCP di dalam agen, A2A di antara agen. Pengumuman v1.0 menegaskan bahwa A2A adalah pelengkap MCP, bukan penggantinya.

Catatan

Prinsip yang paling menentukan: agen A2A buram (opaque) satu sama lain. Mereka bekerja sama berdasarkan kemampuan yang dinyatakan dan informasi yang dipertukarkan, tanpa berbagi pikiran internal, rencana, atau implementasi alat.

Siapa saja yang terlibat

Ada tiga aktor. Pengguna (manusia atau layanan otomatis) punya tujuan. A2A client (aplikasi atau agen lain) bertindak atas nama pengguna. A2A server, yang juga disebut agen jarak jauh, menerima permintaan dan mengerjakannya.

Di antara mereka berpindah lima jenis objek. Tabel ini bisa kamu jadikan peta:

ObjekIsiGunanya
Agent Cardidentitas, antarmuka, kapabilitas, skill, skema keamananclient menemukan agen dan tahu cara memanggilnya
Messagesatu giliran bicara: role dan satu atau lebih Partinstruksi, pertanyaan balik, kabar status
Parttepat satu dari text, raw, url, atau data, plus mediaTypewadah isi apa pun
Taskunit kerja ber-ID dengan siklus hidupmelacak pekerjaan panjang dan multi-giliran
Artifactkeluaran konkret: dokumen, gambar, data terstrukturhasil kerja, terpisah dari obrolan

Pemisahannya tegas: Message untuk berkomunikasi, Artifact untuk hasil. Agen boleh menjawab dengan Message langsung (interaksi singkat tanpa pelacakan) atau dengan Task (pekerjaan yang perlu dipantau). contextId mengelompokkan Task dan Message yang berasal dari satu percakapan.

Perjalanan sebuah Task

Diagram keadaan Task: SUBMITTED menuju WORKING. Dari WORKING, Task bisa berhenti sementara di INPUT_REQUIRED atau AUTH_REQUIRED dan kembali bekerja setelah client mengirim pesan dengan taskId yang sama atau kredensial diterima. Task berakhir di salah satu keadaan terminal: COMPLETED, FAILED, CANCELED, atau REJECTED; REJECTED boleh terjadi sejak awal.
Keadaan Task menurut a2a.proto versi 1.0. Ini alur umum; spesifikasi tidak mewajibkan setiap Task melewati setiap keadaan.Lisensi: Karya sendiri

Seperti paket yang dilacak, sebuah Task selalu punya keadaan. Ada yang masih aktif, ada yang terputus sementara menunggu sesuatu dari client, dan ada yang terminal, artinya sudah berakhir:

KeadaanJenisArtinya
TASK_STATE_SUBMITTEDaktifditerima, belum dikerjakan
TASK_STATE_WORKINGaktifsedang dikerjakan
TASK_STATE_INPUT_REQUIREDterputusagen butuh masukan; client melanjutkan dengan taskId yang sama
TASK_STATE_AUTH_REQUIREDterputusagen butuh otorisasi tambahan
TASK_STATE_COMPLETEDterminalselesai berhasil
TASK_STATE_FAILEDterminalselesai dengan galat
TASK_STATE_CANCELEDterminaldibatalkan
TASK_STATE_REJECTEDterminalagen memutuskan tidak mengerjakannya

Satu aturan penting: Task terminal tidak bisa dimulai ulang. Bila pengguna ingin memperbaiki hasilnya, misalnya "warnai perahunya merah", perbaikan itu menjadi Task baru di contextId yang sama, dengan referenceTaskIds yang menunjuk Task lama. Dengan begitu setiap Artifact selalu bisa ditelusuri ke satu unit kerja.

Satu model data, tiga cara mengirim

Diagram tiga lapis bertumpuk. Lapis 1, model data di a2a.proto: Task, Message, Part, Artifact, AgentCard. Lapis 2, operasi abstrak: Send Message, Get Task, List Tasks, Cancel Task, dan lainnya. Lapis 3, binding: operasi Send Message ditulis sebagai SendMessage di JSON-RPC 2.0, rpc SendMessage di gRPC, dan POST /message:send di HTTP+JSON.
Struktur spesifikasi 1.0: model data, operasi abstrak, dan binding protokol. Diringkas dari bagian 1.3 dan 5.3 spesifikasi.Lisensi: Karya sendiri

Sejak versi 1.0, berkas a2a.proto menjadi satu-satunya definisi resmi semua objek dan pesan. Bentuk JSON-nya diturunkan dari sana (ProtoJSON: nama medan camelCase, nilai enum SCREAMING_SNAKE_CASE). Dari satu model itu lahir tiga binding, yaitu cara konkret mengirimkannya: JSON-RPC 2.0, gRPC, dan HTTP+JSON. Agen yang mendukung lebih dari satu binding wajib memberi fungsi dan perilaku yang setara di semuanya.

OperasiJSON-RPC dan gRPCHTTP+JSON
Send MessageSendMessagePOST /message:send
Send Streaming MessageSendStreamingMessagePOST /message:stream
Get TaskGetTaskGET /tasks/{id}
List TasksListTasksGET /tasks
Cancel TaskCancelTaskPOST /tasks/{id}:cancel
Subscribe to TaskSubscribeToTaskPOST /tasks/{id}:subscribe

Ditambah empat operasi konfigurasi push notification dan GetExtendedAgentCard, semuanya ada 11 operasi inti.

Satu pertukaran utuh

Mari lihat percakapan sungguhan. Permintaan di bawah ini dikirim ke agen contoh kecil yang menghitung kata, dibangun dengan SDK Python resmi (a2a-sdk 1.2.2) dan benar-benar dijalankan:

http
POST / HTTP/1.1
Host: 127.0.0.1:9999
Content-Type: application/json
A2A-Version: 1.0

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "msg-1",
      "role": "ROLE_USER",
      "parts": [{ "text": "halo dunia yang indah" }]
    }
  }
}

Inilah jawabannya, diformat ulang dengan ID dipendekkan dan history dibuang. Perhatikan bahwa hasilnya datang sebagai Artifact di dalam Task yang sudah selesai:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "task": {
      "id": "964868a5-…",
      "contextId": "8d18273a-…",
      "status": {
        "state": "TASK_STATE_COMPLETED",
        "timestamp": "2026-10-08T03:45:28.625074Z"
      },
      "artifacts": [{
        "artifactId": "a2f0e7d5-…",
        "name": "hasil",
        "parts": [{ "text": "4 kata", "mediaType": "text/plain" }]
      }]
    }
  }
}

Peringatan

Jangan lupa header A2A-Version. Tanpa header itu, server wajib menganggap client memakai versi 0.3. Agen contoh ini hanya berbicara 1.0, jadi permintaan yang sama tanpa header ditolak dengan -32009 ("A2A version '0.3' is not supported").

Tiga cara menerima kabar

Diagram tiga lajur antara client dan agen. Polling: client memanggil GetTask berulang sampai Task COMPLETED. Streaming: client memanggil SendStreamingMessage sekali lalu menerima aliran event task, statusUpdate, artifactUpdate, dan statusUpdate COMPLETED. Push: client mendaftarkan webhook, agen mengirim POST ke webhook itu kemudian, lalu client memanggil GetTask.
Polling, streaming SSE, dan push notification, menurut bagian 3.5 spesifikasi.Lisensi: Karya sendiri

Bagaimana client tahu perkembangan pekerjaan yang panjang? Ada tiga cara, mirip tiga cara menunggu kiriman paket: mengecek berkala, ditelepon setiap ada kabar, atau dikirimi pesan ke alamatmu.

  • Polling: panggil GetTask berulang-ulang. Paling sederhana dan berjalan di semua binding, tetapi kabarnya datang lebih lambat.
  • Streaming: SendStreamingMessage atau SubscribeToTask membuka aliran Server-Sent Events. Aliran ini dimulai dengan objek Task, diikuti statusUpdate dan artifactUpdate, dan ditutup saat Task mencapai keadaan terminal. Butuh capabilities.streaming.
  • Push notification: agen mengirim HTTP POST ke webhook client setiap kali keadaan Task berubah, dengan isi berbentuk sama dengan event streaming. Cocok untuk tugas berjam-jam atau client yang tak bisa terus tersambung. Butuh capabilities.pushNotifications.

Secara bawaan, SendMessage menunggu sampai Task terminal atau terputus. Dengan returnImmediately: true, ia langsung kembali begitu Task dibuat, dan client memantaunya lewat salah satu cara di atas.

Versi 1.0: apa yang berubah dari 0.3

Kalau kamu menemukan contoh A2A dari 2025, hati-hati: kemungkinan besar ia memakai versi 0.3. A2A 1.0 terbit 12 Maret 2026, lalu patch 1.0.1 pada Mei 2026, dan perubahannya memutus kompatibilitas di tingkat pesan. Tabel ini membantumu mengenali versi lama:

0.3 (2025)1.0 (2026)
message/send, tasks/get, tasks/cancelSendMessage, GetTask, CancelTask
"state": "completed", "role": "user""TASK_STATE_COMPLETED", "ROLE_USER"
TextPart, FilePart, DataPart dengan medan kindsatu Part: text, raw, url, atau data
event stream dengan kind dan finalpembungkus statusUpdate / artifactUpdate; selesai = aliran ditutup
url, preferredTransport, protocolVersion di akar Agent CardsupportedInterfaces[], masing-masing dengan url, protocolBinding, protocolVersion
galat HTTP+JSON model RFC 9457google.rpc.Status dengan ErrorInfo (domain: a2a-protocol.org) di HTTP+JSON dan JSON-RPC
OAuth implicit dan passworddihapus; ditambah Device Code dan pkceRequired

Ada juga yang baru di 1.0: ListTasks dengan paginasi kursor, medan tenant untuk melayani banyak agen dari satu endpoint, dan Agent Card bertanda tangan (JWS di atas JSON yang dikanonkan dengan RFC 8785). Supaya migrasi bisa bertahap, Agent Card boleh menawarkan antarmuka 0.3 dan 1.0 sekaligus.

Siapa yang merawat A2A

A2A awalnya dikembangkan Google, lalu didonasikan ke Linux Foundation. Komite pengarah teknisnya berisi delapan perusahaan: AWS, Cisco, Google, IBM Research, Microsoft, Salesforce, SAP, dan ServiceNow. Pada 27 Agustus 2026, A2A diterima sebagai proyek tahap Growth di Agentic AI Foundation (AAIF), berdampingan dengan MCP, goose, dan AGENTS.md. Pengumumannya menyebut lebih dari 150 organisasi pendukung, serta dukungan bawaan di Google Cloud, AWS Bedrock AgentCore Runtime, dan Microsoft Azure AI Foundry.

Untuk membangun, kamu tak perlu mulai dari nol:

  • SDK resmi tersedia dalam enam bahasa: Python, Go, JavaScript, Java, C#/.NET, dan Rust. SDK Python (a2a-sdk 1.x) mengimplementasikan 1.0 di ketiga binding dengan mode kompatibilitas 0.3; paket .NET untuk 1.0 di NuGet masih berlabel preview.
  • Alat validasi: A2A Inspector (memeriksa Agent Card dan percakapan lewat antarmuka web) dan A2A TCK (uji kesesuaian lintas tiga binding). Pada 1 Oktober 2026 diumumkan pula A2A CLI resmi (a2a) untuk menemukan, mengirimi, dan memantau agen dari terminal.

Dengar dari para pembuatnya

Dua video ini ditautkan dari repositori resmi A2A dan enak ditonton untuk menangkap gagasan dan arsitekturnya. Keduanya direkam sebelum v1.0, jadi nama metode dan bentuk pesan di dalamnya mungkin masih versi lama.

Tonton di YouTube
Holt Skinner (Google) menjelaskan konsep dan implementasi A2A (8 menit, Februari 2026 — sebelum v1.0). Video ini juga disematkan di beranda a2a-protocol.org.Sumber: Google Cloud Tech di YouTube · Lisensi: Lisensi standar YouTube; disematkan lewat pemutar YouTube
Tonton di YouTube
Cuplikan kursus singkat DeepLearning.AI bersama Google Cloud dan IBM Research tentang A2A (3 menit, Februari 2026 — sebelum v1.0). Kursusnya membangun sistem multi-agen dari agen berlainan framework.Sumber: DeepLearning.AI di YouTube · Lisensi: Lisensi standar YouTube; disematkan lewat pemutar YouTube

Hal yang perlu diingat

  • A2A tidak membawa identitas di dalam pesannya. Autentikasi terjadi di lapis HTTP (OAuth 2.0, OpenID Connect, kunci API, mTLS) sesuai skema yang diumumkan Agent Card, dan kredensialnya diperoleh di luar protokol.
  • Keadaan TASK_STATE_AUTH_REQUIRED bukan izin. Spesifikasi melarang menganggap transisi itu sendiri sebagai otorisasi; makna kredensialnya ditentukan implementasi, penerbit kredensial, atau ekstensi.
  • Spesifikasi belum membakukan API registri agen, jadi penemuan agen lewat katalog masih dibuat sendiri-sendiri.
  • Message bukan saluran yang andal untuk informasi penting. Client yang terputus lalu tersambung lagi bisa kehilangan sebagian pesan status, jadi kirim hasil penting sebagai Artifact.
  • Webhook push adalah permintaan keluar ke URL pilihan client. Tanpa validasi, ia menjadi celah SSRF (server-side request forgery: server dibujuk mengakses alamat yang tak semestinya).

Learning Roadmap

  1. Prasyarat

    Yang perlu kamu kenal dulu: HTTP, JSON-RPC 2.0, dan MCP

    Tiga hal ini akan membuat perjalananmu jauh lebih mulus:

    • HTTP dan JSON: metode, header, kode status, dan Server-Sent Events (text/event-stream), yaitu cara server mengirim kabar terus-menerus lewat satu koneksi. Di A2A, identitas pemanggil dibawa header HTTP, bukan isi pesan.
    • JSON-RPC 2.0: request punya id, method, dan params; response membawa result atau error dengan id yang sama. Binding JSON-RPC adalah cara paling umum memanggil agen A2A.
    • Agen berbasis LLM: kamu pernah membangun agen yang memanggil alat. Topik Model Context Protocol di bidang ini adalah titik mulai yang dianjurkan, karena A2A paling mudah dipahami sebagai pasangannya.

    Untuk mengikuti contoh kodenya dengan SDK resmi, siapkan Python 3.10 atau lebih baru.

  2. 1

    Bedakan A2A dari MCP: agen sebagai rekan, bukan alat

    Langkah pertama adalah melatih mata: mana sambungan antar-agen, mana sambungan ke alat? Gambar ulang diagram ini dan tunjukkan di mana garis A2A dan MCP lewat:

    Diagram: pengguna meminta kepada Agen A, yang berperan client. Agen A mendelegasikan lewat A2A kepada Agen B (tiket) dan Agen C (hotel), dua agen jarak jauh. Di dalam setiap agen jarak jauh ada wilayah buram bagi Agen A, berisi alat-alat yang disambungkan lewat MCP: API maskapai dan basis data harga di Agen B, sistem kamar dan pembayaran di Agen C.
    MCP memberi satu agen alat-alatnya; A2A menyambung agen dengan agen lain. Diringkas dari perbandingan A2A dan MCP di dokumentasi resmi.Lisensi: Karya sendiri

    Untuk setiap sambungan, tanyakan satu hal: yang dihubungi ini alat atau agen?

    • Alat (wilayah MCP) punya masukan dan keluaran yang jelas, dan biasanya tanpa keadaan: kalkulator, kueri basis data, layanan cuaca.
    • Agen (wilayah A2A) bernalar, merencanakan, memakai banyak alat, menyimpan keadaan selama interaksi panjang, dan bisa bertanya balik.

    Tips

    Uji dirimu dengan contoh bengkel mobil dari dokumentasi resmi. Pelanggan berbicara dengan agen Shop Manager (A2A). Agen mekanik memanggil pemindai diagnostik dan basis data manual servis (MCP). Lalu agen mekanik memesan suku cadang ke agen pemasok (A2A).

    Latihan: ambil satu sistem multi-agen yang kamu kenal dan tandai setiap sambungannya sebagai A2A atau MCP. Bila sebuah "agen" bisa dipanggil sekali, tanpa keadaan dan tanpa bertanya balik, mungkin sebenarnya ia alat.

  3. 2

    Kenalkan agenmu lewat Agent Card

    Agent Card adalah kartu nama agen, dan setiap server A2A wajib menyediakannya. Alamat bakunya https://{domain}/.well-known/agent-card.json. Inilah kartu agen contoh di halaman ini, diambil apa adanya dari server yang dijalankan lalu dirapikan formatnya:

    json
    {
      "name": "Agen Penghitung Kata",
      "description": "Agen contoh yang menghitung kata dalam sebuah teks.",
      "supportedInterfaces": [{
        "url": "http://127.0.0.1:9999",
        "protocolBinding": "JSONRPC",
        "protocolVersion": "1.0"
      }],
      "version": "0.1.0",
      "capabilities": { "streaming": true },
      "defaultInputModes": ["text/plain"],
      "defaultOutputModes": ["text/plain"],
      "skills": [{
        "id": "hitung-kata",
        "name": "Penghitung kata",
        "description": "Menghitung jumlah kata dalam teks yang dikirim.",
        "tags": ["teks", "contoh"],
        "examples": ["Hitung kata: halo dunia yang indah"],
        "inputModes": ["text/plain"],
        "outputModes": ["text/plain"]
      }]
    }

    Saat client memilih antarmuka, urutan supportedInterfaces adalah urutan preferensi. Pilih yang pertama yang kamu dukung, pakai URL-nya, dan isi tenant persis seperti tertulis bila ada.

    Selain lewat alamat baku, kartu bisa ditemukan lewat registri terkurasi atau konfigurasi langsung. Server dianjurkan mengirim Cache-Control dan ETag supaya client tak perlu mengunduh ulang kartu yang sama; agen contoh di atas sudah mengirim ETag.

  4. 3

    Pahami Message, Part, dan Artifact

    Satu Message adalah satu giliran bicara. Ia membawa messageId buatan pengirimnya, role (ROLE_USER dari client, ROLE_AGENT dari agen), dan satu atau lebih Part. Anggap Part sebagai wadah: di versi 1.0, satu Part berisi tepat satu dari empat medan.

    MedanIsiContoh mediaType
    texttekstext/plain
    rawberkas sebaris, base64 di JSONimage/png
    urlrujukan ke berkasapplication/pdf
    datanilai JSON terstrukturapplication/json

    Jenis Part dikenali dari medan mana yang ada; medan kind dari versi lama sudah tak dipakai. Panduan migrasi resmi mencontohkannya begini:

    typescript
    if ("text" in part) {
      return part.text;
    } else if ("url" in part) {
      return fetchFile(part.url);
    } else if ("raw" in part) {
      return decodeBase64(part.raw);
    } else if ("data" in part) {
      return part.data;
    }

    Artifact adalah hasil kerja. Ia punya artifactId yang unik di dalam Task-nya, name, dan Part-nya sendiri. Spesifikasi menganjurkan hasil dikirim sebagai Artifact, bukan Message, karena tak semua pesan disimpan di riwayat Task.

    Latihan: rancang Part untuk tiga keluaran: ringkasan teks, grafik PNG, dan tabel hasil dalam JSON.

  5. 4

    Pegang tiga pengenal: Task, contextId, dan taskId

    Diagram keadaan Task: SUBMITTED menuju WORKING. Dari WORKING, Task bisa berhenti sementara di INPUT_REQUIRED atau AUTH_REQUIRED dan kembali bekerja setelah client mengirim pesan dengan taskId yang sama atau kredensial diterima. Task berakhir di salah satu keadaan terminal: COMPLETED, FAILED, CANCELED, atau REJECTED; REJECTED boleh terjadi sejak awal.
    Keadaan Task menurut a2a.proto versi 1.0. Ini alur umum; spesifikasi tidak mewajibkan setiap Task melewati setiap keadaan.Lisensi: Karya sendiri

    Banyak kebingungan di A2A bermula dari pengenal. Tiga aturan ini yang paling sering salah:

    1. taskId selalu dibuat server. Client tak boleh membuat Task dengan ID-nya sendiri; taskId di pesan client wajib merujuk Task yang sudah ada. Bila tidak, jawabannya -32001 (TaskNotFoundError).
    2. contextId mengelompokkan Task dan Message dari satu percakapan. Bila client hanya mengirim taskId, agen menyimpulkan contextId dari Task itu. Bila keduanya dikirim tetapi tak cocok, agen wajib menolak.
    3. Task terminal tak bisa dilanjutkan. Perbaikan berarti Task baru di contextId yang sama, dengan referenceTaskIds.

    Kamu bisa melihat aturan ini bekerja pada agen contoh: pesan ke Task yang sudah COMPLETED dijawab -32004 ("is in terminal state"), dan contextId yang tak cocok dengan Task-nya dijawab -32602.

    Tips

    Pola dari panduan Life of a Task: agen boleh memakai Message untuk menyepakati lingkup kerja lebih dulu, lalu membuat Task begitu ada pekerjaan yang benar-benar dikerjakan dan perlu dipantau.

  6. 5

    Bangun agen A2A pertama dengan SDK Python

    Pasang SDK resmi dengan pip install "a2a-sdk[http-server]" uvicorn. Pembagian kerjanya enak: logika agen tinggal di AgentExecutor, SDK mengurus protokolnya. Ini inti agen penghitung kata di halaman ini, diringkas dari contoh helloworld resmi dan sudah dijalankan dengan a2a-sdk 1.2.2:

    python
    class PenghitungKataExecutor(AgentExecutor):
        async def execute(self, context, event_queue):
            task = context.current_task or new_task_from_user_message(context.message)
            if not context.current_task:
                await event_queue.enqueue_event(task)
            updater = TaskUpdater(event_queue=event_queue,
                                  task_id=task.id, context_id=task.context_id)
            teks = get_message_text(context.message) or ''
            if not teks.strip():
                await updater.update_status(
                    state=TaskState.TASK_STATE_INPUT_REQUIRED,
                    message=new_text_message('Kirim teks yang ingin dihitung katanya.'))
                return
            await updater.update_status(state=TaskState.TASK_STATE_WORKING)
            await updater.add_artifact(
                parts=[new_text_part(text=f'{len(teks.split())} kata',
                                     media_type='text/plain')],
                name='hasil')
            await updater.update_status(state=TaskState.TASK_STATE_COMPLETED)

    Alurnya: ambil atau buat Task, minta teks bila kosong, tandai sedang bekerja, serahkan Artifact, lalu tandai selesai. Untuk menyambungkannya ke web, DefaultRequestHandler menerima executor, InMemoryTaskStore(), dan Agent Card; create_agent_card_routes(card) menyajikan /.well-known/agent-card.json; create_jsonrpc_routes(handler, '/') menerima JSON-RPC; aplikasi Starlette-nya dijalankan dengan uvicorn.

    Peringatan

    InMemoryTaskStore hilang saat proses mati. Agen dengan tugas panjang butuh penyimpanan persisten; SDK Python menyediakan DatabaseTaskStore (PostgreSQL, MySQL, SQLite).

  7. 6

    Sapa agenmu: curl, client SDK, dan alat resmi

    Agen sudah menyala; saatnya menyapanya. Mulailah dari yang paling mentah, satu permintaan HTTP:

    bash
    curl -s http://127.0.0.1:9999/ \
      -H 'Content-Type: application/json' \
      -H 'A2A-Version: 1.0' \
      -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"msg-1","role":"ROLE_USER","parts":[{"text":"halo dunia yang indah"}]}}}'

    Jawabannya Task TASK_STATE_COMPLETED dengan Artifact 4 kata. Berikutnya coba client SDK, yang membaca Agent Card lalu memilih antarmukanya sendiri:

    python
    async with httpx.AsyncClient() as http:
        card = await A2ACardResolver(
            httpx_client=http, base_url='http://127.0.0.1:9999').get_agent_card()
    client = await create_client(agent=card,
                                 client_config=ClientConfig(streaming=True))
    pesan = new_text_message('tujuh kata dalam kalimat yang cukup pendek',
                             role=Role.ROLE_USER)
    async for potongan in client.send_message(SendMessageRequest(message=pesan)):
        print(potongan)
    await client.close()

    Saat dijalankan, client ini menerima empat event berurutan: Task SUBMITTED, status WORKING, Artifact, lalu status COMPLETED.

    Ingin memeriksa agen tanpa menulis kode? Ada A2A Inspector (Agent Card, pemeriksaan kesesuaian dasar, obrolan, dan konsol JSON-RPC mentah) dan A2A CLI (a2a card get, a2a send).

  8. 7

    Ikuti pekerjaan secara langsung: streaming dan berlangganan Task

    Bila Agent Card menyatakan capabilities.streaming: true, kamu bisa menonton pekerjaan agen secara langsung lewat SendStreamingMessage. Server menjawab 200 dengan Content-Type: text/event-stream, dan setiap baris data: berisi satu respons JSON-RPC. Pada agen contoh, alirannya terlihat begini (dipendekkan):

    data: {"result": {"task": {… "state": "TASK_STATE_SUBMITTED" …}}}
    data: {"result": {"statusUpdate": {… "state": "TASK_STATE_WORKING" …}}}
    data: {"result": {"artifactUpdate": {… "text": "3 kata" …}}}
    data: {"result": {"statusUpdate": {… "state": "TASK_STATE_COMPLETED" …}}}

    Spesifikasi menetapkan beberapa aturan untuk aliran ini:

    • untuk Task, event pertama selalu objek Task itu sendiri;
    • urutan event tak boleh berubah, dan setiap aliran yang terbuka untuk Task yang sama menerima event yang sama;
    • aliran ditutup saat Task mencapai keadaan terminal; medan final seperti di 0.3 sudah tidak ada;
    • Artifact besar boleh dikirim bertahap: append: true menyambung potongan ke Artifact ber-ID sama, dan lastChunk: true menandai potongan terakhir.

    Koneksi putus di tengah jalan? Buka aliran baru dengan SubscribeToTask. Event pertamanya Task dalam keadaan terkini, jadi tak ada kabar yang terlewat di antara GetTask dan berlangganan.

  9. 8

    Tugas panjang: returnImmediately, polling, dan push notification

    Menunggu pekerjaan berjam-jam dengan koneksi terbuka tentu tidak praktis. Secara bawaan SendMessage menunggu sampai Task terminal atau terputus; untuk pekerjaan panjang, kirim "configuration": {"returnImmediately": true}. Jawabannya Task yang masih berjalan, dan client bebas memilih cara memantaunya.

    Diagram tiga lajur antara client dan agen. Polling: client memanggil GetTask berulang sampai Task COMPLETED. Streaming: client memanggil SendStreamingMessage sekali lalu menerima aliran event task, statusUpdate, artifactUpdate, dan statusUpdate COMPLETED. Push: client mendaftarkan webhook, agen mengirim POST ke webhook itu kemudian, lalu client memanggil GetTask.
    Polling, streaming SSE, dan push notification, menurut bagian 3.5 spesifikasi.Lisensi: Karya sendiri

    Push notification butuh capabilities.pushNotifications: true. Client mendaftarkan TaskPushNotificationConfig (url webhook, token opsional, dan authentication) di dalam SendMessage atau lewat CreateTaskPushNotificationConfig. Agen lalu mengirim POST berisi StreamResponse: task, message, statusUpdate, atau artifactUpdate.

    • Agen wajib menyertakan kredensial sesuai authentication, dan dianjurkan memvalidasi URL webhook: tolak alamat loopback (127.0.0.0/8), rentang IP privat, dan alamat link-local untuk mencegah SSRF.
    • Webhook client wajib memverifikasi pengirimnya dan menjawab 2xx. Kiriman yang sama bisa datang dua kali, jadi proseslah secara idempoten, lalu ambil Task lengkap dengan GetTask.

    Catatan

    ListTasks (baru di 1.0) memakai paginasi kursor: nextPageToken selalu ada dan berupa string kosong di halaman terakhir. Hasilnya wajib dibatasi pada Task yang boleh dilihat pemanggil.

  10. 9

    Saat agen perlu bertanya: INPUT_REQUIRED dan AUTH_REQUIRED

    Agen yang baik tidak menebak; ia bertanya bila perlu. Coba kirim pesan berisi spasi saja ke agen contoh, dan ia menjawab:

    json
    {
      "task": {
        "id": "969eea8d-…",
        "status": {
          "state": "TASK_STATE_INPUT_REQUIRED",
          "message": {
            "role": "ROLE_AGENT",
            "parts": [{ "text": "Kirim teks yang ingin dihitung katanya." }]
          }
        }
      }
    }

    Client melanjutkan dengan Message baru yang membawa taskId yang sama, dan Task yang sama itu berakhir TASK_STATE_COMPLETED.

    TASK_STATE_AUTH_REQUIRED dipakai saat agen butuh otorisasi di tengah tugas, misalnya token OAuth untuk API lain atau persetujuan manusia sebelum tindakan yang merusak. Agen wajib memakai Task, menyertakan pesan status yang menjelaskan kebutuhannya, dan menerima kredensial di luar jalur A2A, kecuali disepakati lain lewat ekstensi.

    Peringatan

    Transisi ke AUTH_REQUIRED bukan izin. Spesifikasi melarang menganggapnya sebagai otorisasi atas operasi apa pun, dan kredensial yang diterima tak otomatis berlaku untuk pesan berikutnya. Client yang juga agen boleh meneruskan permintaan itu ke client-nya sendiri, membentuk rantai Task AUTH_REQUIRED.

  11. 10

    Amankan: identitas di HTTP, otorisasi per skill, kartu bertanda tangan

    Kabar baiknya, mengamankan agen A2A tidak butuh ilmu baru: perlakukan ia seperti aplikasi web perusahaan biasa.

    • Transport: produksi wajib HTTPS (atau TLS untuk gRPC); TLS 1.3 dianjurkan.
    • Autentikasi: Agent Card mengumumkan skemanya di securitySchemes dan securityRequirements: kunci API, HTTP auth, OAuth 2.0, OpenID Connect, atau mTLS. Kredensial diperoleh di luar protokol dan dikirim di header setiap permintaan, dan server wajib mengautentikasi setiap permintaan.
    • Otorisasi: milik implementasi, misalnya per skill lewat cakupan OAuth. GetTask, ListTasks, dan operasi Task lain wajib dibatasi pada yang boleh dilihat pemanggil, dan pemeriksaannya dilakukan sebelum kueri yang bisa membocorkan keberadaan data.
    • Galat: jangan bedakan "tidak ada" dari "tak berhak"; spesifikasi menganjurkan keduanya dijawab sebagai tidak ditemukan.
    • Kartu lanjutan: detail yang hanya untuk client tertentu (skill tambahan, kuota) taruh di extended Agent Card, yang hanya dikembalikan GetExtendedAgentCard kepada client terautentikasi.
    • Kartu bertanda tangan: buang medan bernilai bawaan dan medan signatures, kanonkan JSON-nya dengan RFC 8785, lalu tanda tangani dengan JWS (RFC 7515). Header terlindungnya memuat alg, typ, dan kid, opsional jku. Client dianjurkan memverifikasi setidaknya satu tanda tangan sebelum memercayai kartu.
  12. 11

    Versi, migrasi, dan uji kesesuaian

    Karena 0.3 dan 1.0 masih hidup berdampingan, kamu perlu paham cara keduanya bernegosiasi. Versi A2A berbentuk Major.Minor (misalnya 1.0); nomor patch tidak dipakai saat negosiasi.

    1. Client wajib mengirim A2A-Version di setiap permintaan (boleh juga sebagai parameter kueri). Nilai kosong dibaca sebagai 0.3.
    2. Server wajib memproses dengan semantik versi yang diminta, atau menjawab VersionNotSupportedError (-32009).
    3. Agen yang sedang bermigrasi menawarkan dua antarmuka di supportedInterfaces, satu dengan protocolVersion 0.3 dan satu 1.0, lalu client memilih yang cocok.

    Pada agen contoh 1.0 kamu bisa melihat akibatnya: tanpa header jawabannya -32009; dengan A2A-Version: 0.5 juga -32009; dan nama metode 0.3 message/send dijawab -32601 (Method not found).

    Sebelum menyatakan agenmu sesuai spesifikasi, jalankan A2A TCK:

    bash
    ./run_tck.py --sut-host http://127.0.0.1:9999 --level must

    TCK menguji binding yang diumumkan Agent Card. --level memilih tingkat RFC 2119 (must, should, atau may), dan laporannya ditulis ke folder reports/.

    Tips

    Saat menyalin contoh dari internet, cari tanda versinya: message/send, "kind": "text", atau "state": "completed" berarti 0.3.

Tools

  • A2A CLI

    Client baris perintah resmi (a2a): membaca Agent Card, mengirim pesan, dan mengikuti Task lewat JSON-RPC, HTTP+JSON, atau gRPC, dengan keluaran JSON untuk skrip dan CI.

    Diumumkan 1 Oktober 2026 dan dibangun di atas CLI dari SDK Go. Mode server --echo dan --exec-nya untuk belajar dan menguji, bukan untuk produksi.

  • A2A Inspector

    Alat web untuk memeriksa agen A2A: menampilkan Agent Card, memeriksa kesesuaian dasarnya dengan spesifikasi, mengobrol dengan agen, dan memperlihatkan pesan JSON-RPC mentah.

    Dipakai begitu agen pertama menyala, untuk melihat kartu dan pesan yang sebenarnya lewat. Dijalankan lokal (Python, uv, dan Node.js) atau lewat Docker.

  • A2A Python SDK

    SDK resmi untuk membangun server dan client A2A di Python. Mengimplementasikan spesifikasi 1.0 di JSON-RPC, HTTP+JSON, dan gRPC, dengan mode kompatibilitas 0.3.

    Dipakai sejak agen pertama: AgentExecutor untuk logika agen, DefaultRequestHandler dan TaskStore untuk protokolnya. Nama paketnya a2a-sdk; butuh Python 3.10 atau lebih baru.

  • A2A TCK

    Technology Compatibility Kit: rangkaian uji kesesuaian untuk implementasi A2A di ketiga binding, dipilah menurut tingkat MUST, SHOULD, dan MAY.

    Dipakai sebelum menyatakan agen sesuai spesifikasi. Butuh Python 3.11 atau lebih baru dan uv; laporannya ditulis ke folder reports.

Mini Project

  • Misi

    Agen peringkas yang bisa ditemukan

    Di proyek pertama ini kamu membangun agen yang bisa ditemukan dan dipakai agen lain. Pakai SDK resmi (Python atau bahasa lain), dan beri agenmu satu skill: meringkas teks yang dikirim. Ringkasannya boleh buatan LLM atau aturan sederhana (misalnya tiga kalimat pertama), karena yang dilatih di sini protokolnya, bukan mutu ringkasan.

    • Agent Card di /.well-known/agent-card.json dengan antarmuka JSON-RPC versi 1.0, capabilities.streaming: true, dan satu skill lengkap dengan examples;
    • hasil dikirim sebagai Artifact bernama ringkasan, bukan sebagai Message;
    • pesan tanpa teks menghasilkan TASK_STATE_INPUT_REQUIRED dengan pertanyaan yang jelas.

    Kamu selesai bila:

    1. A2A Inspector menampilkan kartumu tanpa peringatan kesesuaian;
    2. SendMessage dengan header A2A-Version: 1.0 mengembalikan Task TASK_STATE_COMPLETED dengan tepat satu Artifact;
    3. permintaan yang sama tanpa header A2A-Version ditolak -32009, kecuali kamu sengaja menawarkan antarmuka 0.3 di Agent Card;
    4. SendStreamingMessage menghasilkan aliran yang dimulai dengan objek Task dan ditutup sesudah TASK_STATE_COMPLETED;
    5. pesan kosong menghasilkan TASK_STATE_INPUT_REQUIRED, dan pesan lanjutan dengan taskId yang sama menghasilkan TASK_STATE_COMPLETED pada Task yang sama;
    6. ./run_tck.py --sut-host <alamat agenmu> --level must dijalankan, dan setiap kegagalan di laporannya dicatat beserta alasannya.
  • Misi

    Dua agen, dua protokol: perencana yang mendelegasikan

    Proyek kedua menyatukan halaman ini dengan topik Model Context Protocol, supaya kamu merasakan sendiri "MCP di dalam agen, A2A di antara agen". Bangun dua proses:

    • Agen pelaksana (server A2A) dengan skill kelola-catatan. Di dalamnya ia memakai server MCP catatan dari proyek MCP (cari_catatan dan tambah_catatan) sebagai alatnya.
    • Agen perencana (client A2A) yang menerima permintaan pengguna, membaca Agent Card pelaksana, mengirim Message, lalu memantau Task sampai selesai.

    Pelaksana meminta konfirmasi sebelum menulis: permintaan "tambahkan catatan …" menghasilkan TASK_STATE_INPUT_REQUIRED, dan baru dikerjakan setelah perencana meneruskan jawaban pengguna dengan taskId yang sama.

    Kamu selesai bila:

    1. Agent Card pelaksana tidak menyebut nama tool MCP-nya; perencana hanya melihat skill;
    2. perencana memilih antarmuka dari supportedInterfaces dan mengirim A2A-Version: 1.0 di setiap permintaan;
    3. log perencana mencatat urutan keadaan Task sampai INPUT_REQUIRED, lalu WORKING, lalu COMPLETED;
    4. jawaban "tidak" berakhir terminal, yaitu TASK_STATE_REJECTED dari pelaksana atau TASK_STATE_CANCELED bila perencana memanggil CancelTask, dan tak satu pun berkas catatan ditulis;
    5. pesan berikutnya ke Task yang sudah terminal ditolak -32004, dan perencana menanganinya dengan membuat Task baru di contextId yang sama;
    6. hasil pencarian sampai ke pengguna dari Artifact, dan artifactId-nya tercatat di log perencana.

Resources

Topik terhubung

Pelajari lebih dulu