Skip to content

perf(agent): 只追加续接时只发变了的尾部段,每轮插查证提醒,记录续接与否和原因 - #1246

Merged
SuInk merged 1 commit into
mainfrom
claude/append-skip-sent
Oct 27, 2026
Merged

SuInk merged 1 commit into
mainfrom
claude/append-skip-sent

Conversation

@SuInk

@SuInk SuInk commented Oct 27, 2026

Copy link
Copy Markdown
Owner

只追加续接时,尾部不再整段照发,只发变了的部分:和上文同一标题最近一版相同的段不发,长期记忆、跨群历史按条补新的,可提及成员候选不发。另外在当前消息前固定插一行查证提醒,并为每一轮写一条 append_context 调试记录,写明续接上没有、没续上的原因。10-27 生产三个群各 12 轮模拟,每轮增长从约 1.05 万字降到约 5000 字;DeepSeek 实测命中率从 91.9% 升到 96.2%(现布局 82.9%)。

Why

#1233 上线后,续接时尾部是整段照发的,每轮多出 1 万多字。按段统计,这些内容大半是逐字没变的参考资料(群约定、说话风格、会话进行状态等),或者是上文里已经有的记忆、跨群条目。

只追加对话、尾部一律不发也试过:每轮只增长约 1000 字,但 gpt-6.1-sol 回放 15 轮有 2 轮出错:

  • 缺了本轮路由说明,被 @ 之后的下一轮误判成「没人叫我」,选择了沉默;
  • 少了按当前消息检索出来的记忆,也少了一次查证。

所以状态段变了要补发,记忆和跨群按条补发。

查证方面:现有的查证规则都在头部,续接后离当前消息隔着好几轮对话,模型又看到自己前几轮都是直接回答的,容易照着凭印象答。「我当时不是说过…」那一轮:现布局 5 次查了 2 次,续接不加提醒 3 次查了 1 次。

10-28 01:13 线上升级到 canary.12 后,私聊续接生效了(连续几轮命中 85%~99%)。但 Telegram 群连续两轮都没续上,只命中了 1.8 万的检查点。增长上限、记录被覆盖、sessionKey,以及请求里的头部、契约和工具定义都已排除;具体被哪道校验拦下,线上没有记录,查不出来。

改了什么

  • model/assistant/append_context.go:
    • 尾部按「【标题】」切段。和上文同一标题最近一版逐字相同的段不发。
    • 长期记忆按条,只发上文里没有的;同一发言者的画像不重发,只带一行标题。
    • 跨群历史按整条判断,发过的不再发。
    • 可提及成员候选不发:按最近发言排序、几乎每轮都变,同样的 ID 在历史行里都有。
    • 段和条目都整块保留,不按行删。
    • 当前消息前固定插一行 【本轮提醒】,要求先查证再回答;这一行不参与「和上一版一样就不发」的判断。
  • 诊断记录:
    • appendContextContinuation 返回原因:no_log、head_changed、too_long。
    • Runner 跑完后,在调试轨迹里写一条 append_context:是否续接、原因,以及前缀、追加部分、完整组装各自的 token 数。
    • Runner 的校验键没对上时记 runner_key_changed,并附新旧两把键。
  • model/agent/continuation.go:校验键改成「系统提示.契约.工具定义」三段短指纹,新旧一比就知道是哪一段变了。
  • 文档:更新 docs/group-prompt-cache.md 的「只追加上下文」一节。

影响

  • 续接请求每轮增长约减半,重开更少,命中更高。
  • 换了发言者时,块头会补发;记忆条目还是只补新的。
  • 调试模式下,每轮主回复多一条 append_context 轨迹。

验证

  • DeepSeek 实测(10-27 生产同群连续 8 轮,不计第一轮):

    现布局 尾部整段照发(perf(agent): 主回复只追加上下文,在上一轮实际发出的请求后面续接 #1233) 只发变了的
    命中率 82.9% 91.9% 96.2%
    输入 token 31.5 万 49.1 万 40.4 万
    未命中 token 5.4 万 4.0 万 1.5 万
  • 行为回放(gpt-6.1-sol):

    • 3 个群共 15 轮,只发变了的这一版回的都是当前消息;只追加对话版本里那 2 轮错误,这一版都没有再出现。
    • 加查证提醒后,「我当时不是说过…」那一轮 6 次都先查了聊天记录(现布局 5 次查 2 次);闲聊轮次没有多余的查询。
    • 加提醒后的完整回放里,有 5 轮遇到网关 524/525,没有拿到结果。
  • 跨群:选了两个群跨群条目最多的 10 轮回放,没有出现把之前几轮的跨群内容错接到当前回复的情况。不过这 10 轮里两边的回复都没有直接用上跨群内容,所以这组样本只能说明不会错接,测不出联想效果有没有变。

  • 用 10-28 线上那两轮 Telegram 群的真实请求离线跑续接判断:可以续接,续接请求约 4.8 万 token,上限 8.3 万。

  • 单元测试:

    • TestAppendContextSendsOnlyWhatChanged:同一段没变就不发,状态段变了补上,记忆只补新条目,跨群和可提及成员候选不发,查证提醒紧挨在当前消息前面。
    • TestAppendContextRestartsWhenHeadChangesOrGrowsTooLong:重开时给出 head_changed / too_long 原因。
    • TestSplitContextBlocksRoundTrips。
  • ./model/agent、./model/assistant 在 -race 下通过,./model/agent、./model/assistant、./webui 在 TZ=UTC 下通过。

尾部整段照发每轮多一万多字,大半是逐字没变的参考资料和已经发过的记忆、跨群条目。现在同一标题的段和上文最近一版相同就不发,记忆和跨群按条补新的,可提及成员候选不发;当前消息前固定插一行查证提醒。上线后群聊连续两轮没续上却查不出原因,所以每轮写一条 append_context 调试记录,Runner 校验键拆成三段指纹。
@SuInk
SuInk force-pushed the claude/append-skip-sent branch from 2bd57a8 to 2eaf076 Compare October 27, 2026 19:21
@SuInk
SuInk merged commit 765e19f into main Oct 27, 2026
26 of 27 checks passed
@SuInk
SuInk deleted the claude/append-skip-sent branch October 27, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant