找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2319

积分

0

好友

298

主题
发表于 2 小时前 | 查看: 1| 回复: 0

Milvus ——全球领先的向量数据库

最近一段时间,OpenClaw的热度有目共睹。它不仅能够自主执行任务,调用系统权限,更重要的是,它能记住历史会话和用户偏好,这背后依赖的是一套精心设计的记忆系统。那么,这套被誉为“全量记忆”的系统究竟是如何工作的?它为何能被视为构建AI智能体记忆的参考模板?一位科技博主Manthan Gupta对其进行了逆向工程,本文将对其核心逻辑进行解读。

上下文和记忆,不是一回事

要理解OpenClaw的记忆,首先得厘清两个容易混淆的概念:上下文(Context)和记忆(Memory)。

上下文是指每次向OpenClaw发起请求时,它能接收到的所有信息总和。它的特点是临时性(仅限当前对话有效)、有上限(受模型上下文窗口限制)且成本较高(消耗API费用)。

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

具体而言,上下文主要包括四个部分:静态与条件化的系统提示词、来自 AGENTS.mdSOUL.md 等引导文件的项目上下文、过往的对话历史(包含消息、工具调用记录及其压缩摘要),以及用户当前发送的消息。

其中,AGENTS.md 定义了智能体的指令和记忆使用规则,SOUL.md 设定了其性格与语气,USER.md 记录了用户相关信息,TOOLS.md 则是外部工具的使用指南。这些文件与记忆文件一同存储,配置透明,可随时修改。

记忆,则是持久化存储在你本地磁盘中的数据。它是 MEMORY.md 文件、memory 文件夹中的所有 .md 文件,以及会话转录文件的总和。

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

记忆的优势恰恰与上下文互补:

  • 持久化:无论重启设备还是时隔多日,记忆都不会丢失。
  • 无上限:只要本地存储空间足够,即可近乎无限扩展。
  • 低成本:本地存储不产生任何API费用。
  • 快速检索:系统会为记忆建立索引,需要时能迅速定位历史内容。

OpenClaw如何打造agent记忆?

OpenClaw依靠两个专用工具来访问记忆库:memory_search 负责查找,memory_get 负责读取。

首先看 memory_search 工具。在回答关于过往工作、决策、日期、人物、偏好或待办事项的问题前,它会对 MEMORY.mdmemory/*.md 文件进行语义检索。

该工具的调用参数示例如下:

{
  "name": "memory_search",
  "description": "必选的记忆调取步骤:回答关于过往工作、决策、日期、人物、偏好或待办事项的问题前,先对MEMORY.md和memory/*.md文件进行语义检索",
  "parameters": {
    "query": "我们关于API的决策是什么?",
    "maxResults": 6,
    "minScore": 0.35
  }
}

例如,当你询问“我们之前关于 API 的决策是什么”,它会返回最多6条相关结果,并过滤掉匹配度低于0.35的内容。返回结果示例如下:

{
  "results": [
    {
      "path": "memory/2026-01-20.md",
      "startLine": 45,
      "endLine": 52,
      "score": 0.87,
      "snippet": "## API讨论\n为追求简洁性,决定采用REST而非GraphQL...",
      "source": "memory"
    }
  ],
  "provider": "openai",
  "model": "text-embedding-3-small"
}

第二个工具是 memory_get,它在 memory_search 之后使用。当你通过检索获得相关文件的路径后,可以用此工具精准读取文件中的指定行。

示例如下:

{
  "name": "memory_get",
  "description": "执行memory_search后,读取记忆文件的指定内容行",
  "parameters": {
    "path": "memory/2026-01-20.md",
    "from": 45,
    "lines": 15
  }
}

返回:

{
  "path": "memory/2026-01-20.md",
  "text": "## API讨论\n\n团队讨论了API架构设计方案。\n\n### 最终决策\n基于以下原因,选择REST而非GraphQL:\n1. 实现难度更低\n2. 缓存效果更优\n3. 团队对其更熟悉\n\n### 接口列表\n- GET /users\n- POST /auth/login\n- GET /projects/:id"
}

你可能会问,有读取和查找,写入是如何处理的呢?OpenClaw并没有设计专用的 memory_write 工具,而是直接利用智能体自带的、用于文件操作的标准 writeedit 工具来完成记忆写入。这种设计让系统更轻量,也让用户手动操作更便捷。

所有记忆都以 Markdown 格式存储在本地文件中。除了智能体自动写入,你也可以直接手动编辑这些 .md 文件。只要文件被修改并保存,系统就会自动为新内容重建索引,确保后续能被正常检索。

智能体的写入行为由 AGENTS.md 中的提示词规则驱动,形成了清晰的写入规则:

  • 日常笔记、临时记录:写入 memory/YYYY-MM-DD.md 按日归档。
  • 长期有效的事实、个人偏好、关键决策:写入 MEMORY.md 作为核心知识库。
  • 经验总结、工具实操技巧:写入 AGENTS.mdTOOLS.md,使记忆与能力配置紧密结合。

此外,系统还会在对话历史压缩前的记忆刷写阶段会话正式结束时这两个关键节点自动执行记忆写入,以避免关键信息因对话结束或压缩而丢失。

记忆怎么存?本地双层存储

在OpenClaw的记忆系统中,所有记忆都存储在本地智能体的工作目录中,默认路径是 ~/clawd/。整个架构分为两层:第一层是日常日志,第二层是长期记忆。

目录结构如下:

~/clawd/
├── MEMORY.md              - 第二层:经整理的长期知识库
└── memory/
    ├── 2026-01-26.md      - 第一层:今日笔记
    ├── 2026-01-25.md      - 第一层:昨日笔记
    ├── 2026-01-24.md      - 第一层:往期笔记
    └── ...

日常日志存储在 memory 文件夹中,按日期命名。日常聊天中需要记录的内容会实时写入当天的日志;若你明确指示“记住这件事”,它也会立刻写入该文件。

# 2026-01-26
## 上午10:30 - API讨论
与用户探讨了REST和GraphQL的选型,最终决定:为追求简洁性,采用REST方案。
核心接口:/users、/auth、/projects。
## 下午14:15 - 版本部署
将v2.3.0版本部署至生产环境,全程无异常。
## 下午16:00 - 用户偏好
用户表示相比JavaScript,更倾向使用TypeScript。

内容灵活,按时间线记录,一目了然。

长期记忆则存储在 MEMORY.md 文件中,这是经过OpenClaw整理后的核心知识库。这一层并非事无巨细,只保留重要内容,如用户的长期偏好、关键决策、核心联系人、进行中的项目等。

# 长期记忆
## 用户偏好
- 编程语言:更倾向TypeScript(而非JavaScript)
- 内容需求:喜欢简洁的解释说明
- 正在推进的项目:Acme数据看板
## 重要决策
- 2026-01-15:数据库选用milvus
- 2026-01-20:API架构采用REST而非GraphQL
- 2026-01-26:样式开发使用Tailwind CSS
## 核心联系人
- 艾丽斯(alice@xxx.com):设计负责人
- 鲍勃(bob@xxx.com):后端工程师

例如,你偏好TypeScript、选用Milvus数据库等关键信息都会被整理至此,无论何时,OpenClaw都能快速调取。

关键一环:agent怎么记起内容

你可能好奇,OpenClaw每次对话如何知道该调取哪些记忆?答案是:它有一套固定的记忆读取规则,并搭配了自动的索引构建机制

记忆读取规则存储在自动加载的 AGENTS.md 文件中,每次会话开始都会严格执行。示例如下:

每次会话的必做步骤
开始任何操作前,需完成以下步骤:
1. 读取SOUL.md文件——定义智能体的自身定位
2. 读取USER.md文件——明确服务的用户信息
3. 读取memory目录下今日和昨日的日志文件——获取近期上下文
4. 若为「主会话」(与用户的直接聊天),额外读取MEMORY.md——获取长期记忆
无需向用户申请权限,直接执行即可。

随着使用时间增长,记忆文件增多,检索会变慢。为此,Clawdbot 设计了自动索引构建功能。只要保存了任意记忆文件(无论是智能体自动写入还是手动编辑),系统都会在后台自动触发索引构建流程。

其流程大致为:使用 Chokidar 监控文件变化并设置防抖延迟;将文件内容分割成约400个token的文本块,相邻块保留80个token的重叠区域以保证语义连贯;接着,每个文本块通过嵌入(Embedding)模型转换为1536维的向量数据,最后存储到数据库中。

文本块1:第1-15行 → 与文本块2重叠80个token
文本块2:第12-28行 → 与文本块3重叠80个token
文本块3:第25-40行

数据库中包含存储文本块、向量数据、全文检索内容和向量缓存(用于避免生成重复向量)的核心表。检索时,系统会结合语义检索(向量检索)和关键词检索(BM25)两种方式,按7:3的权重计算最终得分。

最终得分 = 0.7 × 向量检索得分 + 0.3 × 关键词检索得分

这种混合检索方式,既能匹配语义相近的抽象内容(如“关于数据库的讨论”),又能精准捕捉人名、日期等具体信息。值得一提的是,在人工智能领域的RAG(检索增强生成)应用中,类似Milvus这样的向量数据库原生支持混合检索,可以简化这一流程。

如何做多智能体记忆的隔离与管理

OpenClaw支持创建多个智能体(例如,个人智能体对接WhatsApp,工作智能体对接Slack)。用户无需担心记忆混淆,因为每个智能体都有自己专属的工作目录,记忆源文件(.md文件)存储在各目的目录中;而索引文件则统一存放在状态目录里,并用智能体ID区分。

具体的隔离结构示例如下:

~/.clawdbot/memory/              # 索引存储目录
├── main.sqlite                  # 「主智能体」的向量索引
└── work.sqlite                  # 「工作智能体」的向量索引
~/clawd/                         # 「主智能体」的工作目录(记忆源文件)
├── MEMORY.md
└── memory/
    └── 2026-01-26.md
~/clawd-work/                    # 「工作智能体」的工作目录(记忆源文件)
├── MEMORY.md
└── memory/
    └── 2026-01-26.md

默认情况下,每个智能体只能访问自己的记忆,无法读取其他智能体的内容,除非未开启严格沙箱模式。

历史信息过多时,如何管理?

所有大语言模型都有上下文窗口限制。对此,OpenClaw启动了对话历史压缩功能,并搭配了记忆刷写机制。

压缩的逻辑是:将早期的对话总结成简洁摘要,完整保留近期的约10轮对话,然后将摘要存入本地会话转录文件。这能大幅减少上下文占用,例如从18万token压缩至4.5万token。

压缩分自动和手动两种:自动压缩在上下文接近窗口限制时触发;手动压缩可使用 /compact 命令,并可自定义摘要重点。

但压缩是有损操作,可能导致重要信息丢失。为解决此问题,OpenClaw设计了记忆刷写机制——在压缩触发前,先将关键信息存入记忆文件。

当上下文占用达到模型窗口的75%左右时,系统会指示智能体将需要长期保留的内容写入当天的记忆文件;若无内容可存,则回复 NO_REPLY。此过程对用户透明,待关键信息保存后,再执行压缩。

记忆刷写的参数可在 clawdbot.json 配置文件中自定义:

{
  "agents": {
    "defaults": {
      "compaction": {
        "reserveTokensFloor": 20000,
        "memoryFlush": {
          "enabled": true,
          "softThresholdTokens": 4000,
          "systemPrompt": "会话即将触发压缩,请立即存储需要长期保留的记忆。",
          "prompt": "将需要长期记录的内容写入memory/YYYY-MM-DD.md,若无相关内容,回复NO_REPLY。"
        }
      }
    }
  }
}

冗余信息太多,如何裁剪

除了对话历史,工具执行结果也可能包含大量冗余信息(例如长达数万字符的安装日志)。OpenClaw的内容裁剪功能会对此进行处理:对历史工具执行结果进行精简(如截断冗长日志,只保留关键部分);对更早的结果则直接清空,仅保留占位符。需注意,此裁剪仅作用于传递给模型的上下文,磁盘中的完整结果不受影响,后续仍可通过记忆检索找到。

此外,为配合部分模型服务商的提示词前缀缓存机制(缓存有效期通常为5分钟),Clawdbot的裁剪逻辑还会进行优化。系统检测到缓存过期后,会在后续请求前自动修剪旧的工具执行结果,通过减小提示词体积来降低重新缓存的token成本。

核心裁剪配置示例如下:

{
  "agent": {
    "contextPruning": {
      "mode": "cache-ttl",      // 仅在缓存过期后执行裁剪
      "ttl": "600",              // 与模型的缓存有效期保持一致(单位:秒)
      "keepLastAssistants": 3,  // 保留最近3次智能体的工具执行结果
      "softTrim": {
        "maxChars": 4000,
        "headChars": 1500,
        "tailChars": 1500
      },
      "hardClear": {
        "enabled": true,
        "placeholder": "[旧工具执行结果已清空]"
      }
    }
  }
}

总结

至此,相信你已经理解了OpenClaw全量记忆系统的实现逻辑。这套提供7×24小时持久记忆与全量检索的系统,其最高原则是用户可控,主要体现在四个方面:

  1. 透明化:所有记忆均为纯Markdown文件,可见、可编辑,无隐藏存储。
  2. 检索优先:不将所有记忆塞入上下文,而是通过检索获取相关内容,聚焦且节省成本。
  3. 持久化:重要信息存储于本地磁盘,不因对话压缩或会话结束而丢失。
  4. 混合检索:结合语义与关键词检索,兼顾精准度与灵活性。

如果你对AI记忆机制或部署OpenClaw感兴趣,不妨访问其GitHub仓库亲身体验。对于这类结合了本地存储、智能体与复杂检索逻辑的开源项目,在云栈社区这样的开发者平台上,往往能找到更多深入的实战讨论和配置心得。




上一篇:查询扩展实战:LLM改写、HyDE、子问题分解如何解决RAG语义搜索难题
下一篇:理解MMU与虚拟内存:优化程序性能、规避内存错误的关键机制
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-10 04:49 , Processed in 0.331476 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表