Skip to content

[Feature]: agent_core 模型调用超时分层 #310

Description

🚀 背景描述

930 分支上,两条模型调用 HTTP 栈的超时均未按调用阶段分层,企业客户长任务场景暴露三类问题:

  • 读取空闲超时误杀长思考:主力栈(OkHttp)读超时取自模型客户端配置的单一 timeout 字段(默认 60 秒),同一字段同时承载读/写两层;思考型模型在生成大段工具调用前的几十秒停顿超过该值即被误杀——实际并非故障,是模型的正常工作方式。
  • 单次调用超时参数语义错误且调用点传空:单次调用级超时参数在客户端已有接线,但语义被实现为全程总时长硬顶(主力栈 OkHttp callTimeout、推理亲和栈 JDK 请求级超时)——调用方为长任务放宽超时时,引入的恰恰是要消除的总时长硬顶;同时上层全部模型调用点(ReActAgent、LlmAgent 等)仍不传该参数,调用方无法按次覆盖。
  • 两条栈超时语义不齐:主力栈已具备独立连接超时(系统属性,默认 10 秒封顶、快速失败);推理亲和栈(JDK HttpClient)仅以请求级单一超时承载,无连接/读取分层;两条栈对同一调用的超时行为不一致。

针对上述痛点引入:连接建立 / 响应头到达 / 数据段空闲三层独立计时,响应头到达即解除总计时,数据段空闲超时放宽,不设全程总时长硬顶,单次调用参数按层覆盖。

设计思路

按"痛点 → 机制"设计,两条 HTTP 栈同步改造,统一为同一套分层语义:

痛点 对应机制 关键点
误杀长思考 数据段空闲超时分层 空闲计时以相邻数据段间隔为基准(每段到达即重置),默认 600 秒(合理区间 300-900),为思考型模型长停顿留生存线
长回答被掐断 响应头到达解除总计时 首包到达后一切全程级计时解除,长回答写到底;不设全程总时长硬顶,极端卡死由上层取消机制兜底
参数语义错误 单次调用参数按层生效 覆盖该次调用相应超时层(至少覆盖数据段空闲层),不污染客户端级配置,不再映射为总时长硬顶;上层全部模型调用点消除传空
两栈不一致 双栈同步改造 主力栈与推理亲和栈采用同一套三层划分、默认值档位与错误表面;不允许只改一条栈
建连挂起 连接超时独立 只管 TCP/TLS 建连,默认 10 秒(合理区间 5-15),快速失败

错误表面:连接超时、响应头到达前超时、数据段空闲超时三类失败可程序区分,携带三段阶段信息(连接建立前 / 首段数据到达前 / 首段数据到达后);上层主动取消不得归类为超时失败。

涉及到的对外API

模型客户端配置面增量演进:新增连接超时、数据段空闲超时独立配置项(未配置时有可解释默认值,非法值拒绝或回落默认);单次调用超时参数作用于相应超时层。不改既有配置项名称与语义。

与其他模块的相关性描述

  • DFX-002(任务级并发额度):并发额度是 runtime 语义,本特性是 LLM HTTP 客户端层超时语义,两者不重叠;不改连接池容量与行为。
  • 熔断:930 已有模型级熔断器(连接失败不计入记账并清空保活连接池),超时错误表面供其消费;超时类失败与熔断记账的区分口径由后续特性定义。
  • 应用侧 FEAT-054(deepanalyze-java 宿主装配):超时参数经宿主配置面接入,core 特性合入为其前置。
  • SSE 服务面(FEAT-001):只作用于 HTTP 客户端层,不改 SSE 事件结构与序列。

测试设计与测试计划

  • 流式回答超 3 分钟完整读取;长思考停顿接近但未超空闲窗口不被误杀;建连失败在默认 10 秒窗口内快速失败;流中途死链在空闲窗口内检出并释放连接;单次调用参数覆盖生效且不污染共享配置;阻塞调用响应头等待超时保护;推理亲和栈同等语义回归;上层取消不误判为超时。
  • 计划:主力栈分层改造先行 → 推理亲和栈对齐 → 双栈语义一致性回归。

其他信息

感谢您的贡献 🎉!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions