保真模式把只有思考的 length 截断与带未知 delta 键的回答当成失败重试(dissect3) #30
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
dissect3 已按 #29 接入 1.3.9 的
chat(response_mode="openai")(pi 经本地代理调用,见 #29)。独立对抗审查读 1.3.9 源码,发现保真模式里有两处会把上游的正常回答当成失败去重试。两处今天都不阻塞试点,记在这里供修。一:只有思考、没有正文与工具调用的回答被当成空补全
types.py:478-490与transports/openai_compat.py:727:保真模式下,无正文、无工具调用的回答一律抛 TransientError 重试。但下面两种是上游的正常结局,不是抖动:finish_reason: "length":模型把max_tokens全花在思考上,被截断。dissect3 冒烟实测 MiniMax-M3 在max_tokens=65536时 16 趟里有 3 趟如此(每趟首条回复写满 65536 个思考 token)。改动前 pi 把它判成「输出被截断」并结束会话,这是我们要记录的结果;现在会被重抽最多max_attempts次、每次都可能写满上限,最后变成失败。finish_reason: "stop":少见,但同理是模型的回答。需要:保真模式下,只要上游给出了明确的
finish_reason(length、stop、content_filter等),就把这条 completion 原样交回(正文可为空,思考内容照交),不算空补全;只有既无正文、无工具、也无finish_reason(或流异常结束)时才按瞬时错误处理。二:delta 里出现未知键就整条拒绝
transports/_openai_completion.py:98、:114:delta 只认role、content、reasoning_content、tool_calls,多一个键(例如refusal: null、reasoning、reasoning_details)或tool_calls: null即抛 TransientError「未知 delta 字段」。审查员直接调用确认过。2026-10-02 实测中转站当前对 glm-5.3-flash 与 MiniMax-M3 的流(含工具调用)只出现这四个键,所以今天不触发;但 OpenAI 兼容服务常见
refusal: null,渠道一换就会让 100% 的调用失败,而且是以「瞬时错误、重试到耗尽」的形态出现,很难一眼看出原因。需要:未知的 delta 键忽略(或原样保留在 completion 的附加字段里),值为
null的已知键按缺省处理;不因此判失败。验收
reasoning_content、末块finish_reason: "length":交回 completion,content 为空、思考内容完整、finish_reason 为length,attempts=1。refusal: null与tool_calls: null:正常交回,不重试。已在 1.3.10 修复并发布(
polygateway==1.3.10;Release:https://gitea.iomgaa.online/iomgaa/PolyGateway/releases/tag/v1.3.10),与 #31 同根统一修复。一(只有思考 / 空白正文):结局改按 finish_reason 分类。保真模式:只有思考/拒答/空白 + 明确 finish(非上游错误)→ 原样交回;文本模式 length/过滤且无正文 →
ResultInvalidError(length_without_content/filtered_without_content,不重试、不换源、熔断记成功)。零增量且无明确 finish 仍按 2026-07-20 裁决判瞬时。二(未知 delta 键):任意层
null视缺省(refusal: null、tool_calls: null,非流式同样修复);保真模式未知字段按 OpenAI 流式惯例无损合并(字符串拼接、对象递归、带 index 数组按 index、index/type/id/format同值幂等),冲突删键并按源告警一次;reasoning字段计入活性并作文本 thinking 别名。验收:reasoning-only + length → 交回、content 空、思考完整、finish=length、attempts=1;
refusal:null+tool_calls:null→ 正常交回(流式与非流式)。见tests/unit/test_completion_transport.py、test_openai_completion.py。真实中转(magpie glm,max_tokens=50,2026-10-15):
[DONE]AllSourcesExhaustedAllSourcesExhaustedResultInvalidError length_without_content,2–5s 返回不重试后续:文本模式 n>1 → #32;文本"只有思考 + stop"证据收集 → #33。