免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

让 AI 真正「记住」一切!深度拆解 Clawdbot 的本地记忆系统

发布日期:2026-01-29 18:49:48 浏览次数: 1531
作者:Draco正在VibeCoding

微信搜一搜,关注“Draco正在VibeCoding”

推荐语

Clawdbot的本地记忆系统让AI真正实现个性化,彻底摆脱云端限制,打造完全属于你的智能助手。

核心内容:
1. Clawdbot本地记忆系统的独特优势与工作原理
2. 上下文与记忆的关键区别及实现方式
3. 开源特性带来的透明可控与隐私保护

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

 

Clawdbot 如何记住一切:本地记忆系统全拆解

原文:How Clawdbot Remembers Everything 
作者:Manthan Gupta


封面
封面

Clawdbot (译者记:由于Anthropic寄了律师函,已经被迫改名为Moltbot了)是由 Peter Steinberger 创建的开源个人 AI 助手(MIT 许可),在撰写本文时,它在 GitHub 上已获得超过 32,600 颗星(译者记:现在已经8.3万星了)。与运行在云端的 ChatGPT 或 Claude 不同,Clawdbot 在你的本地机器上运行,并与你已经使用的聊天平台集成,比如 Discord、WhatsApp、Telegram 等。

Clawdbot Became Moltbot… What Changed?

让 Clawdbot 与众不同的是它能够自主处理现实世界的任务:管理邮件、安排日历事件、办理航班值机,以及按计划运行后台任务。但真正吸引我的是它的持久记忆系统(persistent memory system),能够 24/7 保持上下文留存(context retention),记住对话并无限期地在过往交互基础上延展。

如果你读过我之前关于 ChatGPT 记忆 和 Claude 记忆 的文章,你会知道我对不同 AI 产品如何处理记忆非常着迷。Clawdbot 采用了截然不同的方法:不是基于云端、由公司控制的记忆,而是把一切都保存在本地,让用户完整拥有自己的上下文和技能。

让我们深入看看它如何运作。


如何构建上下文(How Context is Built)

在深入记忆之前,先看看模型在每次请求中看到什么:

AgentS.md、SOUL.md 等)
[2] 对话历史(Conversation History)(消息、工具调用、压缩摘要)
[3] 当前消息(Current Message)" data-show-line-number="false" style='box-sizing: border-box;margin: 0px;padding: 0.5em 1em 1em;border: 0px solid rgb(229, 229, 229);outline-color: oklab(0.144521 0.00000657141 0.00000288337 / 0.5);font-family: "Fira Code", Menlo, "Operator Mono", Consolas, Monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;border-radius: 4px;display: -webkit-box;overflow-x: auto;text-indent: 0px;color: inherit;background: none;white-space: nowrap;'>[0] 系统提示词(System Prompt)(静态 + 条件指令)
[1] 项目上下文(Project Context)(引导文件: AGENTS.md、SOUL.md 等)
[2] 对话历史(Conversation History)(消息、工具调用、压缩摘要)
[3] 当前消息(Current Message)

系统提示词定义了代理的能力和可用工具。与记忆相关的部分是项目上下文,它包含了会被注入到每次请求中的、用户可编辑的 Markdown 文件:

项目上下文示例
项目上下文示例

这些文件与记忆文件一起存放在代理的工作区中,使整个代理配置透明且可编辑。


上下文 vs 记忆(Context vs Memory)

理解上下文(context)与记忆(memory)的区别,是理解 Clawdbot 的基础。

上下文是模型在一次请求中看到的全部内容:

Context = System Prompt + Conversation History + Tool Results + Attachments

上下文是:

  • • 短暂(Ephemeral)- 仅存在于本次请求
  • • 有界(Bounded)- 受模型上下文窗口限制(例如 200K tokens)
  • • 昂贵(Expensive)- 每个 token 都计入 API 成本和速度

记忆是存储在磁盘上的内容:

Memory = MEMORY.md + memory/*.md + Session Transcripts

记忆是:

  • • 持久(Persistent)- 可跨重启、跨天、跨月
  • • 无界(Unbounded)- 可无限增长
  • • 便宜(Cheap)- 存储不产生 API 成本
  • • 可检索(Searchable)- 为语义检索建立索引

记忆工具(The Memory Tools)

代理通过两个专门工具访问记忆:

1. memory_search

用途:在所有文件中查找相关记忆

{
  "name"
: "memory_search",
  "description"
: "Mandatory recall step: semantically search MEMORY.md + memory/*.md before answering questions about prior work, decisions, dates, people, preferences, or todos",
  "parameters"
: {
    "query"
: "What did we decide about the API?",
    "maxResults"
: 6,
    "minScore"
: 0.35
  }

}

返回

{
  "results"
: [
    {

      "path"
: "memory/2026-01-20.md",
      "startLine"
: 45,
      "endLine"
: 52,
      "score"
: 0.87,
      "snippet"
: "## API Discussion\nDecided to use REST over GraphQL for simplicity...",
      "source"
: "memory"
    }

  ]
,
  "provider"
: "openai",
  "model"
: "text-embedding-3-small"
}

2. memory_get

用途:在 memory_search 之后读取具体内容

{
  "name"
: "memory_get",
  "description"
: "Read specific lines from a memory file after memory_search",
  "parameters"
: {
    "path"
: "memory/2026-01-20.md",
    "from"
: 45,
    "lines"
: 15
  }

}

返回

{
  "path"
: "memory/2026-01-20.md",
  "text"
: "## API Discussion\n\nMet with the team to discuss API architecture.\n\n### Decision\nWe chose REST over GraphQL for the following reasons:\n1. Simpler to implement\n2. Better caching\n3. Team familiarity\n\n### Endpoints\n- GET /users\n- POST /auth/login\n- GET /projects/:id"
}

写入记忆(Writing to Memory)

没有专用的 memory_write 工具。代理会使用标准的 write 和 edit 工具将内容写入记忆文件,就像处理任何文件一样。由于记忆本质上是 Markdown,你也可以手动编辑这些文件(它们会自动重新索引)。

到哪里由 AGENTS.md 的提示驱动:

AGENTS.md 配置
AGENTS.md 配置

自动写入也会在预压缩刷新和会话结束时发生(后文会介绍)。


记忆存储(Memory Storage)

Clawdbot 的记忆系统建立在一个原则之上:"记忆就是代理工作区里的纯 Markdown"

双层记忆系统(Two-Layer Memory System)

记忆位于代理的工作区(默认:~/clawd/):

~/clawd/
├── MEMORY.md              - Layer 2: 长期整理的知识
└── memory/
    ├── 2026-01-26.md      - Layer 1: 今天的笔记
    ├── 2026-01-25.md      - 昨天的笔记
    ├── 2026-01-24.md      - ...以此类推
    └── ...

层 1:每日日志 (memory/YYYY-MM-DD.md)

这些是追加式的每日笔记,代理会在一天中持续写入。当代理想记住某些事,或被明确要求记住某些事时,它就会写在这里。

# 2026-01-26

## 10:30 AM - API 讨论

与用户讨论 REST vs GraphQL。决定:使用 REST 以简化实现。
关键端点:/users、/auth、/projects。

## 2:15 PM - 部署

将 v2.3.0 部署到生产环境。无问题。

## 4:00 PM - 用户偏好

用户提到比起 JavaScript 更喜欢 TypeScript。

层 2:长期记忆 (MEMORY.md)

这是整理过的、持久的知识。代理会在学到重要事件、观点、决策、意见和经验时写到这里。

# 长期记忆

## 用户偏好

-
 比起 JavaScript 更喜欢 TypeScript
-
 喜欢简洁的解释
-
 正在开发 "Acme Dashboard" 项目

## 重要决策

-
 2026-01-15:选择 PostgreSQL 作为数据库
-
 2026-01-20:采用 REST 而非 GraphQL
-
 2026-01-26:使用 Tailwind CSS 进行样式设计

## 关键联系人

-
 Alice (alice@acme.com) - 设计负责人
-
 Bob (bob@acme.com) - 后端工程师

代理如何知道要读取记忆(How the Agent Knows to Read Memory)

AGENTS.md 文件(会自动加载)包含如下指令:

## 每次会话

在做任何其他事情之前:
1.
 读取 SOUL.md - 这定义了你是谁
2.
 读取 USER.md - 这定义了你在帮助谁
3.
 读取 memory/YYYY-MM-DD.md(今天和昨天)以获取最近上下文
4.
 如果在主会话(与人类的直接聊天)中,也要读取 MEMORY.md

不要请求许可,直接执行。

记忆如何被索引(How Memory Gets Indexed)

当你保存一份记忆文件时,背后会发生这些步骤:

┌─────────────────────────────────────────────────────────────┐
│  1. 文件已保存                                               │
│     ~/clawd/memory/2026-01-26.md                            │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  2. 文件监控器检测到变化                                     │
│     Chokidar 监控 MEMORY.md + memory/**/*.md                │
│     防抖 1.5 秒以批量处理快速写入                            │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  3. 分块(Chunking)                                         │
│     分割为约 400 token 的块,重叠 80 token                   │
│                                                             │
│     ┌────────────────┐                                      │
│     │ 块 1           │                                      │
│     │ 行 1-15        │──────┐                               │
│     └────────────────┘      │                               │
│     ┌────────────────┐      │ (80 token 重叠)               │
│     │ 块 2           │◄─────┘                               │
│     │ 行 12-28       │──────┐                               │
│     └────────────────┘      │                               │
│     ┌────────────────┐      │                               │
│     │ 块 3           │◄─────┘                               │
│     │ 行 25-40       │                                      │
│     └────────────────┘                                      │
│                                                             │
│     为什么是 400/80?平衡语义连贯性与粒度。                  │
│     重叠确保跨越块边界的事实被两者捕获。两个值都可配置。      │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  4. 嵌入(Embedding)                                        │
│     每个块 -> 嵌入提供商 -> 向量                            │
│                                                             │
│     "讨论了 REST vs GraphQL" ->                             │
│         OpenAI/Gemini/本地 ->                               │
│         [0.12, -0.34, 0.56, ...]  (1536 维)                 │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  5. 存储                                                     │
│     ~/.clawdbot/memory/<agentId>.sqlite                     │
│                                                             │
│     表:                                                     │
│     - chunks (id, path, start_line, end_line, text, hash)   │
│     - chunks_vec (id, embedding)      -> sqlite-vec         │
│     - chunks_fts (text)               -> FTS5 全文          │
│     - embedding_cache (hash, vector)  -> 避免重新嵌入       │
└─────────────────────────────────────────────────────────────┘

sqlite-vec 是一个 SQLite 扩展,允许在 SQLite 内直接进行向量相似度搜索,无需外部向量数据库。

FTS5 是 SQLite 内置的全文搜索引擎,为 BM25 关键词匹配提供支持。两者结合,使 Clawdbot 能在单一轻量数据库文件中运行混合搜索(语义 + 关键词)。


记忆如何被搜索(How Memory is Searched)

当你搜索记忆时,Clawdbot 会并行运行两种搜索策略。向量搜索(vector search)用于语义匹配,BM25 搜索用于关键词匹配。

结果会用加权评分组合:

finalScore = (0.7 * vectorScore) + (0.3 * textScore)

为什么是 70/30?语义相似度是记忆召回的主要信号,但 BM25 关键词匹配能捕捉向量可能错过的精确术语(名称、ID、日期)。低于 minScore 阈值(默认 0.35)的结果会被过滤。所有这些值都可配置。

这保证了你无论是搜索概念("那个数据库的事")还是具体细节("POSTGRES_URL")都能得到好结果。


多代理记忆(Multi-Agent Memory)

Clawdbot 支持多代理(multi-agent),每个代理的记忆完全隔离

~/.clawdbot/memory/              # 状态目录(索引)
├── main.sqlite                  # "main" 代理的向量索引
└── work.sqlite                  # "work" 代理的向量索引

~/clawd/                         # "main" 代理工作区(源文件)
├── MEMORY.md
└── memory/
    └── 2026-01-26.md

~/clawd-work/                    # "work" 代理工作区(源文件)
├── MEMORY.md
└── memory/
    └── 2026-01-26.md

这些 Markdown 文件(真实来源)位于各自工作区,而 SQLite 索引(派生数据)位于状态目录。记忆管理器以 agentId + workspaceDir 为键,因此不会自动跨代理搜索。

代理能读取彼此的记忆吗?

默认不行。每个代理只看到自己的工作区。不过,工作区是软沙箱(默认工作目录),不是硬边界。代理理论上可以用绝对路径访问另一个工作区,除非你启用严格沙箱。

这种隔离有助于区分上下文。例如,用于 WhatsApp 的"个人"代理和用于 Slack 的"工作"代理,各自有独立的记忆与人格。


压缩(Compaction)

每个 AI 模型都有上下文窗口上限。Claude 为 200K tokens,GPT-5.1 为 1M。长对话最终会触及这个上限。

发生这种情况时,Clawdbot 会使用压缩(compaction):把更早的对话总结为紧凑摘要,同时保留最近消息。

┌─────────────────────────────────────────────────────────────┐
│  压缩前                                                     │
│  上下文:180,000 / 200,000 tokens                           │
│                                                             │
│  [回合 1] 用户:"让我们构建一个 API"                        │
│  [回合 2] 代理:"当然!你需要哪些端点?"                     │
│  [回合 3] 用户:"用户和认证"                                 │
│  [回合 4] 代理:*创建 500 行 schema*                        │
│  [回合 5] 用户:"添加限流"                                   │
│  [回合 6] 代理:*修改代码*                                  │
│  ...(100 个更多回合)...                                   │
│  [回合 150] 用户:"状态如何?"                              │
│                                                             │
│  ⚠️ 接近限制                                               │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  触发压缩                                                   │
│                                                             │
│  1. 将回合 1-140 总结为紧凑摘要                             │
│  2. 保持回合 141-150 完整(最近上下文)                     │
│  3. 将摘要持久化到 JSONL 记录文件                           │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  压缩后                                                     │
│  上下文:45,000 / 200,000 tokens                            │
│                                                             │
│  [摘要] "构建了带有 /users、/auth 端点的 REST API。          │
│   实现了 JWT 认证、限流(100 次/分钟)、                     │
│   PostgreSQL 数据库。部署到 staging v2.4.0。                 │
│   当前重点:生产部署准备。"                                  │
│                                                             │
│  [回合 141-150 保持原样]                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

自动 vs 手动压缩

自动:接近上下文上限时触发

  • • 你会看到:🧹 Auto-compaction complete(在详细模式下)
  • • 原始请求会在压缩后的上下文中重试

手动:使用 /compact 命令

`/compact`

关注决策与未决问题

与一些优化不同,压缩会持久化到磁盘。摘要写入会话的 JSONL transcript 文件,因此未来会话会从压缩后的历史开始。


记忆刷新(The Memory Flush)

基于 LLM 的压缩是有损的。重要信息可能被总结掉并丢失。为了解决这个问题,Clawdbot 使用预压缩记忆刷新

┌─────────────────────────────────────────────────────────────┐
│  上下文接近限制                                             │
│                                                             │
│  ████████████████████████████░░░░░░░░  75% 的上下文         │
│                              ↑                              │
│                    超过软阈值                               │
│                    (contextWindow - reserve - softThreshold)│
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  静默记忆刷新回合                                           │
│                                                             │
│  系统:"预压缩记忆刷新。现在存储持久记忆                      │
│        (使用 memory/YYYY-MM-DD.md)。                       │
│        如果没有要存储的,回复 NO_REPLY。"                    │
│                                                             │
│  代理:审查对话中的关键信息                                  │
│        将关键决策/事实写入记忆文件                           │
│        -> NO_REPLY(用户什么都看不到)                      │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  压缩安全进行                                               │
│                                                             │
│  重要信息现在已在磁盘上                                     │
│  压缩可以继续而不会丢失知识                                 │
└─────────────────────────────────────────────────────────────┘

记忆刷新可以在 clawdbot.yaml 或 clawdbot.json 文件中配置。

agents:
  defaults:

    compaction:

      reserveTokensFloor:
 20000
      memoryFlush:

        enabled:
 true
        softThresholdTokens:
 4000
        systemPrompt:
 "会话接近压缩。现在存储持久记忆。"
        prompt:
 "将持久笔记写入 memory/YYYY-MM-DD.md;如果没有要存储的,回复 NO_REPLY。"

剪枝(Pruning)

工具结果可能非常大。一次 exec 命令可能输出 50,000 个字符的日志。剪枝会修剪这些旧输出而不重写历史。这是有损过程,旧输出无法恢复。

┌─────────────────────────────────────────────────────────────┐
│  剪枝前(内存中)                                           │
│                                                             │
│  工具结果(exec):[50,000 字符的 npm install 输出]          │
│  工具结果(read):[大型配置文件,10,000 字符]               │
│  工具结果(exec):[构建日志,30,000 字符]                   │
│  用户:"构建成功了吗?"                                     │
└─────────────────────────────────────────────────────────────┘

▼(软修剪 + 硬清除)
┌─────────────────────────────────────────────────────────────┐
│  剪枝后(发送到模型)                                       │
│                                                             │
│  工具结果(exec):"npm WARN deprecated...[已截断]          │
│                       ...Successfully installed."           │
│  工具结果(read):"[旧工具结果内容已清除]"                  │
│  工具结果(exec):[保留 - 太近未剪枝]                       │
│  用户:"构建成功了吗?"                                     │
└─────────────────────────────────────────────────────────────┘

磁盘上的 JSONL 文件:未改变(完整输出仍在)

缓存 TTL 剪枝(Cache-TTL Pruning)

Anthropic 会缓存提示词前缀最多 5 分钟,以降低重复调用的延迟和成本。在 TTL 窗口内发送相同提示词前缀时,缓存 token 的成本约低 90%。TTL 过期后,下一个请求需要重新缓存整个对话历史,成本回到完整的"缓存写入"价格。

问题在于:如果会话空闲超过 TTL,下一次请求就会失去缓存,需要以全价重新缓存完整对话历史。

缓存 TTL 剪枝通过检测缓存是否过期,并在下一次请求前裁剪旧工具结果,来降低重缓存成本:更小的提示词意味着更低成本。

agent:
  contextPruning:

    mode:
 "cache-ttl"      # 仅在缓存过期后剪枝
    ttl:
 "600"              # 匹配你的 cacheControlTtl
    keepLastAssistants:
 3   # 保护最近的工具结果
    softTrim:

      maxChars:
 4000
      headChars:
 1500
      tailChars:
 1500
    hardClear:

      enabled:
 true
      placeholder:
 "[旧工具结果内容已清除]"

会话生命周期(Session Lifecycle)

会话不会永远存在。它们会基于可配置规则重置,从而形成自然边界。默认行为是每天重置,但也有其他模式可选。

会话生命周期图
会话生命周期图

会话记忆钩子(Session Memory Hook)

当你运行 /new 启动新会话时,会话记忆钩子可以自动保存上下文:

/new


┌─────────────────────────────────────────────────────────────┐
│  会话记忆钩子已触发                                         │
│                                                             │
│  1. 从结束的会话中提取最后 15 条消息                        │
│  2. 通过 LLM 生成描述性 slug                               │
│  3. 保存到 ~/clawd/memory/2026-01-26-api-design.md         │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  新会话开始                                                 │
│                                                             │
│  之前的上下文现在可以通过 memory_search 搜索                │
└─────────────────────────────────────────────────────────────┘

结论(Conclusion)

Clawdbot 的记忆系统之所以成功,是因为它遵循了几个关键原则:

1. 透明胜过黑盒(Transparency Over Black Boxes)

记忆是纯 Markdown。你可以阅读、编辑、版本控制它。不需要不透明的数据库或专有格式。

2. 搜索胜过注入(Search Over Injection)

不是把所有上下文都塞进去,而是搜索真正相关的内容。这让上下文更聚焦,成本更低。

3. 持久胜过会话(Persistence Over Session)

重要信息存于磁盘文件,而不只是对话历史里。压缩也无法摧毁已保存的内容。

4. 混合胜过纯粹(Hybrid Over Pure)

单纯向量搜索会遗漏精确匹配,单纯关键词搜索会错过语义。混合两者兼得。


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询