AI Skills AI技能 5h ago Updated 1h ago 更新于 1小时前 48

Round-Robin Broke My Agent 轮询算法搞坏了我的 Agent

Round-robin load balancing across multiple LLM resources fails for stateful APIs like the OpenAI Responses API because server-side persisted items (with opaque IDs) must be replayed to the same resource that created them A 400 error carrying a "completed" response body is a diagnostic red flag indicating a routing bug, not a transient failure, often caused by gateway response-body capture logic Retry policies that retry all 4xx errors across a backend pool can waste up to 30x resources by accide LLM网关负载均衡不能简单套用HTTP无状态负载均衡模式,Azure OpenAI的Responses API是有状态的,生成的item ID与创建它的资源绑定 将item ID发送到不同资源会产生确定性400错误("The requested item was created under a different Azure OpenAI resource"),而非瞬态故障 不当的重试策略(>=400重试30次)将路由bug放大为严重的性能和成本问题,正确做法是仅重试429/5xx且重试次数不超过后端数量 三种解决方案:使用store=false实现无状态调用、基于session ID的亲和性

62
Hot 热度
76
Quality 质量
68
Impact 影响力

Analysis 深度分析

TL;DR

  • Round-robin load balancing across multiple LLM resources fails for stateful APIs like the OpenAI Responses API because server-side persisted items (with opaque IDs) must be replayed to the same resource that created them
  • A 400 error carrying a "completed" response body is a diagnostic red flag indicating a routing bug, not a transient failure, often caused by gateway response-body capture logic
  • Retry policies that retry all 4xx errors across a backend pool can waste up to 30x resources by accidentally performing resource-affinity searches at high cost
  • Three viable fixes exist: disable server-side storage for stateless calls, implement consistent-hash session affinity for stateful workloads, or segregate stateful traffic to dedicated resources

Why It Matters

This reveals a critical gap between traditional HTTP load balancing assumptions and the realities of modern LLM APIs, where statefulness is increasingly common. For AI practitioners building production systems, blindly applying round-robin patterns across multiple provider endpoints can silently break agent workflows, inflate costs, and produce misleading error signals that are difficult to diagnose.

Technical Details

  • The OpenAI Responses API with store=true persists every model output item server-side with resource-scoped IDs (fc_, rs_, msg_, resp_ prefixes); replaying these IDs to a different Azure OpenAI resource returns a deterministic 400 with the message "The requested item was created under a different Azure OpenAI resource"
  • Prompt caching is also resource-scoped: round-robin distribution across N backends reduces warm-cache hit rates to roughly 1/N, silently increasing latency and cost without any correctness failure
  • The diagnostic fingerprint for this class of bug is a binomial attempt pattern: N-1 failures followed by 1 success, with failures evenly distributed across all backends, detectable via telemetry queries grouping by operation and attempt shape
  • Gateway response-body truncation at 8192 characters can mask the actual error, attributing a successful response from the retrying host to all failed attempts in the group, creating misleading logs
  • Retry policies conditioned on StatusCode >= 400 retry every client error indiscriminately; the correct approach limits retries to 429/5xx/408 and caps the retry count to the number of distinct backends minus one

Industry Insight

  • Load balancer architectures for LLM traffic must explicitly account for API statefulness; round-robin is only safe for pure stateless endpoints, and any API returning opaque IDs for subsequent turns requires affinity-based routing or stateless mode
  • Pool homogeneity is non-negotiable: independently provisioned LLM resources drift in model versions, content-filter policies, and quota classes, turning a load balancer into a behavioral randomizer—automated drift detection and circuit breakers should be standard
  • Retry budget design should be bounded by the number of useful backends, not optimism; pairing first-fast-retry=true with a count equal to the pool size ensures cross-backend retries explore new hosts immediately rather than burning time on already-refused ones

TL;DR

  • LLM网关负载均衡不能简单套用HTTP无状态负载均衡模式,Azure OpenAI的Responses API是有状态的,生成的item ID与创建它的资源绑定
  • 将item ID发送到不同资源会产生确定性400错误("The requested item was created under a different Azure OpenAI resource"),而非瞬态故障
  • 不当的重试策略(>=400重试30次)将路由bug放大为严重的性能和成本问题,正确做法是仅重试429/5xx且重试次数不超过后端数量
  • 三种解决方案:使用store=false实现无状态调用、基于session ID的亲和性路由、按工作负载分离流量(有状态/无状态分别路由)
  • 后端漂移问题:不同订阅下的资源可能存在内容过滤策略和模型版本差异,导致负载均衡池成员不可互换

为什么值得看

这篇文章揭示了当前LLM网关实现中的一个普遍设计缺陷——将LLM端点视为无状态HTTP端点的错误假设,为AI基础设施工程师提供了可操作的诊断方法和修复方案。对于正在构建或优化LLM网关、负载均衡策略的团队,这篇文章提供了宝贵的生产级经验教训和具体的代码示例。

技术解析

  • Responses API有状态特性:默认store=true时,每个item(函数调用fc_、推理项rs_、消息msg_、响应resp_)都带有资源绑定的ID,Agent框架在后续轮次中通过to_input_list() replay这些ID,发送到不同资源会触发400错误
  • 诊断指纹:通过网关遥测按操作分组统计尝试模式,N-1次失败+1次成功的分布(而非二项式分布)是资源亲和性bug的标志,可编写KQL查询快速检测
  • 重试策略修复:条件应从>=400改为仅429/5xx/408,count设为后端数量-1(3个后端则count=2),配合first-fast-retry=true实现立即故障转移而非等待退避
  • 三种修复方案:1)store=false无状态模式(需验证reasoning encrypted_content自动返回);2)基于x-session-id的consistent hash亲和性路由;3)按工作负载分离流量(有状态agent流量单独路由,无状态embeddings/batch分类走负载均衡池)
  • 后端漂移检测:需验证同池后端的一致性——相同模型版本、相同内容过滤策略、相同配额等级,否则负载均衡会引入不可预测的行为变化

行业启示

  • LLM网关设计需要区分无状态(Chat Completions)和有状态(Responses API、Assistants threads)端点,不能一刀切地应用传统HTTP负载均衡策略,建议在网关层增加API类型感知和路由策略配置
  • 重试策略是生产环境的"放大器",配置不当会将路由bug放大为严重的成本和延迟问题,应建立重试预算等于后端数量的硬限制,并严格区分可恢复错误(429/5xx)与客户端错误(400)
  • 负载均衡池的"成员可互换"假设需要显式验证和持续监控,建议在生产部署前执行一致性检查(模型版本、过滤策略、配额类),并建立后端漂移检测和自动剔除机制

Disclaimer: The above content is generated by AI and is for reference only. 免责声明:以上内容由 AI 生成,仅供参考。

LLM 大模型 Agent Agent Deployment 部署 Inference 推理