Claude Code 干到一半,关掉会话,换 Codex 进同一个目录——新会话对昨天改过的接口、踩过的坑一无所知,ai-memory 就是冲这件事来的。它把会话归档成一份 Markdown 项目 wiki,自带的只读/web界面是整套系统里唯一不烧 Token 的入口。TaoToken 的 Key 和 Base URL 先在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=web_viewer 拿齐。
很多人在装完 ai-memory 之后,第一反应是把所有助手钩子接满、把所有 LLM 能力打开,结果发现账单在涨、页面在合并、矛盾检测在跑,自己却连项目里到底存了哪些记忆都没看过一眼。这其实是顺序装反了。ai-memory 的分层很清楚:采集与浏览是零成本的,只有摘要生成、页面合并、矛盾检测这些"写作"动作才会打模型 API。而/web这个只读界面,正好落在零成本那一侧。
下文按"先看、再配、后排障"的顺序走一遍:怎么把/web打开、项目树长什么样、全文检索和 Markdown 渲染各自能做到哪一步、TaoToken 的 Key 应该填进哪一层 provider、Codex 的config.toml和 Claude Code 的settings.json分别怎么写、以及摘要在哪一步才开始消耗 Token。
1. 只读 /web 是 ai-memory 唯一不烧 Token 的入口
先把 ai-memory 的能力拆成三层,后面所有配置都围绕这个分层展开。
第一层是采集层。会话里的提示词、工具调用、会话起止边界,由 native hook 在本地落进队列。这一步不需要任何模型,也不需要 API Key,纯本地字符串处理和路径规则判断。敏感内容在进入本地队列之前就被拦截掉,仓库内可以声明忽略规则让匹配路径的事件直接丢弃,也可以反过来配置成只在有标记的文件里采集。
第二层是索引与浏览层。采集到的观察会写进 SQLite,配合 FTS5 做全文检索,同时保留显式声明的实体和实体之间的图邻域。这一层同样不调模型,检索退化成关键词 + 实体匹配。/web就挂在这一层上,提供项目树浏览、全文检索和 Markdown 渲染三个只读视图。
第三层才是写作层。生成会话摘要、把零散页面合并成连贯条目、检测两条记忆之间是否矛盾、自动改进既有页面——这些动作需要模型参与,是 Token 真正被消耗的地方。不接 provider 的时候,摘要由规则生成,能力弱一点但流程能跑通;接入 provider 之后,这一层才被激活。
把这三层摆开,结论就很直接:你随便刷/web、随便全文检索、随便点开 wiki 页面看 Markdown,都不会产生任何模型调用。真正要花钱的是"会话结束时生成那段交接说明"和"后台把几天积累的碎片合并成页面"这两类批处理动作。
所以正确的接入节奏是:先把/web跑起来确认记忆确实在积累,再决定要不要给写作层接上模型。而不是反过来,一上来就把 LLM provider 配好,然后对着一个自己没看过的知识库付账单。
2. 把服务跑起来:/web 访问路径与项目树的一次实拍
ai-memory 本体是一个常驻服务,装好之后再把各个助手接上来。安装方式任选其一,零 LLM 模式下都不需要 API Key。
Docker 是最省事的路径。先把 CLI 包装脚本装到本机,它负责把HOME挂进容器,并在本机转发status、bootstrap这类命令。然后启动服务,默认只绑本地回环:
# 启动常驻服务,只监听 127.0.0.1,单用户笔记本上外部连不进来 docker run -d --name ai-memory \ --restart unless-stopped \ -p 127.0.0.1:8765:8765 \ -v "$HOME/.ai-memory:/data" \ -v "$PWD:/workspace" \ ai-memory:latest # 确认服务状态与真实监听端口(端口以这里的输出为准) ai-memory statusmacOS 走原生二进制。从 Releases 页下载ai-memory-macos-aarch64.tar.gz(Apple 芯片)或ai-memory-macos-x86_64.tar.gz,解压后把ai-memory放进PATH,然后初始化:
tar -xzf ai-memory-macos-aarch64.tar.gz sudo mv ai-memory /usr/local/bin/ ai-memory init ai-memory statusLinux / WSL2 同理。Arch 用户可以直接装 AUR 包;其他发行版下载ai-memory-linux-x86_64放到/usr/local/bin再初始化。Windows 目前建议走 WSL2 复用 Linux 路径,原生ai-memory.exe还在实验阶段。
访问/web。服务起来之后,浏览器打开:
http://127.0.0.1:8765/web端口号不要照抄,以ai-memory status打印的实际监听地址为准。如果你的 Docker 命令里绑的是别的宿主端口,就换成那个。
项目树一次实拍(文字版截图说明)。打开/web之后,左侧是一棵按项目分组的树。根节点是项目身份,每个项目按 git 仓库根映射到独立目录,用稳定的 UUID 做分组键——同一个仓库的不同 worktree 共享同一个项目身份,不会因为开了个新分支就分裂成两棵树。展开根节点,下面是 wiki 页面清单,每页对应一个 Markdown 文件:交接说明、会话摘要、决策页、项目规则页各自成节点,文件名带 git 版本号。右侧是页面正文区,Markdown 的标题层级、列表、代码块、表格都会渲染出来,链接可以点,不会给你看一堆裸语法。
一个容易被忽略的细节:重命名项目只涉及一条字段更新,删除项目直接rm -rf对应目录,不影响其他项目。这棵树的隔离粒度就是"一个 git 仓库",不是"一个用户"也不是"一台机器"。
3. 项目树、全文检索、Markdown 渲染:/web 里三件事的边界
/web是只读的,这一点必须先说清楚,否则很容易期待错方向。
它能做的三件事:
浏览项目树——看清这个项目里到底沉淀了哪些页、每页什么时候写的、最近一次改动是哪次会话带出来的。这是排查"记忆有没有在长"最直接的窗口。
全文检索——输入关键词,走 FTS5 加实体匹配,把相关的决策页、规则页、摘要页捞出来。检索是跨会话的,所以你能用"我们当时为什么选 Postgres"这种自然语言描述去查,而不需要记得当时那句话被存进了哪个文件。
Markdown 渲染——页面本身就是普通 Markdown,放进 git 仓库,能用grep直接搜、能拖进 Obsidian 当笔记看、能用rsync备份。/web只是给这些文件套了一层浏览器里的阅读视图,不改写内容。
它不能做的:
不能在/web里编辑记忆。想新增一条长期保留的笔记,正确做法是在会话里告诉助手"把这条记成项目规则",让它写一页带 git 版本号的 wiki 页,之后这条会一直出现在检索结果里,直到你主动修改。
不能在/web里触发摘要生成或页面合并。这些是写作层的动作,由会话结束钩子或后台流程触发,/web只负责展示结果。
检索排序的解释在哪看。每条结果为什么排在这个位置,是有依据的,但这个开关在 CLI 侧。用ai-memory search --help看当前版本的确切参数名,比照着一篇旧博客的参数硬敲要靠谱——这个项目的 CLI 还在快速迭代,参数名变动不算少见。
记忆是证据,不是指令。这点官方文档写得很直白:检索返回的页面内容不具备权威效力。它能告诉你"上次是怎么想的",但不能替代你读现在的代码、跑现在的测试。落地之前以当前代码库为准。比较稳的用法是把历史记忆和活的结构化代码工具放在一起用——LSP 告诉你符号现在定义在哪,记忆告诉你当初为什么这么定义,两者各管一段。
4. 摘要层才消耗 Token:TaoToken Key 填入 provider 的完整对照
现在进入真正要配 Key 的环节。再强调一次边界:这一节的配置只影响写作层,不影响/web浏览。如果你只是想先看看/web长什么样,这一节可以整段跳过,服务照样跑,采集照样进行,检索照样能用。
第一步,去官网拿 Key。打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=web_viewer ,在控制台里创建 API Key。创建好之后把 Key 存成环境变量,不要硬编码进配置文件:
export TAOTOKEN_API_KEY="YOUR_API_KEY"第二步,记住 Base URL。工具配置里填的是:
https://taotoken.net/api注意这个地址不要在后面拼 UTM 参数,UTM 是给网页链接用的,API 请求带上会污染签名和路由。
第三步,把 Key 填进 ai-memory 自己的 provider。ai-memory 的写作层要调模型,走的是它自己的 provider 配置。Docker 方式启动时直接追加环境变量:
docker run -d --name ai-memory \ --restart unless-stopped \ -p 127.0.0.1:8765:8765 \ -v "$HOME/.ai-memory:/data" \ -v "$PWD:/workspace" \ -e AI_MEMORY_LLM_PROVIDER=anthropic \ -e ANTHROPIC_BASE_URL=https://taotoken.net/api \ -e ANTHROPIC_API_KEY=YOUR_API_KEY \ ai-memory:latest原生二进制安装的话,把这几个变量写进 shell 的 profile 或者 systemd 的Environment=,重启服务后同样生效。
第四步,确认写作层真的被激活。跑一次会话,正常提问、正常调用工具,然后结束会话,回到/web看有没有新的交接说明页出现。出现了,说明摘要链路通了;没出现,先去看第 6 节的排障清单,不要急着改配置。
一个常见误区:把"浏览不耗 Token"和"接不接模型"混为一谈。不接 provider 时,钩子照常采集,检索退化成 FTS5 加显式实体与图邻域,摘要由规则生成。这套组合在只查历史决策、只看项目规则这两个场景下已经够用。什么时候必须接模型?当你要跨会话做页面合并、想让它自动发现两条记忆互相矛盾、或者希望摘要读起来像人写的段落而不是规则拼出来的条目——这时候再接。
5. Codex 的 config.toml 与 CC Switch 三件套:跨工具共用一份记忆
ai-memory 覆盖的工具已经不少:Claude Code、Codex、OpenCode、Cursor、Gemini CLI、Devin、Kiro、Grok Build CLI、Kimi Code,以及只走 MCP 的 Zed 和 VS Code Copilot。
这里要分清两套完全不同的配置:一套是 ai-memory 自己的 provider 配置(上一节),另一套是各个编程助手自己的模型供应商配置。两者互不相干,但都指向同一个 Base URL。别把 Claude Code 的ANTHROPIC_*变量抄到 Codex 的配置文件里,那样是不会生效的。
Claude Code 侧,用settings.json配。把供应商指向 TaoToken:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "<在 TaoToken 模型对话页选定的模型 id>" } }ANTHROPIC_AUTH_TOKEN和ANTHROPIC_API_KEY在不同版本里认的名字不完全一致,如果其中一个不生效,换成另一个再试。模型 id 别猜,去模型对话页复制。
Codex 侧,用config.toml配。注意这里不能用ANTHROPIC_*系列变量,Codex 走的是它自己的 provider 表:
model_provider = "taotoken" model = "<你选定的模型 id>" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api/v1" env_key = "TAOTOKEN_API_KEY"base_url具体要不要带/v1后缀,以你控制台里显示的调用地址为准,两种写法在不同版本里都出现过。env_key指向的是本地环境变量名,不是 Key 本身,所以先在 shell 里把TAOTOKEN_API_KEY导出去。
CC Switch 三件套。如果你同时在 Claude Code、Codex、Cursor 之间来回切,手动改配置文件会疯。CC Switch 这类切换器的作用就是把配置抽象成三个槽位,一次填好:
- 供应商槽:
base_url填https://taotoken.net/api,名称随便写,比如taotoken。 - 密钥槽:填
YOUR_API_KEY,对应到各工具时分别映射成ANTHROPIC_AUTH_TOKEN或TOKOKEN_API_KEY。 - 模型槽:填你在模型对话页选定的模型 id,Claude Code 和 Codex 可以各存一份。
三个槽位填完之后,切换工具只需要换当前激活的供应商条目,不用再动各个工具的原始配置文件。这样做的额外好处是:所有工具的模型调用都指向同一个 Base URL,配额和用量在一个地方看得清,不会出现"Claude Code 走 A 供应商、Codex 走 B 供应商、月底对不上账"的情况。
把助手接上 ai-memory。这一步和上面的模型配置无关,是让助手把会话写进记忆库。基本是两行命令的事,换工具时把 client / agent 名字换掉即可。接完之后正常开会话,每次提示和工具调用就会自动落进 ai-memory。
一个必须记住的例外:Codex、Grok 这类工具没有真正意义上的"会话结束"钩子,靠自动触发是收不了尾的。这类情况下手动跑一次ai-memory finalize-session,把这段会话封口,摘要才会进写作层的队列。
6. 排障清单:/web 打不开、项目树空、摘要有延迟
/web打不开。先看服务是不是真在跑:ai-memory status。再确认宿主端口映射和实际监听端口一致——Docker 命令里写了-p 127.0.0.1:8765:8765,浏览器就得开8765。如果是在远程机器上跑,绑回环意味着本机以外访问不到,这是刻意设计的默认值,不是 bug。
项目树是空的。三种可能。一是当前目录不在一个 git 仓库根下,ai-memory 按仓库根做项目映射,找不到 git 根就没有项目身份。二是助手钩子没接上,会话内容根本没进采集队列。三是接上了但会话里没有产生任何被收录的观察——检查一下仓库内的忽略规则有没有写得太宽,把所有路径都排除了。
有采集但没摘要。先确认会话是真的结束了。有钩子的工具会自己收尾,Codex、Grok 这类得手动ai-memory finalize-session。其次确认写作层是否激活:没配 provider 的时候摘要由规则生成,本来就不会出现"像人写的段落"那种效果,这是预期行为,不是坏了。
摘要生成报 401 / 403。九成是 Base URL 或 Key 的问题。检查三件事:ANTHROPIC_BASE_URL是不是https://taotoken.net/api、有没有误把 UTM 参数拼到 API 地址后面、YOUR_API_KEY有没有被 shell 转义吃掉。Docker 场景下还要确认-e传进去的变量在容器内可见。
/web里看到的和代码不一致。这是正常现象,不是 bug。记忆是历史快照,代码是当前事实。以代码为准,用记忆解释"当初为什么这么写"。
想给老项目补记忆。项目已经写了几个月才接进来,跑一次ai-memory bootstrap,它会读 git log、README、docs 和模块头,把既有历史总结成种子页面,后续会话在这个基础上继续累积。这一步会走一遍写作层,是少数几个"主动消耗 Token"的操作,心里有个数就行。
7. 一条最短可复现链路:bootstrap → 会话 → /web 复核
把上面的内容压成一条从零到跑通的路径,照着做一遍,半小时内应该能看到结果。
第 1 步,拿到 Key 和 Base URL。去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=web_viewer 创建 Key,记下 Base URLhttps://taotoken.net/api。这一步只做一次。
第 2 步,起服务。用第 2 节的 Docker 命令把 ai-memory 跑起来,先不加任何AI_MEMORY_LLM_PROVIDER环境变量。目的是先验证采集和浏览这条零成本链路是通的。
第 3 步,把助手接上。在你的主力工具里执行接入命令,client 名字换成你实际用的那个。然后正常开一个会话,随便问几个和项目相关的问题,让工具调用发生几次。
第 4 步,收口。有会话结束钩子的工具退出即可;没有的手动跑ai-memory finalize-session。
第 5 步,打开/web复核。访问http://127.0.0.1:8765/web,左侧项目树里应该出现你这个仓库对应的节点,展开后能看到刚生成的摘要页或交接说明页。点开一页,确认 Markdown 渲染正常、git 版本号在、内容没有把敏感路径写进去。
第 6 步,补历史(可选)。如果这是个有历史的项目,跑一次ai-memory bootstrap。
第 7 步,接写作层。到这一步再回到第 4 节,把 provider 环境变量加上,重启服务。之后新会话的摘要质量会明显不同——从规则拼接变成连贯段落,页面合并和矛盾检测也会开始工作。这一刻起,Token 开始被消耗,消耗方是摘要生成和页面合并,不是你刷/web这个动作。
第 8 步,把供应商配置统一。按第 5 节把 Claude Code 的settings.json、Codex 的config.toml、以及 CC Switch 的三件套都指向同一个 Base URL。这样无论你切到哪个助手,模型调用和记忆写入都走同一条链路,用量在控制台里是合并可见的。
8. 什么时候该把记忆接上 TaoToken
回到最开始那个问题:ai-memory 解决的是一件很实在的事——你在一个项目上花掉的上下文,不该因为关掉一个会话窗口就蒸发。它没把这件事包装成新概念,核心就是一句话:把每次会话整理成 Markdown,放进一个 git 仓库,下一个助手来取。
而/web是这个仓库的窗户。它的价值在于把"记忆到底长成什么样"这件事变成肉眼可见的:项目树告你有几页、全文检索告你能查到什么、Markdown 渲染告你写得清不清楚。这三件事全都不花 Token,所以没有任何理由不先打开看一眼。
真正需要想清楚的是写作层。什么时候值得为摘要和页面合并付费?大致是三种情况:你确实会在多个助手之间来回切换,交接说明的质量直接影响你重述背景的时间成本;项目跨度长,决策页积累到几十条之后人工已经理不清;团队里有人要接手,需要一份能 grep、能时间回溯、能审计的历史记录。
不满足这三条的时候,零 LLM 模式跑着就行,检索退化成 FTS5 加实体匹配,摘要由规则生成,流程照样闭环。
要付出的代价也得说清楚:得常驻一个服务、装几个钩子、给写作层配一次 Key。它不是装上就忘的工具,更像项目里多养了一个需要偶尔打理的小部件。值不值,取决于你打算在这个项目上待多久。
准备把写作层接起来的话,按顺序走这几步:先在 模型对话 里选定要用于摘要生成的模型,再去 Coding Plan 确认配额够不够页面合并这类批处理动作开销,然后到 API Keys 创建 Key 并替换掉配置里的YOUR_API_KEY,最后照着 Claude Code 文档 把settings.json和config.toml两套配置写完整。四步走完,/web负责看,写作层负责写,边界就清楚了。