预算:summary-first 是架构,不是优化
反编译一个函数可能几万字,一张调用图可能几十万个节点。REA 的做法不是截断,而是把"分析完整"和"交付多大"拆成两个问题。
预算:summary-first 是架构,不是优化
逆向工具的输出天然不适合直接塞进模型上下文:一个函数的伪代码几千字,一个 JavaScript bundle 的模块图几万个节点,一份 HAR 可能有几十万条请求记录。
多数工具的处理方式是截断:取前 N 条,加一句”还有更多”。REA 没有这么做。它把”分析完成”和”这次交付多少”拆成两个独立的状态。
完整结果先进账本
一次 analyze_function 的成功结果,不管多大,都会先变成 Evidence 存进账本。交付给模型的可以是摘要,但账本里始终是完整记录。
// 默认返回 summary,完整档案留在账本
analyze_function({ address: "0x100012340" })
// → normalized_result.parent_evidence_id = "ev_..."
摘要不是”从完整结果里切一段”,而是一个独立的、带 parent_evidence_id 的视图记录。后续要取细节,用 inspect_analysis_view:
{
"source": { "kind": "retained-evidence", "evidence_id": "ev_..." },
"view": { "kind": "native", "facet": "pseudocode", "offset": 0, "limit": 64 }
}
limit、offset、fields 都是视图参数;页面耗尽只说明这一页读完,不说明整个结果只有这些。
响应超限时的三步
MCP 的 stdio 接收缓冲有上限,REA 自己的单字符串长度也有上限(Node 的单字符串上限再减 1024 个 UTF-16 单元)。当一条完整结果放不下时,ToolResultDelivery 不会截断 JSON,而是走三步:
- 如果调用方已经选了一个分页,把
limit减半,再试一次。 - 如果没选分页,给出这个操作类型的”第一页”:函数档案给伪代码第一页,批量反编译给 items 第一页,原生清单给 64 条第一页。
- 如果连第一页都放不下,返回
resource_constraint,并在details里给出下一步:换inspect_analysis_view、导出 bundle,或者用 CLI 的流式输出。
源码里的分页续接很直白:
const smaller = smallerPage(selected);
const view = smaller ?? ownerFirstPage(evidence);
return continuationOf(
{ kind: "retained-evidence", evidence_id: evidence.evidence_id },
view,
);
这里没有”截断”分支,只有”换一个更小的视图”。
为什么 summary-first 是架构
如果摘要只是可选的优化,调用方就会默认拿完整结果,然后由客户端截断——这时模型看到的是一段不完整的 JSON,它不知道自己看到的是全部还是前 10%。
REA 把默认值反过来:默认交付摘要,完整记录留在账本。这不是为了省 token,而是为了让”当前看到的是视图”成为协议的一部分。摘要记录里有:
parent_evidence_id:完整结果是谁。- 这份视图的
evidence_id:这一页本身也是一条可引用记录。 - 视图的类型、偏移、限制、字段选择。
模型可以明确地说”我看的是第 0–63 条”,而不是”我猜这是全部”。
账本也有预算
证据不是无限存的。EvidenceLedger 的上限是当前 V8 可用堆的四分之一;超过就返回资源约束错误,要求导出或分页,而不是悄悄丢旧记录。
导出有两个层次:
get_evidence_bundle可以只取摘要,按 operation、目标 SHA-256、profile digest、地址过滤。export_evidence_bundle写完整 bundle 到调用方指定的路径。
reset_investigation 可以带 save_path,在清空之前把完整 bundle 落盘;新进程再导入,Evidence ID 和未知项修订链都能复原。REA 明确说”保留是有界的,不是自动持久化”——这句话很重要,它避免了”以为工具记得住”的幻觉。
交付层还做了两件小事
一是 compact schema。 输入 schema 默认紧凑,只有需要完整字段说明时才打开 full。这把”工具目录本身”的上下文成本也纳入了预算。
二是给结果加来源标记。 带目标内容的回复会带 _meta.provenance.untrusted_content,提示模型这是数据不是指令。它不改变结果大小,但改变了模型解读结果的方式——也算一种预算:注意力预算。
一句话总结
REA 不假设上下文无限,也不接受”截断后假装完整”。它的做法是:分析结果完整落账,交付按视图分页,超限时给出可执行的下一步。
下一篇讲边界:当工具真的能启动进程、写文件、连网络、操作设备时,REA 用什么约束保证”能执行”不等于”随便执行”。