send 失败无兜底:发送抛异常时模型既不知情、Delta 缓冲也不写 #95

Closed
opened 2026-07-29 08:24:09 +00:00 by KumaAgent · 0 comments
Member

来源:2026-07-29 全 ADR 查漏。第一批第三张。查漏对它的评价是「在首个 host 接入当天就会咬人」——QQ 的禁言/风控/频控导致 send 失败是常态而非异常

Problem

ADR-0012「决策 → 7. 基础设施(既定后果)」断言:

send 失败下一轮回灌上下文(m7 发送失败)供模型知情

实际runtime_loop.py::_flush 的循环里 _send_pending裸调用runtime_loop.py 全文只有两处 except 且都是 PoolExhausted、都不在发送路径。

后果比 ADR 描述的更重_append_delta_flush 之后才调用,所以发送抛异常时——

  1. 模型下一轮不知道发失败(ADR 说的那半);
  2. 连那几条内容本身都不记得(Delta 缓冲根本没写)。

也就是说一次平台侧发送失败,会让这一轮对话在智能体的记忆里彻底不存在。

为什么 ADR-0013 不覆盖它:ADR-0013 管的是进程崩溃(丢弃在途请求不重放),不覆盖「平台 API 返回错误但进程活着」。所以这条断言没有被后续 ADR 取代,仍然现行有效。

Acceptance criteria

  • _send_pending 包 try/except;单条失败不得中断整个 flush 序列(同批其余消息该发还是发)。
  • 失败的句柄记录失败状态(Sent Log 侧),供下一轮上下文渲染。
  • 下一轮上下文里渲染出「某句柄发送失败」的事实,让模型知情——措辞形状参考 ADR-0012 原文的 m7 发送失败
  • _append_delta 的调用位置要一并复核:当前它在 _flush 之后,发送失败即整轮不写 Delta。修完必须保证「发送失败但对话内容仍进 Delta 缓冲」。这条是本票真正的价值所在,比「模型知情」那半更重要。
  • 测试:注入一个会抛异常的 egress,断言 ① 其余消息照常发出 ② Delta 缓冲里有本轮内容 ③ 下一轮上下文含失败事实。
    • 注意别写成空转测试:只断言「没崩溃」在修复前后都成立。必须锁定 Delta 缓冲的实际内容与下一轮上下文的实际文本。

Not in scope

  • 不做重试/退避策略——ADR-0012 只要求「回灌供模型知情」,不要求 core 自动重发。加重试是新的架构决定,需要单独拍板(涉及幂等性与平台风控,core 不了解任意平台的语义)。
  • 不碰 ADR-0013 的崩溃恢复语义(在途请求仍然丢弃不重放,不变)。
  • 不做任何结构调整。
> 来源:2026-07-29 全 ADR 查漏。**第一批**第三张。查漏对它的评价是「在首个 host 接入当天就会咬人」——QQ 的禁言/风控/频控导致 send 失败是**常态而非异常**。 ## Problem ADR-0012「决策 → 7. 基础设施(既定后果)」断言: > send 失败下一轮回灌上下文(`m7 发送失败`)供模型知情 **实际**:`runtime_loop.py::_flush` 的循环里 `_send_pending` 是**裸调用**,`runtime_loop.py` 全文只有两处 `except` 且都是 `PoolExhausted`、都不在发送路径。 **后果比 ADR 描述的更重**:`_append_delta` 在 `_flush` **之后**才调用,所以发送抛异常时—— 1. 模型下一轮**不知道发失败**(ADR 说的那半); 2. **连那几条内容本身都不记得**(Delta 缓冲根本没写)。 也就是说一次平台侧发送失败,会让这一轮对话在智能体的记忆里彻底不存在。 **为什么 ADR-0013 不覆盖它**:ADR-0013 管的是**进程崩溃**(丢弃在途请求不重放),不覆盖「平台 API 返回错误但进程活着」。所以这条断言没有被后续 ADR 取代,仍然现行有效。 ## Acceptance criteria - [ ] `_send_pending` 包 try/except;单条失败不得中断整个 flush 序列(同批其余消息该发还是发)。 - [ ] 失败的句柄记录失败状态(Sent Log 侧),供下一轮上下文渲染。 - [ ] 下一轮上下文里渲染出「某句柄发送失败」的事实,让模型知情——措辞形状参考 ADR-0012 原文的 `m7 发送失败`。 - [ ] **`_append_delta` 的调用位置要一并复核**:当前它在 `_flush` 之后,发送失败即整轮不写 Delta。修完必须保证「发送失败但对话内容仍进 Delta 缓冲」。这条是本票真正的价值所在,比「模型知情」那半更重要。 - [ ] 测试:注入一个会抛异常的 egress,断言 ① 其余消息照常发出 ② Delta 缓冲里有本轮内容 ③ 下一轮上下文含失败事实。 - **注意别写成空转测试**:只断言「没崩溃」在修复前后都成立。必须锁定 Delta 缓冲的实际内容与下一轮上下文的实际文本。 ## Not in scope - 不做重试/退避策略——ADR-0012 只要求「回灌供模型知情」,不要求 core 自动重发。加重试是新的架构决定,需要单独拍板(涉及幂等性与平台风控,core 不了解任意平台的语义)。 - 不碰 ADR-0013 的崩溃恢复语义(在途请求仍然丢弃不重放,不变)。 - 不做任何结构调整。
Yushu closed this issue 2026-07-30 08:22:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#95
No description provided.