资讯动态

Claude Code 源码分析(五):分层记忆体系 —— AI Agent 的知识持久化架构与 TaoToken 统一接入实践

发布时间:2026/10/18 11:00:22 来源:尧图企业网站定制
1. 从一次上下文丢失说起分层记忆体系到底解决什么问题如果你用 Claude Code 写过稍大一点的项目大概率遇到过这种场景上午跟它聊清楚了整个模块的目录结构和命名约定下午新开一个会话它又像失忆一样问你「这个项目用什么框架」。这不是模型变笨了而是单次会话的上下文窗口天然有边界——一旦触发压缩早期对话就被摘要甚至丢弃跨会话更是完全从零开始。Claude Code 的分层记忆体系本质上就是给 AI Agent 装了一套「分时间尺度的记忆系统」。我把它类比成人的记忆会话内记忆像工作记忆处理当前手头的事跨会话记忆像长期记忆沉淀项目级知识Agent 级记忆像专业技能记忆让不同角色的 Agent 各自积累领域经验。三者协作才让 Agent 从「一次性问答工具」变成「越用越懂你项目的协作伙伴」。这套架构在源码里对应几个核心目录src/services/SessionMemory/负责会话内记忆的提取与管理src/services/extractMemories/负责跨会话知识提取src/tools/AgentTool/agentMemory.ts和agentMemorySnapshot.ts负责 Agent 级记忆的目录管理与快照同步。理解它们的分工是你在自己项目里落地知识持久化架构的第一步。本文面向正在构建 AI Agent 的 TypeScript 开发者会从源码机制讲到可复制的配置片段并演示如何通过 TaoToken 统一接入通道把记忆模块接进实际工作流。你不需要读完整个 Claude Code 源码但需要有一点 Agent 循环和上下文管理的概念。2. 三层记忆的源码拆解SessionMemory、extractMemories 与 agentMemory2.1 会话内记忆基于活动量的增量提取src/services/SessionMemory/目录下有三个文件核心逻辑围绕「什么时候提取」和「提取到哪」展开。提取时机由shouldExtractMemory(messages)判断它内部会调用countToolCallsSince(messages, lastMessageId)统计自上次总结以来的工具调用次数。这种基于活动量的触发机制很关键——太频繁会浪费 API 调用太稀疏又会丢失重要信息。并发控制是另一个容易被忽略的细节。markExtractionStarted()和markExtractionCompleted()配合一把锁防止两次提取同时跑waitForSessionMemoryExtraction()则让后续操作能等待提取完成确保读到最新记忆状态。我在自己项目里复刻这套逻辑时踩过的坑是没加等待结果压缩线程读到了半截记忆文件导致摘要错乱。位置追踪靠getLastSummarizedMessageId()和setLastSummarizedMessageId(id)这对函数。它记录「上次总结到哪条消息」让增量提取不重复处理。注意一个关键点当对话被压缩后这个标记会被重置为undefined因为旧消息的 UUID 已经不存在了。这个重置逻辑在autoCompact.ts里通过setLastSummarizedMessageId(undefined)完成。记忆大小分析由analyzeSectionSizes(content)和generateSectionReminders(sizes)负责。前者把记忆文件按 section 统计字符数后者在某个 section 过大时生成优化建议。这防止了记忆文件无限膨胀——毕竟记忆不是越多越好冗余信息反而会稀释有效上下文。2.2 跨会话记忆CLAUDE.md 的沉淀机制src/services/extractMemories/负责把对话中可复用的知识提取出来持久化到CLAUDE.md。你可以把CLAUDE.md理解成项目级的「AI 说明书」——类似.editorconfig或.eslintrc但存的是 AI 助手需要了解的项目知识编码规范、架构决策、常用命令、目录约定。提取发生在会话结束时或用户显式触发时提取出的知识被追加到CLAUDE.md。这里有个设计取舍值得学习它不做全量重写而是增量追加避免覆盖用户手写的记忆内容。如果你自己实现建议给每条记忆加上时间戳和来源标记方便后续清理过期知识。2.3 Agent 级记忆目录隔离与快照同步agentMemory.ts为每个 Agent 类型维护独立记忆目录。sanitizeAgentTypeForPath(agentType)把 Agent 类型名转成安全的文件系统路径比如把code-reviewer里的特殊字符处理掉getAgentMemoryDir(agentType, scope)返回具体目录isAgentMemoryPath(absolutePath)则用于权限检查——Agent 对自己的记忆目录有特殊读写权限这个判断在权限系统里很关键。agentMemorySnapshot.ts实现了快照与同步。getSnapshotDirForAgent、getSnapshotJsonPath、getSyncedJsonPath分别定位快照目录、快照 JSON 和同步后的 JSONcopySnapshotToLocal(agentType)把共享快照复制到本地让 Agent 在离线环境也能访问记忆。这套机制支持记忆的版本管理和跨作用域同步适合多 Agent 协作场景。2.4 记忆与压缩的协同src/services/compact/sessionMemoryCompact.ts实现了基于会话记忆的压缩策略。当上下文需要压缩时系统优先尝试「记忆压缩」——把对话关键信息提取为记忆再用记忆替代原始对话。这比简单截断保留了更多有价值信息。配置通过setSessionMemoryCompactConfig、getSessionMemoryCompactConfig、initSessionMemoryCompactConfig三个函数管理。2.5 记忆在 Agent 派生中的传递当 Agent 加载记忆时会记录遥测事件tengu_agent_memory_loaded带上agent_type、scope、source字段。不同类型的 Agent 对CLAUDE.md需求不同比如EXPLORE_AGENT设置了omitClaudeMd: true——它是快速只读搜索代理不需要了解编码规范主 Agent 会基于它的结果做判断。嵌套记忆去重靠ToolUseContext里的loadedNestedMemoryPaths: Setstring。源码注释提到readFileState是 LRU 缓存繁忙会话中会驱逐条目导致readFileState.has()检查失效同一个CLAUDE.md可能被注入数十次。独立去重集合解决了这个问题——这个坑我在自研 Agent 时也遇到过症状是 token 消耗莫名飙升。3. 用 TaoToken 统一接入可复制的分层记忆配置片段理解了机制接下来落地。Claude Code 本身通过 Anthropic 官方通道调用模型但在自研 Agent 或需要统一管理多个模型通道时用 TaoToken 做统一接入会更省心——一个 Key 走通对话、编码、Agent 工作流Base URL 和 Model ID 集中配置。先拿 Key访问https://taotoken.net/api-keys带 UTM?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建 API Key。然后按你的工具形态选配置方式。方式一Claude Code 的 settings.json如果你在 Claude Code 里接入编辑~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }三件套齐全Base URL 指向https://taotoken.net/apiKey 用刚创建的Model ID 按需替换。方式二Codex 的 auth.json如果你用 Codex 形态编辑~/.codex/auth.json{ OPENAI_BASE_URL: https://taotoken.net/api, OPENAI_API_KEY: sk-你的TaoToken密钥, model: gpt-4o }方式三Cline MCP 配置在 Cline 的 MCP 设置里填{ mcpServers: { taotoken: { command: npx, args: [-y, taotoken/mcp-server], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-你的TaoToken密钥, TAOTOKEN_MODEL: claude-sonnet-4-20250514 } } } }记忆模块的接入点配置好通道后把记忆模块挂到 Agent 循环里。核心是在每轮对话结束后调用提取逻辑伪代码import { shouldExtractMemory, waitForSessionMemoryExtraction } from ./services/SessionMemory; async function onTurnEnd(messages: Message[]) { if (shouldExtractMemory(messages)) { await waitForSessionMemoryExtraction(); await extractToClaudeMd(messages); } }extractToClaudeMd内部走 TaoToken 通道调用模型做知识提取把结果追加到项目根目录的CLAUDE.md。这样下次会话启动时Agent 读取CLAUDE.md就恢复了项目级记忆。4. 验证请求确认记忆模块真的在工作配置完别急着跑业务先做三步验证。第一步验证通道连通用 curl 打一次对话接口curl https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoToken密钥 \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 回复 OK}] }返回里能看到content数组和usage字段说明通道正常。如果返回 401检查 Key 是否复制完整。第二步验证记忆提取触发在 Agent 里连续调用几次工具比如读文件、搜索观察是否触发shouldExtractMemory。你可以在提取函数里加日志console.log([memory] extract triggered, toolCalls, countToolCallsSince(messages, lastId));看到日志输出且CLAUDE.md有新内容追加说明会话内记忆在工作。第三步验证跨会话恢复关掉会话重新启动让 Agent 读取CLAUDE.md。问它一个只有记忆里才有的项目细节比如「这个项目的测试命令是什么」。如果它能答出来跨会话记忆就通了。成功结果长这样CLAUDE.md里出现结构化的 section比如## 编码规范、## 常用命令新会话启动时日志显示tengu_agent_memory_loadedtoken 消耗没有因为重复注入CLAUDE.md而异常飙升。5. 常见报错排查401、local proxy failed 与 reading choices401 Unauthorized最常见。原因通常是 Key 没带对前缀或者ANTHROPIC_AUTH_TOKEN和ANTHROPIC_API_KEY混用。Claude Code 读的是ANTHROPIC_AUTH_TOKENCodex 读的是OPENAI_API_KEY别填错字段。另外确认 Base URL 是https://taotoken.net/api不要多加/v1后缀导致路径重复。local proxy failed这个报错通常出现在本地代理层。检查你的settings.json里 Base URL 是否被其他工具覆盖或者环境变量里有残留的旧地址。清理掉ANTHROPIC_BASE_URL的环境变量只保留配置文件里的设置。reading choices 报错如果你用的是 OpenAI 兼容格式返回体里应该有choices数组。报reading choices说明返回结构不对多半是 Model ID 填错了——比如把 Anthropic 的模型名填到了 OpenAI 格式的请求里。对照三件套检查Base URL、Key、Model ID 是否匹配你选的接口形态。OAuth 相关报错Claude Code 某些版本会走 OAuth 流程如果你用 API Key 接入需要在配置里显式关闭 OAuth。检查settings.json里是否有forceLoginMethod之类的字段设成apiKey模式。记忆重复注入导致 token 飙升症状是每轮对话 token 消耗异常高。检查loadedNestedMemoryPaths去重集合是否生效。如果你自己实现确保在ToolUseContext里维护这个 Set并且在读取CLAUDE.md前先has()判断。记忆文件膨胀如果CLAUDE.md越来越大检查analyzeSectionSizes和generateSectionReminders是否在跑。可以设一个阈值比如单个 section 超过 2000 字符就触发清理建议。6. 把记忆接进你的 Agent 工作流分层记忆体系的价值不在于单点技术而在于三个时间尺度的协同会话内记忆保证压缩不丢关键信息跨会话记忆让项目知识持续积累Agent 级记忆让专业角色各自成长。源码里的并发锁、位置追踪、去重集合这些细节都是踩过坑之后沉淀下来的工程经验。如果你要长期跑编码 Agent 或构建多 Agent 协作系统建议用 TaoToken 的 Coding Plan 统一管理通道把 Base URL、Key、Model ID 集中配置记忆模块只管调用不用关心底层走哪个模型。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite里面有各形态的完整配置示例。最后给一个实用技巧记忆提取的 prompt 模板别写太泛明确告诉模型「只提取可跨会话复用的项目知识忽略一次性调试细节」。我试过把模板收紧之后CLAUDE.md的信噪比明显提升Agent 恢复上下文时也更快进入状态。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑