Local Compact 不是在本地运行摘要模型,而是 Core 自己构造一轮带总结指令的普通模型采样,再由本地代码从输出中提取摘要、筛选保留用户消息并整体替换 History。它与 Remote Compact 的区别在“谁定义压缩协议和返回形状”。
触发后创建独立 Compact Turn
手动 Compact 和自动 Compact 最终进入 run_compact_task_inner。流程先执行 pre-compact hooks,发出 ContextCompaction started item,再把本次 compact input 追加到一个 History 快照,使用同一 ModelClientSession 重试采样。
async def local_compact(session, turn, compact_input):
await hooks.pre_compact(turn)
working = session.history.snapshot()
working.record(compact_input)
while True:
try:
await drain_summary_response(session, working.for_prompt())
break
except ContextWindowExceeded:
if len(working.items) <= 1:
raise
working.remove_first_item() # pair-aware
return await install_local_summary(session, turn)
网络错误按 provider 的 stream retry 上限和 backoff 重试;Interrupted/TurnAborted 不重试。若总结请求仍超窗,就从最旧端删除一个 item,配对项同步删除,最近历史尽量保留。
替代历史保留什么
采样完成后从真实 Session History 取本次 Compact Turn 最后一条 assistant message,添加 SUMMARY_PREFIX。collect_user_messages 筛出用户消息,再由 build_compacted_history 按保留上限构造“必要用户输入 + 摘要”的新列表。
def build_local_replacement(raw_history, assistant_summary):
users = collect_real_user_messages(raw_history)
summary = Message.user(SUMMARY_PREFIX + "\n" + assistant_summary)
return retain_recent_users_with_budget(users) + [summary]
Pre-turn/手动压缩使用 DoNotInject,正常 Turn 会在压缩后再完整注入当前上下文;Mid-turn 则必须在替代历史中把初始上下文插到最后真实用户消息之前,并让 compaction summary 保持最后一项,以符合模型训练形状。
源码与测试锚点
codex-rs/core/src/compact.rs:完整 Local Compact 状态机。codex-rs/prompts:SUMMARIZATION_PROMPT与SUMMARY_PREFIX。codex-rs/core/src/compact_tests.rs:用户消息保留、插入位置和失败重试。
评论
登录后即可评论