Thread、Session、Turn:Codex 的五种生命周期

读 Agent harness 源码时,最容易踩的坑出现在概念层:开发者常把 Thread、Session、Turn 一概称作「会话」。这三个词在界面上经常互相替换,在代码里却对应三套不同的生命周期,存活时间相差极大。Codex 在这套对话机制上同时暴露了五个概念:Thread、Session、Turn、Submission、Event,每个概念解决一个独立问题。混用的代价很具体:中断一个执行轮次时误删整段历史,或者进程重启后找不回原本的任务。

为什么一次对话需要五个概念

一个 Agent 执行任务时,内部同时存在多条时间线。用户在 Agent 工作时追加要求、审批一条命令、点击中断,这三件事可能在同一秒内到达;模型请求会失败重试,工具进程会超时报错,上下文会被压缩。如果系统只用一个「会话」对象承载这一切,任何一侧的异常都会牵连其他侧。我们的做法是把状态按生命周期切开,分成五层:长期任务、运行实例、目标周期、输入通道、输出通道。

上一代聊天机器人的状态机很简单:一个请求进,一个回复出,Session 基本等同于一次连接。Agent 把这条直线换成了一个循环------模型决定调用工具,工具结果再喂回模型,中间还可能向人发起审批。循环一旦成立,「一次请求」这个单位就不够用了,必须同时描述「这个人正在处理的长期任务」「这个进程里正在跑的执行体」「这一轮目标」以及进出执行体的两股消息流。下面逐层看 Codex 的实现。

Thread:用户可见的长期任务

Thread 是侧边栏里能看到、日后还能继续的任务。「排查登录超时」是一个 Thread,它内部可以连续发生多次提问、修改和测试。Thread 拥有稳定 ID,可以被列出、恢复、fork、归档和删除。

ThreadManager 负责创建 Thread,并在内存里维护 ThreadId → CodexThread 的映射。CodexThread 是控制这个任务的句柄------通过它提交操作、读取事件、查询状态、关闭任务;运行逻辑全在它指向的实例内部。把句柄与实例分成两个类型,界面上的按钮和生命周期操作就不需要直接触碰执行体。

Session:Thread 当前的运行实例

Thread 可以长期存在,进程却不会永远运行。历史 Thread 被加载进当前进程后,会得到一个新的 Session。Session 持有真正的运行资源:配置、模型客户端、认证、工具、MCP(Model Context Protocol,连接模型与外部工具的开放协议)、扩展、历史、输入队列以及当前活动的 Turn。

医院里的类比很方便:Thread 是病历号,Session 是这次住院期间占用的床位、医生和设备。病历长期保存,床位可以退掉再开一次。

Codex 创建 Session 时同时启动 submission_loop 后台任务。这个循环持续从队列取出指令并处理,直到收到 Shutdown 或所有发送端关闭。Session 因此带有活的行为:它有启动、有循环、有关闭。判断资源归属时按这条规则操作------随 Session 结束而失效的,属于运行实例;退出后被存下来、下次加载可恢复的,属于 Thread。

Turn:一次用户目标的执行周期

Turn(执行轮次)从一条用户任务开始,到 Agent 给出本轮最终结果为止。一个 Thread 包含许多 Turn,一个 Turn 又包含多次模型请求和多次工具调用。

复制代码
Thread:修复登录问题
├─ Turn 1:分析调用链
│  ├─ 模型请求 1
│  ├─ 工具调用:搜索代码
│  └─ 模型请求 2
├─ Turn 2:实现修复
└─ Turn 3:运行测试

上例中 Turn 1 用两次模型请求夹一次搜索,仍然只是一个 Turn。判断 Turn 边界的依据是本轮目标是否完成,与内部请求次数无关。

TurnContext 保存本轮相对稳定的运行条件:模型、推理强度、权限、沙箱、工作目录、环境选择和 Turn ID。它的作用是隔离配置漂移。执行到一半时外部设置发生变化,本轮语义不受影响,新的条件从下一个 Turn 开始生效。少了这个快照,一次中途修改模型参数会让同一段推理的前半与后半来自不同模型,事后无法解释输出为什么跳变。

Submission:送给 Session 的内部信封

界面向 Session 施加动作时,中间隔着 Submission(内部信封)。用户的一次操作被包装成信封送入有界队列,信封内容包含唯一 ID、具体操作 Op、追踪信息以及父子 Turn 信息。

操作可以是启动 Turn、中断、审批结果、用户回答、刷新 MCP、压缩上下文、更新设置或关闭。后台的 submission_loop 顺序接收信封,再分派给对应处理器。

这层消息边界解决并发写入的问题。补充要求、审批命令和中断点击同时到达时,统一排队让顺序可推理;若让多个界面回调直接改写 Session 状态,最终状态取决于调度时机,难以复现。有界队列还提供背压,防止界面高频操作压垮执行端。唯一 ID 派上用场的地方在回执:审批结果必须绑定到当初发出的那条审批请求,否则两次同名请求会互相认领。

Event:Session 向外发出的事实

Submission 表达外界希望 Session 做什么,Event 记录 Session 已经发生了什么。Session 持续发出配置完成、Turn 开始、文本增量、工具开始、审批请求、工具结束、Token 用量和 Turn 完成等事件。

界面消费事件流,Session 的内部字段保持私有。App Server 可以把同一组核心事件映射成对客户端更稳定的协议通知,客户端版本与内部数据结构因此解耦,两边独立演进。Token 用量事件支撑计费与上下文水位判断,水位触顶后系统安排一次压缩上下文的 Submission,整个过程仍然走同一条输入通道,界面无需理解内部实现。

五层放在一起

vbnet 复制代码
ThreadManager 管理 Thread
Thread 加载后拥有 Session
Session 接收 Submission、产生 Event
Session 在每个 Turn 中运行 Agent Loop
TurnContext 固定本轮运行条件

切分的价值在故障处理路径上显现。模型请求失败时,Turn 可以在本轮内重试;Turn 被中断时,Thread 仍保留已完成的 Turn 历史;进程退出使 Session 结束,持久化的 Thread 下次加载时重建运行实例。每种故障只影响自己那一层,重试、恢复和并发才有清晰语义。五个命名各占一段生命周期,这套切分才有落点。

对 harness 设计的启示

只装了历史、当前请求、工具进程和 UI 状态的巨大 Conversation 对象,迟早出现状态互相污染。常见的表现有两条:一次中断清掉了本该保留的上下文,一条迟到的回调改写了新请求的参数。

自建 Agent 系统时,建议先画清五层边界:长期身份、当前运行实例、单次目标、输入命令、输出事件。命名可以与 Codex 不同,边界不能缺少。检验边界是否画对的办法很实际:任意一层挂掉时,能否明确说出上层是否还在、要不要恢复、恢复后从哪里接上。三问都答得出,分层才成立。

源码可以按这条线索读:

bash 复制代码
codex-rs/core/src/thread_manager.rs       ThreadManager、NewThread
codex-rs/core/src/codex_thread.rs         CodexThread
codex-rs/core/src/session/mod.rs          Session、SessionIo
codex-rs/core/src/session/turn_context.rs TurnContext
codex-rs/protocol/src/protocol.rs         Submission、Op、EventMsg

读这套代码的顺序建议从字段定义开始:先看 SubmissionEventMsg 两个枚举弄清系统允许的输入和输出,再跟一遍 submission_loop 的分派看动作如何改变状态,最后回到 ThreadManagerSession,确认实例的创建与销毁时机。五段生命周期各自安好之后,「会话」这个词在代码里反而不再需要出现。

相关推荐
u1301301 小时前
AI 日报(2026年9月9日)
人工智能
老余说AI1 小时前
从开源换脸工具到商业级 AI 换脸平台:SoundView 视频换脸的产业定位与边界
人工智能·音视频·视频换脸
Anhty1 小时前
叮咚变声器上手实测,iOS短板、安卓悬浮窗使用感受分享
android·人工智能·功能测试·ios·智能手机
四方云1 小时前
低配4C4G服务器,10秒录音1秒转写!解决电销系统混合录音质检最大难题
大数据·人工智能·自动化·电销破局
Henry-SAP1 小时前
SAP PP 反冲机制业务解析
人工智能·云原生·sap·erp
Akir.weiwen1 小时前
⑤ 消费格式差异:同一份契约的四角色消费格式
人工智能·编译·设计规范·语义
广凌股份(广凌科技)1 小时前
实验室安全检查包括哪些内容?智能管理平台筑牢校园实验安全防线
大数据·人工智能
差不多的周周1 小时前
《MotionLLM:从人体运动和视频理解人类行为》论文核心部分详解
人工智能·深度学习·机器学习·计算机视觉·语言模型·音视频
麻雀飞吧1 小时前
搜索“近期量化入门”时,先补交易理解再看 Python 和 API
人工智能·python