This repository has been archived on 2026-07-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-05-03 21:09:59 +08:00

9.8 KiB
Raw Permalink Blame History

name, phases, description
name phases description
dev-changelog
all
三层开发进程记录系统。在 Agent 完成代码改动后自动记录,提供从一句话概要到完整日志的 多级上下文,帮助 Agent 在跨会话场景下保持对项目开发进展的感知。 当用户提到"开发日志"、"changelog"、"最近改了什么"、"回顾改动"等时触发。

Dev Changelog

三层开发进程记录系统,解决 Agent 跨会话的上下文断裂问题。

三层架构

层级 文件 信息密度 条目数量 注入方式
L1 完整版 changelog-full.md 5-15 行/条) 无上限,只追加 用户手动唤醒
L2 中期版 changelog-recent.md 3-5 行/条) 滚动窗口 ~20 条 检测到关联时自动读取
L3 概要版 changelog-headlines.md 1 行/条) 滚动窗口 ~50 条 每次会话自动注入

所有数据文件存放在 .opencode/data/changelog/ 目录下。

锚点 ID 机制

每条记录在写入时生成一个锚点 ID,格式为 CL-YYYYMMDD-HHMM(如 CL-20260412-1430)。 同一分钟内有多条时追加字母后缀(CL-20260412-1430aCL-20260412-1430b)。

锚点 ID 在三层文件中保持一致,用于跨层精准定位:

  • L3 一句话条目以 [CL-xxx] 开头
  • L2 摘要条目的 H3 标题包含 [CL-xxx]
  • L1 完整条目的 H3 标题包含 [CL-xxx]

这使得从 L3 → L2 → L1 的逐级查找可以通过 Grep 精准定位,无需全文读取。

逐级上溯机制

当 Agent 在使用 L3 概要作为上下文时,如果某条记录的一句话描述语义模糊 (如无法判断改动的具体范围、与当前任务的关系不明确),执行以下逐级查找:

1. 从 L3 条目中提取锚点 ID如 CL-20260412-1430
2. 在 changelog-recent.mdL2中 Grep 该 ID
   - 找到 → 读取该条目的 3-5 行摘要,通常足以消除歧义
   - 未找到(已滚出 L2 窗口)→ 进入步骤 3
3. 在 changelog-full.mdL1中 Grep 该 ID
   - 找到 → 用 Read 工具读取该 ID 所在行号 ±20 行范围(精准读取,不读全文)
   - 未找到 → 放弃上溯,该条目上下文不可用

上溯原则

  • 按需触发:只有在 L3 信息不足以支撑当前任务判断时才上溯,不预防性地批量读取
  • 精准读取:对 L1 的访问必须通过 Grep 定位行号 + Read 局部读取,禁止全文读取
  • 最小化:一次上溯通常只涉及 1-3 条记录,不批量上溯

操作 A记录写入核心流程

触发条件

Agent 完成了一个涉及代码或配置文件实质性改动的任务后,自动触发。

以下情况不触发

  • 纯对话讨论、方案设计、问题解答(无文件改动)
  • 只读操作(查看文件、搜索代码)
  • 只改动了 .opencode/ 目录下的基础设施文件如画像、延期方案、changelog 自身)

写入流程

1. 生成锚点 IDCL-YYYYMMDD-HHMM检查是否与已有 ID 冲突,冲突则追加字母后缀)

2. 从刚完成的任务中提取以下信息:
   - 做了什么what一句话概括
   - 为什么这样做why动机和背景
   - 改了哪里where受影响的文件/模块列表
   - 关键决策decisions如果有方案选择记录选了什么、放弃了什么
   - 注意事项notes后续可能受影响的地方、已知限制等

3. 生成三层内容(共享同一个锚点 ID
   - L1 完整条目(包含以上全部信息)
   - L2 摘要条目what + why + where3-5 行)
   - L3 一句话what不超过 80 字)

4. 写入三个文件(按以下顺序):
   a. 读取 changelog-full.md在 "## 记录" 下方追加 L1 条目
   b. 读取 changelog-recent.md在顶部插入 L2 条目,如超过 20 条则移除最旧的
   c. 读取 changelog-headlines.md在顶部插入 L3 条目,如超过 50 条则移除最旧的

5. 在回复末尾附一行提示:"[已记录到开发日志]"

静默写入原则

  • 不需要用户确认——Agent 自己做的改动,对"做了什么"的认知是一手的
  • 用户如果觉得记录不准确,可通过操作 D 修改或删除
  • 回滚操作也要记录("回退了 XX 改动"),真实反映开发过程

操作 BL2 自动触发读取

触发条件

由 AGENTS.md 中的"开发日志上下文注入"和"L2 自动触发"规则调度。当 Agent 开始处理一个新任务时,判断该任务是否与近期改动相关。

匹配策略(文件 + 标签双匹配)

1. 从当前任务中提取:
   - 涉及的文件路径
   - 语义关键词(模块名、功能领域等)

2. 读取 changelog-recent.md逐条检查
   - 硬匹配:当前任务涉及的文件出现在条目的 affected_files 中
   - 软匹配:当前任务的语义关键词与条目的 tags 有交集

3. 任一匹配命中 → 将匹配到的 L2 条目作为上下文纳入考量
4. 在回复中自然融入,不显式提及"根据开发日志"

操作 CL1 手动检索

触发条件

用户主动要求回顾完整改动记录时触发。典型话语:

  • "回顾一下最近的改动"
  • "XX 模块之前改过什么"
  • "查看开发日志"
  • "changelog"

流程

1. 读取 changelog-full.md
2. 根据用户需求过滤:
   - 按时间范围
   - 按模块/文件
   - 按 tags
3. 展示匹配的条目摘要表,用户可以进一步查看某条的完整内容

操作 D记录管理

用户可以对已有记录进行管理:

操作 说明
删除 从三层文件中同步移除对应条目
修改 修改某条记录的描述(三层同步更新)
清理 手动触发 L1 的归档(如按月分文件,暂不实现,作为演进方向)

条目格式

L1 完整条目

### [CL-20260412-1430] YYYY-MM-DD HH:MM — 一句话标题
- **tags**: tag1, tag2, tag3
- **affected_files**:
  - path/to/file1
  - path/to/file2
- **what**: 做了什么的简要描述
- **why**: 动机和背景
- **decisions**: 选择了 A 方案(放弃了 B 因为 xxx
- **notes**: 后续注意事项
- **source_chat**: [对话简述](chat-uuid)

L2 摘要条目

### [CL-20260412-1430] YYYY-MM-DD — 一句话标题
- **tags**: tag1, tag2, tag3
- **affected_files**: file1, file2
- **summary**: 做了什么 + 为什么3-5 行)

L3 一句话条目

- [CL-20260412-1430] 一句话描述改动内容(不超过 80 字)

滚动窗口维护

L2 窗口(~20 条)

写入新条目后,检查总条目数:
- <= 20 条:不做处理
- > 20 条:移除文件底部(最旧的)条目,直到恰好 20 条

L3 窗口(~50 条)

写入新条目后,检查总行数(排除文件头部的标题和说明):
- <= 50 条:不做处理
- > 50 条:移除文件底部(最旧的)条目,直到恰好 50 条

被移除的条目不需要额外归档——L1 完整版保留了所有历史。

数据文件模板

首次写入时,如对应文件不存在,按以下模板创建。

changelog-full.md

# Dev Changelog — Full

完整的开发改动记录,按时间倒序排列。作为主动 RAG 的数据源,用户手动唤醒时读取。

## 记录

changelog-recent.md

# Dev Changelog — Recent

最近 ~10 次改动的摘要记录,按时间倒序排列。
当 Agent 检测到当前任务与近期改动相关时自动读取。

changelog-headlines.md

# Dev Changelog — Headlines

最近 ~50 次改动的一句话概要,按时间倒序排列。每次会话自动注入上下文。

与其他系统的协作

系统 关系 说明
AGENTS.md 下游消费者 每次会话注入 L3自动触发 L2 读取
deferred-decisions Skill 互补 deferred 记"没做什么"changelog 记"做了什么"
profile-memory Skill 结构对称 profile 是"是什么"changelog 是"做了什么"
epee-orchestrator Skill 注册 在 registry.md 中注册本 Skill

自迭代日志

本节记录使用本 Skill 过程中发现的必要检查项。

已知必要检查

  1. 大任务收尾遗漏风险 — 当单次任务涉及 5+ 个文件改动时Agent 容易在输出总结回复后遗漏被动写入流程。应在生成最终回复前,先执行 AGENTS.md 中的"任务完成 Checklist",确认三层日志已写入后再输出回复。绝不能"先回复再补写"。

  2. L3/L2 滚动窗口必须落地 — 操作 A 第 4 步不是「插入即结束」写入后必须数清条目L3 为以 - [ 开头的列表行L2 为 ### [CL- 标题行。L3 超过 50 条、L2 超过 20 条时,必须从**文件底部(最旧)**整段删除条目直至恰好满足上限;禁止长期只追加不修剪。

  3. 顶部插入必须保持旧首条目完整性 — 使用编辑工具在文件顶部插入新条目时anchorold_string)有且仅有两种合法选择: (a) 只包含新条目之前的"稳定前缀"(如 L1 的 ## 记录\n\n 或 L2 的整段文件头说明),不触及任何已有条目的任何一行new_string = 稳定前缀 + 新条目完整内容 + 空行。 (b) 把旧首条目的完整多行内容(标题行 + 全部字段行)都纳入 old_stringnew_string = 新条目完整内容 + 空行 + 旧首条目完整内容。

    绝对禁止:只把旧首条目的标题行(或前 1-2 字段)当 anchor 而不带上剩余字段行——编辑工具会吞掉这些 anchor 行但不动剩余字段,造成"旧标题丢失、字段游离"的半损坏状态。

    写入后自检Read 文件头部 30 行,确认看到新条目完整 + 旧首条目标题行仍存在且字段完整跟随。L3 的一行条目不受本条约束(它就是单行,天然无此风险)。