Appearance
长任务 API 用普通 REST 还是 Streaming HTTP
前置:一次 HTTP 调用经历什么:Lifecycle、Connection Pool 与 Timeout Layers
核心问题:一个可能运行几分钟的 Agent Run,应该用同步 REST、异步 Job API 还是 Streaming,选择依据是什么?
一个 2 小时 Agent Run 不应该依赖同一个 HTTP request 活着。更稳妥的接口通常先创建 run_id,用普通 REST 查询/控制 durable state,再按需要建立 streaming response 观察实时事件。
REST
REST 只是 API 资源/HTTP 语义的一种设计方式;Agent 内部 tool contract 不必机械映射成每个 REST endpoint。
REST/普通 request-response 适合短、边界清晰操作;Agent API 可把创建 Run 与查询状态分开,长任务不必维持单个 HTTP 请求。
Streaming HTTP
Streaming HTTP 允许响应 body 分段到达,适合把 token、progress 或 Run event 逐步交给客户端,但它仍只是观察通道。真正的 Run 状态应独立持久化;stream 需要明确 completion/error/cancel,并考虑 partial data、代理缓冲和断线恢复。具体 SSE / WebSocket 选择放到下一篇。
一个更稳的长 Run API 形态
长 Run 最稳妥的设计通常是创建任务和观察任务分开:
text
POST /runs
→ 202 + run_id
GET /runs/{run_id}
→ 当前 durable status
GET /runs/{run_id}/events
→ SSE / streaming events
POST /runs/{run_id}/cancel
→ durable cancellation request这样 Event Stream 断开只影响“观察通道”,不会让业务 Run 跟着消失;客户端可以之后用同一个 run_id 重新查询或续接事件。
如果一个任务几秒内稳定完成,普通 request/response 更简单。只有需要渐进反馈、长等待或后台继续执行时,才引入 streaming,而不是把所有 API 都做成长连接。
Failure Modes
断流后没有统一终止语义
症状: 客户端 stream 中断后,response buffer 或连接相关后台 task 继续存活,或者服务端误把“连接断了”直接等同于“Run 已取消”。
为什么危险: 会留下资源泄漏、重复重连、半个 structured output,甚至在用户离开后继续产生费用。
处理: 定义 stream completion/error/cancel,传播 cancellation,并在 finally 中释放 buffer/connection/task。
如何验证
| Case | 断言 |
|---|---|
| 断流后没有统一终止语义 | 在随机 delta 位置断开连接,断言没有悬挂 task,未完成 Item 不进入 Runtime。 |
自测
- 一个 Run 需要 5 分钟才能完成,但中间有持续事件。为什么“把 REST timeout 调到 10 分钟”未必是最好接口?
- 普通 REST 返回最终结果与 Streaming 返回进度事件时,Run 的 durable lifecycle 应不应该依赖 HTTP 连接存活?