A2A vs HTTP:Agent 协议性能压测的指标口径陷阱
导读:本文对比同一套 Agent 服务走 A2A 协议通道与 HTTP 会话通道两种接入方式的阶梯压测结果,核心教训是"跨协议对比之前必须先对齐指标口径":A2A 的 TTFT 指 task 帧到达(P50 约 1~2s,仅为服务端受理信号),HTTP 的 TTFT 指"首字"到达(P50 约 4~8s),两者直接比数字会得出"HTTP 慢三四倍"的假结论;真正可比的是完整时延,实测同阶梯下 HTTP 路径中位系统性快约 6s(约 -30%~-40%),且断连需区分 client 主动断与超时断,帧间隔要说明是相邻哪类帧。适合做跨协议/跨通道性能对比、对外交性能报告的测试与性能工程师。
分类:性能测试 | 标签:A2A、协议对比、压测、性能测试
为什么要对比两种通道
年底给「品牌 Agent 性能报告」交数据时,绕不开一个问题:同一套 Agent 服务,对外存在两种不一样的接入方式——A2A 通道和 HTTP 会话通道。
A2A 通道:遵循 Google 开源的 Agent2Agent 协议(公开协议,名称可保留),由测试环境内网的编排层暴露 POST /api/v1/a2a 入口,SSE 流式返回,帧语义为 task → artifact-update* → status-update final=true。
HTTP 会话通道:传统的"会话 Cookie"风格网关,先 POST /api/sessions 建会话,再 POST /api/sessions/{id}/messages 用 SSE 增量返回文本,鉴权走真实用户会话 Cookie。
业务侧其实不关心协议先进不先进,只关心一件事:用户走哪条通道体验更稳、能扛多少并发。所以我们用同一套问题词表、同一个并发阶梯(5 / 10 / 15 / 20 并发 × 5 轮,每路 250 样本),对两条通道分别跑了一轮阶梯压测,中间还验证了一个很容易踩的坑:
跨协议对比之前,指标口径到底对齐了没有?
先交代两路的差异背景(这也是"结果不能直接比"的一半原因):
- A2A 一路:公网网关的沙箱鉴权凭据当时尚未接入正式授权体系,公网入口仍返回 401,最终回退到测试环境内网编排入口;每请求独立用户 ID + 新 contextId(即每请求新会话)。
- HTTP 一路:走公网网关,每请求新建会话;鉴权用真实用户会话 Cookie(Cookie 会过期,复测前需刷新)。
- 两路都是客户端计时,均未计入 OAuth 授权耗时、事件回调与 H5 渲染;问题词表两路同源。
核心:跨协议对比必须先对齐指标口径
两条通道的帧 / 流语义完全不同
先说清楚两条通道在"一个对话回合"里各自是怎么流式返回的。
A2A 通道(SSE 帧语义,公开协议约定):
task —— 编排层确认受理任务(服务端已收到请求、开始调度)
artifact-update* —— 内容产物增量(一问多答/工具调用会多次出现)
status-update —— final=true,流结束
HTTP 会话通道:
建会话 POST /api/sessions → 返回 session 标识
发消息 POST /api/sessions/{id}/messages → SSE 流
首个带 content 的增量("首字")→ 内容增量* → 流结束(有文本)
两条通道表面上都是 "发请求 → SSE → 结束",但每种事件到达的时点含义完全不同。如果不看协议语义直接拿数字比,就掉进陷阱了。
TTFT:A2A 的 "task 帧" ≠ HTTP 的 "首字"
这是本次最核心的一条经验:
| 指标 | A2A 通道 | HTTP 会话通道 |
|---|---|---|
| TTFT | 发请求 → 首个 kind=task 帧 |
发消息 → 首个带 content 的 SSE 增量("首字") |
| 完整时延 | 发请求 → final=true |
发消息 → SSE 流结束且有文本 |
| E2E | 不含独立建会话(无此环节) | 含建会话(/api/sessions) |
task 帧只是服务端确认受理、开始调度的信号;而 "首字"是模型真正吐出第一个文本片段的时刻。一次对话里,task 帧远早于首个 content——两者时间差动辄数秒。
所以实测中看到:
- HTTP 首字 TTFT P50 约 4~8s;
- A2A task TTFT P50 只有 1~2s。
如果不懂口径,会得出"HTTP 慢三四倍"的结论;但这是指标定义不同造成的系统差值,不是性能差距。这类对比要么把两路统一到同一个口径(例如都报"首事件/首文本"),要么各自注明帧语义再交表,绝不能把两列数字放进同一张表里当同一个指标用。
完整时延倒是可以比的——它近似"对话回合从开始到结束"的总耗时,两路语义都是"流真正结束"。本次对照也主要依赖这一列。
断连也要分类:client 主动断 vs 超时断
SSE 压测里"断连"不能只数一个总数,至少要分成两类:
- client 主动断:客户端主动关闭连接(例如拿到答案后中止、或客户端自身超时设置)。
- 超时断:服务端超过约定阈值(如 30s)未产出任何帧,客户端判定超时。
- 另有两类服务端异常断:未发终帧(final)就关连接、进程崩溃 / TCP 层断开。
评判口径要跟线上监控一致:成功 = HTTP 200 + final=true + state=completed + 至少一段 message 文本;空答 / 流失败 / 异常断连分别计数。本次两路 250/250 全部 success,0 空答、0 流失败、0 断连——但表格里仍然要保留"断连率"这一行,否则读者无法判断成功率是怎么算出来的。
一句话口径表
| 项 | HTTP 会话通道 | A2A 通道 |
|---|---|---|
| 入口 | 公网网关 /api/sessions + /messages |
内网编排 /api/v1/a2a |
| 鉴权 | 真实用户 Cookie | 每请求独立用户 ID |
| 会话 | 每请求新建 session | 每请求新 contextId |
| TTFT | 发消息 → 首个带 content 的增量(首字) | 发请求 → 首个 kind=task |
| 完整时延 | 发消息 → SSE 流结束且有文本 | 发请求 → final=true |
| E2E | 含建会话 | 不含(A2A 无独立建会话) |
结论:TTFT 两路不可直接比数字(task 帧远早于首字 content);完整时延可比"对话回合耗时"量级。
压测设计与数据(脱敏示意)
设计要点:同一问题词表;阶梯 5/10/15/20 并发 × 5 轮;客户端计时;每请求新会话。以下数值保留原始数量级,已做脱敏示意,不代表任何真实业务数据。
A2A 通道(内网编排入口)
| 并发 | N | 成功率 | 断连率 | 完整 P50 | 完整 P95 | 完整 P99 | TTFT(task) P50 | TTFT P99 | 帧间隔 P50 | 帧间隔 P99 | 吞吐 rps |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 5 | 25 | 100% | 0% | 14.2s | 18.1s | 18.9s | 1.03s | 1.63s | 1.5ms | 90ms | 0.34 |
| 10 | 50 | 100% | 0% | 16.4s | 22.9s | 25.8s | 1.37s | 3.13s | 5.5ms | 144ms | 0.54 |
| 15 | 75 | 100% | 0% | 20.9s | 32.3s | 34.7s | 1.73s | 6.77s | 7.9ms | 156ms | 0.65 |
| 20 | 100 | 100% | 0% | 22.6s | 39.8s | 44.5s | 1.88s | 4.73s | 8.7ms | 145ms | 0.76 |
对照品牌 Agent 报告的模板门槛:
| 模板指标 | 门槛 | 本轮 | 结论 |
|---|---|---|---|
| TTFT | P50 ≤ 1s · P99 ≤ 3s | 5 并发 P50=1.03s 贴线;≥10 并发 P50 1.37~1.88s、P99 3.13~6.77s 部分超线 | 高并发未达字面门槛 |
| 成功率 | ≥ 99% | 四档 100% | 达标 |
| 完整响应 | P50 ≤ 5s · P99 ≤ 15s | P50 14~23s,P99 19~45s | 未达字面门槛(Agent+LLM 长链路) |
| 帧间隔 | P50 ≤ 100ms | 1.5~8.7ms | 达标 |
| 断连 | < 1% | 0% | 达标 |
| 并发承载 | 退化可控 | 5→20 完整 P50 14.2→22.6s(+59%),成功率不降 | 延迟抬升明显,错误率无退化 |
HTTP 会话通道(公网网关)
| 并发 | N | 成功率 | 建会话 P50 | TTFT(首字) P50 | TTFT P99 | 完整 P50 | 完整 P95 | 完整 P99 | E2E P50 | 帧间隔 P50 | 吞吐 rps |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 5 | 25 | 100% | 181ms | 4.0s | 8.9s | 7.9s | 11.6s | 25.6s | 8.0s | 1.3ms | 0.51 |
| 10 | 50 | 100% | 237ms | 5.3s | 11.7s | 10.6s | 15.7s | 18.6s | 10.8s | 4.1ms | 0.81 |
| 15 | 75 | 100% | 245ms | 7.9s | 15.0s | 14.9s | 22.3s | 24.2s | 15.1s | 6.8ms | 0.90 |
| 20 | 100 | 100% | 334ms | 7.6s | 13.9s | 16.6s | 24.2s | 30.7s | 16.9s | 3.4ms | 1.01 |
全部样本 success(0 空答 / 0 失败 / 0 超时)。
跨通道对比(只比完整时延,不比 TTFT)
| 并发 | HTTP 完整 P50 | A2A 完整 P50 | 差值 | HTTP TTFT(首字) P50 | A2A TTFT(task) P50 |
|---|---|---|---|---|---|
| 5 | 7.9s | 14.2s | −6.3s(HTTP 更快) | 4.0s | 1.03s |
| 10 | 10.6s | 16.4s | −5.8s | 5.3s | 1.37s |
| 15 | 14.9s | 20.9s | −6.0s | 7.9s | 1.73s |
| 20 | 16.6s | 22.6s | −6.0s | 7.6s | 1.88s |
解读:
- 稳定性:HTTP 会话通道在 20 并发下仍 0 失败,与 A2A 一致,两路成功率均为 100%。
- 完整时延:同环境同阶梯下,HTTP 公网路径中位完整时延系统性优于 A2A 约 6s(约 −30%~−40%)。可能因素:链路差异(网关直连会话 vs A2A 翻译层)、词表命中/模型负载波动、首字后的吐字节奏不同。
- TTFT:HTTP 首字(4~8s)明显高于 A2A task(1~2s),符合口径差异;若要对外对齐,HTTP 侧应另报"首事件/首 thinking",或共用 A2A
kind=task口径交表。 - 建会话:P50 约 180~330ms,相对完整时延占比很小;E2E 与"仅消息"相差 0.1~0.3s。
- 舒适区:HTTP 路径 5~10 并发体验更稳;15~20 并发完整 P50 抬到 15~17s,但仍无错误率退化。
OAuth / 授权环节在总耗时中的位置
对话压测本身不包含鉴权,但"总耗时"里其实有鉴权的位置:实际产品链路是 OAuth 授权 → 建会话 → 对话流。为了搞清楚这一环占多少,我们对授权接口单独跑了一轮小规模压测(auth_code → access_token,测试环境 mock 链路,非正式授权服务;1/5/10/20 并发 × 20 轮,共 720 次)。数值已脱敏示意:
| 并发 | N | 成功率 | token P50 | token P99 | token 最大 | issue+token P50 |
|---|---|---|---|---|---|---|
| 1 | 20 | 100% | 18.7ms | 69ms | 72ms | 99.6ms |
| 5 | 100 | 100% | 17.4ms | 54ms | 55ms | 97ms |
| 10 | 200 | 100% | 22.5ms | 80ms | 82ms | 114ms |
| 20 | 400 | 100% | 24.3ms | 108ms | 115ms | 118ms |
三点结论:
- 授权环节本身是毫秒级:token 接口 P50 约 17~24ms,P99 ≤ 108ms,相对秒级的对话完整时延占比很小;对照模板"授权时间 P50 ≤ 1s / P99 ≤ 3s"轻松达标。做对话压测时,把鉴权耗时分出去单独测,比混在完整时延里更干净。
- 鉴权的"位置"决定 TTFT 可比性:如果 A2A 一侧用"每请求独立用户 ID"绕开了正式授权、HTTP 一侧却把真实 Cookie 的鉴权算进"首帧之前",两路的 TTFT 口径就又差了一层。要在报告里写明 TTFT 计时点是否含鉴权。
- mock 环境要注明:测试环境的 mock 授权接口不代表生产正式授权服务的耗时,交表时必须标注,避免误导。
结论与选型建议
口径铁律(本文最想传达的一条):
跨协议做性能对比,第一步永远是"对齐指标口径"。A2A 的 TTFT 是
task帧到达时间,HTTP 的 TTFT 是"首字"到达时间,两者不可直接比;只有完整时延(回合总耗时)在同一量级上可比。断连要分 client 主动断 / 超时断,帧间隔要说明是相邻哪类帧的间隔。
本次可交表的:成功率、断连率、帧间隔(P50)、完整时延阶梯(HTTP 与 A2A 各一套)、授权单独链路数据。
需与模型服务商协商的:模板里的"完整响应 P50 ≤ 5s / P99 ≤ 15s"对 Agent + LLM 长链路不现实,本轮实测 P50 14~23s、P99 19~45s;高并发下 TTFT(P50 ≤ 1s / P99 ≤ 3s)也只适合承诺低并发档位,≥10 并发首帧排队明显抬升,不宜对外承诺。
选型建议:
- 聊天类 / 公网终端用户场景:HTTP 会话通道更直接。它省掉协议翻译层,完整时延中位系统性快约 6s,且 5~10 并发舒适区体验稳定;建会话开销只有 200~300ms 量级,可忽略。
- 多 Agent 互操作 / 协议标准化场景:A2A 的价值不在单次延迟而在互操作(公开协议、标准化帧语义),选它时应按协议语义约定新口径,而不是拿它跟自定义 HTTP 通道的"首字 TTFT"硬比。
- 对外并发承诺:建议保守承诺 ≤10 并发;交表代表值建议用 5 并发档;20 并发在实测中无错误率退化,但延迟抬升明显(完整 P50 +59%)。
最后是两个后续观察项:公网网关的正式鉴权打通后,应再补一档"同链路(都在公网)下的 A2A vs HTTP"对照,排除链路位置差异;服务端加三时刻埋点(收到请求 / 首帧写出 / 终帧写出)后,客户端计时可以升级成服务端口径,误差可解释。