7大开源Agent源码对比解读——性能设计

7大开源Agent源码对比解读------性能设计

本文是「7大开源Agent源码对比解读」系列第 8 篇。评估对象:codex、gemini-cli、qwen-code、opencode、kimi-code、deepseek-harness(下称 dsh)、oh-my-pi(下称 omp)。缓存与计价机制均附源码引证。

文章 内容速览
总述 拆了七大开源 Agent 的源码,最高分竟然不是 Codex 总体结论、评估方法与评分卡
01 架构对比 四种流派与分化根源、主循环与事件机制、插件化与耦合风险
02 上下文管理 压缩触发阈值、摘要方式、token 计数口径、跨会话记忆
03 会话管理 持久化模型三层次、并发控制、崩溃恢复与 resume / fork
04 工具调用 注册与可见性、并行调度四种语义、审批门控、错误处理
05 重连与容错 重试预算、流中断处理、降级链、副作用安全
06 系统提示词与指令遵循 四种组装范式、动态注入、注入防御三层与共同敞口
07 思维链与工作流编排 思维链接入、plan 模式语义、子代理治理、工作流引擎
08 性能设计 前缀缓存三档分化、启动优化、成本核算
09 可扩展性 MCP 接入、自定义工具、多 provider、SDK 与 API
10 安全与权限控制 沙箱两种语义、审批默认姿态、企业管控、敏感数据保护

性能设计的核心工程问题是:让长会话的每一轮都命中前缀缓存。缓存读价通常是标准价的 10%,长会话里这笔钱很可观。七个项目在这个问题上分成三档。

三档分化

第一档:把缓存断点放置当一等工程问题。 opencode 在协议无关层写统一的缓存策略,omp 把「稳前缀」做进数据结构,专门设计了 append-only 上下文和 fork 缓存身份继承。

第二档:吃 provider 原生缓存但做会话亲和。 codex、kimi、qwen 用 prompt_cache_keymetadata.user_id 把同一会话的请求钉到同一缓存槽。

第三档:只读不写。 gemini-cli 依赖 Gemini 隐式缓存,只读响应里的 cachedContentTokenCount;dsh 连断点都不碰,只把 provider 返回的 cache 字段透传进账本。

缓存机制对比

项目 缓存机制
codex prompt_cache_key 会话亲和 + WS 增量请求 + 粘性路由
gemini-cli Gemini 隐式缓存,只读计量,不主动建缓存资源
qwen-code OpenAI 前缀缓存标记 + Anthropic cache_control 自动放置
opencode CachePolicy 默认 3 断点,仅 2 种协议注入 wire 标记
kimi-code prompt_cache_key 三协议全注入 + fork 缓存探针
dsh 不放断点,透传 provider 的 cache 用量字段
omp append-only 稳前缀 + 1h TTL + fork 继承缓存身份

逐家看点

codex:增量请求与粘性路由

codex 优先走 Responses-over-WebSocket。同一 turn 内连续发多次请求时,客户端缓存上一轮的完整请求与响应,判断当前请求是否是上一请求的增量扩展:只有当 model、instructions、tools 等非 input 字段全部不变,且 input 是上一 input 的前缀扩展时,才只发新增的条目加 previous_response_id,不重发整段历史(client.rs:1232-1273)。直接降低出站字节量,也利于 provider 侧前缀命中。

粘性路由是客户端与服务端的契约:turn 启动时服务端在响应头返回 x-codex-turn-state token,此后该 turn 的所有请求(重试、增量、续写)原样回放这个 token,不同 turn 之间不能混用(client.rs:278-288)。效果是同一 turn 粘到同一后端节点,保连接复用和缓存局部性。

启动优化做成了可观测的独立句柄:会话启动时异步发一个 generate=false 的预热请求,提前建好 WebSocket、跑完认证、拿到 previous_response_id,首条用户消息到达时直接复用(session_startup_prewarm.rs:26-247)。超时、取消都有专门遥测指标。这是七家中唯一把连接预热做成一等公民的。

opencode:协议无关的缓存策略

CachePolicy 定义在协议无关层:auto 模式在最后一个工具定义、最后一个 system part、最新一条 user message 三处放断点(cache-policy.ts:18-97)。关键门控是只有 anthropic-messagesbedrock-converse 两种协议会真正注入 wire 标记;OpenAI 系、Gemini、Azure 等协议走 provider 原生隐式前缀缓存,整个策略 pass 直接跳过,注释的理由是「发标记无害但没意义」。断点策略只填补调用方留空的缺口,手动标记会被保留。
#mermaid-svg-Zppe4oEWsOyDPijj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Zppe4oEWsOyDPijj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Zppe4oEWsOyDPijj .error-icon{fill:#552222;}#mermaid-svg-Zppe4oEWsOyDPijj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Zppe4oEWsOyDPijj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Zppe4oEWsOyDPijj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Zppe4oEWsOyDPijj .marker.cross{stroke:#333333;}#mermaid-svg-Zppe4oEWsOyDPijj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Zppe4oEWsOyDPijj p{margin:0;}#mermaid-svg-Zppe4oEWsOyDPijj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Zppe4oEWsOyDPijj .cluster-label text{fill:#333;}#mermaid-svg-Zppe4oEWsOyDPijj .cluster-label span{color:#333;}#mermaid-svg-Zppe4oEWsOyDPijj .cluster-label span p{background-color:transparent;}#mermaid-svg-Zppe4oEWsOyDPijj .label text,#mermaid-svg-Zppe4oEWsOyDPijj span{fill:#333;color:#333;}#mermaid-svg-Zppe4oEWsOyDPijj .node rect,#mermaid-svg-Zppe4oEWsOyDPijj .node circle,#mermaid-svg-Zppe4oEWsOyDPijj .node ellipse,#mermaid-svg-Zppe4oEWsOyDPijj .node polygon,#mermaid-svg-Zppe4oEWsOyDPijj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Zppe4oEWsOyDPijj .rough-node .label text,#mermaid-svg-Zppe4oEWsOyDPijj .node .label text,#mermaid-svg-Zppe4oEWsOyDPijj .image-shape .label,#mermaid-svg-Zppe4oEWsOyDPijj .icon-shape .label{text-anchor:middle;}#mermaid-svg-Zppe4oEWsOyDPijj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Zppe4oEWsOyDPijj .rough-node .label,#mermaid-svg-Zppe4oEWsOyDPijj .node .label,#mermaid-svg-Zppe4oEWsOyDPijj .image-shape .label,#mermaid-svg-Zppe4oEWsOyDPijj .icon-shape .label{text-align:center;}#mermaid-svg-Zppe4oEWsOyDPijj .node.clickable{cursor:pointer;}#mermaid-svg-Zppe4oEWsOyDPijj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Zppe4oEWsOyDPijj .arrowheadPath{fill:#333333;}#mermaid-svg-Zppe4oEWsOyDPijj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Zppe4oEWsOyDPijj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Zppe4oEWsOyDPijj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Zppe4oEWsOyDPijj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Zppe4oEWsOyDPijj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Zppe4oEWsOyDPijj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Zppe4oEWsOyDPijj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Zppe4oEWsOyDPijj .cluster text{fill:#333;}#mermaid-svg-Zppe4oEWsOyDPijj .cluster span{color:#333;}#mermaid-svg-Zppe4oEWsOyDPijj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Zppe4oEWsOyDPijj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Zppe4oEWsOyDPijj rect.text{fill:none;stroke-width:0;}#mermaid-svg-Zppe4oEWsOyDPijj .icon-shape,#mermaid-svg-Zppe4oEWsOyDPijj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Zppe4oEWsOyDPijj .icon-shape p,#mermaid-svg-Zppe4oEWsOyDPijj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Zppe4oEWsOyDPijj .icon-shape .label rect,#mermaid-svg-Zppe4oEWsOyDPijj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Zppe4oEWsOyDPijj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Zppe4oEWsOyDPijj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Zppe4oEWsOyDPijj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 出站请求(auto 模式放三个断点)
最后一个工具定义
最后一个 system part
历史消息
最新一条 user 消息
断点 ①
断点 ②
断点 ③
仅 anthropic-messages / bedrock-converse 注入 wire 标记,

其余协议走隐式缓存、整个策略 pass 直接跳过

成本核算也下了功夫:模型定价从 models.dev 目录拉取,支持按上下文长度分档计价,超 200k token 有独立档价(含 cache_read/cache_write 分别计价),避免用单一单价外推(models-dev.ts:25-50)。

启动优化:Bun 单二进制,为每个平台额外构建不带 AVX2 的 baseline 变体兼容旧 CPU。

omp:稳前缀是数据结构问题

omp 的思路最彻底:缓存友好不靠请求时打标记,靠数据结构本身(append-only-context.ts:1-15)。

两个机制:StablePrefix 把 system prompt 加工具规格算一次后冻结,后续 turn 复用完全相同的字节序列,除非显式失效或指纹变化;AppendOnlyLog 里消息只增不改,历史 turn 永不重序列化。两者叠加,每轮缓存未命中的只有用户新消息那一段增量。
#mermaid-svg-Rdhs8zzSoJ4gSBs5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .error-icon{fill:#552222;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .marker.cross{stroke:#333333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 p{margin:0;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster-label text{fill:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster-label span{color:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster-label span p{background-color:transparent;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .label text,#mermaid-svg-Rdhs8zzSoJ4gSBs5 span{fill:#333;color:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node rect,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node circle,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node ellipse,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node polygon,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .rough-node .label text,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node .label text,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .image-shape .label,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .rough-node .label,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node .label,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .image-shape .label,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .icon-shape .label{text-align:center;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node.clickable{cursor:pointer;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .arrowheadPath{fill:#333333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster text{fill:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .cluster span{color:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .icon-shape,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .icon-shape p,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .icon-shape .label rect,#mermaid-svg-Rdhs8zzSoJ4gSBs5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .hit>*{fill:#d8f3dc!important;stroke:#2d6a4f!important;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .hit span{fill:#d8f3dc!important;stroke:#2d6a4f!important;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .miss>*{fill:#ffe8b3!important;stroke:#b07d2b!important;}#mermaid-svg-Rdhs8zzSoJ4gSBs5 .miss span{fill:#ffe8b3!important;stroke:#b07d2b!important;} StablePrefix 冻结段

system prompt + 工具规格

字节序列完全相同
AppendOnlyLog 历史轮次

只追加,永不重序列化
本轮新消息

唯一未命中缓存的增量
syncMessages:需要归一化改写消息时,

只 trim 到最长稳定前缀,

避免整段缓存失效

syncMessages() 处理了一个隐蔽的坑:归一化消息进 log 时,找到最长字节稳定前缀,原地改写只 trim 到该前缀(:188-214)。这修复的是「单条消息被改写导致整段缓存失效」的问题。

fork 继承缓存身份:/fork 等路径把父会话的 providerPromptCacheKey 传给子会话,子会话首请求能命中父会话已建立的缓存前缀(session-entries.ts:45-52)。注意只有 exact-route full fork 才继承,分支型 fork 会冷未命中。

Anthropic 族支持 cache_control 的 5 分钟和 1 小时两档,按模型能力选择,同一 block 多个声明取最强保留(anthropic-messages-server.ts:281-295)。

kimi-code:全协议亲和与 fork 探针

会话 ID 作为缓存亲和键注入三家协议的请求体:Anthropic 映射到 metadata.user_id(注释说明这是 Anthropic 侧对应 prompt_cache_key 的等价物),OpenAI 和 Kimi 直接注入 generationKwargs.prompt_cache_key(provider-manager.ts:268-375)。

fork 探针是独有的遥测:fork 出的子代理首轮 usage 记录完成后,发一个 prompt_cache_probe 事件,携带输入、缓存读、缓存创建等字段,专门度量「父会话缓存身份在子会话是否仍命中」(cacheProbeService.ts:23-49)。想优化 fork 场景的缓存继承,先要有这样的度量。

其余三家

gemini-cli 不主动创建缓存资源,依赖 Gemini 隐式前缀缓存,客户端只读 cachedContentTokenCount 进遥测和 UI 度量。启动优化上它是七家中唯一带公开性能回归框架的:perf-tests/ 目录有基线文件和测试,冷启动 927.6ms 是提交进仓、有 CI 守护的回归阈值(baselines.json:5-6)。其余六家没有类似基线,性能数字不可横向引用。

qwen-code 对 OpenAI 族标记可复用的历史前缀,Anthropic 族自动放置 cache_control 断点(system 文本、最后一个工具、尾部 user 消息),支持 1 小时扩展档。另有 V8 字节码编译缓存加速冷启动。/stats 命令展示缓存命中率。

dsh 的策略是「provider 给什么记什么」:不放断点,只把返回的 cacheReadTokenscacheWriteTokens 透传进账本,并明确要求三类输入计数互斥(不含缓存的输入、缓存读、缓存写分开记,把缓存命中折叠进总数的 provider 要减出来,types.ts:127-141)。token-meter 逐节点计价,每条消息、每个内容块单独定价,保证上下文明细和计价服务用同一套启发式。

成本核算的对比

项目 成本核算特色
codex 缓存读、缓存写分别作为独立 span 属性上报,不合并
gemini-cli 12 个 LLM 角色分开记账(主对话、子代理、压缩器、循环检测器等)
qwen-code telemetry 聚合 + 会话级 token 限额
opencode 分档计价 + 超 200k 独立档 + stats 命令
kimi-code usage 区分 cache read / cache creation
dsh token-meter 逐节点计价 + 会话统计投影
omp 本地看板实时显示 tokens/s、cache rate、成本

gemini-cli 的分角色记账值得展开:LlmRole 枚举 12 个值,主对话、子代理之外,压缩器、摘要器、路由器、循环检测器、下一发言判断、编辑纠正等辅助调用各占一个角色,每个 token 事件带角色字段(llmRole.ts:7-20)。成本分析时能直接回答「钱是主推理花的还是辅助调用花的」。辅助 LLM 调用一多(循环检测、压缩、标题生成),没有分账就是笔糊涂账。

给 Agent 开发者的借鉴清单

  1. 稳前缀优先做进数据结构。 冻结前缀字节、历史只追加、消息改写只 trim 到稳定前缀(omp 三件套),比在请求时找位置打断点更根本。
  2. 会话亲和键全协议注入。 prompt_cache_keymetadata.user_id,让同一会话钉在同一缓存槽(kimi 的三协议映射表可以直接抄)。
  3. fork 要继承缓存身份,并度量它。 继承与否的命中率差异要有遥测(kimi 的 fork 探针)。
  4. 缓存断点策略放协议无关层。 只对支持显式标记的协议注入,其余走隐式缓存并跳过(opencode 的门控集合)。
  5. 缓存读写分开计量。 读是省钱,写是成本,合并了就看不清(codex、kimi、dsh 都分)。
  6. 辅助 LLM 调用分角色记账。 压缩、裁判、路由各算各的(gemini-cli 的 LlmRole)。
  7. 性能基线进仓库。 冷启动、长会话恢复这类指标做成回归测试,数字才可比较(gemini-cli 是唯一示范)。
  8. 连接预热做成可观测句柄。 带超时、取消、遥测,集中管理而非散在启动流程里(codex 的 prewarm handle)。

文档地图

文章 内容速览
总述 拆了七大开源 Agent 的源码,最高分竟然不是 Codex 总体结论、评估方法与评分卡
01 架构对比 四种流派与分化根源、主循环与事件机制、插件化与耦合风险
02 上下文管理 压缩触发阈值、摘要方式、token 计数口径、跨会话记忆
03 会话管理 持久化模型三层次、并发控制、崩溃恢复与 resume / fork
04 工具调用 注册与可见性、并行调度四种语义、审批门控、错误处理
05 重连与容错 重试预算、流中断处理、降级链、副作用安全
06 系统提示词与指令遵循 四种组装范式、动态注入、注入防御三层与共同敞口
07 思维链与工作流编排 思维链接入、plan 模式语义、子代理治理、工作流引擎
08 性能设计 前缀缓存三档分化、启动优化、成本核算
09 可扩展性 MCP 接入、自定义工具、多 provider、SDK 与 API
10 安全与权限控制 沙箱两种语义、审批默认姿态、企业管控、敏感数据保护
相关推荐
VIP_CQCRE27 分钟前
用 Ace Data Cloud 开启 AI 能力商业化:推广平台,或打造自己的白标 AI 平台
ai·api·mcp·ace data cloud·白标平台
TechEdu20260635 分钟前
[人工智能]豆包(Doubao):模型能力、应用架构与工程实践
人工智能·ai
GHL2842710901 小时前
用codex做一个简单技能学习
学习·ai
小新科研测评1 小时前
2026 年 3 种 PDF 文献翻译方案横评:公式/表格/双栏排版保真度实测
人工智能·ai·pdf·自动翻译
笨蛋©2 小时前
2026年制造业数字化:如何通过 Infra CONVERT 中国代理 实现检验计划自动化
ai·数字化·cad·质量管理·制造业
新知图书2 小时前
16.1 基于MCP的多Agent旅行规划助手系统概述
人工智能·agent·ai agent·智能体
闪学it3 小时前
周瑜零基础手写agent
agent
闪学it3 小时前
大模型与Agent智能体开发实战
agent