Repository navigation
perf(atomic-memory): send each Source body once to extraction - #2163
jasondeng1997 wants to merge 1 commit into
Conversation
`project_atomic_memory_evidence` gave the model two independent body carriers: `content`, and a full dump of the stored Source in `source_metadata`. Every Source body therefore arrived twice, and three times for an observation, where `payload.content` and the text-evidence projection repeat it again. Those copies spend the input token budget on text the model has already read, so a batch crosses `atomic_memory_input_tokens_limit` and `_reduce_window()` bisects it instead of extracting. Compact the metadata at the projection site. Only values that repeat the body are removed: `ContentSource.content`, `payload.content`, the `content` key inside a projection value, and `wire_content` when it is the same value as the body. Every other provenance key stays, including `metadata`, `payload.metadata`, `definition_version` and `working_note`. One 3,982-character Source, measured on the complete extraction input with the character estimator: 2,142 -> 1,143 tokens for a native Source (46.6% less) and 3,243 -> 1,195 for an observation (63.2% less). At 24,000 tokens that is 11 -> 20 Sources per window for the HTTP capture path. Source storage, the journal and Artifact lineage are untouched; this changes what the prompt sees.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
| if not isinstance(value, SourceObservation): | ||
| body = dumped.get("content") | ||
| dumped.pop("content", None) | ||
| if body is not None and dumped.get("wire_content") == body: |
There was a problem hiding this comment.
[P2] 结构化 wire_content 仍把同一份正文送两遍,标题的「每份 Source 只送一次」只对字符串 wire 成立
:146 的判据是 dumped.get("wire_content") == body,即 dict 与 str 比较。真实写入路径是
records.create_source 的 content = _canonical_source_text(content)(RFC 8785 规范化 JSON)+
wire_content = <原始 JsonValue>;集成侧传的是结构化 JSON,因此这里恒为 False,整个 wire_content
连同其中的正文一起留在 source_metadata 里,而 content 已经是同一段文本的规范化 JSON。
探针 probes/probe_structured_wire.py(同一 Head 树,走 project_atomic_memory_evidence 公开入口后
AtomicMemoryExtractionInput.model_dump_json() 计数):
wire_content = {"text": <body>, "kind": "note"}⇒ 正文出现 2 次,input 738 bytes(wire_content保留);wire_content = <body>(字符串)⇒ 1 次,553 bytes;wire_content = {"messages": [...]}(不含正文)⇒ 0 次,580 bytes。
test_wire_bytes_that_carry_something_else_survive 用的正是第三种,所以用例自洽,但覆盖不到真实采集形态。
建议:按「wire 的规范化文本是否等于 content」判定(复用 _canonical_source_text / rfc8785.dumps),
而不是比较对象与字符串;并补一条 {"text": <body>, ...} 结构性 wire 的用例。
另需协调:#2139 修改的是同一个 project_atomic_memory_evidence 与同一插入点,去重边界与本 PR 不一致
(本 PR 无条件删 payload.content,并对任意 projection 的 value.content 一律剥离;#2139 仅在等于投影正文时删、
其余 projection 完整保留;结构化 wire_content 反而是 #2139 删、本 PR 保留:同场景实测 #2139 为 1 次 / 586 bytes)。
两者只能合入其一,后合的一方会在同段落必然冲突,建议在 PR 正文写明与 #2139、Issue #2137 的协调结论。
hidb4ai
left a comment
There was a problem hiding this comment.
Please preserve distinct Source evidence during compaction. The current implementation can omit facts from extraction while still advancing the Source cursor.
| continue | ||
| projected = projection.get("value") | ||
| if isinstance(projected, dict): | ||
| projection = {**projection, "value": {key: item for key, item in projected.items() if key != "content"}} |
There was a problem hiding this comment.
[P2] Preserve content that differs from the extraction body
This drops content from every projection by name, and line 153 does the same to payload.content, even when those values differ from the selected text evidence. With a valid registered Source whose text projection is Use canary deployment., raw content is The deployment region must be eu-west-1., and another projection's content is The deployment budget is 37 units., submitting to SQLite and then flushing removes both independent facts from the extractor input while advancing the cursor to 1. Both facts survive at base 88899876.
Only remove values proven redundant with the actual extraction body. The native branch at line 145 needs the same safeguard when adapter.read() returns a different value.
What this changes
project_atomic_memory_evidence()built oneAtomicMemoryEvidenceper Source with two independent body carriers:content, and a fullmodel_dump()of the stored Source insource_metadata. The model therefore received every Source body two or three times, and the repeated copies spent theatomic_memory_input_tokens_limitbudget on text it had already read.source_metadatais now compacted at the projection site by_compact_source_metadata(): it keeps Source provenance and drops only the values that repeat the body.native(ContentSourcevia HTTPcapture_content_source)content+source_metadata.contentcontentobservation(SourceObservationvia the SDK transport)content+source_metadata.payload.content+ the text-evidence projectioncontentMeasured with
character_token_estimator()on the completeAtomicMemoryExtractionInputfor one 3,982-character Source (996 tokens on its own):nativeobservation(text projection)The remaining overhead is provenance, not body: 147 tokens for a native Source and 199 for an observation.
What is kept
evidence_id,source_ref,journal_position,content,via_artifact, and theAtomicMemoryEvidenceschema are unchanged.metadata,payload.metadata,name,description,definition_version,materialization,working_note,source_type,definition_fingerprint, and any furtherpayloadkey.wire_contentis dropped only when it is the same value as the body. A structured wire body is distinct evidence and stays.contentkey inside its value is removed.contentis that projection — the entry then carries nothing the response does not already have.Tests
New
tests/builtin/artifacts/atomic_memory/test_extraction_evidence.pypins the invariant "one Source body, one copy" for all four shapes — native, native with a repeatedwire_content, observation with a text projection, observation without one — and asserts the surviving provenance field by field, so a future compaction cannot delete evidence while passing the body-count check.ruff check,ruff format --checkandty checkare clean on both files.Out of scope
Nothing else in #2137 is required for this: there is no contract, config or storage change.
_reduce_window()behaviour is unchanged — fewer redundant bytes simply mean it triggers less often for the same batch.