让AI代理告别金鱼记忆:三档文件系统实现低成本、高可用的长期记忆

你有没有试过养一群“金鱼型”AI代理?
它们每天准时上线,干活利索,报告漂亮——但一到第二天,就彻底失忆:
– 昨天被坑过的 bounty 平台,今天又踩一遍;
– 上周注册过的空投钱包,这周还要你手输地址;
– 写了 20 篇技术文章,却从不记得哪类标题点击率翻倍……

这不是 AI 不行,而是它默认「没脑子」——没有持久记忆,每次启动都是全新出厂。

别急着上向量数据库、RAG 或语义搜索。
这篇讲的,是一个用纯文本文件 + 3 个文件夹 + 3 条铁律就能落地的实战方案,
连刚学完 fs.appendFile 的前端同学,1 小时就能搭起来。


🧠 人类怎么记事儿?AI 就怎么记

我们没用复杂模型,只照搬人脑记忆分层逻辑:

  • 短时记忆(HEARTBEAT.md):像贴在显示器上的便利贴,只记「此刻正在干啥」,上限 50 行,任务结束自动清空;
  • 中期记忆(memory/2026-04-08.md):像每日手账,每个代理当天干了啥、踩了啥坑、赚了多少钱,全按日期存成独立 .md 文件;
  • 长期记忆(MEMORY.md):像老师傅的笔记本,只收真正有用的「经验」——比如「Galxe 项目要抢在截止前 2 小时提交」「Zora 空投必须用主网交易」,每周人工整理一次,严格控在 500 行内。

✅ 关键不是“存得多”,而是“挑得准”。
❌ 别让 AI 自己总结“教训”——它真会写出:“完成任务很重要”这种废话。


📁 文件结构:简单到不像话

/workspace/
├── MEMORY.md              # 长期记忆(人工维护,≤500行)
├── HEARTBEAT.md           # 短时状态(自动清理,≤50行)
├── memory/                # 中期日志(每天一个文件,30天后自动删)
│   ├── 2026-04-01.md
│   ├── 2026-04-02.md
│   └── ...
├── reports/               # 各代理输出报告(不参与记忆)
└── articles/              # 内容产出(不参与记忆)

💡 为什么不用一个大文件?四个理由够硬核:

  • 你说“查查上周二 bounty-hunter 干了啥”,grep -r "bounty-hunter.*2026-04-02" memory/ 一秒出结果;
  • 想删旧数据?find memory/ -mtime +30 -delete 一行命令搞定;
  • 六个代理同时写日志?各自 append 同一天的文件,零锁冲突;
  • 新人接手项目?打开 MEMORY.md,5 分钟看懂团队核心规则和雷区。

🛠️ 代码怎么写?三段真·能跑的 Node.js 示例(带中文注释)

① 代理写今日日志(追加模式,安全不覆盖)

// 代理运行结束后,自动记一笔到当天日志
async function writeDailyLog(agentName, content) {
  const today = new Date().toISOString().split('T')[0]; // 格式:2026-04-08
  const logPath = `/workspace/memory/${today}.md`;

  const timeCN = new Date().toLocaleTimeString('zh-CN', { 
    timeZone: 'Asia/Shanghai',
    hour: '2-digit', 
    minute: '2-digit' 
  });

  // 拼接成标准格式:### bounty-hunter (10:23)\n- 提交了3个任务...\n\n
  const entry = `### ${agentName} (${timeCN})\n${content}\n\n`;

  await fs.appendFile(logPath, entry, 'utf-8');
}

② 启动时读取记忆(优先级:长期 > 近3天日志 > 当前心跳)

// 每个代理启动第一件事:加载上下文
async function initializeAgent() {
  // 1. 长期记忆(必读,500行以内,稳定可靠)
  const longTerm = await fs.readFile('MEMORY.md', 'utf-8');

  // 2. 近3天日志(最多读3个文件,避免爆内存)
  const recentLogs = [];
  for (let i = 0; i < 3; i++) {
    const date = new Date(Date.now() - i * 24 * 60 * 60 * 1000);
    const dateStr = date.toISOString().split('T')[0];
    try {
      const log = await fs.readFile(`memory/${dateStr}.md`, 'utf-8');
      recentLogs.push(log);
    } catch (e) {
      // 文件不存在?跳过,不报错
    }
  }

  // 3. 当前心跳(如果存在,否则留空)
  let heartbeat = '';
  try {
    heartbeat = await fs.readFile('HEARTBEAT.md', 'utf-8');
  } catch (e) {}

  return {
    longTermMemory: longTerm,
    recentLogs: recentLogs.join('\n'), // 合并成一段供 LLM 读取
    heartbeatState: heartbeat,
  };
}

③ 周五下午手动更新长期记忆(这才是灵魂!)

// 每周日花 15 分钟,把本周日志里的干货抄进 MEMORY.md
async function updateLongTermMemory(lesson, category) {
  const memoryPath = '/workspace/MEMORY.md';
  const content = await fs.readFile(memoryPath, 'utf-8');

  // 如果分类不存在,先加个标题
  const header = `## ${category}`;
  if (!content.includes(header)) {
    await fs.appendFile(memoryPath, `\n${header}\n\n`);
  }

  // 追加具体经验(带短横线,保持格式统一)
  await fs.appendFile(memoryPath, `- ${lesson}\n`);
}

📈 效果立竿见影:从“人工客服”变“老员工”

场景 加入记忆前 加入记忆后
bounty-hunter 每天重试已失败的 scam 项目 自动跳过黑名单平台(BounceBit)
airdrop-hunter 反复问“我上次用的哪个钱包?” 查 MEMORY.md → 直接填 Zora 主网地址
hunter-content 文章标题全靠猜 读到“Lessons from X Trades 标题点击率+100%”,立刻复刻

更实在的是——
以前每天花 30 分钟给代理“讲背景”,现在省下时间喝咖啡;
每月 Token 成本约 ¥9,换来的是 人力成本直降 ¥450+


⚠️ 什么情况别硬套这套?(避坑指南)

  • 你的代理只做一件事(比如每天备份服务器),那真不需要记忆;
  • 你设计的就是“每次重启都清零”,比如风控扫描器,那就别加;
  • 你没法坚持每周花 15 分钟整理 MEMORY.md——那日志只会变成垃圾山;
  • 你要存 API Key、私钥、身份证号?千万别放这里! 用专门的 secrets manager。

✅ 最后说一句大实话

这套系统的技术含量,可能还没你写的第一个 fetch 请求高。
真正的门槛是:
– 愿意每周亲手整理一次 MEMORY.md
– 敢删掉 30 天前的日志(哪怕“总觉得以后有用”);
– 强制自己和代理都守规矩:HEARTBEAT.md 超 50 行?先删旧的,再写新的。

当你的 AI 开始说:“哦,这个我们上周试过,失败因为……”,
你就知道——它终于不是工具,而是队友了。

直达网址:https://github.com/openclaw/workspace

作加

类似文章