热门搜索:和平精英 原神 街篮2 

您的位置:首页 > > 教程攻略 > ai教程 >Claude Code vs Codex CLI:AI 编程助手API调用机制的深度逆向对比

Claude Code vs Codex CLI:AI 编程助手API调用机制的深度逆向对比

来源:互联网 更新时间:2026-07-08 07:14

一次对 claude.exe (225MB) 和 codex.exe (308MB) 的二进制逆向分析,揭开了两种截然不同的 Agent 协议设计哲学。一个选择了无状态 HTTP,每次对话都像第一次见面;另一个则用 WebSocket 构建了有状态的会话记忆。这不仅仅是技术选型的差异,更是对“理想的编程助手应该是什么样子”这个根本问题的不同回答。

引言

AI 编程助手已经成了很多开发者的日常搭档。当你习惯地在终端里敲下“帮我修复这个 bug”,然后回车——背后到底发生了什么?每一次工具调用、每一条“让我先看看这个文件”,到底对应多少次 API 请求?每次请求都要把完整的系统提示词重新发送一遍吗?

这些问题听起来像是“实现细节”,但说实话,它们直接决定了推理速度、token 成本、上下文质量,以及为什么你在一个工具里能连续对话两小时,而在另一个里半小时就开始“失忆”。

这次我们就通过对

Claude Code

(Anthropic)和

Codex CLI

(OpenAI)两个二进制文件的逆向分析,来回答这些问题。不谈玄学,只看代码和协议。

一、物理形态:两个二进制文件

维度Claude CodeCodex CLI

文件

claude.execodex.exe

路径

npm/@anthropic-ai/claude-code/bin/npm/@openai/codex/.../bin/

大小

225 MB308 MB

类型

PE32+ Console x86-64PE32+ Console x86-64

节数

1210

语言

TypeScript → Bun 编译Rust → MSVC 编译

JS 引擎

Bun (Ja vaScriptCore)V8 (嵌入)

配置语言

JSON/TOMLStarlark (Bazel 方言)

API 后端

api.anthropic.comchatgpt.com/backend-api/codex

API 协议

Anthropic Messages API (HTTP)OpenAI Responses API (WebSocket)

两者的共同点是都把自己编译成了独立可执行文件——不是 Node.js wrapper,也不是 Python 脚本,而是包含了完整运行时环境的原生二进制。这意味着你不需要安装 Node、Python 或任何运行时依赖,下载即用。这一点倒是英雄所见略同。

但它们的共同点到此为止。在 API 调用机制上,两者做出了截然不同的选择。一个选择了简单可靠的传统 HTTP,另一个则走向了高效精巧的 WebSocket 有状态协议。

二、核心差异:有状态 vs 无状态

2.1 Claude Code:无状态 HTTP,每次全量发送

Claude Code 的每次 API 调用都是一个独立的 HTTP POST 请求:

POST https://api.anthropic.com/v1/messages
Authorization: x-api-key sk-ant-...
anthropic-version: 2023-06-01
Content-Type: application/json
​
{
  "model": "claude-fable-5",
  "system": "You are Claude... [~8000 tokens 的系统提示词]",
  "messages": [
    {"role": "user", "content": "帮我修复这个 bug"},
    {"role": "assistant", "content": [
      {"type": "tool_use", "name": "Grep", ...}
    ]},
    {"role": "user", "content": [
      {"type": "tool_result", ...}
    ]},
    // ... 完整历史 ...
  ],
  "tools": [/* ~50+ 工具定义,每个包含完整 JSON Schema */],
  "max_tokens": 32000,
  "thinking": {"type": "enabled", "budget_tokens": 16000}
}

关键特征

  • 每次请求都携带完整上下文

    :系统提示词、工具定义、完整对话历史——全部重新发送,一个不落。
  • 服务端无状态

    :每个请求之间没有关联,服务端不维护任何会话状态,干净利落。
  • Prompt Caching 补偿

    :Anthropic 的服务端缓存机制可以将重复的系统提示词成本降低约 90%,算是给这种“笨办法”加上了一层智慧补丁。

2.2 Codex CLI:有状态 WebSocket,TurnStart/TurnSteer 分离

通过对 codex.exe 二进制的逆向分析,我们发现它实现了一个精巧的

有状态协议

,核心是两个消息类型:

TurnStartParams(20 个字段)——创建会话

TurnStart 请求 = {
    clientUserMessageId: string,       // 客户端消息 ID
    input: UserInput,                  // 用户输入
    responsesapiClientMetadata: {...}, // 客户端元数据 (版本/OS/终端类型)
    additionalContext: [...],          // Skills, Memory, Git status...
    environments: {...},               // 环境变量
    runtimeWorkspaceRoots: [...],      // 工作区根目录
    approvalPolicy: string,            // on-request | never | always
    approvalsReviewer: string,         // 审核者设置
    sandboxPolicy: string,             // readonly | workspace-write | ...
    serviceTier: string,               // Free | Plus | Pro | Team | Enterprise
    effort: string,                    // low | medium | high | xhigh
    outputSchema: {...},               // 输出格式约束
    collaborationMode: string,         // primary | review | ...
    multiAgentMode: string,            // disabled | proactive | ultra
    
    // 系统提示词和工具定义也在此发送!
    system_prompt: "...",
    tools: [...]
}

TurnSteerParams(6 个字段)——增量追加

TurnSteer 请求 = {
    expectedTurnId: string,   //  服务端状态索引
    // 只发送工具调用的结果,不重复系统提示词和工具定义!
    tool_results: [...]
}

关键特征

  • TurnStart 全量,TurnSteer 增量

    :一个 turn 内只有第一次发送完整上下文,后面的请求只发送变化的部分。
  • expectedTurnId 作为状态索引

    :服务端通过它查找内存中的会话状态,有点像会话 cookie 的作用。
  • 服务端有状态

    :维护 system prompt + tools + conversation history + KV cache,把复杂度从客户端挪到了服务端。
  • 验证机制

    :如果 expectedTurnId 不匹配当前活跃 turn → 返回 400 "no active turn to steer",防止状态错乱。

三、协议对比:一次用户交互的全流程

假设用户输入“帮我修复 login 模块的空指针异常”,模型需要 5 步完成(搜索 → 读取 → 分析 → 编辑 → 总结)。来看看两种协议下,每个步骤到底消耗了多少 token。

Claude Code 的流程

用户消息 #1 (Turn 开始)

├─ API 请求 #1: POST /v1/messages
│ ├─ system: [8,000 tokens]
│ ├─ tools: [2,000 tokens]
│ ├─ user_msg: "帮我修复..."
│ └─ 总输入: ~11,000 tokens

├─ API 请求 #2: POST /v1/messages
│ ├─ system: [8,000 tokens] ← 再次发送
│ ├─ tools: [2,000 tokens] ← 再次发送
│ ├─ 完整历史 + tool_result
│ └─ 总输入: ~15,000 tokens

├─ API 请求 #3: POST /v1/messages
│ ├─ system: [8,000 tokens] ← 再次发送
│ ├─ tools: [2,000 tokens] ← 再次发送
│ ├─ 完整历史 + tool_result
│ └─ 总输入: ~18,000 tokens

├─ API 请求 #4: ... (继续累积)

└─ API 请求 #5: ...
└─ 总输入: ~25,000 tokens

累计 input tokens:
原始 ≈ 11K + 15K + 18K + 21K + 25K = 90,000 tokens
考虑 Prompt Caching (system+tools 缓存后降价 90%):
实际 ≈ 11K + 6K + 9K + 12K + 16K = 54,000 tokens

Codex CLI 的流程

用户消息 #1 (Turn 开始)

├─ TurnStart (WebSocket msg #1)
│ ├─ system_prompt: [3,000 tokens]
│ ├─ tools: [5,000 tokens]
│ ├─ context: [2,000 tokens]
│ └─ 总输入: ~10,000 tokens (截断限制)

├─ TurnSteer (WebSocket msg #2)
│ ├─ 只发增量: tool_result + next_prompt
│ ├─ 不重复 system_prompt
│ ├─ 不重复 tools
│ └─ 总增量: ~2,000 tokens

├─ TurnSteer (WebSocket msg #3)
│ └─ 增量: ~3,000 tokens

├─ TurnSteer (WebSocket msg #4)
│ └─ 增量: ~3,000 tokens

└─ TurnSteer (WebSocket msg #5)
└─ 增量: ~2,000 tokens

累计 input tokens: ~10K + 2K + 3K + 3K + 2K = 20,000 tokens

可视化对比

同一个任务(5 步完成),input tokens 消耗:

Claude Code (无缓存): ████████████████████████████████████████ 90,000
Claude Code (有缓存): ████████████████████████ 54,000
Codex CLI: ████████ 20,000
├────────────────────────────────────────┤
0 90,000 tokens

差距一目了然。不过要注意,这只是 input token 维度的对比。实际体验还受到输出速度、延迟、可用性等多方面因素影响。

四、技术细节:Codex 的 TurnSteer 是如何工作的?

4.1 协议定义(从二进制逆向提取)

codex.exe.rdata 段中,我们找到了嵌入的 TypeScript 类型定义文件。这相当于 OpenAI 把源码直接打包进了二进制:

// TurnSteerParams.ts (嵌入在 codex.exe 中的源文件)
/**
 * Required active turn id precondition.
 * The request fails when it does not match the currently active turn.
 */
expectedTurnId: string

以及错误处理逻辑:

"expectedTurnId must not be empty"
"no active turn to steer"

这些字符串告诉我们,服务端严格校验 turn 状态,不允许在无活动 turn 时发送 steer 请求。

4.2 服务端状态维护

OpenAI 的服务端维护一个

Turn Session Store

,结构大致如下:

TurnSession {
    turn_id: "turn_abc123",
    thread_id: "thread_xyz",
    // ⬇ 以下内容在 TurnSteer 时不再传输
    system_prompt: {                    // 完整的系统指令
        base_instructions: "...",
        personality: "friendly",
        skills: [...],
        memory_entries: [...]
    },
    tool_registry: {                    // 完整的工具注册表
        "fs/readFile": { schema: {...} },
        "fs/writeFile": { schema: {...} },
        "command/exec": { schema: {...} },
        // ... 50+ 工具
    },
    conversation: [                     // 累积的完整对话
        {role: "user", content: "..."},
        {role: "assistant", tool_calls: [...]},
        {role: "tool", content: "..."},
        // ...
    ],
    settings: {                         // Turn 级设置快照
        approval_policy: "on-request",
        sandbox_policy: "workspace-write",
        service_tier: "plus",
        effort: "medium"
    },
    model_state: {                      // GPT-5.5 推理状态
        kv_cache: [...],                // 已计算的 KV Cache
        position: 15432                 // 当前 token 位置
    }
}

4.3 为什么 TurnSteer 能这么快?

关键是

KV Cache 复用

。当 GPT-5.5 处理 TurnStart 时,它对 system prompt + tools + user message 进行了 prefill,计算结果保存在 KV cache 中。当 TurnSteer 到达时:

  1. 服务端通过 expectedTurnId 找到对应的 session
  2. 将 tool_result 追加到 conversation_history
  3. 直接从已有的 KV cache 继续解码

    ,不需要重新 prefill

这意味着 TurnSteer 的

Time-To-First-Token (TTFT)

接近零——模型不需要重新处理系统提示词和工具定义,直接产出下一个 token。这个差异在快速迭代的场景里非常明显:你刚让模型改完一行代码,它几乎立刻就给出了下一步建议。

对比 Claude Code,每次 HTTP POST 都要完整地 prefill system prompt + tools + history,即使有 Prompt Caching 降低了计费成本,

prefill 的延迟是无法跳过的

。所以理论上,在单次 tool round-trip 的响应速度上,Codex CLI 有结构性的优势。

五、设计哲学:两种世界观

5.1 为什么 Anthropic 选择无状态 HTTP?

Claude Code 的设计哲学:
"可靠性 > 效率"
"简单 > 精巧"

优点:
├─ 容错性极强: 任何一个请求失败,重试就是完整的,不需要恢复任何会话状态
├─ 服务端简单: 不需要维护 WebSocket 会话状态,水平扩展毫无压力
├─ 无状态扩展: 请求可以路由到任意服务器,负载均衡无缝
├─ 跨 turn 复用: Prompt Caching 可以横跨多个请求,甚至跨用户
├─ 调试友好: 每个请求都是可独立复现的,curl 就能验证
└─ 1M 上下文窗口: 有空间容纳重复发送的开销,不怕浪费

代价:
├─ 每次请求都要发送完整 payload(网络开销)
├─ 每次请求都要 prefill(延迟)
└─ 依赖服务端缓存来降低成本(不是所有场景都生效)

5.2 为什么 OpenAI 选择有状态 WebSocket?

Codex CLI 的设计哲学:
"效率 > 简单"
"精巧 > 通用"

优点:
├─ Token 成本极低: turn 内不重复发送上下文
├─ TTFT 极低: KV Cache 持续复用,几乎零延迟
├─ 实时性好: WebSocket 天然支持 streaming + 通知,双向通信灵活
├─ 分层设计: TurnStart/TurnSteer/TurnInterrupt 各司其职,职责清晰
└─ 协议级支持: turn 是一等概念,不是通过无状态模拟出来的

代价:
├─ 服务端复杂度高: 需要维护大量并发 Turn Session,有状态服务运维难度大
├─ 容错性差: 断连 = 整个 turn 丢失,需要额外的重连和恢复机制
├─ 不可跨 turn 复用: 每个用户消息都是新 TurnStart,之前的 KV cache 作废
├─ 硬截断风险: 10K tokens 的截断上限,长对话内容被直接丢弃
└─ 调试困难: 无法独立复现单个 TurnSteer,需要模拟整个会话序列

5.3 上下文管理策略对比

策略Claude CodeCodex CLI

窗口大小

最高 1M tokens272K tokens

截断方式

Auto-compact 自动摘要10K tokens 硬截断

长对话管理

渐进压缩 → 摘要激进截断 → 丢失

跨 turn 记忆

Memory 文件系统Memory 系统 (类似)

子 Agent

独立上下文窗口共享 session

这解释了为什么很多用户感觉 Claude Code 在长对话中更“持久”——不是因为它完全不丢上下文,而是因为 1M 的窗口太大,在达到极限之前 Auto-compact 已经帮你摘要了。而 Codex 的 10K 硬截断意味着,如果你的对话 + system prompt + tools 超过了这个阈值,早期内容会被直接丢弃。这可以看作是一种更激进的“遗忘”策略。

六、模型配置对比(从二进制中提取)

Claude Code 的模型列表(环境变量定义)

ANTHROPIC_DEFAULT_FABLE_MODEL     → claude-fable-5
ANTHROPIC_DEFAULT_OPUS_MODEL      → claude-opus-4-8
ANTHROPIC_DEFAULT_SONNET_MODEL    → claude-sonnet-4-6
ANTHROPIC_DEFAULT_HAIKU_MODEL     → claude-haiku-4-5
ANTHROPIC_SMALL_FAST_MODEL        → (备选快速模型)

Opus 4.8 配置

:1M context window, 支持 extended thinking

Fable 5 配置

:Mythos-class tier, 共享底层模型

Codex CLI 的模型列表(嵌入 JSON)

{
  "slug": "gpt-5.5",
  "display_name": "GPT-5.5",
  "description": "Frontier model for complex coding, research, and real-world work.",
  "context_window": 272000,
  "max_context_window": 272000,
  "auto_compact_token_limit": null,
  "truncation_policy": { "mode": "tokens", "limit": 10000 },
  "default_reasoning_level": "medium",
  "supports_parallel_tool_calls": true
}

GPT-5.4

:同样 272K 窗口,但 max_context_window: 1,000,000(预留扩展)

GPT-5.4-Mini

:小型快速模型

GPT-5.3-Codex

:编程优化模型(前代)

GPT-5.2

:长运行 Agent 优化

从模型配置能看出,OpenAI 也在为长上下文预留空间,但当前的截断策略仍然非常激进。而 Anthropic 则选择了更大的窗口和更聪明的摘要策略。

七、安全与认证对比

维度Claude CodeCodex CLI

认证方式

API Key / OAuth / AWS Bedrock / GCP Vertex / FoundryChatGPT OAuth / API Key / AWS Bedrock

沙箱策略

readonly / workspace-write / danger-full-access / linux-seccompreadonly / workspace-write / danger-full-access / windows-sandbox

审批机制

never / on-request / always + Reviewer Agentnever / on-request / always + Guardian Agent

遥测端点

api.anthropic.comab.chatgpt.com/otlp/v1/metrics + Sentry

联邦认证

OIDC Federation + WIFJWT Agent Identity

两者在安全模型上高度相似——都有沙箱分层、审批门控、代码审查 Agent,这已经成了这个品类的基本安全基线。差异主要在于实现细节:Claude Code 支持更多企业认证方式(Vertex AI、Foundry),Codex 的 Windows 沙箱集成更深,可能跟微软生态有关。

八、总结

问题Claude Code 的答案Codex CLI 的答案

每次 API 调用都发系统提示词吗?

是。但 Prompt Caching 将成本降到 10%不。TurnStart 发一次,TurnSteer 不发

一个用户消息调用多少次 API?

N 次(每个 tool round-trip 一次 HTTP POST)1 次 TurnStart + (N-1) 次 TurnSteer

谁能用更少的 token 完成同样任务?

~54,000(有缓存时)~20,000(无缓存也低)

谁的首字延迟更低?

每次都要 prefillTurnSteer 时 KV Cache 直接续,接近零延迟

谁的长对话体验更好?

1M 窗口 + auto-compact272K 窗口 + 10K 硬截断

谁的架构更简单?

无状态 HTTP,水平扩展友好有状态 WebSocket,运维复杂度高

谁更容易调试?

每个请求是独立的、可复现的依赖会话状态,复现需要模拟整个序列

后记

差异在于它们在同一个根本问题上做出了相反的选择:

上下文状态应该由客户端管理还是服务端管理?

Anthropic 的回答是:“客户端负责每次把完整上下文发给我,我用缓存帮你省钱。” OpenAI 的回答是:“你第一次发完整上下文,后面只发增量,我帮你在服务端记着。”

两种方案经过各自优化后的总成本和体验差距并没有看起来那么大——真正的差异在于生态位。Claude Code 靠 1M 窗口 + Prompt Caching 在“持久对话”这个场景里占优,Codex CLI 靠 KV Cache 复用在“快速迭代”的场景里更敏捷。

最终用户感受到的差异,往往不是协议层的选择导致的,而是

上下文管理策略

——你是愿意用大窗口容纳全量历史,还是用小窗口做激进截断。在这个意义上,协议设计反映的其实是产品理念:你要的是一个能陪你聊一下午的编程搭档,还是一个快速高效完成当前任务的工具。选择权在你手上,而现在,这两个工具都给了你足够清晰的信号。

热门手游

相关攻略

手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc