LESSON 01 / 12 18 分钟
Harness 的边界:状态、协议与执行
从公开组件的职责和状态生命周期开始,明确后续讨论的范围。
整个运行系统怎样连接
先沿编号读完一条请求,再看状态在哪里变化、执行限制在哪里生效。图中保留源码名称,后续各课按这一地图展开。
学完你能做到
- 能区分生成与程序执行
- 能解释为什么一个问题可能触发多次请求
- 知道公开源码能证明什么、不能证明什么
本课目录 · 3 节
Harness 在代码里不是单个组件
本文用 指围绕服务的运行系统:接受输入、生成请求、维护历史、调度工具、处理权限与生命周期。它不是一个同名类,也不是推理本身。入口组件和这些核心机制之间通过类型、事件和服务接口交互。
公开仓库既有 、 和非交互执行入口,也有 及执行环境组件。阅读其中的协议与启动器,可以确认集成接口;不能据此还原闭源桌面客户端或服务端的全部实现。
分清四种生命周期
| 对象 | 主要职责 | 为何分开 |
|---|---|---|
Session / CodexThread | 承载长期配置、历史、服务和线程状态 | 用户连续输入不应重建全部连接和运行状态。 |
TurnContext | 一次的输入、取消与运行设置 | 一个用户可能包含多次请求;结束不等于结束。 |
StepContext | 本步已经解析的设置、环境与工具计划 | 工具可以稍后才执行,需要保留曾向展示它的那一步。 |
ModelClientSession | 本请求使用的传输与增量状态 | 代码复用连接和请求状态;认证所有权变化会使缓存状态失效。 |
传输状态的生命周期 ↗codex-rs/core/src/client.rs:1–17
延迟执行仍保留原 StepContext ↗codex-rs/core/src/tools/parallel.rs:44–54
模型输出不是执行结果
服务返回文字、工具请求和其他协议项。工具请求随后被解析、匹配执行实现、授权、运行并记入历史。下一次请求读取的是更新后的历史。失败和取消也要进入相应的事件或结果路径,不能用“想执行”代替“系统已经执行”。
真实源码 · Apache-2.0 · 未改写
/// Takes initial turn input and runs a loop where, at each sampling request,
/// the model replies with either:
///
/// - requested function calls
/// - an assistant message
///
/// While it is possible for the model to return multiple of these items in a
/// single sampling request, in practice, we generally one item per sampling request:
///
/// - If the model requests a function call, we execute it and send the output
/// back to the model in the next sampling request.
/// - If the model sends only an assistant message, we record it in the
/// conversation history and consider the turn complete.这个注释给出基础循环;完整实现还处理待输入、停止、重试和预算变化。
查看原文及相邻代码 ↗沿着源码读
以下定位均锁定本课程版本。先读注释与分支,再深入类型定义。
- 仓库明确的产品入口与范围
README.md:1–12 - 模型客户端的生命周期说明
codex-rs/core/src/client.rs:1–17 - 回合执行循环的入口
codex-rs/core/src/session/turn.rs:150–171
实现推演
沿 ModelClient、、 和 ToolCallRuntime 各找一个构造或使用点。判断哪些状态可以跨用户复用,哪些必须与某次工具请求绑定。
阅读练习无需模型账号。示例命令请先确认目录与环境。
自测与边界检查
提出 请求,是否等于命令已经成功执行?
展开自测答案
不是。工具请求只是意图。执行可能被拒绝、失败或取消;框架必须收集实际结果,才能在后续请求里让依据结果回答。
这门课能还原桌面端的全部行为吗?
展开自测答案
不能。我们只解释固定版本的公开实现与能直接定位的接口。闭源客户端或服务端的行为,需要独立证据。
学习记录保存在本机