AB
AiBoss
Tutorials

用 Markdown 文件核查 AnyModelBot 的长期记忆:定位、读取与 journal 审计

Tutorials

用 Markdown 文件核查 AnyModelBot 的长期记忆:定位、读取与 journal 审计

AnyModelBot 把智能体的长期记忆存成磁盘上的普通 Markdown 文件,而不是藏在向量库里。这篇教程讲清 team / bot / group 三种记忆作用域的文件路径、MEMORY.md 与 topics 的结构、300 / 4000 / 16000 字符与 40 个主题的上限、写入前的密钥过滤、journal.jsonl 审计日志的字段与查询命令,并给出从建机器人到验证记忆落盘、验证密钥被拒、核对 journal 的完整流程。

AnyModelBot 是一个本地优先的智能体应用,可以跑在 Windows、macOS、Linux 上,也可以跑在 Docker 主机里。它和很多同类产品不一样的地方在于:长期记忆不是藏在向量数据库里,而是以普通 Markdown 文件的形式放在数据目录下。这意味着不用打开应用,用任何编辑器就能读、能改、能 diff、能备份。这篇教程只讲一件事——怎么自己打开这些文件,确认智能体到底记住了什么、什么时候记的、有没有把不该记的东西写进去。适合已经装好 AnyModelBot、想核对记忆内容或排查记忆问题的使用者。

需要先说明一点:AnyModelBot 本身不在本地跑大模型,推理需要网络。记忆文件在本地,但模型调用不是。所以「本地优先」指的是数据落在你自己的磁盘上,不是指离线可用。

准备工作

安装与启动方式

有两种方式可以跑起来,任选其一:

  • 从 Releases 下载桌面版安装包,按平台安装后启动。
  • 按 README 里的 Docker 步骤启动容器。容器内数据目录固定为 /data,通常挂一个名为 amb-data 之类的卷。

如果直接用源码跑(npm start),数据目录默认是当前工作目录下的 ./data,可以用环境变量 AMB_DATA_DIR 覆盖。

模型接入

启动后需要登录一次 Modelflare,或者直接填入自己的官方 API Key。走 Modelflare 时是一个账号调用 70 多个模型、按 token 计费;走自己的 Key 时请求直接发到对应厂商,不经过 Modelflare。具体可用模型、计费方式与额度以官网当前信息为准,本文不列具体数字。

数据目录在哪

记忆文件全部位于数据目录下的 memory/ 子目录。各运行方式对应的数据目录如下:

运行方式数据目录
桌面版 · Windows%APPDATA%\anymodel bot\data
桌面版 · macOS~/Library/Application Support/anymodel bot/data
桌面版 · Linux~/.config/anymodel bot/data
源码运行./data(可用 AMB_DATA_DIR 覆盖)
Docker 容器内/data

下文用 $DATA 代指你的数据目录,实际执行时替换成上表对应的路径。

你需要知道的三个作用域

记忆不是一个巨大的单文件,而是按作用域分开存放的。理解这三个作用域,是读懂目录结构的前提:

作用域含义数据目录下的路径
bot属于某一个机器人memory/bots/<botId>/
group应用内的机器人分组共享memory/groups/<groupKey>/
team整个安装实例共享memory/team/

每个作用域内部结构相同:一个 MEMORY.md 放短条目和主题索引,一个 topics/ 目录放深入展开的主题笔记。记忆根目录下还有一个 journal.jsonl,记录每一次增删。

操作步骤

第一步:列出记忆目录

先确认目录结构和你预期一致。Linux 桌面版示例:

ls -R ~/.config/anymodel\ bot/data/memory

macOS 示例:

ls -R "$HOME/Library/Application Support/anymodel bot/data/memory"

已经在 Docker 里跑的情况:

docker exec amb ls -R /data/memory

这里假设容器名为 amb,按你自己的容器名替换。

第二步:读 MEMORY.md

MEMORY.md 是每个作用域的入口文件,里面是短条目加一个主题索引。典型内容长这样:

# 机器人
- 偏好简短回答 [source: chat; added: 2026-11-09]
- 日报每天 17:00 发出 [source: chat; added: 2026-11-09]

## Index
- [[project]] — 2 条

每条记忆后面都带着来源和添加日期,方便你判断这条信息是什么时候、通过什么渠道进来的。索引区列出的是主题名和条目数,主题正文不在这个文件里。

批量查看所有机器人的 MEMORY.md:

sed -n '1,80p' ~/.config/anymodel\ bot/data/memory/bots/*/MEMORY.md

Docker 下:

docker exec amb sh -c 'cat /data/memory/bots/*/MEMORY.md'

第三步:读主题笔记

当一个话题积累到需要展开时,内容会落到 topics/<topic>.md。主题名会经过 validTopic 规范化成小写、连字符分隔的形式;memory、index 这类保留名会被拒绝,不会成为主题文件名。

主题正文不会每次全部塞进提示词。智能体通过 remember、forget 和召回类工具按需读取,所以你在文件里看到的内容,不一定每一轮对话都进了模型上下文。

第四步:核对容量上限

源码里写死的上限是字符数,不是模糊的 token 估算。对照下表检查你的文件有没有接近上限:

对象常量上限
单条条目ENTRY_MAX300 字符
MEMORY.md 正文MEMORY_MAX4000 字符
单个主题文件TOPIC_MAX16000 字符
单个作用域的主题文件数TOPICS_MAX40 个

接近上限时,条目会被截断或写入失败,具体表现取决于调用路径。用 wc -m 可以快速量一下:

wc -m "$DATA/memory/bots/<botId>/MEMORY.md"
wc -m "$DATA/memory/bots/<botId>/topics/"*.md

第五步:验证密钥过滤

每次 remember 调用都会先跑一遍 looksSecret() 检查。它覆盖的模式包括:OpenAI 风格的 sk-…、GitHub token、AWS 的 AKIA…、Slack 的 xox…、Google 的 AIza…、Stripe 的 sk_live_… / rk_live_…、Hugging Face 的 hf_…、PEM 私钥、形似 JWT 的字符串,以及「密码是 …」这类措辞。

匹配到的一行不会被写入。注意这不是「加密后保存」,而是直接拒绝写入——设计上宁可失败,也不让记忆目录变成凭据保险箱。

验证方法:在对话里让机器人记住一个形似 sk- 开头的假字符串,然后回到 MEMORY.md 里找,应该找不到。这个模式列表并不完备,误报和漏报都是需要反馈的问题。

第六步:读 journal.jsonl

每一次成功的添加或删除,都会往 memory/journal.jsonl 追加一行 JSON。字段含义:

字段含义
atUnix 毫秒时间戳
scope作用域,如 team、bot:<id>、group:<key>
fileMEMORY 或主题名
opadd 或 remove
text条目正文
by触发来源,多数是 chat 或 tool

一行示例:

{"at":1731168000000,"scope":"bot:abc","file":"MEMORY","op":"add","text":"偏好简短回答","by":"chat"}

常用查询:

tail -n 50 "$DATA/memory/journal.jsonl"
grep '"file":"project"' "$DATA/memory/journal.jsonl"

Docker 下:

docker exec amb tail -n 20 /data/memory/journal.jsonl

这个日志是只追加的,没有轮转机制,长期使用后文件会变大,需要自己留意。

第七步:理解模型实际看到什么

记忆进入模型上下文有两条路径:

  • 快照:每段对话开始时,MemoryStore.snapshot() 按 team → bot → group 的顺序,把各作用域 MEMORY.md 里的短条目拼成一份冻结的 Markdown,同时列出主题名供按需召回。这个前缀的字节序列保持稳定,内容没变时能复用 prompt cache。
  • 召回与检索:主题正文不会每轮全量注入,而是由智能体调用 remember、forget 和召回类工具按需读取。

另外,通用的 bash 和文件工具看不到记忆目录,这是有意隔离的。

一个完整示例

下面从零走一遍,验证记忆确实落盘、密钥确实被拒、journal 确实有记录。以 Linux 桌面版为例。

1. 启动并登录

安装桌面版或按 README 的 Docker 步骤启动,登录一次 Modelflare,或填入自己的官方 API Key。

2. 建机器人

新建一个机器人,写一段简短的 persona,权限保持默认的 Workspace——它只能在自己的文件夹内写,越界需要审批。

3. 让它记住一条偏好

在对话里说「偏好简短回答」这类你确实希望保留的偏好,让它记住。

4. 确认落盘

ls -R ~/.config/anymodel\ bot/data/memory
sed -n '1,80p' ~/.config/anymodel\ bot/data/memory/bots/*/MEMORY.md

应该能在对应 bot 的 MEMORY.md 里看到那条条目,带 [source: chat; added: …] 标注。

5. 确认密钥被拒

再让它记住一个形似 sk- 开头的假字符串,然后重新读 MEMORY.md,这一行不应该出现。

6. 确认 journal 有记录

tail -n 20 ~/.config/anymodel\ bot/data/memory/journal.jsonl

应该能看到第 3 步那条 add 记录,scope 是 bot:<id>,by 是 chat。

7. 切换模型,确认作用域不变

在对话中用 /model 切换模型再切回来。记忆文件的路径和作用域不会因为换模型而改变——作用域是机器人和分组的概念,和模型厂商无关。

注意事项

文件权限与写入方式

文件以 0600 模式创建,目录是 0700。写入采用先写临时文件再 rename 的方式,避免留下写了一半的 Markdown。

删除行为

在应用内删除一个分组时,dropGroup 会删掉该分组的记忆目录。删除机器人时,它的对话也会一起消失。需要保留历史的话,记忆备份要自己做——这个产品不提供云端同步。

数据边界

留在本机的内容:对话(SQLite)、记忆文件、工作区、密钥。离开本机的内容:所选模型为了作答需要的东西,包括提示词、用到的记忆、文件、工具结果。本地控制台监听 127.0.0.1,桌面版每次启动会生成新的 UI token。开启电脑操作、让模型看屏幕时,截图也会离开本机。通过聊天渠道(如 WeChat、Feishu)收发的消息同样会离开本机。

经 Modelflare 的请求会在 Modelflare 侧留下请求日志;用官方 API Key 的调用直接发往对应厂商,不经过 Modelflare。图像和视频生成目前只走 Modelflare。

已知限制

  • 不是离线本地大模型,推理需要网络。
  • 不是密码管理器。看起来像密钥的字符串会被有意跳过,记忆目录不能当凭据库用。
  • 不是云同步产品。笔记本休眠时,定时规则不会执行。
  • 没有独立的移动端应用。手机侧是通过已有的聊天应用,和已经启动的桌面端或容器里的机器人对话。
  • 电脑操作使用内置的 Cua 驱动,在 macOS 上处于 Beta。
  • Feishu 渠道目前只支持私聊。
  • 不要把 3600 端口直接暴露到公网,这一点和 README 的提醒一致。

关于过滤器的反馈

密钥过滤的模式列表既不完整也可能误伤。误报(正常内容被拒)和漏报(密钥被写入)是两类不同的失败,反馈时最好分开描述,并给出可复现的最小输入,这样更容易定位。