原来,99%的人都搞错了:Agent框架不是模型的包装器,而是模型的一部分。附万字长文实验论证和现象解析。
这篇来自OpenAI的研究员,Ryan,的一篇文章。总结下来就是:别在同一个编码智能体下切换不同的LLM,不然效果会差别很大。比如我们经常用claude code和cc switch使用来切换不同的大模型,虽然可行,但可能没有原生适配到claude code的ops等模型效果好。

文章做了啥
这篇文章通过实证研究、代码分析和行业案例,揭示了一个被严重低估的智能体设计约束:模型-框架适配。

文章做了什么:
- 对比实验:在相同环境和相同模型下,对 Claude Code、Codex CLI、GitHub Copilot CLI 三个框架运行完全相同的提示词,观察到明显不同的行为输出。
- 源码级解剖:深入分析三个框架的底层实现,比较了它们的编排协议、工具表面、记忆机制、引用格式、系统提示结构等方面的差异。
- 排行榜分析:引用 Terminal-Bench 2.0 数据,证明同一个模型搭配不同框架时,通过率差距可达 4.5 个百分点(如 Claude Opus 4.6 + ForgeCode 达 79.8%,而 + Capy 仅 75.3%)。
- 行业案例:引述 Cursor、Anthropic、LangChain 等团队的实践,验证"只改框架就让智能体排名从 Top30 跃升至 Top5"等发现。
文章核心结论
模型不能在框架之间随意切换。框架不是模型的包装器,而是模型有效参数的一部分。

- 模型是针对特定框架后训练的:模型学会的不是通用能力,而是特定框架的"本能"——特定的工具名称、参数格式、引用标签、记忆仪式等。
- 切换框架等于切换模型:即使权重相同,换框架后模型会表现出不同的行为,性能会显著下降(丢失引用信号、工具调用错误、记忆失效等)。
- 最佳实践是"模型+框架"作为匹配对:供应商应像 Copilot CLI 那样,为不同模型提供不同的工具表面,而不是追求"模型无关"的通用框架。
- 共同进化循环:有用的框架原语被训练进下一代模型,模型成熟后可以淘汰某些框架脚手架。匹配对随着模型升级而动态变化。
正文开始…
模型-框架-适配(Model-Harness-Fit)
使用带有原生框架的大语言模型(如Claude Code或Codex)更好,还是使用可按需切换模型的通用框架更好?
OpenAI工程师Ryan(@_lopopolo)今早发布了这张有趣的梗图,于是作者决定深入研究Codex、Claude Code和GitHub SDK的框架实现来寻找答案。框架真的那么重要吗?

作者在同一台工作站上同时运行着三个编码智能体。一个终端里是Claude Code,另一个是Codex CLI,第三个是GitHub Copilot CLI。相同的文件、相同的git树、相同的bash环境。三个看起来无法区分的不同框架。
作者对这三个框架运行了相同的提示词,它们的行为表现出明显差异,这些差异远超作者预期的不同供应商之间在风格和速度上的表面区别。
笼统的回答是"模型行为不同是因为它们本来就是不同的模型",但这里作者测试的是相同的模型和不同的框架。
模型是在针对框架的后训练中形成的,而不仅仅是针对API。它们期望的工具名称、输出的输入模式、包裹记忆事实的引用标签、调用的技能文件结构、当框架说"先制定计划"时遵循的规划协议——这些都不是模型的通用能力。
这些都是针对特定框架对特定模型进行后训练时融入的字节级约定。将模型从其框架中剥离出来,你就放弃了无法通过修改任何一方就能挽回的性能。
这带来了一个直接的后果,任何试图推出"模型无关"智能体的人都遇到过。你不能只是简单地切换模型。
支持自带密钥和多模型(这是负责任的做法,因为依赖单一供应商是有风险的!)确实增加了真正的工程复杂性。
要干净地切换模型,你必须同时切换它的框架:工具表面、模式形状、命名这些工具的技能主体、引用约定、记忆仪式、系统提示结构,有时还包括规划协议。
模型之上的所有东西都必须随着模型的移动而移动。这就是为什么每个支持多个提供商的智能体供应商最终要么(a)对他们支持的每个模型运行一个降级变体,要么(b)为每个模型维护一个独立的完整技术栈,并将选择权暴露给用户,即"你选择的是一个产品,而不仅仅是一个模型"。选项(b)是在质量上胜出的路径,为了避免被锁定在单一实验室,这笔工程成本是值得的。
切换编排器不是表面上的改变。它是伪装的模型切换。前沿实验室在过去一年里将模型的"本能"塑造成适应特定的工具表面、特定的记忆仪式、特定的技能格式。当你混搭时,你就在浪费这项工作。
作者认为这是当今智能体设计中最被低估的限制因素,它有一个简洁的名称:模型-框架-适配。
底层究竟是如何体现的呢?
作者深入研究了当前发布的三款开源实现:Codex CLI(OpenAI,完全开源在github.com/openai/codex)、Claude Code(Anthropic,闭源二进制,但有一个名为claw-code的Rust移植版在github.com/ultraworkers/claw-code,它足够紧密地跟踪上游行为)以及GitHub Copilot CLI(其SDK在github.com/github/copilot-sdk上完全开源许可)。
作者将涵盖以下内容:
证据:Terminal-Bench 2.0:排行榜实际显示了关于模型-框架对的什么信息
三个框架,三种赌注:SQ/EQ vs 类型化对话循环 vs JSON RPC监督器
工具表面:后训练最明显的地方
技能承载工具规范:为什么"相同的SKILL.md格式"并不意味着"可互换"
记忆层:同步实时写入 vs 延迟批量写入 vs 服务端写入,以及为什么引用标签很重要
引用规范:模型如何与框架对话
系统提示骨架:十个部分ID就是一个约定
路由的现实:GitHub Copilot CLI实际上在做什么
聊天中途切换模型:最清晰的失败模式
实验室的说法:Cursor、Anthropic和LangChain都在趋同于同一个框架
身份文件约定:CLAUDE.md、AGENTS.md、SOUL.md、USER.md以及各自的用途
这意味着什么:模型本身不再是护城河,并且匹配对会随着模型的成熟而改变
作者在《智能体记忆工程》中详细介绍了记忆层。本文主要讨论其他内容,只在记忆与编排交叉的地方重新提及。如果你想详细了解MEMORY.md索引、系统提醒注入、天数老化警告和信号门控的工作原理,请先阅读那篇文章。
证据:Terminal-Bench 2.0
在任何关于架构的争论之前,先看看排行榜。Terminal-Bench 2.0在bash密集型多步骤任务上评估智能体,它按框架加模型的组合排名,而不仅仅是模型。来自2026年4月30日的数据:
TERMINAL-BENCH 2.0 顶级组合 通过率======================================Codex + GPT-5.5 82.0%ForgeCode + GPT-5.4 81.8%TongAgents + Gemini 3.1 Pro 80.2%ForgeCode + Claude Opus 4.6 79.8%SageAgent + GPT-5.3-Codex 78.4%ForgeCode + Gemini 3.1 Pro 78.4%Droid + GPT-5.3-Codex 77.3%Capy + Claude Opus 4.6 75.3%Simple Codex + GPT-5.3-Codex 75.1%Terminus-KIRA + Gemini 3.1 Pro 74.8%
有两件事很突出。
第一,Claude Opus 4.6与ForgeCode配对达到79.8%,而同一个模型与Capy配对只有75.3%。相同的权重,不同的框架,在一个每个组合都在争夺零点几个百分点的基准测试中,两者之间有4.5个百分点的差距。有趣!
第二,排名靠前的并不是训练这些模型的实验室。ForgeCode是一个第三方框架,通过在不同模型家族之间路由,拿下了前六名中的三个位置。斯坦福大学的IRIS实验室将Opus 4.6与一个名为Meta-Harness的自动化框架进化系统配对,在相同的基准测试中将同一个模型推到了76.4%,远远超过了他们开始时的最佳基线。框架带来的分数提升超过了模型升级带来的提升。
Cursor的研究团队更尖锐地指出了这一点。在他们4月30日关于框架工程的文章中,他们指出,他们"只通过改变框架,就将自己的编码智能体从Terminal Bench 2.0的前30名提升到了前5名"。相同的模型,相同的基准测试,不同的脚手架。在一个公开排行榜上跃升了25个名次,这完全归功于框架。干得漂亮,Cursor!
LangChain的Vivek Trivedy用一句话总结了同样的观察:"Claude Code中的Opus 4.6得分远低于其他框架中的Opus 4.6。"Anthropic的旗舰模型在其自家的旗舰框架中,输给了在第三方脚手架中的相同权重。如果你只在规格表上看到模型名称,你无法预测这一点。
这就是模型-框架适配的经验案例。固定模型,切换框架,通过率的变化足以超过一代模型升级带来的提升。
那么为什么?框架到底做了什么,让同一个模型的两个实现产生不同的分数?
三个框架,三种赌注
每个框架选择不同的编排协议。模型正是在该协议的确切线路格式上进行训练的。

这不是同一个想法的三种实现。它们是模型和运行时之间的三种不同约定。
Codex 是一种类型化的异步协议。模型发出一个包含 Op 的 Submission,并收到一个类型化 Event 消息的流。该协议在 codex-rs/protocol/src/protocol.rs 中定义,使用显式的 #[serde(tag = "type", rename_all = "snake_case")] 枚举。在此基础上还分层了第二个协议:app-server-protocol/src/protocol/v2.rs 是一个10,721行的JSON RPC,用于跨进程客户端(IDE插件、桌面应用),其中v1(245行)已冻结,所有新的RPC都进入v2。方法命名为 <resource>/<method>,使用单数资源名称,驼峰式线路格式。这两个协议堆叠:进程内使用智能体层,跨进程使用JSON RPC层。模型被训练来发出 Submission 并消费 Event。
Claude Code 是一个直接的类型化对话循环。运行时的 ConversationRuntime::run_turn 从 ApiClient::stream 消费每轮的 Vec<AssistantEvent>。AssistantEvent 的变体包括 TextDelta(String)、ToolUse { id, name, input }、Usage(TokenUsage)、PromptCache(PromptCacheEvent) 和 MessageStop。没有单独的提交队列。协议就是Anthropic Messages API加上一个紧密的进程内工具调度器。模型被训练在助手消息内部发出工具调用,并在下一轮响应工具结果。
GitHub Copilot CLI 是一种监督器协议。主机应用不运行智能体循环。它将打包的 @github/copilot 二进制文件作为子进程启动,通过stdio打开一个 vscode-jsonrpc 通道,并发送带有完整配置的 session.create:模型、系统消息、工具、MCP服务器、自定义智能体、技能目录、钩子标志。智能体循环在子进程内部运行。主机收到 session.event 通知回来。它在这个监督器内部运行,并发出监督器可以路由的JSON RPC事件。
你可以看到每个设计中固化的架构承诺。Codex的 AGENTS.md 字面上就在管控crate的增长:"抵制向 codex-core 添加代码。最大的crate明确禁止新特性。"每个Rust模块500行软限制,800行硬限制。新特性以新crate的形式支付代价。这是一种应用于智能体框架的编译器工具链态度,模型正是在其中被训练的。
Claude Code的移植强制执行不同的规则:“一个智能体循环,而不是专门的智能体扇出”,这就是为什么Claude Code中的子智能体以全新的上下文开始且不能递归。Copilot CLI的监督器模型使得一个二进制文件可以服务三个表面(终端、云智能体、第三方主机)。每个表面获得相同的模型行为,因为模型总是在同一个监督器内部运行。
现在想象你切换模型。拿一个被训练成发出 Submission { id, op: UserTurn, trace } 的模型,并将其输入Claude Code的 Vec<AssistantEvent> 流。这个模型被教导了一种线路形状。框架期望另一种。这种不匹配不会表现为彻底的失败,而是表现为悄无声息的降级:遗漏的工具调用、错误的推理努力程度、不一致的压缩触发、框架永远不会解析的引用标签。线路格式是模型的一部分。
工具表面
这是后训练最明显的地方。
每个框架都有一个工具注册表。名称在顶层看起来很相似:read、write、bash、grep、glob。但一旦你超越了前六个,表面就会以模型被教导利用的方式产生分歧。
Codex 工具表面
Codex的 tools/src/lib.rs 暴露了一个特定的词汇表:
apply_patch— Codex的自定义差异格式。两种风格:一种是tool_apply_patch.lark中的自由形式Lark语法,另一种是JSON变体。模型被训练成以这种格式输出补丁。它不能与Claude Code的edit_file(采用old_string/new_string)互换。local_shell— bash家族。加上exec_command_tool和write_stdin_tool,用于模型可以在事后通过stdin写入驱动的长期运行进程。update_plan_tool— 计划/待办事项工具。未在此工具上训练的模型将使用不同的约定来跟踪工作。request_permissions_tool— 模型可以在回合中请求扩展权限。Codex是唯一拥有这个确切动词的框架。agent_tool— 多智能体编排,包含spawn_agent_v1、spawn_agent_v2、wait_agent_v1、wait_agent_v2、send_message、close_agent_v1、close_agent_v2、resume_agent。八个动词。模型知道所有八个。tool_search、tool_suggest— 寻找其他工具的工具。Codex对延迟工具加载的解决方案。goal_tool—create_goal、get_goal、update_goal。与迁移0029_thread_goals.sql相关联。
Claude Code 工具表面
Claude Code的移植在 mvp_tool_specs() 中列举了40个规范:
read_file、write_file、edit_file— 内部使用小写名称,暴露给模型时使用驼峰式(Read、Write、Edit)。模型是在驼峰式变体上训练的。Edit需要old_string、new_string、可选的replace_all。与Codex的apply_patch形状不同。Bash具有最深的沙盒表面:command、timeout、description、run_in_background、dangerouslyDisableSandbox、namespaceRestrictions、isolateNetwork、filesystemMode。模型知道何时设置run_in_background: true并将其与Monitor工具配对。Skill和ToolSearch— 懒加载原语。Agent— 用于子智能体调度的单一工具。接受description、prompt、可选的subagent_type、可选的model。后训练使模型为这些输出简短的必要描述。EnterPlanMode/ExitPlanMode— 都需要WorkspaceWrite权限。切换工作树的本地覆盖。EnterWorktree/ExitWorktree— 包装git worktree add以实现子智能体隔离。Monitor— 流式传输后台进程的stdout。与Bash run_in_background: true配对。模型知道这种模式;Codex没有。TodoWrite— 工作流脚手架工具。模型以特定模式写入{content, activeForm, status}三元组。
GitHub Copilot CLI 工具表面
Copilot CLI捆绑了不同的默认工具集,来自公开的变更日志:
grep、glob(捆绑的ripgrep)、view、view_range— 带显式范围参数的文件读取。web_fetch— 内置(v0.0.374)。拒绝file://URL。read_bash、write_bash、stop_bash— 三个动词的交互式shell控制。task— 带深度和并发限制的子智能体调度。read_agent、write_agent— 多轮子智能体控制。形状与Codex的六个动词智能体表面不同。ask_user— 交互式澄清。store_memory— 与远程后端相关的持久记忆。这里的记忆不是本地文件。apply_patch— 专门在为Codex模型服务时包含。一个与Codex自己的补丁工具链不同的补丁工具链。create_pull_request、sql、exit_plan_mode、list_copilot_spaces、show_file。

一个在Codex的八个动词子智能体表面上训练的模型知道如何向正在运行的子智能体发送消息。一个在Claude Code的 Agent 工具上训练的模型在其本能集合中没有那个动词。
框架可以用路由器来掩盖这一点,但路由器无法给予模型它没有的本能。
Cursor的框架团队直白地阐述了底层机制。根据他们4月30日的研究文章:"OpenAI的模型被训练成使用基于补丁的格式编辑文件,而Anthropic的模型则在字符串替换上训练。任何一个模型都可以使用任意一种工具,但给它不熟悉的工具会消耗额外的推理token并产生更多错误。因此,在作者们的框架中,作者们为每个模型提供其在训练期间使用的工具格式。"这是作者从任何供应商那里看到的关于模型-框架适配最清晰的描述,这不是关于模型偏好的含糊其辞,而是一个具体的、可测量的推理token成本,伴随着可观察到的错误率增加,在生产环境中数百万个智能体回合的规模上记录。
这是模型-框架适配最明显体现的地方。工具表面是模型与世界的词汇表。在不同的词汇表上交叉训练,你就会在每一次交互中失去精确性。
技能承载工具规范
技能表面上看起来是可互换的。所有三个框架都使用带有YAML前置元数据(名称、描述、可选元数据)的 SKILL.md 文件。Codex甚至内置了交叉兼容性:core-skills 解析Claude风格的markdown技能。Copilot CLI显式地读取 .claude/ 配置。格式如此相似,以至于同一个 SKILL.md 的主体可以在三个框架中被解析。
但技能不仅仅是markdown。一个技能携带了一个关于它期望调用哪些工具的隐式约定。这个约定不在前置元数据中。它嵌入在主体中,以命令式指令的形式存在,这些指令按名称、特定的参数形状以及模型必须发出的特定动词来命名特定工具。
看看每个框架作为系统技能发布了什么。
Codex的引导技能,通过 include_dir! 内置,并在首次启动时提取到 $CODEX_HOME/skills/.system,共有五个:imagegen、openai-docs、plugin-creator、skill-creator、skill-installer。skill-installer 的主体调用 list-skills.py 和 install-skill-from-github.py 作为脚本(codex-rs/skills/src/assets/samples/skill-installer/SKILL.md)。它假设模型可以调用bash来运行Python脚本。它假设模型知道技能文件夹中 scripts/ 里的脚本是可调用的。它假设私有仓库的稀疏检出回退。这些都不在前置元数据中。全部都在主体中。
Claude Code的技能不同。superpowers 插件提供了 superpowers:test-driven-development、superpowers:writing-plans、superpowers:verification-before-completion、superpowers:requesting-code-review、superpowers:dispatching-parallel-agents,还有更多。主体调用Claude的特定工具:Skill 来引导进入工作流,TodoWrite 来跟踪步骤,Agent 来调度并行子智能体,Read / Edit 来更改文件,Grep / Glob 来搜索。这些技能还编码了硬性流程规则:“在任何创造性工作之前使用此技能”、“在声称工作完成时使用”。这些规则锚定在框架的 <system-reminder> 注入模型上,而Codex没有相同形式的这个模型。
Copilot CLI的技能是插件市场生态系统的一部分,变更日志揭示了不同的姿态。v1.0.5 增加了"每轮基于嵌入的动态检索MCP和技能指令"作为实验性功能。模型被训练成消费由嵌入排序器选择的、作为每轮注入传递的技能指令,而不是作为描述匹配。一个假设"你将在系统提醒中看到所有技能"的技能主体,在框架通过嵌入对技能进行排序并且只注入前三个时,行为会有所不同。
相同的 SKILL.MD,不同的行为===================================一个技能主体说: "步骤1:调用 TodoWrite,包含三个子任务的列表。 步骤2:通过 Agent 使用 subagent_type='Explore' 调度每个子任务。 步骤3:等待结果,然后在声称完成之前用 Bash 进行验证。"在 Claude Code 中: TodoWrite 是内置的。Agent 是内置的。subagent_type='Explore' 有一个框架强制执行的特定允许工具集。Bash 返回 模型知道如何解析的截断输出。 ✅ 按设计工作。在 Codex 中: TodoWrite 不存在。最接近的是 update_plan_tool,但 模式不同。不存在那种确切形状的 Agent。 Codex 有 spawn_agent_v1 / v2。Bash 的等价物是 local_shell。 ❌ 技能静默失败或执行降级版本。在 Copilot CLI 中: TodoWrite 作为动词不存在。Agent 调度通过 task 或 read_agent / write_agent。Bash 的等价物是三个动词 read_bash / write_bash / stop_bash。此外,技能在本轮甚至可能无法 加载到提示中(嵌入排序器决定)。 ❌ 技能不可见或针对不存在的表面执行。
这就是为什么"作者们都使用 SKILL.md"具有误导性。格式相同,但底层的约定不同。技能隐式地携带工具规范,而这些隐式规范是固定在其编写者的框架上的。
同样的道理也适用于插件清单。Copilot CLI的v1.0.22明确添加:“使用 .claude-plugin/ 或 .plugin/ 清单目录的插件现在能正确加载其MCP和LSP服务器。” 这是GitHub将Claude Code的插件格式视为在文件级别进行互操作的底层平台。但这些插件中的技能仍然带有关于Claude Code工具表面的假设。加载文件并不会给模型正确的词汇表。
这个教训是普遍适用的。一个声称跨框架的技能市场是一个路由问题,而不仅仅是解析问题。每个技能需要要么显式声明其目标框架,要么为每个框架重写,要么在一个翻译工具调用方言的路由器内部运行。这些都不是免费的。
记忆层
作者在《智能体记忆工程》中详细介绍了记忆,所以本节作者只保留与框架适配相关的部分。
三种记忆架构,三种不同的赌注:
HERMES CLAUDE CODE CODEX========== ========== ==========同步实时写入, 同步实时写入, 延迟批量写入,会话开始时冻结快照, 每个记忆一个 .md 文件, 两阶段流水线,无衰减,字符容量限制 始终加载 MEMORY.md 由闲置6+小时触发, 索引,按需读取主体, gpt 5.4 mini 提取, 带天数老化的 gpt 5.4 合并, <system-reminder> 针对git基线GITHUB COPILOT CLI==========服务端记忆后端,store_memory 工具,每个仓库,远程检索,如果后端不可用,智能体会挂起(v1.0.23 专门修复了:"当记忆后端不可用时,智能体不再在首轮挂起")
架构选择已经不同。但框架适配的故事比这更尖锐。每个模型都被训练成使用具有特定模式的特定工具来写入记忆,并使用具有特定格式的特定标签来引用记忆。
Codex 的模型通过第一阶段提取写入一个结构化的原始记忆工件,使用严格的JSON模式:
description: 简洁但信息密集的描述task: <主要任务签名>task_group: <cwd_或_工作流桶>task_outcome: <success|partial|fail|uncertain>cwd: <单个最佳主工作目录>keywords: k1, k2, k3
第二阶段的合并提示有841行。additionalProperties: false。模式验证在解析时拒绝格式错误的输出。模型的引用包裹在 <oai-mem-citation> 块中。框架在 citations.rs:6-43 有一个解析器,每当引用到达时,它会增加SQLite状态数据库中的 usage_count。这就是模型的记忆仪式。
移除引用标签,框架就失去了其衰减信号。
Claude Code 的模型使用标准的 Write 和 Edit 工具写入记忆,每个记忆一个文件,放在 ~/.claude/projects/<encoded-cwd>/memory/ 下。没有单独的记忆工具。模型通过文件名前缀选择四种类型之一(user、feedback、project、reference)。主体使用 **Why:** / **How to apply:** 约定作为行为规则。框架将每次读取的主体包装在一个 <system-reminder> 块中,附带动态的天数老化和一个验证提醒。模型被训练成通过这个包装器来阅读记忆,相应地权衡其重要性,并跳过过时的声明。
Copilot CLI 的模型调用 store_memory 作为一个专用工具。记忆的主体发送到远程后端。跨会话记忆在v0.0.412中作为实验性功能添加。检索表面是服务端查询,而不是本地grep。模型期望后端存在。当后端不可用时(v1.0.23修复),智能体会在首轮挂起。这是一个承载依赖的环节。
现在混合搭配。在Claude Code的框架上运行Codex训练的模型。模型会寻找一个记忆写入工具,找到 Write,然后写入一个文件——但它会以Codex的结构化格式写入文件,带有 task_group: 头和 cwd: 注释,放入Claude Code在下一次会话不会自动加载的目录中。框架不知道要注入索引。下一次会话看不到这个记忆。
关键的是,模型会发出 <oai-mem-citation> 块,而Claude Code永远不会解析它们。记忆在下一轮实际上不存在。
在Codex的框架上运行Claude训练的模型。模型不会发出引用标签。Codex的 usage_count 衰减信号停止增加。被使用过的记忆无声地排在未使用的记忆之下,因为框架看到零引用。几周之内,错误的记忆会被驱逐。
在带有远程后端的Copilot CLI框架上运行上述任何一个模型。模型的本地文件本能不会迁移。store_memory 工具是唯一的路径,模式不同,跨会话检索是针对服务器的关键词搜索,而不是模型被训练所依赖的"始终加载的索引加上按需主体读取"模式。最初几轮看起来没问题,因为模型具有记忆塑造的本能。但保留情况会不同。
记忆层是模型-框架适配最密集的冲突面。工具、模式、引用标签、衰减信号、检索仪式——所有这些都耦合在一起,都是在后训练期间一起学习的,当你切换其中一侧时,它们都不能干净地转移。
引用规范
<oai-mem-citation> 标签是更大问题的一个缩影。
Codex的模型在每次引入记忆时,会在助手消息的末尾发出一个小型XML块:
<oai-mem-citation thread_id="xyz" raw_memory_id="abc">this entry: <description string></oai-mem-citation>
框架有一个解析器,在向用户显示助手消息之前剥离这个块,并使用解析出的 thread_id 来增加 stage1_outputs 表中的 usage_count 和 last_usage 列。解析器位于 citations.rs:6-43。SQL在迁移 0016_memory_usage.sql 中:
ALTER TABLE stage1_outputs ADD COLUMN usage_count INTEGER;ALTER TABLE stage1_outputs ADD COLUMN last_usage INTEGER;UPDATE stage1_outputsSET usage_count = COALESCE(usage_count, 0) + 1, last_usage = ?WHERE thread_id = ?
这是模型与框架的约定。引用你使用过的内容。框架将通过保持其活跃来奖励你引用的内容。第二阶段合并器按 usage_count 对记忆进行排序,并衰减任何在30天内没有引用且没有新鲜 source_updated_at 的内容。
Claude Code的模型没有等效的引用标签。框架不需要它,因为记忆是通过标准的 Read 工具读取的,而智能体的验证grep就兼作"作者使用了这个"的信号。每次读取主体前的提醒文本明确告诉模型:"记录会随时间过时。在推荐之前进行验证。"没有衰减循环,因为框架假设用户会修剪,或者验证会在原地失败。
Copilot CLI的模型与远程记忆后端通信。存储、检索和排序逻辑在服务端。模型不需要引用标签,因为后端自己跟踪读取。
现在看看在跨框架运行时会发生什么。
训练分布 vs 运行时Codex 模型在后训练期间 ↓ 运行时解析发出了 12,000 个示例回合 <oai-mem-citation>,其中包含 <oai-mem-citation> 增加 usage_count。块。 ✅ 记忆被正确排序和衰减。同一个模型在 Claude Code ↓ 运行时忽略标签,框架上发出 <oai-mem-citation> 将其留在向用户显示的在助手文本中。 助手文本中。 ❌ 用户看到原始 XML。 ❌ Claude Code 的记忆中 没有衰减信号。Claude 训练模型在 Codex ↓ 没有引用标签,框架上内联使用记忆, usage_count 从不增加。从不将其包装在标签中。 ❌ Codex 的衰减循环 驱逐好的记忆,因为 它们看起来未被使用。
一个六个字符的XML标签就成为了一个记忆系统是随使用而改进还是无声退化的分水岭。
这就是作者所说的"线路格式是模型的一部分"的含义。引用标签不是路线图上的一个功能。它是模型在后训练期间养成的一个习惯,而这个习惯只有在教导它的框架内部才能得到回报。
系统提示骨架
Copilot CLI SDK将其系统提示暴露为一个具有十个部分ID的结构化对象。主机可以覆盖每个部分、替换它或完全控制。来自github.com/github/copilot-sdk/nodejs/src/types.ts:636的开源TypeScript:
const SYSTEM_PROMPT_SECTIONS = { identity: "智能体身份前导和模式声明", tone: "回复风格、简洁性规则、输出格式", tool_efficiency: "工具使用模式、并行调用、批处理", environment_context: "CWD、操作系统、git根目录、目录列表、可用工具", code_change_rules: "编码规则、linting/测试、生态系统工具、风格", guidelines: "提示、行为最佳实践", safety: "环境限制、禁止操作、安全", tool_instructions: "每个工具的使用说明", custom_instructions: "仓库和组织自定义说明", last_instructions: "提示结束:并行工具调用、持久性"};
这不仅仅是文档,更是模型训练分布的公开约定。每个部分都有特定的作用,模型被训练成将每个部分作为特定类型的指令来阅读。安全部分比指南部分更严格。tool_instructions 部分在模型进行工具调用时被查阅。last_instructions 部分是模型在发出一个回合之前阅读的内容。
Codex有自己的等价物,不那么明确。开发者提示按以下顺序组装:
CODEX 开发者提示======================- 权限说明- 基础开发者说明- memory_summary.md(5K token,始终存在)- 协作模式- 实时更新- 个性- 应用
记忆出现在策略和身份之后,行为覆盖之前。模型被训练成按此确切顺序阅读。
Claude Code的静态前缀:
CLAUDE CODE 静态前缀==========================<基础智能体系统提示><环境块:cwd、平台、操作系统># claudeMd ← 项目 CLAUDE.md 内容# auto memory ← MEMORY.md 索引,限制200行 <描述 user/feedback/project/reference 类型的块> <何时保存指南> <在依据记忆行动前的验证规则> <完整 MEMORY.md 内容># userEmail# currentDate
不同的形状,不同的排序,以及关于模型应将其视为有约束力的一组不同的优先级声明。
Claude训练的模型知道 # auto memory 指令"覆盖任何默认行为,你必须完全按照书面形式遵守"。这个短语存在于框架内部而非模型本身,但模型被训练成识别这个标题并将其内容视为有约束力。针对此前缀训练的模型会寻找 # auto memory 并作出相应反应,而针对不同前缀训练的模型根本不会以同样的方式看待这个标题,只会给予它与其他任何上下文片段相同的权重。
这与引用标签是同一个教训,只是规模更大。系统提示不是通用的。它是一个结构化的工件,具有模型被教导以特定方式阅读的部分约定。切换框架,你保留了模型的阅读习惯,但失去了它们所应用的结构。
路由的现实:GitHub Copilot CLI 正在做什么
GitHub Copilot CLI是此次比较中最有趣的框架,因为它明确尝试跨模型家族进行路由。Sonnet是默认模型。选择器公开了Sonnet、Opus、Haiku和GPT 5.x家族。v1.0.32添加了自动模式,每会话选择。
Copilot CLI如何处理模型-框架适配问题?查看变更日志,其策略有三个支柱。
1. 按模型包含工具
apply_patch 工具仅在活动模型来自Codex家族时包含。v0.0.366:“Codex特定的补丁工具链。” 框架知道哪些模型是在 apply_patch 上训练的,并且只向这些模型暴露它。Anthropic模型得到它们训练时使用的 Edit 和 Write 形状。
这不是一个转换层。这是一个按模型区分的工具表面。路由器不假装 apply_patch 和 Edit 是相同的操作。它为正确的模型提供正确的工具。
2. 按模型的工具搜索
v1.0.13:“Claude模型的工具搜索。” 含义:Claude训练的模型期望通过 ToolSearch 实现延迟工具加载模式。框架只向这些模型暴露发现循环。
OpenAI训练的模型没有得到相同的循环。它们一开始就得到完整的工具列表,因为那是它们训练的方式。
3. 使用互补模型的批评者智能体
v1.0.18:“新的批评者智能体自动使用互补模型审查计划和复杂实现,以便及早发现错误(在Claude模型的实验模式下可用)。”
批评者是与主智能体不同的模型。计划由互补模型审查。这是内置于框架中的多模型编排,路由是显式的。
以下是您提供内容的简体中文翻译:**Copilot CLI 的多模型路由**==================================用户提示 ↓活动模型(Sonnet 4.6 或 GPT 5.4 或 Opus 4.7) ↓对于 Claude 模型: 对于 OpenAI 模型: 暴露 Edit、Write、 暴露 apply_patch、 带完整沙箱的 Bash local_shell、exec_command、 延迟加载的 ToolSearch 提前提供完整工具列表 启用 ↓ ↓ 评审代理(不同的 无评审代理 模型)审核计划 ↓ ↓发送助手消息 发送助手消息
这就是一个真实的路由器应该有的样子。不是"将所有内容翻译成一种通用方言",而是"为每个模型提供正确的方言"。这需要更多的代码、更多的状态、更多的遥测。这也是从每个模型获得最佳性能的唯一途径。
这种方法的代价是诚实。框架必须承认"Copilot CLI上的Claude"和"Copilot CLI上的GPT"是不同的产品。用户选择其中一个,得到不同的行为。没有中立的共同点。
这是对模型-框架适配的正确且诚实的答案,而Copilot CLI是唯一在开源或半开源集合中真正实现了这一点的框架。对于2026年任何严肃的智能体平台来说,多模型是关键赌注。
无论供应商是否承认,大多数客户都在运行多模型工作流,而让每个模型发挥最佳性能的唯一方法是在框架内部构建按模型的路由表面。
聊天中途切换模型:最清晰的失败模式
模型-框架适配最尖锐、最具体的实例来自于用户在对话中途切换模型时发生的情况。Cursor的研究团队在他们4月30日的文章中详细描述了这一点,失败面值得深入探讨,因为这里被打破的每一个假设都是一个单一的模型-框架对静默依赖的。
在模型切换的时刻,有三件事会出问题。
首先,对话历史本身现在处于分布之外。前一个模型以其原生词汇表产生了工具调用:apply_patch 块、<oai-mem-citation> 标签、六个或八个动词的子智能体调度。新模型是在不同的词汇表上训练的,现在必须推理一个充满它自己不会发出的工具调用的对话记录。Cursor通过注入一个自定义指令来处理这个问题,明确告诉模型"你正在中途从另一个模型接管对话"(作者觉得这非常聪明!),并引导它远离先前模型的工具。
这减轻了代价,但并未消除。模型仍然在阅读与其本能不匹配的记录。
其次,提示缓存损坏了(很痛苦!)。缓存是特定于提供商和模型的,这意味着切换必然导致缓存未命中。对于一个长会话来说,这将切换后的第一轮变成对每个字节的系统提示和对话历史的完整价格重新输入。Cursor的缓解措施是在切换时总结对话,生成一个更短的干净记录,重新缓存的成本更低,但代价是丢失了总结未保留的细节。
第三,工具本身改变了形状。新模型的框架加载其本机工具集。如果用户正沉浸在一组动词的子智能体调度流程中,下一轮就会出现一组不同的动词。模型必须弄清楚先前的工具是否仍然有效(它们无效),以及它自己的哪些工具映射到用户表面的意图。
Cursor在构建缓解措施后的建议是诚实的:“作者们通常建议在对话期间坚持使用一个模型,除非你有理由切换。”
他们描述的最干净的解决方法是生成一个具有不同模型的子智能体,而不是切换主对话。子智能体从一个全新的上下文窗口开始,没有记录偏差,没有需要破坏的缓存,并且从第一轮开始就具有新模型的原生工具表面。
这些失败模式中的每一个都直接映射回本文的中心论点。记录、缓存前缀和工具表面都是模型所训练的线路格式的一部分。改变模型,你就同时改变了所有三方面的约定。模型切换不仅仅是模型替换。它是框架替换、工具替换和缓存失效,所有这些同时发生。
实验室的说法
Cursor的Stefan Heule和Jediah Katz(@jediahkatz)将他们的框架工作描述为"痴迷地堆叠小优化",特别指出因为阶跃变化很少见,且收益只在匹配对内复合。他们的团队为每个提供商和每个模型版本构建自定义提示,将OpenAI的字面精确性与Claude对不精确指令的容忍度作为具体区分因素,这些因素反过来又影响到提示设计。
他们报告在一次专注的开发冲刺中,将意外的工具调用错误减少了一个数量级。
工具调用的可靠性不是模型属性。它是框架属性,并且随着智能体保持活跃的每一轮而复合。
Anthropic的@rgb_prithvi在他3月24日关于长期运行应用程序开发的文章中进行了一个相关实验。其架构:一个规划器、一个生成器和一个评估器智能体,以生成对抗网络为模型。
评估器使用Playwright MCP实际像用户一样点击浏览正在运行的应用程序,然后根据评分标准进行评分。Rajasekaran报告说,开箱即用,“Claude是一个糟糕的QA智能体”——它识别出合法问题,然后又说自己还是会批准这项工作。经过多轮调整评估器提示,才将其变成一个可靠的评判者。
框架创造了判断的表面;模型自身做不到。
Rajasekaran工作中更深层的教训是关于框架应如何随着模型改进而演变。他针对Claude Sonnet 4.5构建了一个框架,该模型表现出足够强烈的"上下文焦虑",以至于仅靠压缩是不够的。框架需要在会话之间进行完整的上下文重置,并带有结构化的交接工件来跨边界传递状态。
当Opus 4.6发布时,这种行为基本消失了。Rajasekaran移除了整个上下文重置机制,并连续运行了一个超过两小时的会话。框架中的每个组件都编码了一个关于模型自身无法做什么的假设。这些假设会过时。
匹配对不是静态的。它会随着模型的成熟而移动,框架必须淘汰不再承载重量的脚手架——这就是作者在"LLMs吃早餐吃掉了脚手架"中写到的教训。 LangChain的Vivek Trivedi拥有最清晰的框架:“智能体 = 模型 + 框架。如果你不是模型,你就是框架。” 在这种观点下,框架是除权重本身之外的每一段代码、配置和执行逻辑。系统提示、工具描述、捆绑的基础设施、编排逻辑、钩子、中间件。从期望的智能体行为逆向工作,每个框架原语通过修补特定的模型差距来赢得自己的位置。文件系统用于持久状态,bash用于任意操作,沙盒用于安全执行,记忆用于持续学习,规划和自作者验证用于长远视野。每个原语开始时都是对模型在训练时存在的特定缺陷的解决方法。其中一些原语会随着时间的推移被吸收回模型中。其他的则会复合。
Trivedi还命名了使模型-框架适配如此持久的机制:一个共同进化的反馈循环。“有用的原语被发现、添加到框架中,然后在训练下一代模型时被使用。随着这个循环的重复,模型在其被训练的框架内变得更加有能力。” 理解这一点非常重要。
这就是使匹配对代际之间变得牢固的流水线。一个新的框架原语在第一周发布。到第三个月,它出现在数百万个智能体轨迹中。到第六个月,这些轨迹成为下一个模型的训练数据。到第十二个月,下一个模型将该原语内化到其本能中,框架可以依赖它。这个循环使得"切换到一个陌生的框架"不仅是笨拙的,而且是复合性的笨拙。模型的本能是由其自身框架的前一代塑造的,而该框架本身又是由前一代塑造的。横向移动,你就跳过了这个复合循环的每一个周期。
Trivedi诚实地说明了这个循环的代价,作者想干净地指出反方论点。引用他的话:“一个真正智能的模型在补丁方法之间切换应该没有什么困难,但是在循环中使用框架进行训练造成了这种过拟合。” 如果模型的工具格式偏好是对其训练框架的过拟合,你可以辩称,正确的长期举措是针对更多样化的框架集进行训练,以便模型能够泛化。这个论点有其道理。将一个模型和一个框架作为一对交付的实验室,是以模型的便携性为代价来换取短期性能。这个交易是否正确取决于用户是否看重便携性,而目前用户主要看重的是排行榜。
三篇独立的文章在几周内相继发表,都趋同于同一个论点:模型只是系统的一半,框架是另一半,匹配对是适当的分析单元,而将匹配对作为单一产品交付的供应商目前正坐在排行榜的顶端。
身份文件约定
框架方面的约定已经收敛到每个关注点一个markdown文件,并且这些文件名现在在生态系统中承载着重要信息。在一个框架上训练的模型能识别这些文件名,并知道哪个文件带有哪种权威。
每个关注点一个MARKDOWN文件的约定(2026年4月)=====================================================CLAUDE.md Claude Code会话的静态项目指令。 Anthropic的专有格式。在会话开始时加载。 自2024年以来的事实标准。与Anthropic的 后训练紧密配对。AGENTS.md 流程规则的跨工具标准。"你做什么以及怎么做。" 被Codex CLI、OpenClaw、Cursor采用。 截至2026年4月,Claude Code原生不读取AGENTS.md (社区功能请求开放中)。GitHub Copilot CLI 的变更日志明确添加了AGENTS.md作为上下文源。SOUL.md 个性、声音、世界观。来自github.com/ aaronjmars/soul.md。被OpenClaw和Aeon框架使用。 "一个像你一样思考和说话的人工智能" vs "一个谈论你的聊天机器人"。选择加入的约定, 尚未融入主流框架。USER.md 用户是谁。Hermes将记忆分为 MEMORY.md(智能体学到的)和USER.md(用户是谁)。 这种拆分让模型将用户事实视为权威, 将项目事实视为不断演变的。MEMORY.md 自动记忆索引。Claude Code在每一轮中 在 `# auto memory` 下加载它,并将其视为覆盖 默认行为。Codex称其索引为 memory_summary.md, 带有5K token上限,并延迟加载主体。STYLE.md 声音和写作模式(SOUL.md生态系统)。SKILL.md 每个技能的文件夹,带有YAML前置元数据。跨框架 采用:Claude Code、Codex CLI、GitHub Copilot CLI 都读取此格式。主体约定仍然不同。IDENTITY.md 轻量级公开信息卡片,包含姓名、角色、元数据。 OpenClaw约定。
关键的观察是:文件名现在成为线路格式的一部分。一个被训练成在 MEMORY.md 标题下寻找 # auto memory 块的模型,会在每一轮中精确地寻找那个标题。一个针对 AGENTS.md 训练的模型会寻找 AGENTS.md 而错过 CLAUDE.md。一个针对 SOUL.md 训练的模型会从 SOUL.md 加载个性,并将相同的内容放在 STYLE.md 中时则会忽略它。
这就是为什么针对Anthropic仓库的 AGENTS.md 功能请求很重要。这不仅仅是文档迁移。这是一个要求模型的训练分布扩展其文件识别词汇表的请求。在Anthropic对Claude进行后训练以读取 AGENTS.md 之前,即使该文件与 CLAUDE.md 并排放在仓库中,它对Claude Code也是不可见的。
SOUL.md 生态系统是对这个论点的压力测试。SOUL.md 尚未被任何主流框架的默认加载器识别。因此,SOUL.md 仓库的安装说明很有启发性:将你的 soul/ 目录复制到项目中,然后在 CLAUDE.md 中添加几行,将模型指向它。这是一个从未被识别约定到被识别约定的人工桥梁。SOUL.md 的作者明白,除非模型知道在哪里找,否则这些字节不起作用,而"在哪里找"是后训练中固定的习惯。
同样的问题在开源中也显现出来。GitHub Copilot CLI v1.0.4 添加:“读取 .claude/settings.json 和 .claude/settings.local.json 作为额外的仓库配置源。” v1.0.36 部分撤回:“来自 ~/.claude/ 的自定义智能体、技能和命令不再被 Copilot CLI 加载。” 这是一个试图对文件名宽容的路由器,然后在用户界面变得混乱时收窄。教训隐藏在变更日志之下:即使是运行Claude模型的框架,也不能在不与用户协商哪些约定有效的情况下,将 .claude/ 文件视为权威。
选择一个约定。发布匹配的后训练。或者发布一个明确将每个文件映射到识别它的模型的路由器。那种"宽容一点,加载任何看起来合理的东西"的中间道路每次都会失败。
这意味着什么
框架不再仅仅是模型的包装器。框架是模型有效参数的一部分。后训练过程将框架的工具表面、模式形状、记忆仪式、引用约定和系统提示结构嵌入到模型的本能集合中。你可以将权重带到不同的框架,但你不能带走本能。只有当框架以与后训练呈现世界相同的方式呈现世界时,这些本能才会被激发。
这有三个值得命名的后果。
对于智能体平台构建者:选择一个框架,选择一个模型,将它们作为一对发布。不要假装模型是可移植的。不要假装框架是中立的。前沿实验室正在发布模型-框架对,无论他们是否明说,而每对的性能才是唯一重要的数字。Copilot CLI的"不同模型使用不同工具"的方法是诚实的版本。不诚实的版本发布一个共同点,并在其服务的每个模型上都表现不佳。
对于模型实验室:框架是产品战略,不是基础设施。框架是实验室后训练投资复合的地方。Anthropic的 <system-reminder> 注入模型、类型化记忆分类法、每次读取主体时的验证,都不是基础设施选择。它们是模型被塑造所依赖的表面,也是使模型变得不那么可互换的护城河。Codex的两阶段记忆流水线、引用标签、严格的JSON模式也是如此。Copilot CLI的十部分系统提示骨架也是如此。框架是模型变得不可替代的地方。
对于用户:切换的成本比看起来要高,但比供应商希望你认为的要低。更高是因为模型和框架经过数月的训练融合在一起,你无法干净地将它们分开。更低是因为底层的简单技术栈是共享的,顶层的约定是可文档化的。一个诚实的移植——复制工具表面、复制引用约定、复制系统提示结构、复制记忆仪式——将缩小大部分差距。只是它的成本与最初建立后训练一样高。
匹配对不是静态的。它会随着模型的成熟而改变。这是Rajasekaran的Anthropic文章中最有用的细微差别。一个对Sonnet 4.5来说承载重量的框架组件(上下文重置、冲刺分解、积极压缩)在Opus 4.6上变成了死重,因为模型开始本地完成这些工作。三月份适合一个模型的框架,十月份不一定适合该模型的继任者。规范是阅读轨迹,识别哪些组件仍然赢得自己的位置,并淘汰那些现在只是解决已解决问题补丁的组件。Cursor的博客用不同的话说了同样的事情:“框架中的每个组件都编码了关于模型自身无法做什么的假设,而这些假设会过时。”
所以,回到作者开始时的问题。为什么同样的提示词,在运行相同模型的三个框架上,会产生明显不同的输出?
因为运行在三个框架上的模型实际上是三个不同的模型,即使磁盘上的权重字节对字节相同。运行时激发的本能不仅存储在权重中,它们还受到权重所训练框架的制约,而这些本能结果是在任何给定回合中,助手输出中表现出的主要内容。
现在有趣的设计举措不是更好的模型。也不是更好的框架。而是匹配对,端到端设计,后训练和运行时在一轮又一轮中相互强化,直到模型在这个特定框架所奖励的事情上变得明显地更好。
你可以看到主要的构建者从三个不同的起点汇聚到这个想法上。Anthropic发布了Claude Code作为Claude的规范框架,后训练和运行时作为单一产品共同设计。OpenAI发布了Codex CLI作为Codex的规范框架,在OpenAI这边具有相同的垂直整合。
2026年的前沿工作不是关于新的模型架构。而是关于新的框架原语。Ralph循环,其中钩子拦截模型的退出尝试,并在一个干净的上下文窗口中重新注入原始提示,迫使智能体继续朝着目标努力。即时框架组装,其中工具表面和系统提示按任务组成,而不是按会话预配置。自作者追踪智能体,它们读取自己的日志以发现框架级别的故障模式,并在无人干预的情况下修补它们。其中每一个都是一个原语,最终会有一些模型针对它进行后训练,而这种配对将出现在下一个排行榜的顶部。
再次强调,如果你想保持在最前沿,当新模型发布时,你必须删除大部分代码。大语言模型以脚手架为早餐。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)