Appearance
应用服务器协议 — 练习
练习 1:分析协议消息格式
阅读协议定义,分析请求和响应消息的完整格式。
参考答案
App Server Protocol 使用 JSON-RPC 2.0 格式,ClientRequest 通过宏生成 60+ 个变体,每个变体包含:
请求格式:
json{ "jsonrpc": "2.0", "id": 1, "method": "submitOp", "params": { "thread_id": "...", "op": { "UserInput": { "content": "..." } } } }每个请求有唯一的
request_id(RequestId类型)和强类型的params。响应格式:
json{ "jsonrpc": "2.0", "id": 1, "result": { "success": true } }通知格式(服务器推送):
json{ "jsonrpc": "2.0", "method": "turnItemUpdated", "params": { "thread_id": "...", "item": { ... } } }序列化作用域:
ClientRequestSerializationScope控制请求的并发执行。例如Thread { thread_id }作用域确保同一线程的请求串行执行,而不同线程可以并发。认证:
AuthMode枚举定义四种认证方式,在连接建立时协商。AgentIdentity用于自动化场景,Chatgpt用于交互式登录。
协议定义在 app-server-protocol/src/protocol/common.rs 中,通过 Rust 宏自动生成序列化/反序列化代码。
练习 2:追踪 Backend Client 调用
追踪一次完整的 LLM 后端调用流程,从请求构建到响应处理。
参考答案
Backend Client 的完整调用流程(core/src/client.rs):
创建 ModelClientSession:
ModelClient::new_session()创建 turn-scoped 的会话- 检查缓存的 WebSocket 连接是否可用
传输选择:
- 优先 WebSocket:
prewarm_websocket()预热连接 - 若 WebSocket 不可用(
disable_websockets = true或连接失败),降级到 HTTP SSE force_http_fallback()方法强制使用 HTTP
- 优先 WebSocket:
请求构建:
ModelClientSession::stream()构建请求- 注入认证头(
X_CODEX_INSTALLATION_ID_HEADER、X_CODEX_TURN_STATE_HEADER) - 包含上下文数据(system prompt + history + tools)
- 若
enable_request_compression,压缩请求体
发送请求:
- WebSocket:发送增量 delta(只发送变化部分)
- HTTP SSE:POST 到
/responses端点 - 两者都使用 Responses API 格式
接收响应:
- 返回
ResponseStream(异步流) - WebSocket:通过
send_response_processed()确认接收 - SSE:通过 EventSource 解析 SSE 事件
- 返回
响应处理:
ResponseStream产生ResponseEvent变体- Session 解析事件,提取文本输出和工具调用
turn_state记录 turn 的状态
自定义 HTTP 头:
X_CODEX_INSTALLATION_ID_HEADER:安装 IDX_CODEX_TURN_STATE_HEADER:turn 状态X_CODEX_TURN_METADATA_HEADER:turn 元数据X_RESPONSESAPI_INCLUDE_TIMING_METRICS_HEADER:性能指标
练习 3:分析会话生命周期
分析一个完整会话从创建到销毁的生命周期管理。
参考答案
会话生命周期在 App Server 的多个模块协同管理:
创建阶段:
- 客户端发送
ClientRequest::StartThread(或类似) MessageProcessor路由到request_processorsThreadState创建新线程,调用Codex::spawn(CodexSpawnArgs)CodexSpawnArgs包含完整的初始化参数(config、auth、models_manager、mcp_manager 等)- 返回
thread_id给客户端
- 客户端发送
活跃阶段:
- 客户端通过
submit(Op)提交操作 thread_events处理代理事件,通过OutgoingMessageSender推送config_manager支持运行时配置变更dynamic_tools支持运行时添加/移除工具mcp_refresh监控 MCP 配置变更并热更新
- 客户端通过
恢复阶段:
- 客户端断开后,线程状态保存在
ThreadState中 - 重连后通过
thread_id恢复 Session通过apply_rollout_reconstruction()重建对话历史
- 客户端断开后,线程状态保存在
终止阶段:
- 客户端请求关闭:
shutdown_and_wait() SessionLoopTermination管理事件循环的优雅退出- 清理
ModelClient的 WebSocket 连接 - 释放
McpConnectionManager的所有连接 RolloutRecorder持久化最终状态
- 客户端请求关闭:
归档:
- 用户可选择归档线程
- 归档的线程存储在
ARCHIVED_SESSIONS_SUBDIR - 活跃线程存储在
SESSIONS_SUBDIR
拓展挑战
- 分析
ClientRequest宏的生成逻辑,理解如何定义新的请求类型 - 研究
in_process模式如何避免序列化开销 - 分析
TransportEvent的所有变体和传输层状态机 - 追踪
McpRefresh的配置热更新流程