AI记忆插件测评:改善AI遗忘与日常小问题的高效工具
Wingman:AI Agent 长期记忆与数据对接助手
长期使用AI编程辅助后,代码生成效率确实显著提升,但实际工作量并未减少。AI时常会错误修改已有逻辑,某些约定需要反复重申。当项目迭代加速时,历史决策的溯源变得极为困难。为解决这些痛点,我们开发了Wingman——一个专注于上下文记忆与接口契约对齐的Agent插件。
Wingman目前提供以下核心能力模块:
1. Memory:长期记忆管理
AI长期使用中常遇到的记忆力短板包括:
- 一个月前的任务细节难以通过对话记录快速检索。
- 已在其他模块正确实现的逻辑,在新场景下重复时出现错误。
- 项目内已有的类似组件或工具函数被AI重复创建。
- 历史决策动机无人能够追溯。
- 近期强调过的规则需要反复重申。
为此我们设计了Memory系统,将项目中稳定的规则、工作上下文和历史决策分别持久化存储。
启用配置:
/memory-setup
执行后会在仓库根目录创建 .wingman 文件夹,用于存放记忆数据。
在进行重大改动前,可调用加载记忆指令使Agent感知项目上下文:
/memory-load 搜索下这个模块之前的逻辑,当时为什么要这么写
完成重要变更后,执行同步指令以更新记忆:
/memory-sync 整理下对话,更新记忆
初始化后,/memory-load 和 /memory-sync 可自动触发,记忆文件同步更新,无需人工干预。需确保对话在Agent环境中运行,手动调用skill可增加可靠性。
示例说明:
/memory-setup
会创建以下目录结构:
.wingman/memory/
brief.md
context.md
brief.md 内容大致如下:
# 记忆简报 (Memory Brief)## 0. 记忆设置 (Memory Settings)
- **语言 (Language)**: `zh-CN`## 1. 架构决策 (ADR - 全局规则)
> 记录影响整个项目的全局规则。每条规则必须包含 `[WHY]`(原因)。## 2. 领域注册表 (Domain Registry)
| 领域 (Domain) | 何时读取 (Read When) | 当前文件 (Current File) | 历史记录 (History) | 别名 (Aliases) | 相关领域 (Related Domains) | 状态 (Status) |
| --- | --- | --- | --- | --- | --- | --- |## 3. 记忆布局 (Memory Layout)
- `brief.md`: 全局规则、架构决策(ADRs)、记忆设置以及领域注册表。
- `context.md`: 当前任务、待办工作以及近期的高价值日志。
- `domains/`: 当前持久化的领域真相,按需创建。
- `history/`: 建立索引的事件历史,按需创建,默认不读取。## 4. 权威顺位 (Authority Order)
当前规则会覆盖历史事件(优先级从高到低):1. `brief.md`:全局规则和当前的架构决策(ADRs)。
2. `domains/`:当前的领域真相。
3. `context.md`:热点工作上下文。
4. `history/`:历史事件和审计轨迹。
context.md 内容大致如下:
# 记忆上下文 (Memory Context)## 待办任务 (Pending Tasks)
- [ ] 待计划## 当前工作 (Current Work)
- 暂无。---
## 近期日志 (Recent Logs)
### [Init] Wingman 记忆已启用
- **目标 (Goal)**: 启用仓库级别的 Wingman 记忆,以便 AI 智能体在工作前加载当前项目上下文,并在工作后同步重要的产出。
- **核心文件 (Core Files)**:
- `.wingman/memory/brief.md`: 存储全局 ADRs、记忆设置和领域注册表。
- `.wingman/memory/context.md`: 存储短期进度、待办任务和近期工作上下文。
- **备注 (Notes)**: `domains/` 和 `history/` 仅在出现持久化的领域真相或历史事件时才会创建。
memory-sync 会持久化什么
例如,当团队确认了一条业务规则:
订单列表里不能用 payment_status 推导 order.status。
`status` 表示订单生命周期,`payment_status` 只表示支付状态。
开发者可指示Agent同步该规则:
/memory-sync 订单列表里不能用 payment_status 推导 order.status。
`status` 表示订单生命周期,`payment_status` 只表示支付状态。
若该规则具有长期性,Wingman将自动创建领域文件:
.wingman/memory/domains/order.md
内容类似:
# 订单领域 (Order Domain)## 何时读取此领域 (When To Read This Domain)
- 修改订单列表、订单详情、订单状态展示、支付状态展示时
- 对接订单 API、订单 DTO、订单前端 ViewModel 时## 当前真相 (Current Truths)
- 绝不能将 `Order.status` 和 `Order.payment_status` 互相替代使用。[WHY]:`status` 描述的是订单生命周期,而 `payment_status` 描述的是支付结算状态。
- **证据 (Evidence)**: 在对接订单列表时确认的 API 契约决策
- **适用场景 (Applies When)**: 未来将订单 API 数据映射到 UI、领域模型、过滤器、徽章或工作流状态时
- **状态 (Status)**: `current` (现行有效)
- **起始时间 (Since)**: `2026-05-26`
- **替代 (Supersedes)**: `None` (无)
- **相关领域 (Related Domains)**: `payment` (支付)
- **历史记录 (History)**: `None` (无)
同时,brief.md 的领域注册表(Domain Registry)会新增一行,帮助后续Agent判断何时加载该领域规则:
| Order | 订单 API, 订单列表, 订单详情, 状态映射 | domains/order.md | None | 订单, order status | payment | current |
如果本次改动对后续会话同样有价值,context.md 还可能追加一条近期日志:
### [2026-05-26] 订单 API 状态契约已对齐
- **目标 (Goal)**: 保持订单生命周期状态和支付结算状态之间的语义独立性。
- **核心文件 (Core Files)**:
- `src/features/orders/orderMapper.ts`: 集中处理 API DTO 到订单视图模型的映射,并保持 `status` 与 `paymentStatus` 的分离。
- `src/features/orders/OrderStatusBadge.tsx`: 仅读取生命周期状态,不再通过支付状态推导订单状态。
- **备注 (Notes)**: 未来涉及订单 UI 的工作,在修改状态映射前,都应先读取 `.wingman/memory/domains/order.md`。
2. align-contracts:数据对接
align-contracts 最初是为了约束AI在对接后端API字段时避免随意修改命名。随后我们将这一理念扩展至任何系统间的数据交换场景,定义了AI在处理接口映射时的标准做法。
常见问题场景:
前端开发阶段使用 userName 等字段,当AI对接真实后端接口后,为了将后端字段(如 user_name、image)映射到UI组件期望的格式,生成了大量无意义的转换代码。AI无法判断前期代码处于调试阶段,因此不会主动修改原有组件接口。例如:
// 数据源:[{ id: 1, user_name: "Alex", image: "xxxxx" }, ...]
export function UserList({ userListApiData }) {
return (
{userListApiData.map((user) => {
// 在 map 内部执行 Scenario A:轻量级解构映射
const {
id,
user_name: userName,
image: img
} = user;
return (
-
{userName}
{img}
);
})}
);
}
现有UI组件 ProductCard 原本期望传入 title、img 和 points。但新的API返回的却是 product_name、image_url,并且有时会缺失 price 字段。
// 错误的做法:
// 父组件 (Parent Component)
export function ProductList({ apiData }) {
return (
{apiData.map(item => (
))}
);
}
// 正确的做法:
// 子组件:ProductCard.tsx
// 动作 1 直接修改组件的 Interface,拥抱后端的命名
interface ProductCardProps {
product_name: string; // 以前叫 title,现在直接叫 product_name
image_url: string; // 以前叫 img,现在直接叫 image_url
price?: number; // 打上问号,承认后端有时候会不传这个字段
}
// 组件入参直接使用后端字段
export function ProductCard({ product_name, image_url, price }: ProductCardProps) {
// 动作 2 遇到没传 price 时,别报错,给个默认值 0,并留下 FIXME 证据
const displayPrice = price ?? 0; // TODO: Field [price] missing in API
return (
{product_name}
价格: ${displayPrice}
);
}
// 改完之后的父组件 (Parent Component)
export function ProductList({ apiData }) {
return (
{apiData.map(item => (
// 完美:没有任何翻译代码,直接把后端的一整条数据扔进去!
))}
);
}
AI在对接接口时错误地修改了UI样式——这完全偏离了预期。
其他高级用法目前功能尚不稳定,可通过 /using-wingman 命令查看当前可用技能。
安装指南
由于Cursor和Codex均未开放官方插件市场(Codex甚至没有插件入口),目前仅支持手动安装。
Codex用户可使用以下脚本安装:
curl -fsSLO
bash install-codex-wingman.sh --self-delete
安装完成后重启Codex生效。
Cursor用户只需在Agent对话窗口中输入以下指令即可快速安装:
/add-plugin wingman@
项目仓库与反馈
Wingman目前仍处于早期迭代阶段,我们会根据实际使用体验持续改进。诚邀开发者提供使用反馈,协助完善边缘场景,共同推动项目成熟。
