RFC: service-class extension — agent role primitive (utility | principal | ephemeral)
- 主要語言
- Shell
- 星號
- 25.7k
- 分支
- 2.6k
- 平均合併
- 3 天 6 小時
- 30 天內合併 PR
- 16
描述
## Proposal
Add a **service-class** primitive to the A2A protocol — a self-declaration on the AgentCard about *what kind of availability promise the agent is making*. Three classes, additive evolution, no breakage.
```
service_class: "utility" | "principal" | "ephemeral"
```
| Class | Promise | Offline = | Examples |
|---|---|---|---|
| `utility` | Continuous service availability. Advertises an SLA. | SLA breach (real failure). | search engines, payment APIs, weather feeds, indexers. |
| `principal` | User/intent-driven. Comes online with work, otherwise idle. | Expected; not a quality signal. | shopping assistants, game-playing bots, occasional crawlers. |
| `ephemeral` | Short-lived, task-scoped. | Expected past TTL. | one-shot delegation targets, ad-hoc summarizers, tool-use sub-agents. |
## Why this matters
Today the AgentCard schema has no role/class field. The only `role` enum (Section 6.4 `Message`) is a per-message participant marker (`user` | `agent` | `system`), not a declaration about the agent itself. This leaves anyone publishing per-agent metrics with a structural problem: **a single "X% callable" rate flattens roles** in exactly the way A2A is supposed to enable better-than-static observability.
A search engine that goes offline is failing its SLA. A shopping assistant that goes offline is just idle. Same offline state, opposite quality signal. Without a role primitive, every consumer that publishes metrics either (a) flattens the rate and gets fact-checked, or (b) invents their own classification scheme. We've been doing (b), but having every implementer do that fragments the ecosystem.
## Relation to existing A2A discussions
- **[#1328 — Add tags field to AgentCard for agent categorization](https://github.com/a2aproject/A2A/issues/1328)** (Dec 2025, open) proposes a free-form `agent_type` string field (`"llm"`, `"workflow"`, `"assistant"`, `"retrieval"`, `"code-executor"`). **This proposal is orthogonal, not competing.** `agent_type` describes *what* the agent does (functional category); `service_class` describes *how* the agent is operated (availability promise). A search agent could be `agent_type=retrieval, service_class=utility`. A shopping assistant could be `agent_type=assistant, service_class=principal`. The two fields can — and probably should — coexist:
| Question | Field | Values | Source |
|---|---|---|---|
| What does this agent do? | `agent_type` (#1328) | free-form string | functional taxonomy |
| What kind of availability is it promising? | `service_class` (this RFC) | three-value enum | operational contract |
Picking one without the other leaves either "I know it's a retrieval agent but I have no idea if it promises uptime" or "I know it promises continuous service but I don't know what it actually does." Both questions matter for different consumers (catalog discovery vs. SLA-aware routing).
- **[#1667 — Heartbeat-based agents: availability metadata and offline-first task handling](https://github.com/a2aproject/A2A/issues/1667)** (Mar 2026, 41 community comments, no maintainer engagement yet, no spec PR). Proposes an `availability` extension namespace for *fine-grained scheduling and latency metadata* — `scheduleType: cron|interval|persistent|manual`, `cronExpression`, `nextActiveAt`, `taskLatencyMaxSeconds`, etc. **This proposal is orthogonal, not competing.** `service_class` is a coarse three-value role enum; `availability` (#1667) is fine-grained schedule+latency mechanics. They compose:
| Layer | Question | Field | Granularity |
|---|---|---|---|
| Role | What kind of agent is this? | `service_class` (this RFC) | coarse enum (3 values) |
| Schedule | When is it up; how long do tasks take? | `availability` (#1667) | fine-grained scheduling metadata |
A `service_class: utility` agent can declare `availability.scheduleType: persistent` (always-on utility) or `availability.scheduleType: cron` (scheduled utility — e.g., a 4h-cycle indexer that's always-on within its wake windows). A `service_class: principal` agent typically declares `availability.scheduleType: manual`. The two primitives answer different questions and either can ship without the other.
- **[#1755 — Empirical data: Near-zero real-world A2A protocol compliance despite widespread endpoint advertisement](https://github.com/a2aproject/A2A/issues/1755)** (Apr 2026, open) documents the same gap that motivates this RFC: agents advertise but don't actually comply. `service_class` is the primitive that makes follow-up empirical reporting **role-aware** instead of flattening across mixed cohorts (a `utility`-class non-compliance is an SLA failure; a `principal`-class non-compliance is just "agent isn't running right now"). Without this primitive, future versions of the #1755 dataset have to either flatten or invent ad-hoc classifications.
- **[#1672 — Agent Identity Verification for Agent Cards](https://github.com/a2aproject/A2A/issues/1672)** (Mar 2026, open) proposes signed/verified card attestation. Adjacent to Phase 4 of this proposal (signed class declarations); the two slot together cleanly — verifiable identity is the prerequisite for verifiable class claims.
- **[#1318 — What's the idea behind ROLE_UNSPECIFIED?](https://github.com/a2aproject/A2A/issues/1318)** (Dec 2025) is about the per-message participant role enum (`user`/`agent`/`system`), not the per-agent role. We use a deliberately distinct field name (`service_class`) to avoid collision.
## Prior art / related work
- [w3c/activitystreams#563](https://github.com/w3c/activitystreams/issues/563) — open issue on the ActivityPub side acknowledging that `Application` vs `Service` actor types have no agreed semantic distinction. This proposal explicitly *doesn't* try to map onto AP types in v1; the role signal stands alone in A2A.
- [AgentSLA paper (arxiv 2511.02885, Nov 2025)](https://arxiv.org/html/2511.02885v1) — formal SLA model for AI agents, JSON DSL, A2A-compatible. The phasing below adopts AgentSLA's `GuaranteeTerm`/`SLO` shape for Phase 3 SLA declarations.
- [W3C DID 1.0](https://www.w3.org/TR/did-1.0/) — service endpoint `type` is intentionally minimal with registry-based interop. Lesson: keep the type set small and let community consensus refine.
- [NIST AI Agent Standards Initiative](https://www.nist.gov/news-events/news/2026/02/announcing-ai-agent-standards-initiative-interoperable-and-secure) (CAISI, Feb 2026) — defining agentic AI interop standards. Service-class declaration falls in scope; a candidate primitive that could feed into their working group.
## Proposed shape
Use the existing `AgentExtension` mechanism (§5.5.2.1):
```json
{
"uri": "https://a2a-protocol.org/extensions/service-class",
"required": false,
"params": {
"class": "utility | principal | ephemeral"
}
}
```
Default-absence = unknown. The extension is opt-in; agents that don't ship it stay backward-compatible with all existing consumers.
## Phasing
- **Phase 1 (v1 of the extension)** — class declaration only, the schema above.
- **Phase 2** — per-class behaviour expectations are documented in the spec (utility implies SLA-style promises; principal implies idle-by-default; ephemeral implies TTL).
- **Phase 3** — additive `sla` block in `params` for utility-class agents (uptime, latency, throughput targets), adopting [AgentSLA's GuaranteeTerm/SLO shape](https://arxiv.org/html/2511.02885v1).
- **Phase 4+** — verifiable class attestations (signed declarations).
All phase additions are strictly additive — older parsers ignore unknown fields without breaking.
## Reference implementation
A live in-the-wild implementation is operating at the extension URI `https://connect.actex.ai/extensions/service-class`. The substrate behind it (Actex Connect — `connect.actex.ai`) ships per-class measurements at `connect.actex.ai/state-of-a2a` and a redaction-controlled real-traffic feed at `connect.actex.ai/activity`.
We'd much rather this become part of the spec than stay a Connect-only flavor — agent ecosystems should converge on one role primitive, not many. If A2A picks this up, we adopt the upstream URI and retire the Connect-specific one. If not, the Connect URI stays canonical and the schema continues evolving independently.
## Open questions for the working group
1. **Class set.** Three classes (utility / principal / ephemeral) is what we landed on after debating two-vs-four options. Is there a reason to add `proxy`, `oracle`, or other distinguishable classes at v1?
2. **Naming.** `service_class` vs `kind` vs `actor_class` vs `role` — we picked `service_class` because `role` collides with the existing message participant enum, and `class` is reserved in many languages. Is the working group's preferred field name something else?
3. **Where in the AgentCard.** Top-level field, nested under `capabilities`, or extension-only? We chose extension-only to avoid forking the spec; happy to take input on whether direct inclusion is preferred.
4. **Coordination with NIST CAISI work.** Should we coordinate this proposal with the [NIST AI Agent Standards Initiative](https://www.nist.gov/news-events/news/2026/02/announcing-ai-agent-standards-initiative-interoperable-and-secure) directly, or let the A2A working group handle external coordination?
Happy to write a more formal RFC if there's interest.
貢獻指南
評估
這個 Issue 還沒有評估資料。