自我修复(自修正规则引擎)
一种自我修正的记忆与学习引擎,将用户的修正、项目约定和错误修复记录到持久的规则文件(autofix.json)中。它确保代理不断适应,跨会话消除重复错误,并严格遵守用户偏好。
为什么有效: AI 代理在全新会话中往往会重复相同的默认假设或风格错误。通过将学到的知识外部化为带有严格优先级(新规则优先)的命令式版本化 JSON 规则集,代理能够保持针对特定用户和存储库的硬边界。
存储与配置
技能按优先级顺序在以下位置之一查找规则文件:
.agents/autofix.jsonautofix.json(位于工作区根目录).rules/autofix.json
如果需要在上述位置添加新规则但文件不存在,则根据项目约定创建 .agents/autofix.json(或根目录的 autofix.json)。
规则模式
每条规则存储在一个 JSON 数组中,遵循以下模式:
[
{
"Rule_number": 1,
"Category": "CODE",
"Instruction": "永远不要为 React 组件使用默认导出——始终使用具名导出。",
"Why": "确保与代码库一致,简化重构。"
}
]
允许的类别
| 类别 | 描述 | 示例 |
|---|---|---|
[STYLE] | 代码格式化、命名约定、导入顺序、注释 | “始终对辅助函数使用 camelCase” |
[CODE] | 语言模式、库选择、类型定义、错误处理 | “永远不要在 TypeScript 中使用 any;使用带类型守卫的 unknown” |
[ARCH] | 目录结构、模块边界、架构层次 | “API 路由位于 src/server/routes/,而不是 src/api/” |
[TOOL] | CLI 命令、构建工具、包管理器、测试框架 | “始终使用 pnpm 而不是 npm 或 yarn” |
[PROCESS] | Git 工作流、提交信息、PR 要求、测试门 | “永远不要在提交信息中添加表情符号” |
[DATA] | 数据库模式、迁移、缓存策略、状态形状 | “始终在表中包含 created_at 和 updated_at 时间戳” |
[UX] | UI 行为、文案约定、可访问性标准 | “始终为纯图标按钮提供显式的 aria-label” |
[OTHER] | 一般项目或特定领域偏好 | “始终在 Markdown 表格中记录公共 API 端点” |
操作工作流
[会话开始 / 接收任务]
│
▼
┌───────────────────────────────┐
│ 1. 任务前扫描 │ ◄── 读取 autofix.json
│ - 加载所有规则 │
│ - 解决冲突(新规则优先) │
│ - 构建活动约束集 │
└───────────┬───────────────────┘
│
▼
┌───────────────────────────────┐
│ 2. 任务执行 │
│ - 应用约束 │
│ - 执行代码 / 编辑 │
└───────────┬───────────────────┘
│
├─────────────────────────────────────────┐
│ │
[无修正] [检测到触发器]
│ │
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ 任务完成 │ │ 3. 自我修复与捕获 │
│ 将输出交付给用户 │ │ - 构建命令式规则 │
└───────────────────────────────┘ │ - 追加至 autofix.json │
│ - 确认学习 │
└─────────────┬─────────────────┘
│
▼
┌───────────────────────────────┐
│ 4. 重新执行与修正 │
│ 修正当前任务输出 │
└───────────────────────────────┘
详细分步执行
1. 任务前扫描(执行任何操作之前)
在规划或修改任何任务中的文件之前:
- 定位并加载
autofix.json。 - 扫描规则:
- 检查是否有任何规则直接适用于当前提示中涉及的文件、工具或模式。
- 解决冲突:
- 如果两条规则给出相互矛盾的指导,则编号更高(更新)的规则优先。
- 保持约束激活:
- 将所有活动规则视为硬约束(相当于提示协约中的
CONSTRAINTS)。
- 将所有活动规则视为硬约束(相当于提示协约中的
2. 何时添加规则(触发条件)
出现以下任一情况时,立即触发规则捕获:
- 用户明确修正输出:例如“不,不要用 X,用 Y 来做”、“我们这里不用类组件”。
- 用户拒绝某个文件、方法或模式:例如“不要把测试文件放在源代码旁边”。
- 用户陈述个人/团队偏好:例如“始终将提交信息格式化为约定式提交”、“永远不要在文档中使用表情符号”。
- 由错误假设导致的 Bug:代理假设的库或文件位置导致失败。
- 用户运行
/learn或要求记住某条规则。
3. 追加新规则
当触发条件发生时,执行以下原子更新:
- 读取现有的
autofix.json数组。 - 确定下一个连续的
Rule_number:- 如果现有最高规则编号为 $N$,则新规则为 $N + 1$。
- 如果文件为空或新建,从
1开始。
- 格式化新规则对象:
- Rule_number:连续的整数。
- Category:标准类别之一(
STYLE、CODE、ARCH、TOOL、PROCESS、DATA、UX、OTHER)。 - Instruction:采用严格的命令式格式:
“永远/始终 做 X - 因为 Y。” - Why:简短原因(例如“用户偏好”、“代码库模式”、“框架限制”)。
- 将规则追加到 JSON 数组中,并以 2 空格缩进格式保存文件。
- 永远不要删除现有规则。如果旧规则被替代,则编写新规则,使其更高的编号优先。
- 简短通知用户:
“已学习规则 #
<N>([CATEGORY]):<Instruction>— 已记录至autofix.json。”
4. 示例规则文件(autofix.json)
[
{
"Rule_number": 1,
"Category": "PROCESS",
"Instruction": "永远不要在提交信息中添加表情符号——保持提交标题为纯约定式提交。",
"Why": "用户偏好"
},
{
"Rule_number": 2,
"Category": "ARCH",
"Instruction": "始终将 API 路由处理器放在 'src/server/routes/' 中,绝不放于 'src/api/'——保持后端架构一致。",
"Why": "现有代码库模式"
},
{
"Rule_number": 3,
"Category": "CODE",
"Instruction": "始终对所有外部入口点使用 Zod schema 进行输入验证——防止无类型的运行时输入。",
"Why": "防止运行时错误并强制类型"
}
]
最佳实践与边界情况
- 原子 JSON 写入:始终解析现有 JSON 数组,追加新对象,然后写回有效的 JSON。切勿以未转义的文本破坏文件。
- 具体且命令式:编写其他 AI 能够无歧义遵循的规则。避免模糊的建议如“编写干净的代码”;优先使用“始终在
.types.ts文件中与组件实现一起导出类型”。 - 无无限循环:记录规则时,不要为规则文件本身触发单独的自我修复循环。
- 替代规则:如果规则 1 说“使用 Axios”,而用户后来指示“全部迁移到 Fetch”,则添加规则 4 “始终使用原生 Fetch 代替 Axios”,其中
Why: "用户要求迁移到原生 Fetch(替代规则 1)"。