芥末
发布于 2026-04-29 / 0 阅读
0
0

用洁癖 Skill 让 AI Agent 持续维护项目文档和记忆

AI Agent 写代码时,真正拖后腿的经常不是模型能力,而是项目上下文已经变脏了。

代码已经从 SQLite 切到了 PostgreSQL,但项目说明里还写着 SQLite;接口新增了 5 个路由,CLAUDE.md 里有记录,docs/integration-guide.md 里却没有;环境变量换了名字,部署手册仍然沿用旧字段。Agent 每次启动都会读这些材料,一旦材料过期,它就会把错误信息当成事实,然后基于错误前提继续写代码。

洁癖 Skill 解决的就是这个问题:在一次任务结束时,让 Agent 自动审查项目文档、项目约束和记忆文件,把过期、重复、冲突的信息清掉,把新事实沉淀到该去的位置。

它不是让模型“参数变聪明”,而是让 Agent 每次工作时拿到更准确的项目事实。

仓库地址:

https://github.com/KKKKhazix/khazix-skills

它可以用于 Claude Code、Codex、OpenCode、OpenClaw 这类 AI 编程 Agent。最常见的使用方式是在任务结束后输入:

/neat

也可以直接用自然语言说:

审查一下项目文档和记忆,把需要同步的地方整理干净。

为什么 Agent 会越用越乱

一次对话里的上下文,只是 Agent 看到的信息之一。真实项目里,Agent 还会读取很多持久化材料:

  • README
  • docs/ 目录
  • CLAUDE.md
  • Agent 自己的记忆文件
  • 任务记录、约束说明、运行手册
  • 接口文档、部署文档、架构说明

这些内容本来是为了帮助 Agent 理解项目,但它们有一个前提:必须是准确的。

如果文档不维护,项目就会出现“上下文腐败”:

flowchart TD
    A[代码持续迭代] --> B[功能、接口、依赖、架构发生变化]
    B --> C[文档和记忆没有同步更新]
    C --> D[Agent 读取过期信息]
    D --> E[基于错误前提生成代码]
    E --> F[出现莫名其妙的 bug]
    F --> C

很多 Vibe Coding 项目尤其容易遇到这个问题。前期通过对话快速做功能,速度很快;项目变大后,如果没有工程化的文档维护习惯,README、运行手册、项目约束和 Agent 记忆就会逐渐分裂。到最后,Agent 不是“不理解项目”,而是同时读到了多份互相矛盾的项目说明。

典型例子是数据库迁移。

假设项目一开始使用 SQLite,后面切到 PostgreSQL。代码迁移完成后,如果文档没有同步更新,Agent 下次可能仍然写出 SQLite 风格的 SQL,或者继续建议使用本地文件数据库。这个问题不是模型不会 PostgreSQL,而是项目材料告诉它“这里用 SQLite”。

项目知识应该分成三层维护

AI 编程项目里的知识,不应该全部塞进一个记忆文件,也不应该全部写进 README。不同材料服务的对象不同,承载的信息也不同。

层级典型文件主要读者应该记录什么不适合记录什么
Agent 记忆Agent memory、会话摘要Agent 自己项目当前状态、长期约定、已经确认的事实大段接口文档、完整操作手册
项目约束CLAUDE.md 或同类规则文件AI 编程工具编码规范、目录结构、禁用做法、关键红线、常用命令面向外部使用者的接入教程
项目文档README.mddocs/人、Agent、协作者、下游系统架构说明、接入指南、部署手册、API 文档、运维说明只对当前 Agent 有意义的临时偏好

这三层不能互相替代。

比如新增了 5 个 API 路由:

  • CLAUDE.md 里需要提醒 Agent:这些路由已经存在,不要重复创建,新增接口要遵循同一风格。
  • docs/integration-guide.md 里需要告诉调用方:每个路由怎么请求、参数是什么、返回结构是什么。
  • 记忆文件里可以留下摘要:当前项目已完成某模块的 API 扩展,后续开发要基于新版路由。

如果只更新记忆,项目文档仍然是旧的;如果只更新 README,Agent 的项目约束可能仍然缺关键红线;如果只更新 CLAUDE.md,协作者和下游调用方还是不知道怎么接入。

洁癖 Skill 的价值就在于,它不是只整理单点记忆,而是把这三层一起纳入审查范围。

核心原则:合并优于追加,删除优于保留

很多人维护文档时,会下意识保留所有信息,理由是“万一以后用得上”。在 AI 协作场景里,这个习惯很危险。

对 Agent 来说,过期信息比没有信息更糟糕。

没有信息时,Agent 可能会问你;读到过期信息时,它会以为那是真的,并继续执行。尤其是数据库、鉴权、路由、部署命令、环境变量这类事实,一旦新旧版本同时存在,Agent 很容易选错。

洁癖 Skill 遵循两个清理原则:

原则含义例子
合并优于追加同一件事不要散落在多个重复段落里,要合并成一个清晰版本同一个 API 的说明在 3 个文档里各写一半,应合并成一份权威说明,再在其他地方引用
删除优于保留明确过期的信息要删除,不要留着“备查”数据库已迁移到 PostgreSQL,就不要继续保留“项目使用 SQLite”的约束

这不是为了让文档更短,而是为了让文档里的事实更唯一。

理想状态下,Agent 读完项目材料后,不会看到两个互相冲突的答案。

洁癖 Skill 的工作流程

运行 /neat 后,Skill 会按固定流程处理项目知识。它做的不是简单总结对话,而是把本次变更映射到整个项目文档体系里。

flowchart TD
    A[运行 /neat] --> B[盘点所有 Markdown 文档]
    B --> C[识别本次对话产生的新事实]
    C --> D[使用变更影响矩阵判断哪些文件受影响]
    D --> E[更新 docs 和 README]
    E --> F[更新 CLAUDE.md 或同类项目约束]
    F --> G[整理 Agent 记忆]
    G --> H[执行自检清单]
    H --> I[输出变更摘要]

1. 盘点项目里的 Markdown 文件

清理文档不能只改眼前那一个文件。很多项目的问题就在于:某个关键说明藏在一个旧文档里,Agent 没有读到,最后新旧信息并存。

所以洁癖 Skill 的第一步是机械式盘点,把项目中所有相关 Markdown 文件列出来并读取,包括:

README.md
CLAUDE.md
docs/**/*.md
runbook/**/*.md
architecture/**/*.md
integration/**/*.md

如果平台使用的不是 CLAUDE.md,而是其他项目规则文件,也应该纳入同一类扫描。

这一步的目标是避免漏改。只要旧信息还留在某个文档里,它就有机会在未来被 Agent 读到。

2. 用变更影响矩阵判断该改哪里

一次开发对话里可能产生很多新事实,但不是每个事实都需要写进所有文件。洁癖 Skill 会根据变更类型判断影响范围。

变更类型READMEdocsCLAUDE.md记忆文件需要重点检查
新增 API可能需要需要更新接入文档需要记录路由约束记录模块状态参数、返回值、鉴权、错误码
数据库迁移需要更新依赖说明需要更新架构和部署文档需要删除旧数据库约束删除旧记忆并写入新事实SQL 方言、连接串、迁移命令
新增环境变量需要更新启动说明需要更新部署手册需要提醒 Agent 使用新变量可记录配置变化示例值不能泄露密钥
删除功能需要移除入口说明需要删除旧教程需要禁止继续调用旧模块删除旧记忆是否仍有旧路由、旧命令
跨项目依赖变化可能需要依赖方文档也要更新记录联动关系记录上下游状态项目 A 改动是否影响项目 B

这个矩阵解决的是“波及范围”问题。

例如项目 A 改了接口返回结构,项目 B 依赖这个接口。只更新项目 A 的接口文档还不够,项目 B 的接入说明、类型定义、运行手册也可能要同步更新。跨项目依赖是文档维护里很容易漏掉的部分。

3. 按顺序更新 docs、项目约束和记忆

洁癖 Skill 的更新顺序是:

docs/ 和 README
        ↓
CLAUDE.md 或同类项目约束
        ↓
Agent 记忆

这样做有一个好处:先把面向人和项目的权威文档修正,再把 Agent 的工作约束对齐,最后把长期记忆整理成摘要。

如果反过来先改记忆,Agent 可能只是记住“某件事变了”,但项目正式文档仍然没有更新。下一次换一个 Agent、换一个会话、换一个协作者,问题还会回来。

4. 执行自检清单

文档更新后,还需要检查新旧事实是否完全对齐。洁癖 Skill 会用自检清单找常见遗漏。

常见检查项包括:

检查项为什么重要
新增环境变量是否同时出现在启动说明、部署手册和项目约束中避免本地能跑、部署失败
数据库类型、连接方式、迁移命令是否一致避免 Agent 写错 SQL 或使用旧依赖
新增路由是否有参数、返回值、错误码说明避免调用方只能看代码猜接口
删除功能后是否残留旧文档、旧命令、旧记忆避免 Agent 继续调用不存在的模块
是否存在“昨天、最近、当前版本”这类相对时间相对时间会随时间失效,最好改成明确状态
跨项目依赖是否同步更新避免上游变了,下游文档仍然指向旧协议
是否保留了互相冲突的说法冲突信息会让 Agent 随机选一个相信

自检的目的不是追求文档数量,而是让项目里只保留当前准确的事实。

5. 输出变更摘要

整理结束后,Skill 会给出一份摘要,让使用者知道它改了哪些东西。一个比较理想的摘要结构类似这样:

## Neat 变更摘要

### 已更新
- docs/database.md:将数据库说明从 SQLite 更新为 PostgreSQL。
- docs/deployment.md:补充 POSTGRES_URL 环境变量。
- CLAUDE.md:移除 SQLite 相关约束,新增 PostgreSQL 查询约定。
- memory:删除旧数据库记忆,记录当前数据库架构状态。

### 已删除
- docs/legacy-sqlite-setup.md 中过期启动说明。
- CLAUDE.md 中“使用本地 SQLite 文件”的旧规则。

### 需要人工确认
- 生产环境 PostgreSQL 备份策略尚未写入 runbook。
- 旧版本迁移脚本是否仍需保留,需要确认兼容范围。

这份摘要很关键。自动整理文档不能变成黑盒,尤其是删除旧信息时,最好让人能快速确认修改范围。

一个数据库迁移场景

假设项目完成了一次数据库迁移:

旧状态:SQLite
新状态:PostgreSQL
相关变化:连接串、依赖包、SQL 方言、部署配置、迁移命令

如果只改代码,不整理文档,项目里可能出现这种冲突:

文件残留问题
README.md安装步骤仍然说无需启动数据库
docs/deployment.md没有 POSTGRES_URL 环境变量
docs/architecture.md架构图仍然画成本地 SQLite 文件
CLAUDE.md仍然要求 Agent 使用 SQLite 语法
记忆文件仍然记录“项目使用轻量级 SQLite”

运行 /neat 后,应该把这些内容统一到 PostgreSQL 版本:

flowchart LR
    A[数据库迁移完成] --> B[README 更新依赖和启动方式]
    A --> C[部署文档新增 PostgreSQL 配置]
    A --> D[架构文档更新存储层说明]
    A --> E[CLAUDE.md 删除 SQLite 约束]
    A --> F[记忆文件替换为新数据库事实]

这样新会话启动后,Agent 看到的是统一上下文:

项目当前使用 PostgreSQL。
新增查询必须使用 PostgreSQL 兼容语法。
本地开发需要配置 POSTGRES_URL。
旧 SQLite 说明已删除,不再作为参考。

这比在对话里反复提醒“别用 SQLite”稳定得多。对话会关闭,文档会留下。

适合哪些场景

洁癖 Skill 对“项目会持续迭代、Agent 会反复参与开发”的场景更有价值。

场景是否适合原因
Vibe Coding 做出来的中长期项目适合文档维护习惯往往弱,功能增长后容易上下文混乱
多次会话持续开发同一个项目适合每次收尾都能把对话信息沉淀到文档
多个 Agent 或多个人协作适合需要统一的项目事实来源
接口、部署、数据库频繁变化的项目适合这些变化最容易造成旧文档误导
一次性脚本或临时 Demo不一定需要没有长期上下文维护成本
文档已经由严格工程流程维护的团队可作为补充仍然可以用于检查遗漏,但不能替代代码评审和测试
对自动修改文档完全不放心的项目谨慎使用可以只让它输出建议,不直接写文件

它尤其适合任务收尾阶段,而不是任务刚开始的时候。比较自然的节奏是:

做功能 / 修 bug
        ↓
跑测试或手动验证
        ↓
运行 /neat
        ↓
检查变更摘要和 git diff
        ↓
提交代码与文档

上手方式

仓库可以直接克隆:

git clone https://github.com/KKKKhazix/khazix-skills.git

不同 Agent 平台的 Skill 或 Command 安装方式不完全一样,可以按平台自己的规则导入仓库中的洁癖 Skill。通用流程是:

1. 克隆或下载 skills 仓库
2. 找到洁癖 Skill 对应目录
3. 按 Claude Code、Codex、OpenCode、OpenClaw 的导入方式安装
4. 重启或刷新 Agent 的 Skill 列表
5. 在项目任务结束时运行 /neat

使用时不需要写复杂提示词。最短命令就是:

/neat

如果想让它更明确,可以这样说:

/neat

请全面审查本次对话产生的项目变化,同步更新 docs、README、CLAUDE.md 和记忆文件。
需要删除过期信息,合并重复说明,并输出变更摘要。

在没有斜杠命令的环境里,也可以直接写成自然语言:

请整理项目文档和记忆:
- 盘点所有 Markdown 文档
- 根据本次变更更新 docs、README 和项目约束文件
- 删除过期记忆,合并重复事实
- 检查是否存在新旧冲突
- 最后输出变更摘要

使用时要注意的坑

不要把它当测试工具

洁癖 Skill 主要整理项目知识,不负责证明代码正确。功能是否能跑,仍然要靠测试、类型检查、人工验证或 CI(持续集成)。

更稳妥的顺序是先验证代码,再整理文档:

# 示例:按项目实际命令调整
npm test
npm run lint

确认功能没问题后,再运行:

/neat

删除信息前最好看 diff

“删除优于保留”不等于无脑删除。运行后建议查看版本差异:

git diff

重点看三类修改:

  • 是否误删仍然需要保留的兼容说明
  • 是否把未确认的事实写成了确定结论
  • 是否在文档里暴露了密钥、内部地址、私有配置

敏感配置只能写示例

环境变量、连接串、Token、内部域名这类内容要谨慎。文档里可以写变量名和示例格式,不应该写真实密钥。

推荐写法:

POSTGRES_URL=postgresql://user:password@localhost:5432/app_db

不推荐写法:

POSTGRES_URL=postgresql://real_user:real_password@prod-db.example.internal:5432/prod

记忆文件不要变成垃圾堆

记忆不是越多越好。适合进入记忆的是长期有效的项目事实,例如:

项目当前使用 PostgreSQL。
后端 API 统一放在 src/routes。
新增接口必须补充 integration guide。

不适合进入记忆的是临时过程:

刚才尝试了方案 A,但是失败了。
今天先临时注释掉某段代码。
这个 bug 可能明天再看。

这些内容如果没有长期价值,就不应该污染后续会话。

更好的使用节奏:把 /neat 当成存档

AI 编程会话越长,上下文越容易变得臃肿。与其把所有细节都堆在一个长对话里,不如在一个阶段结束时把真正有价值的信息写回项目文档,然后新开会话继续。

推荐节奏是:

sequenceDiagram
    participant U as 使用者
    participant A as AI Agent
    participant D as 项目文档
    participant M as 记忆文件

    U->>A: 开发功能或修复 bug
    A->>U: 完成代码修改
    U->>A: 运行 /neat
    A->>D: 更新 README、docs、项目约束
    A->>M: 合并新事实,删除旧记忆
    A-->>U: 输出变更摘要
    U->>U: 检查 diff 后提交
    U->>A: 新会话继续开发

这样做的关键变化是:项目知识不再依赖某一次对话,而是沉淀在持久化文档里。对话可以关闭,窗口可以重开,但 README、docs、CLAUDE.md 和记忆文件仍然能把 Agent 带回正确状态。

洁癖 Skill 的核心价值可以概括成一句话:

过期的就删,重复的就合,模糊的就改,让项目里只保留当前最准确的事实。

对 AI Agent 来说,干净的上下文就是稳定的工作环境。文档越准确,Agent 越不容易被旧信息带偏;记忆越克制,新会话越容易快速进入状态。


评论