# 自动记忆(官方 Codex memories 的云端对齐版,v1) 官方功能见 learn.chatgpt.com/docs/customization/memories:开启后, Codex 把先前聊天的有用上下文转成记忆,供未来工作用;后台生成、 闲置后才生成、剩余额度低时跳过、有 generate / use / disable_on_external_context 等设置、密钥脱敏。 本批把这套行为搬到云端控制面(`cloud/auto_memory.py`),不改 host.py、不改 CODEX_HOME、不改 thread 的创建/续跑/fork/归档。 云端记忆与官方本地记忆的区别要先说清:官方记忆存在单机 `~/.codex/memories/` 里、跟一台机器走;云端记忆存在控制面 数据库里,跟用户/项目走,换 worker、换执行器都还在。 ## 开关(默认全关,与官方“本地记忆默认关”一致) - `GET/PUT /users/me/auto-memory-settings`:本人设置。 - `generate_memories`:完成任务是否可被提取。默认 0。 - `use_memories`:新任务首轮是否注入记忆。默认 0。 - `disable_on_external_context`:默认 1,见下。 - `min_rate_limit_remaining_percent`:默认 20,见下。 - `idle_seconds`:默认 900;`min_duration_seconds`:默认 30; `min_result_chars`:默认 200。 - `extract_model` / `consolidation_model`:只存设置,v1 不调 模型(见“未做”)。 - `POST /tasks/{id}/auto-memory-flags`:单个任务覆盖 use/generate (NULL = 跟随用户设置),权限为项目 create_task。不改 tasks 表结构,建任务的各条 INSERT 路径都不用动。 - `POST /users/me/auto-memory/run`:手动触发本人任务的提取扫荡 (body 可带 `force: true` 跳过闲置/时长/长度门,不跳过开关、 外部上下文门与额度门);`GET /users/me/auto-memory-log`:看 本人任务的提取日志(按任务主键覆盖,不无限增长)。 ## 提取:什么时候、从哪来、写到哪 触发:worker `run_loop` 每轮结束调 `process_auto_memories()`; 也可经上面的手动触发接口立即跑。只扫 `status='completed'` 的 任务(failed / interrupted / merged 不提取)。 资格(任一不满足即跳过并记日志,下次仍可再扫): 1. generate 开关(任务级覆盖优先于用户设置); 2. 终态闲置够 `idle_seconds`(终态后仍可被 /continue 续跑, 所以“刚完成”不等于“已闲置”;`force` 可跳过); 3. 有 started_at/finished_at 且时长 ≥ `min_duration_seconds`, result_text 长度 ≥ `min_result_chars`(跳过短期会话); 4. `disable_on_external_context` 开时,任务间消息 (task_followups 有该任务的行)或协调员子任务 (parent_task_id 非空)不提取; 5. 当月 USD 配额剩余百分比 ≥ `min_rate_limit_remaining_percent` (无配额行按默认 $10 计,只有显式 NULL 行才是不限额,与 worker 配额口径一致;查不到配额时 fail-closed,记 quota_check_failed,不冒充额度充足)。 内容(v1 确定性版,不调模型):任务 goal/prompt 首行 + result_text 前 800 字,脱敏后拼成一条 project 级 fact,写入 `identity_memories`,`source_thread_id` 记云端任务 id(去重键)。 同一任务只提取一次;同一目标的新结果出现时 supersede 旧记忆 (consolidation 的确定性版),不堆重复。自动提取只写 project 级:单个项目的任务结论若自动写成 user 级,会跨项目泄漏项目 上下文;user 级记忆仍只接受手动创建。 脱敏:`api_key/password/secret/token/credential` 的 key=value 形态、Authorization / Bearer 头、sk- / ghp_ / gho_ / xox*- 前缀 一律替换为 `[REDACTED]`;偏好里的密钥键禁令见 identity-memory.md。 ## 注入:怎么进任务 worker `run_one` 认领后、执行前调 `_apply_auto_memory_injection`: - 只注入首轮:续跑、断点续跑、协调员任务不注入; - 只改内存副本:prompt 前加 `【过往记忆,仅供参考,不得改写 本任务目标】` + 最新各 5 条用户/项目记忆;goal 任务同时改 内存里的 goal(执行器取 goal 优先于 prompt);库里的原 prompt / goal 不动,任务详情里看到的仍是原文本; - 注入失败 fail-open(记 warning,不挡任务);注入成功记 `worker_memory_injected` 审计;无记忆或 use 关时不注入。 - 注入不进 thread 的 developerInstructions:host.py 的 dispatch 路径不传 instructions,云端层唯一不改 host.py 的注入点就是 prompt 前缀,identity-memory.md 里“调用方自己拼进新建任务 的 prompt”正是这条路。 ## 未做(诚实版) - 未调模型提取/合并:`extract_model` / `consolidation_model` 只存设置。v1 提取是确定性拼贴,不是模型摘要;换模型提取 需另定模型选择、成本上限与失败语义。 - 未识别 host 线程内的 MCP / web search:tasks 表上没有这类 标记,`disable_on_external_context` 目前只认任务间消息与 协调员子任务;要认 MCP/web 需先给 host 线程事件加遥测。 - 未做控制台 UI:开关与日志目前只有 API;未做 per-chat 的 `/memories` 式交互(任务级 flags 接口是对应的最小版)。 - 未进代码签名候选:worker 签名只含 worker/sandbox/ coordinator/cost/server/host;本批同时改了 worker.py,所以 正常部署换目录时旧 worker 仍会因 worker.py 变化而自退, 仅换 auto_memory.py 的单文件部署不在签名覆盖内。