文章类型技术长文 所属专栏Agent 网络通信 预计阅读39 分钟 文档状态已发布
返回

Agent 网络通信全景——协议、状态与主流架构差异

从用户接入、模型推理、MCP、沙箱出网、控制面到结果投递,建立理解 Claude Code、Codex、Gemini CLI、Cline、OpenCode 与 Hermes 网络架构的统一语言。

开始阅读全文7844 字 · 39 分钟 查看系列目录Agent 网络通信
关键词 Agent网络通信MCPClaude CodeCodex
栏目 AgentNetworking;专栏 Agent 网络通信;标签 Agent、网络通信、MCP、Claude Code、Codex

资料边界:本文仅依据截至 2026 年 8 月 5 日可公开核验的官方文档、协议规范和官方开源仓库撰写。文中的 Connection—Session—Turn—Tool Call 四层模型是为比较不同 Agent 而提出的工程抽象,不是任何厂商声明的统一行业标准。

核心结论#

Agent 的网络层不是“客户端调用一次模型 API”,而是由六条相互独立、又被同一个 Agent Loop 串联起来的通信链路组成:

  1. 用户接入链路;
  2. 模型推理链路;
  3. MCP 与工具链路;
  4. Shell、沙箱和子进程出网链路;
  5. 控制面与认证链路;
  6. 最终结果投递链路。

不同主流 Agent 在 TCP、TLS、HTTP 这些基础层面没有本质差异,真正拉开架构差距的是更上层的四个问题:

  • 一次模型流被如何表达和消费;
  • 连接、会话和任务状态分别保存在哪里;
  • 工具调用的副作用如何被关联、确认和恢复;
  • 流中断之后,是重连、续接、完整重放,还是切换传输方式。

Agent 的六条网络链路


1. Agent 网络层究竟包括什么#

1.1 用户接入链路#

用户接入链路负责把人的操作转换为 Agent 可处理的输入事件。它可能是:

  • CLI 中的一行命令;
  • IDE 面板中的自然语言请求;
  • 浏览器中的任务表单;
  • Telegram、微信、Slack 等消息平台中的消息;
  • CI、Webhook 或定时任务触发的自动任务。

这条链路传输的不只是文本。一个完整输入通常还包含:

  • 当前项目或工作区标识;
  • 已选择的文件、代码片段或图片;
  • 用户身份与权限;
  • 会话 ID;
  • 本轮任务 ID;
  • 中断、批准、拒绝等控制事件。

Claude Code 官方将其能力暴露在终端、IDE、桌面端和浏览器等多个 surface 上,并说明这些 surface 连接同一个底层 Claude Code engine;这说明“用户界面”与“Agent 执行引擎”在架构上可以分离。[1] Cline 也同时提供 IDE 扩展、CLI 与 SDK 形态,并把文件编辑和终端命令的批准作为用户控制的一部分。[15]

关键点:用户接入链路中断,不一定意味着 Agent 后端任务也停止。浏览器刷新、IDE 重载或手机断网,都可能只切断界面与 Agent 的连接,而后端任务仍在执行。因此,生产系统必须明确:

  • UI 断开是否触发任务取消;
  • 用户重新连接后从哪里恢复事件;
  • 重连后是否会重复显示已经消费过的输出。

1.2 模型推理链路#

模型推理链路负责在 Agent Runtime 与模型服务之间传输:

  • system instructions;
  • 当前对话历史;
  • 工具定义;
  • 用户输入与附件;
  • tool result;
  • 流式文本、reasoning、tool call 和完成事件。

它通常不是“一问一答”的单次 RPC。复杂任务会反复经历:

模型请求 → 工具调用 → 工具执行 → 结果回填 → 下一次模型请求

Anthropic Messages API 使用 SSE 增量返回文本、tool use 与 extended thinking 事件;工具输入以局部 JSON 字符串逐步到达,需要累积到内容块结束后再解析为完整对象。[3][4] OpenAI Codex 官方源码则同时实现 Responses WebSocket 与 HTTP/SSE 路径,并显式管理 WebSocket 连接复用、turn state 和传输降级。[9][10][11][12]

模型链路承担的是决策流,而不是最终业务副作用。模型说“创建 Pull Request”仍只是一个结构化意图,真正创建 PR 的动作发生在工具链路。

1.3 MCP 与工具链路#

工具链路把模型产生的结构化调用映射到外部能力,例如:

  • 读取 GitHub Issue;
  • 查询数据库;
  • 搜索内部文档;
  • 操作 Jira;
  • 调用浏览器;
  • 创建 Pull Request。

MCP 规范使用 JSON-RPC 编码消息,并定义两种标准传输:

  • stdio:客户端启动 MCP Server 子进程,通过 stdin/stdout 交换 JSON-RPC;
  • Streamable HTTP:客户端通过 HTTP POST 发送消息,服务端可用 JSON 或 SSE 返回事件。[7]

这条链路与模型链路应当分开观测。否则当 Agent 卡住时,很难判断是:

  • 模型没有生成 tool call;
  • tool call 参数尚未完成;
  • MCP Client 没有发送请求;
  • MCP Server 已收到但未返回;
  • 工具已完成,结果却没有回填模型。

1.4 Shell、沙箱和子进程出网链路#

代码 Agent 经常通过 Shell 启动:

  • 测试进程;
  • 编译器;
  • 包管理器;
  • Git 客户端;
  • 浏览器驱动;
  • 自定义脚本。

这些子进程形成独立的出网路径。主 Agent 能访问模型 API,不代表 npmpipgit 或测试程序也能访问网络。常见约束包括:

  • 子进程是否继承 HTTP_PROXYHTTPS_PROXYNO_PROXY
  • 沙箱是否允许目标域名和端口;
  • 企业 CA 是否进入子进程信任库;
  • 是否允许访问 localhost、Unix Socket 或内网地址;
  • 工作区外文件系统是否可见。

Claude Code 官方沙箱文档说明,其 Bash 沙箱同时约束文件系统与网络,网络请求通过沙箱外的代理执行,并可按域名控制;沙箱限制还会传播到 Bash 启动的子进程。[6]

这里最容易出现一种误判:模型调用成功,所以团队认为“网络正常”;但真正失败的是测试进程下载依赖或 Git 子进程连接远程仓库。

1.5 控制面与认证链路#

控制面决定一个请求能否发出、发到哪里、以谁的身份发出,以及可以花多少资源。典型内容包括:

  • API Key、OAuth、登录令牌和临时凭证;
  • provider 与模型路由;
  • 组织、项目和租户标识;
  • 代理、CA 与 mTLS;
  • 权限模式与工具审批;
  • 配额、限流和预算;
  • trace、日志与审计策略。

控制面虽然不直接生成回答,却会改变整个数据面。例如同一条模型请求可能被路由到不同 provider;同一个 MCP Server 可能因 OAuth scope 不足而只能列出资源、不能执行写操作;同一个 Shell 命令可能因工作区信任状态不同而被允许、拒绝或要求人工批准。

1.6 最终结果投递链路#

最终结果投递是从 Agent Runtime 到用户界面的最后一跳:

  • CLI:写入 stdout、stderr 或终端 UI;
  • IDE:更新 Chat、diff、诊断信息与批准面板;
  • Web:通过 SSE、WebSocket 或轮询更新页面;
  • 移动端:调用消息平台 API,发送或编辑消息。

Hermes 将这一层独立成 Messaging Gateway:平台适配器把消息路由到 per-chat session store,再交给 AIAgent 处理;最终回答通过平台适配器投递。[18] Hermes 还使用持久化 delivery ledger 记录回复,若进程在生成结果和平台确认之间崩溃,重启后重投保存的回答,而不是重新运行整个 Agent turn。[18]

这说明“任务完成”和“用户收到结果”是两个不同状态。若不分开记录,系统会把投递失败错误地当成任务失败,从而重复执行已有副作用。


2. 用一个完整任务串起全部网络阶段#

统一案例:

用户要求 Agent 读取 GitHub Issue、分析代码、修改文件、执行测试、创建 Pull Request,并返回结果。

从 Issue 到 Pull Request 的端到端时序

2.1 用户请求进入 Agent#

接入层将用户输入归一化为一条任务事件。生产系统至少应在此生成或绑定:

  • session_id:长期会话;
  • turn_id:本次用户任务;
  • user_id / tenant_id:身份和配额;
  • workspace_id:目标代码库;
  • cancel_token:取消传播;
  • trace_id:跨链路追踪。

如果来自 IDE,还会附带当前文件、选区和工作区信息;如果来自移动端,则要保留 chat、thread 和 message ID。

2.2 Agent 请求模型#

Agent Runtime 组装请求:

系统约束
+ 项目上下文
+ 对话历史
+ 当前用户任务
+ 工具定义
+ 权限边界

然后选择 provider、模型与传输方式,建立或复用连接。此阶段常见失败包括 DNS、代理、TLS、认证、429、5xx 和建连超时。

2.3 模型流式生成 Tool Call#

模型可能先输出分析文本,随后生成:

{
"name": "get_issue",
"input": {
"owner": "example",
"repo": "payment-service",
"issue_number": 314
}
}

在真实流里,这个 JSON 可能分成多段到达。以 Claude SSE 为例,tool_useinput_json_delta 是局部 JSON 字符串,客户端应累计到 content_block_stop 再得到稳定对象。[4]

因此,Agent 不能因为看到 "name": "get_issue" 就立刻执行;它必须等到该工具块达到协议定义的完整边界。

2.4 Agent 调用本地工具或 MCP#

执行器根据工具注册信息选择路径:

  • GitHub API 封装工具;
  • 远程 MCP Server;
  • 本地 stdio MCP;
  • Shell 中的 gh CLI;
  • 内置文件与搜索工具。

对于读取 Issue 这种只读操作,失败后通常可安全重试。对于创建 PR 这种写操作,必须记录 tool call ID、请求参数和外部资源 ID,防止超时后重复创建。

2.5 Tool Result 回填模型#

工具执行完成后,结果必须与原始 tool call 精确关联:

{
"tool_call_id": "call_7f2...",
"status": "success",
"content": {
"issue_title": "Payment request times out after 30s",
"issue_body": "..."
}
}

Tool Result 不是普通用户文本,而是 Agent Loop 的状态转换信号。它告诉模型:哪个调用完成、结果是什么、是否需要下一步。

如果工具已经成功,但结果在回填前丢失,系统不能简单重跑写工具;应先从执行日志或外部系统查询实际状态。

2.6 多轮请求直至任务结束#

一次完整任务可能是:

  1. 读取 Issue;
  2. 搜索代码;
  3. 读取相关文件;
  4. 生成修改方案;
  5. 编辑文件;
  6. 执行测试;
  7. 根据失败结果继续修改;
  8. 再次测试;
  9. 创建分支、提交和 Pull Request;
  10. 生成最终总结。

每一次模型请求只解决当前可见状态下的下一步决策。Agent Loop 的作用,就是把这些离散请求拼成一条任务轨迹。

2.7 最终结果返回 CLI、IDE 或移动端#

最终回答通常包括:

  • 修改了什么;
  • 测试结果;
  • PR URL;
  • 尚存风险;
  • 用户下一步需要做什么。

CLI 和 IDE 可以直接渲染;移动平台还要处理消息长度、Markdown 子集、消息编辑频率和平台限流。结果投递成功后,才应把 delivery_status 标记为完成。

2.8 阶段、状态与故障对照#

阶段主要数据必须关联的状态典型故障
用户进入prompt、附件、workspacesession、turn、userUI 断开、重复事件
模型请求instructions、history、toolsresponse、connectionTLS、认证、429、首事件超时
流式生成text/tool deltassequence、content block流中断、半截 JSON
工具执行tool name、inputtool call、approvalMCP 断开、超时、权限拒绝
结果回填tool resulttool call → result执行成功但结果丢失
下一轮新上下文turn、previous response状态续接失败、完整重放
最终投递final answer、artifactsdelivery ID平台 429、确认丢失、重复投递

3. Agent 中实际使用的通信方式#

本节只讨论这些方式在 Agent 中承担什么职责,不展开通用网络协议原理。

Agent 通信方式与职责映射

3.1 普通 HTTPS 请求#

适合:

  • 获取模型列表或账户信息;
  • 创建、查询外部资源;
  • OAuth 回调;
  • MCP 的单次 POST;
  • 上传附件;
  • 非流式管理 API。

它的优点是部署成熟、代理兼容性好、故障边界清晰。缺点是无法天然表达持续事件,长推理任务若只用同步 HTTP,会增加等待和超时压力。

3.2 SSE 流式响应#

适合模型服务向客户端单向推送事件。Claude Messages API 在 stream: true 时使用 SSE,增量返回 text、tool use、thinking、ping、error 和完成事件。[3]

在 Agent 中,SSE 的职责是:

  • 降低首 token 等待;
  • 让 UI 实时显示进度;
  • 尽早发现 tool call;
  • 把推理输出转成连续事件。

但 SSE 连接成功不代表任务成功。错误可以出现在事件流内部;Anthropic 文档明确给出了流内 error 事件。[3]

3.3 WebSocket 长连接#

适合需要双向事件、连接复用或粘性会话的场景。Codex 官方源码使用 Responses WebSocket,并在每个 turn 创建 ModelClientSession,缓存懒加载的 WebSocket 连接;还可通过预热请求让正式请求复用连接和 previous_response_id。[9]

消息平台也大量使用 WebSocket:Slack Socket Mode 通过 WebSocket 接收 Events API 事件;Discord Gateway 使用持久 WebSocket 推送实时事件。[20][21]

在 Agent 中,WebSocket 更适合:

  • turn 内多次请求复用连接;
  • 双向控制与事件传递;
  • 保持服务端路由状态;
  • 降低重复握手成本。

代价是状态管理、代理兼容、心跳和重连逻辑更复杂。

3.4 MCP Streamable HTTP#

MCP Streamable HTTP 使用一个 MCP endpoint。客户端通过新的 HTTP POST 发送每条 JSON-RPC 消息,并声明同时接受 application/jsontext/event-stream;服务端可返回普通 JSON,也可返回 SSE 流。[7]

它在 Agent 中承担的是远程工具协议,而不是模型 token 流。优势包括:

  • 复用企业 HTTP 基础设施;
  • 易于认证、审计和网关治理;
  • 可用 SSE 承载异步消息;
  • 可按协议维护 MCP session。

规范还要求远程实现关注 Origin 校验、localhost 绑定与认证,避免 DNS rebinding 等风险。[7]

3.5 本地 stdio#

stdio 适合本地 MCP Server 和工具桥接。MCP 规范中,客户端启动 server 子进程,server 从 stdin 读取 JSON-RPC,从 stdout 返回消息;stderr 可用于日志。[7]

它的职责是:

  • 无需开放端口即可扩展本地工具;
  • 利用 OS 进程边界隔离工具;
  • 降低本地调用延迟。

它的故障更多表现为进程问题,而非网络问题:子进程退出、stdout 被日志污染、管道阻塞、父进程取消未传播等。

3.6 Webhook、长轮询和平台 Socket#

三者主要服务于用户接入和结果投递:

  • Webhook:平台主动调用 Agent Gateway;
  • 长轮询:Gateway 持续请求平台获取新事件;
  • 平台 Socket:通过持久连接接收事件。

Telegram Bot API 将 getUpdates 长轮询和 webhook 作为两种互斥的更新方式。[19] Slack Socket Mode 和 Discord Gateway 则使用持久 WebSocket 接收实时事件。[20][21]

3.7 选型不是“谁更先进”#

需求更合适的方式原因
模型单向 token 流SSEHTTP 兼容好,事件模型直接
turn 内双向复用WebSocket可保持连接与路由状态
远程 MCPStreamable HTTP协议标准化、易治理
本地 MCPstdio无端口、低延迟、进程隔离
外部平台主动触发Webhook平台推送,延迟低
无公开回调地址长轮询 / Socket客户端主动建立出站连接
创建 PR 等一次性动作HTTPS请求—响应和错误语义清晰

4. Agent 网络状态的四层划分#

为了避免把所有故障都笼统称为“连接断了”,本文将 Agent 状态划分为四层。

Connection、Session、Turn、Tool Call 四层状态

4.1 Connection:底层连接#

Connection 是最短生命周期状态,可能是:

  • 一次 HTTPS 连接;
  • 一条 SSE 流;
  • 一条 WebSocket;
  • 一组 stdio 管道。

它关注:

  • 是否建连;
  • 是否通过 TLS/认证;
  • 是否仍有事件;
  • 是否正常关闭。

Connection 丢失不应自动清空 Session 或 Turn。

4.2 Session:一次 Agent 会话#

Session 跨越多个 turn,通常保存:

  • 对话历史;
  • 项目目录;
  • provider 与模型选择;
  • 用户身份和权限模式;
  • MCP 配置;
  • 长期恢复信息。

Claude Code 官方把 CLI session 定义为与项目目录绑定、持续保存在本地的对话;恢复时可还原包括工具调用和结果在内的完整历史。[2]

Codex 官方源码则把 ModelClient 设计为 session 生命周期对象,保存 provider、认证、conversation ID 与 transport fallback state。[9]

可见“session”是跨产品共有的概念,但其存储内容和位置并不相同。

4.3 Turn:一次用户任务轮次#

Turn 从一条用户输入开始,到 Agent 对这一输入给出最终结果为止。一个 turn 内可以包含:

  • 多个模型 response;
  • 多个 tool call;
  • 多次测试和修改;
  • 多次连接重建。

Codex 在每个 turn 创建 ModelClientSession,缓存该 turn 的 Responses WebSocket,并保存 x-codex-turn-state 等 turn 级状态。[9]

把 turn 独立出来非常重要,因为“重试当前模型请求”和“重跑整个用户任务”不是同一件事。

4.4 Tool Call:一次工具副作用操作#

Tool Call 是最细、也最敏感的一层。它至少需要:

  • tool_call_id
  • 工具名称;
  • 完整输入;
  • 审批结果;
  • 执行状态;
  • 输出或外部资源 ID;
  • 是否已经回填模型。

读取文件可安全重试,创建 PR 未必可以。网络恢复必须以 Tool Call 的副作用语义为边界,而不能只以连接状态为边界。

4.5 四层之间的关系#

Session
└── Turn A
├── Connection 1:模型 SSE / WS
├── Tool Call 1:读取 Issue
├── Tool Call 2:运行测试
├── Connection 2:下一轮模型请求
└── Tool Call 3:创建 PR
└── Turn B
└── ...

一次 turn 可以换连接,一次 session 可以包含多个 turn,而一个 tool call 即使在连接断开后,也可能已经产生外部副作用。


5. 流式事件如何进入 Agent Loop#

5.1 文本增量事件#

文本增量用于实时渲染,但它是未提交状态。在 response.completed 或协议对应完成事件到达之前,客户端不能假定输出完整。

Agent 通常会把原始 provider 事件转换为内部统一事件:

{
"turn_id": "turn_42",
"response_id": "resp_8a",
"sequence": 17,
"kind": "text_delta",
"payload": {"text": "正在检查超时配置"}
}

这样 UI、日志和恢复模块不必直接依赖每个 provider 的原始事件格式。

5.2 Thinking 或 Reasoning 事件#

Reasoning 事件可能用于:

  • UI 中显示“正在分析”;
  • 记录推理阶段的 token 使用;
  • 调试模型行为;
  • 驱动不同的展示策略。

不同 provider 对 reasoning 的可见性和事件格式不同,Agent 内部最好把它当成可选能力,而不是假设所有模型都提供同一种事件。

5.3 Tool Call 参数增量#

工具参数增量的主要风险是半结构化状态:

{"owner":"example","repo":"payment-

此时:

  • 不能执行;
  • 不能做最终 schema 校验;
  • 可以用于 UI 预览,但必须标记为 partial。

5.4 Tool Call 完成事件#

只有工具块完成后,执行器才能进行:

  1. JSON 解析;
  2. Schema 校验;
  3. 权限判断;
  4. 去重检查;
  5. 实际执行。

把“完成事件”和“参数增量”分开,是防止半截调用进入副作用系统的第一道防线。

5.5 Response Completed#

完成事件是当前模型 response 的提交边界。它通常用于:

  • 关闭当前流;
  • 固化 token usage;
  • 确认没有更多 content block;
  • 决定是否执行剩余 tool call;
  • 判断是否进入下一轮 Agent Loop。

Codex WebSocket 代码会持续读取直到 response.completed;若连接在此之前关闭,会被视为流错误。[11]

5.6 流式消费中的背压#

背压是:生产事件的速度超过消费速度。它可能发生在:

  • provider → 网络读取任务;
  • 网络读取任务 → 内部事件队列;
  • 事件队列 → UI;
  • tool call → 工具执行队列;
  • 最终文本 → 消息平台编辑队列。

推荐做法:

  • 使用有界队列,而不是无限缓存;
  • 文本 delta 可合并批量刷新 UI;
  • tool call 和 completed 等控制事件不能随意丢弃;
  • 让取消信号能中断读取与执行;
  • 对平台消息编辑做节流,而不是每个 token 都发一次 API。

异步迭代器或 channel 的价值在于,它们把事件生产和消费显式连接起来;消费端变慢时,系统可以自然形成流量反馈,而不是悄悄耗尽内存。


6. Agent 网络故障发生在哪里#

6.1 建连失败#

发生在任何有效业务事件之前,常见原因:

  • DNS 失败;
  • 代理不可达;
  • TLS/CA/mTLS 错误;
  • 认证失败;
  • WebSocket Upgrade 被网关阻止;
  • 本地 MCP 子进程无法启动。

恢复粒度通常是 Connection,不应重建整个 Session。

6.2 首事件超时#

连接已经建立,但在预期窗口内没有收到第一条有效事件。这与 connect timeout 不同:

  • connect timeout:通道没建起来;
  • first-event timeout:通道建起来了,但服务端没有开始返回任务事件。

首事件超时可能来自排队、模型冷启动、代理缓冲或服务端阻塞。

6.3 流中断#

流中断最难处理,因为客户端可能已经收到:

  • 部分文本;
  • 部分 reasoning;
  • 半截 tool call;
  • 已完成但尚未执行的 tool call;
  • 已执行、尚未回填的工具结果。

恢复前必须识别最后一个稳定事件边界。Codex 官方源码在可重试流错误后执行退避;当 WebSocket 重试达到上限且可以切换时,会发出从 WebSocket 降级到 HTTPS 的警告并重置重试计数。[10]

6.4 MCP 断开#

MCP 断开只影响工具能力,不一定影响模型连接。系统应区分:

  • 某一个 MCP Server 不可用;
  • 所有工具层不可用;
  • 当前正在执行的调用结果未知;
  • 仅能力列表过期。

对于 Streamable HTTP,协议定义了 session management 和基于 SSE event ID 的恢复能力;但实际是否可恢复,取决于 client/server 实现。[7]

6.5 工具执行完成但结果丢失#

这是副作用系统最危险的故障窗口。例如创建 PR 的请求超时:

  • PR 可能未创建;
  • PR 可能已创建,但响应丢失;
  • PR 可能创建成功,Tool Result 未写回模型。

正确恢复不是“再创建一次”,而是:

  1. 通过业务唯一键查询现状;
  2. 若已存在,补记外部资源 ID;
  3. 将结果回填当前 turn;
  4. 只有确认不存在时才重试写操作。

6.6 最终回复生成但投递失败#

此时模型和工具任务均可能已完成,只有用户未收到消息。恢复范围应限于 Delivery,而不是 Turn。

Hermes 的 delivery ledger 正是将最终回复持久化在平台发送前后,进程重启后只重投回答,不重跑整个任务。[18]

6.7 故障点与恢复范围#

故障点最小恢复范围不应默认执行的动作
建连失败Connection清空 Session
首事件超时Request / Connection重跑全部工具
文本流中断Response直接重跑整个 Turn
Tool Call 参数中断Content block执行半截参数
MCP 断开MCP connection / call重启所有模型连接
工具成功、结果丢失Tool Result无条件重做写操作
最终投递失败Delivery重跑模型与工具

7. 主流 Agent 网络架构横向比较#

主流 Agent 网络架构对比

7.1 Claude Code:本地 Agent Loop 加远程模型和 MCP#

官方可确认的关键特征:

  • Claude Code 可运行于终端、IDE、桌面和 Web;本地 CLI 可编辑文件、运行命令并创建 PR。[1]
  • CLI session 与项目目录绑定,并持续保存工具调用和结果等历史。[2]
  • Claude 模型流使用 SSE 增量事件。[3]
  • 可通过 MCP 接入远程 HTTP 或本地 stdio 工具。[5][7]
  • Bash 沙箱对文件系统和网络进行限制,子进程继承边界。[6]

因此可把其典型本地拓扑概括为:

CLI / IDE
Claude Code Engine
├── Claude API / Provider
├── MCP Client → Remote / stdio Server
└── Sandbox → Shell / Git / Tests

7.2 Codex:Responses API、WebSocket 与 HTTPS 双传输#

Codex 官方仓库将其定位为运行在终端中的本地 coding agent。[8] 其公开源码进一步明确:

  • ModelClient 是 session 级对象;
  • 每个 turn 创建 ModelClientSession
  • turn 内缓存 Responses WebSocket;
  • 支持 x-codex-turn-state 粘性路由;
  • 可用 generate=false 做 WebSocket prewarm;
  • 重试耗尽时可从 WebSocket 降级到 HTTPS。[9][10]

这是一种比“每轮单独发 HTTP 请求”更显式的传输状态模型。

7.3 Gemini CLI:本地 CLI 与模型 Provider#

Gemini CLI 官方仓库将其定义为把 Gemini 带入终端的开源 Agent。公开能力包括:

  • 查询和编辑大型代码库;
  • 执行自动化任务;
  • MCP 扩展;
  • checkpoint 保存和恢复复杂会话。[13]

其 MCP 文档支持 stdio、SSE 和 Streamable HTTP 等 server 类型。[14] 典型拓扑仍是“本地 CLI Runtime → 模型服务 / MCP / Shell”。

7.4 Cline 类 IDE Agent:Webview、Extension Host 与模型服务#

Cline 官方仓库将其描述为 IDE 扩展、CLI 或 SDK 形态的 coding agent,并支持多个模型 provider、MCP/插件以及对文件编辑和终端命令的人工批准。[15]

IDE Agent 与纯 CLI 的主要网络差异不是模型协议,而是多了一层宿主边界:

IDE UI / Webview
Extension Host / Agent Runtime
├── Model Provider
├── MCP / Plugins
└── Local Files / Terminal

UI 重载和 Extension Host 重启可能与后端请求生命周期不一致,因此要额外处理会话重连和事件恢复。

7.5 OpenCode 类 Provider-neutral Agent#

OpenCode 官方文档显示,其 TUI 是连接本地 HTTP Server 的客户端;server 提供 OpenAPI 3.1 接口和 SSE 事件流,因此可支持多个客户端和程序化接入。[17] Provider 文档则强调多 provider 接入。[16]

它体现的是“客户端—Agent Server—Provider”分层:

TUI / IDE / Web Client
↓ HTTP + SSE
OpenCode Server
├── Provider Adapter
├── Sessions / Tools / MCP
└── Project Runtime

这种结构比单进程 CLI 多一个可远程化的 Agent Server 边界。

7.6 Hermes:模型 Agent 外增加多端消息网关#

Hermes 官方 Messaging Gateway 是单一后台进程,可同时连接 Telegram、Discord、Slack、WeCom、Weixin 等平台;平台适配器把消息路由到 per-chat session store,再交给 AIAgent。[18]

其核心不在模型 provider 本身,而在:

  • 多平台事件归一化;
  • chat/thread 到 session 的映射;
  • 平台 typing 与流式消息编辑;
  • 平台限流;
  • durable delivery ledger。[18]

因此 Hermes 比普通 CLI Agent 多出一层长期在线的接入与投递网关。

7.7 横向比较表#

系统主要接入形态模型主链路工具链路核心状态位置公开架构亮点
Claude CodeCLI / IDE / Desktop / WebClaude SSE 或 provider 路径MCP、内置工具、ShellCLI session 本地持久化;不同 surface 有各自历史本地引擎、MCP、沙箱出网
Codex本地 CLIResponses WebSocket;HTTP/SSE 备用本地工具 / MCPsession 级 client、turn 级 client session预热、粘性 turn state、WS→HTTPS 降级
Gemini CLI本地 CLIGemini providerMCP、Shell、内置工具会话 checkpoint开源终端 Agent 与 MCP 扩展
ClineIDE / CLI / SDK多 providerMCP、插件、TerminalIDE/Agent 侧会话IDE 宿主、人类批准、多 provider
OpenCodeTUI / IDE / Web Clientprovider adapterTools、MCPAgent HTTP Server 的 sessionClient/Server、OpenAPI、SSE events
HermesTelegram/微信/Slack 等下游 Agent 的模型链路下游 Agent 工具per-chat session + delivery ledger多端网关、可靠投递

8. Claude Code 与 Codex 的核心差异结论#

8.1 主模型传输方式#

Claude Code:官方公开的 Claude Messages 流式接口是 SSE;Claude Code 还可通过不同 provider 路径访问模型。[1][3]

Codex:官方源码明确实现 Responses WebSocket 和 HTTP/SSE,并在运行时管理二者之间的回退。[9][10][12]

结论:两者都使用流式事件,但 Codex 当前公开源码对“WebSocket 主路径 + HTTPS 降级”的传输状态表达更显式。

8.2 连接复用粒度#

Claude Code:公开文档重点描述 session、工具和多 surface 行为,没有对内部模型连接复用粒度作出同等细节的稳定承诺,因此不应仅凭社区逆向材料写死实现。

CodexModelClientSession 按 turn 创建,并在 turn 内缓存 WebSocket;prewarm 让后续请求复用连接和 previous_response_id。[9]

结论:Codex 的 turn 内复用粒度可由官方源码直接确认;Claude Code 应只写官方可确认的 API 与 session 行为。

8.3 会话状态保存位置#

Claude Code:CLI session 与项目目录绑定并持续保存到本地 transcript,历史包含 tool calls 和 results;不同 surface 各自维护 session history。[2]

Codex:session 级 ModelClient 保存 provider、认证、conversation ID 与 transport fallback;turn 级 ModelClientSession 保存 WebSocket 与 sticky routing state。[9]

结论:Claude Code 的公开 session 模型偏“对话与项目状态持久化”;Codex 的源码还显式把传输回退和 turn 路由纳入状态对象。

8.4 流中断后的恢复路径#

Claude Code / Claude API:SSE 可在流内发送 error;客户端必须处理未知事件和未完成的内容块。[3][4]

Codex:可重试流错误采用退避;WebSocket 重试耗尽后可切换 HTTPS transport,并向上层发送警告。[10]

结论:两者都必须处理部分流,但 Codex 当前公开实现展示了更明确的跨传输降级状态机。

8.5 MCP 和工具连接方式#

Claude Code:官方文档明确支持远程 HTTP 和本地 stdio MCP,并把 MCP 作为连接外部工具与数据的核心扩展方式。[5]

Codex:同样具备本地工具和 MCP 能力,但其公开网络实现最突出的部分是 Responses 主通道的状态管理。

结论:Claude Code 的公开产品文档对 MCP、工具权限和沙箱网络面的说明更集中;Codex 的公开源码对模型传输层说明更深入。

8.6 企业代理与沙箱网络控制#

Claude Code:官方提供系统级沙箱、域名网络控制、自定义代理等文档,且子进程继承沙箱限制。[6]

Codex:公开代码同样构造统一 HTTP client/provider 路径并支持网络配置,但本篇比较中,其差异化重点仍是 WebSocket/HTTPS 双传输和 turn 状态。

8.7 总体判断#

如果只看 DNS、TCP、TLS、HTTP,请求都要经过相似的基础网络栈;如果看 Agent 应用层,两者差异已经足够大:

  • Claude Code 更像“本地开发 Agent 引擎 + Claude 流 + MCP + 沙箱工具面”;
  • Codex 更像“本地开发 Agent + 显式 Responses 会话传输状态机”。

因此,不能笼统地说二者网络层“完全一样”,也不应说它们从底层协议开始就完全不同。准确说法是:

基础传输栈高度相似;模型流、连接复用、turn 状态与故障恢复的应用层设计存在显著差异。


结语#

理解 Agent 网络通信,最有效的方法不是从协议名出发,而是从状态边界出发:

  • Connection 只负责链路;
  • Session 保存长期对话与配置;
  • Turn 表达一次用户任务;
  • Tool Call 承载真实副作用;
  • Delivery 表达用户是否最终收到结果。

当这几个边界被明确后,SSE、WebSocket、MCP、stdio、Webhook 和平台 Socket 就不再是一堆零散术语,而是分别承担明确职责的传输工具。后续深入 Claude Code、Codex、断线恢复和限流时,也不必重复解释基础概念,只需继续追问:哪个状态丢了,恢复应发生在哪一层,副作用是否可以安全重放。


参考资料#

以下资料均为官方文档、官方协议规范或官方开源仓库,检索日期为 2026 年 8 月 5 日。

  1. Claude Code Docs — Overview
  2. Claude Code Docs — Manage sessions
  3. Claude Platform Docs — Streaming messages
  4. Claude Platform Docs — Fine-grained tool streaming
  5. Claude Code Docs — Connect Claude Code to tools via MCP
  6. Claude Code Docs — Configure the sandboxed Bash tool
  7. Model Context Protocol Specification — Transports (2025-06-18)
  8. OpenAI Codex — Official Repository
  9. OpenAI Codex — codex-rs/core/src/client.rs
  10. OpenAI Codex — codex-rs/core/src/responses_retry.rs
  11. OpenAI Codex — Responses WebSocket implementation
  12. OpenAI Codex — Responses HTTP/SSE implementation
  13. Google Gemini CLI — Official Repository
  14. Google Gemini CLI — MCP Server Integration
  15. Cline — Official Repository
  16. OpenCode Docs — Providers
  17. OpenCode Docs — Server
  18. Hermes Agent — Messaging Gateway
  19. Telegram Bot API
  20. Slack Developer Docs — Socket Mode
  21. Discord Developer Docs — Gateway
Agent 网络通信全景——协议、状态与主流架构差异
https://jupiter-ws.cn/posts/agent-networking/01-agent-network-communication-overview/
作者
Jupiter
发布于
2026-08-05
许可协议
CC BY-NC-SA 4.0