perf(adk): 降低嵌套 AgentTool checkpoint 放大 - #1234
Open
shentongmartin wants to merge 19 commits into
Open
Conversation
Capture main checkpoint bytes and verify both current and v0.9.18 readers can resume them before changing persisted formats. Change-Id: I81068999292d405449848b0afbe37e87b44572d5
Store the child runner checkpoint once in versioned AgentTool state and propagate only public interrupt contexts to the parent. Change-Id: I553ec1a656bcbc75da1c11e479de94a3137c3377
Merge child-owned interrupt state without overwriting consumed entries and validate versioned layout metadata before resume. Change-Id: I9b866d6f3cff4aee3cacc3f7b6ab0dafe9fcd970
Write sparse versioned checkpoint state maps, guard forward-incompatible readers with a gob sentinel, and retain full routing indexes for targeted resume. Change-Id: Iee06fa136cbc4e35dea3fcc3706980d68c7098a2
Persist each interrupt state only in its owning graph checkpoint and add version sentinels that fail loudly in older SDKs. Change-Id: Idbba32d73bdc4ddc826d15de9e01c7b42de42d26
Add a versioned reader for minimal tool-call checkpoint state while preserving the legacy writer after the compact-size gate failed. Change-Id: I9685e3d8b35bcb48e75124b3ced5733f396ae263
Change-Id: I3ad900fee1056276a745ba7498b941598858df10
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1234 +/- ##
==========================================
+ Coverage 83.71% 84.07% +0.35%
==========================================
Files 162 164 +2
Lines 23887 25777 +1890
==========================================
+ Hits 19998 21672 +1674
- Misses 2628 2733 +105
- Partials 1261 1372 +111 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Change-Id: I3fc67c65d981a141007559eba11bc579e591af53
Change-Id: Ieb7cbd93c0f98c04129b1cb21f890b45e61aed4e
Change-Id: I68cdd004ee6d6edb07d486377600c6278f70241c
Change-Id: I16baaf0aea497e2c9f5f26fc071118bacb7d680b
Change-Id: I5deda094c9075928598f702f26ff82b03638e626
Change-Id: Ia9330a0993bd7dd845e9e46496a10b0879606da1
Change-Id: Ib5d3f9fea5f4a7155f456763ea00a84882b5cf98
Change-Id: Ie59d875f0ca03cc16fb8155f7ca18fd7202e615b
Change-Id: I5524d11e527b2e6133936d529a1c014a9c664aa8
Change-Id: I3b7d5b9c7024e8f717ac1e7b88c98a4d221217f6
Change-Id: I21707dfc8539bd6a2f66f85f7fcb28330be0fed2
Reject ambiguous and conflicting persisted state, make corruption errors deterministic, and keep migration and traversal semantics consistent with compact checkpoint references. Strengthen compatibility, attack, size, and regression tests. Change-Id: I9e860ecece23c3c049b59fa6ce6a28e608967d2b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A Child model payload was serialized repeatedly across Runner state, AgentTool bridge state, compose subgraphs, ToolsNode rerun state, and legacy interrupt metadata. A 320 KiB Child response produced a 6.97 MB outer checkpoint, while deeper AgentTool nesting multiplied the same logical data again.
Solution
The checkpoint now follows explicit ownership boundaries:
main@60e1d992remain readable.Projection is conservative: missing IDs, conflicting IDs, or values that cannot preserve exact
ResumeInfo.Dataremain inline. Hydration validates versions, counts, coordinates, digests, ownership paths, and routing ancestry before execution, then deep-clones restored values to avoid mutable aliases.Decisions
Size thresholds are measurements, not phase gates. All planned phases are implemented even where a local optimization alone did not meet an intermediate target.
Inputsand channel values remain inline when replacing them cannot preserve byte-identical resume data. ToolsNode pre-handlers keep their existing lifecycle; persisted effective ToolCalls override the resumed input after the handler runs.Key Insight
Compose subgraphs and AgentTool children are different restore boundaries. A subgraph shares the parent resume scope and owns state at its deepest routing checkpoint. An AgentTool child restores an independent Runner checkpoint. Preserving that distinction removes repeated payload ownership without weakening targeted resume semantics.
Result
6,972,730 B→393,641 B22,111,550 B→1,114,536 B8,409,917 Bsingle-agent baseline →1,114,527 Bnested final357,235 → 393,643 → 444,316 → 526,734 BThe remaining growth is approximately linear with payload size, depth, and sibling count instead of multiplicative duplication.
Verification
go test ./...go test -race ./adk/... ./compose/...GOTOOLCHAIN=go1.18.10 go test -race ./adk ./compose ./internal/coregolangci-lint run --new-from-rev=origin/main ./...问题
同一份 Child model payload 会被重复写入 Runner state、AgentTool bridge state、compose subgraph、ToolsNode rerun state 和 legacy interrupt metadata。实测 320 KiB 的 Child 输出会生成 6.97 MB checkpoint,多层 AgentTool 嵌套还会继续重复放大。
方案
checkpoint 现在按明确的所有权边界保存状态:
main@60e1d992生成的冻结 checkpoint 仍可读取。Projection 只处理能够严格证明相同的数据。缺少 ID、ID 冲突或无法保证
ResumeInfo.Data字节级一致时继续 inline。恢复前会校验版本、数量、坐标、digest、owner path 和 routing ancestry,并对恢复对象做深拷贝,避免可变别名。决策
体积目标只作为测量值,不再作为中止后续阶段的门槛,因此计划中的全部阶段都已实现。
Inputs和 channel value 在无法保持恢复数据完全一致时继续 inline。ToolsNode pre-handler 生命周期保持不变,恢复时由持久化的有效 ToolCalls 覆盖 handler 输出。关键认识
compose subgraph 与 AgentTool Child 是两个不同的恢复边界:subgraph 共享父级 resume scope,state 归最深路由 checkpoint 所有;AgentTool Child 则恢复独立的 Runner checkpoint。只要保持这一区分,就能消除重复 payload,同时不破坏 targeted resume。
结果
6,972,730 B→393,641 B22,111,550 B→1,114,536 B8,409,917 B单 Agent 基线 →1,114,527 B嵌套最终值357,235 → 393,643 → 444,316 → 526,734 B剩余增长随 payload、深度和并行宽度近似线性,不再是重复序列化造成的乘法放大。
验证
go test ./...go test -race ./adk/... ./compose/...GOTOOLCHAIN=go1.18.10 go test -race ./adk ./compose ./internal/coregolangci-lint run --new-from-rev=origin/main ./...