Skip to content

fix(adk): avoid duplicate nested checkpoint payloads - #1232

Merged
shentongmartin merged 1 commit into
mainfrom
fix/agenttool-checkpoint-size
Aug 31, 2026
Merged

fix(adk): avoid duplicate nested checkpoint payloads#1232
shentongmartin merged 1 commit into
mainfrom
fix/agenttool-checkpoint-size

Conversation

@shentongmartin

Copy link
Copy Markdown
Contributor

Avoid Exponential AgentTool Checkpoint Growth

Problem

ChatModelAgent checkpoint bytes were persisted twice by Runner: once as the
authoritative interrupt state and again inside the deprecated
ChatModelAgentInterruptInfo.Data view.

AgentTool embeds a child Runner checkpoint in its parent checkpoint. Repeating
the duplicate payload at every nested boundary caused checkpoint size to grow
exponentially with depth. Three layers around a 1 MiB payload produced an
8.4 MiB checkpoint.

Solution

Persist the checkpoint bytes only in InterruptID2State. The serialized legacy
view records the interrupt state ID instead of another copy of the bytes.
During load, Runner resolves that ID and reconstructs
ChatModelAgentInterruptInfo.Data before resume callbacks or agents observe it.

Compaction is applied only when the legacy bytes exactly match the root
interrupt state. Custom, mismatched, and unaddressed interrupt data remains
inline and unchanged.

Decisions

The existing gob schema remains additive. Old inline checkpoints continue to
load, while malformed compacted references fail instead of silently resuming
with incomplete state.

Key Insight

For nested AgentTool execution, the child Runner checkpoint is already the
canonical state of the AgentTool interrupt. Persisting the same bytes in the
legacy presentation field changes linear checkpoint composition into
approximately twofold growth at every agent level.

Summary

Problem Solution
Nested AgentTool checkpoints duplicate the full child payload at every Runner layer Store one canonical payload and persist an internal reference
Existing consumers expect ChatModelAgentInterruptInfo.Data during resume Reconstruct the legacy view while loading
Corrupt references could cause incomplete resume state Reject missing or invalid referenced state

避免 AgentTool Checkpoint 随嵌套层级指数膨胀

问题

ChatModelAgent 的 checkpoint bytes 会被 Runner 持久化两次:一份位于权威的
interrupt state 中,另一份位于已废弃的 ChatModelAgentInterruptInfo.Data 兼容视图中。

AgentTool 会把 Child Runner checkpoint 嵌入 Parent checkpoint。每层都重复完整
payload,导致 checkpoint 大小随嵌套深度指数增长。三层包装 1 MiB payload 时,
checkpoint 会增长到约 8.4 MiB。

方案

checkpoint bytes 只持久化在 InterruptID2State。序列化后的 legacy 视图不再保存
第二份 bytes,而是记录对应的 interrupt state ID。加载时,Runner 根据该 ID 恢复
ChatModelAgentInterruptInfo.Data,因此 Resume callback 和 Agent 看到的行为不变。

只有当 legacy bytes 与根 interrupt state 完全一致时才会去重。自定义、不一致或
缺少地址的 interrupt data 仍按原方式内联保存。

决策

继续使用可增量兼容的 gob schema。旧的内联 checkpoint 可以正常读取;新的引用
如果缺失或类型错误,则明确失败,避免用不完整状态继续 Resume。

核心认识

在嵌套 AgentTool 场景中,Child Runner checkpoint 已经是 AgentTool interrupt 的
权威状态。同一份 bytes 再写入 legacy 展示字段,会让原本线性的 checkpoint 组合
变成每经过一层 Agent 都近似翻倍。

总结

问题 解决方式
嵌套 AgentTool 在每层重复完整 Child payload 只持久化一份权威 payload,并保存内部引用
现有调用方在 Resume 时依赖 ChatModelAgentInterruptInfo.Data 加载 checkpoint 时重建 legacy 视图
损坏引用可能产生不完整 Resume 状态 缺失或类型不匹配时明确报错

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.73%. Comparing base (0e01b2a) to head (26b4c14).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1232      +/-   ##
==========================================
+ Coverage   83.68%   83.73%   +0.04%     
==========================================
  Files         162      162              
  Lines       23851    23887      +36     
==========================================
+ Hits        19960    20001      +41     
+ Misses       2630     2627       -3     
+ Partials     1261     1259       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Persist ChatModelAgent checkpoint bytes once in the interrupt state map and reconstruct the deprecated ResumeInfo data view when loading. This prevents checkpoint size from doubling at every nested AgentTool boundary while retaining legacy checkpoint compatibility.

Change-Id: I6b1bd4f2961fe8fb259824427a73e7fb0bd01258
@shentongmartin
shentongmartin force-pushed the fix/agenttool-checkpoint-size branch from c6701be to 26b4c14 Compare August 31, 2026 04:08
@shentongmartin
shentongmartin merged commit 60e1d99 into main Aug 31, 2026
19 checks passed
@shentongmartin
shentongmartin deleted the fix/agenttool-checkpoint-size branch August 31, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants