Skip to content

Latest commit

 

History

History
132 lines (88 loc) · 5.21 KB

File metadata and controls

132 lines (88 loc) · 5.21 KB

22. CLI Structured IO、Control Protocol 与 Transports

所属专题簇:运行协议与接入面

建议前读:10. Bridge、Remote 与 IDE 集成

建议后读:23. API Client、鉴权与 Provider 路由28. Direct Connect、Server 与 Upstream Proxy

研究问题

Claude Code 为什么不只是一套 REPL,而要实现 structured IO、control protocol 和多种 transport?

一句话结论

Claude Code 把 CLI 设计成了一个可被外部宿主接管的 agent runtime;REPL 只是其中一种前端,structured IO 和 transports 才是它对外暴露“可编排执行能力”的协议层。

这篇讲什么

这一章解释 Claude Code 如何在终端之外,通过标准输入输出、JSON-RPC 风格控制消息、SSE / WebSocket / Hybrid transport 和 remote IO 与外部宿主协作。

如果你不看源码,只看这一章,应该记住什么

  • Claude Code 不是只有本地 TUI,它还有一层正式的宿主控制协议。
  • tool permission、hook 输出、session state、control request 都会被编码进 structured IO。
  • transport 层不是附件,而是把 agent 能力接到远程宿主、SDK、worker 和 IDE 的关键基础设施。

Claude Code 在这里想解决什么

如果 Claude Code 只是一个终端聊天程序,那么把全部逻辑放在 REPL 就够了。但当前快照明显走得更远:它既要在本地终端工作,也要能把同一套 agent loop 暴露给外部宿主、远程连接和 SDK。

这就要求系统把“显示给人看的文本输出”与“给程序消费的控制语义”分开。structured IO 正是在做这件事:它让权限请求、hook 回调、tool 结果、session 状态变化都能被机器可靠识别,而不是只能靠解析自然语言。

机制直觉

可以把它理解成两层:

  • REPL 负责本地人机交互。
  • structured IO + transport 负责把同一个 agent 会话搬运到宿主程序和远程连接里。

这样 Claude Code 的核心执行逻辑不需要为每种界面重写一次。

源码依据

Mermaid 图:宿主控制协议图

flowchart TD
    A["Claude Code query loop"] --> B["structuredIO"]
    B --> C["StdoutMessage / control response"]
    D["宿主程序 / SDK"] --> E["StdinMessage / control request"]
    E --> B
    B --> F["permission prompt"]
    B --> G["hook output"]
    B --> H["session state change"]
    B --> I["tool lifecycle"]
Loading

structured IO 不是普通打印层

src/cli/structuredIO.ts 能直接确认这层会处理:

  • SDKMessage
  • SDKUserMessage
  • HookInput
  • PermissionUpdate
  • SessionExternalMetadata
  • RequiresActionDetails

这说明 structured IO 不是简单的 console.log 包装,而是在承接 agent 运行过程中的控制平面语义。

permission prompt 会被协议化转发

同一文件中还能看到:

  • SANDBOX_NETWORK_ACCESS_TOOL_NAME
  • permission decision / reason 序列化
  • permission update 的应用和持久化

这说明当 Claude Code 处在 SDK host 或 remote 控制环境中时,权限请求会被当作正式 control request 向外转发,而不是只能在本地 TUI 弹窗里确认。

transport 层负责“怎么连”

src/cli/transports/ 下能看到至少几种路径:

src/cli/transports/SSETransport.ts 里还能直接看到:

  • 断线重连预算
  • keepalive / liveness timeout
  • permanent HTTP rejection code
  • POST retry 配置

这说明 transport 的目标不是“把 HTTP 请求发出去”,而是维持一个长期在线、可恢复的控制链路。

这和普通 CLI 有什么不同

普通 CLI 通常只需要:

  • 解析参数
  • 打印文本
  • 退出进程

Claude Code 这层则额外承担:

  • 双向控制消息
  • 机器可读权限交互
  • hooks 与 session state 外发
  • 远程宿主接管

这已经更接近 agent runtime SDK,而不是传统命令行工具。

你真正应该记住的点

  • REPL 只是 Claude Code 的一个界面,不是它唯一的运行面。
  • structured IO 让 Claude Code 具备了被程序化接管的能力。
  • transport 层说明 Claude Code 从一开始就在为远程、宿主和多前端运行形态做准备。

延伸阅读