让 Claude Code 拥有自我进化和记忆系统|得物技术

发布时间:2026/8/1 15:50:50
让 Claude Code 拥有自我进化和记忆系统|得物技术 一、背景每次打开 Claude Code 开始新对话它都是一张白纸。昨天你花了 10 分钟解释的项目架构、你反复纠正的代码风格偏好、你建立的特殊开发规范------全部归零。但是使用过 OpenClaw 和 Hermes 的同学都知道这 2 个 agent 具备持久化记忆系统这让我开始思考能不能给 Claude Code 装上一套长期记忆系统更进一步不只是被动记忆而是主动学习观察我的行为模式、项目架构提炼行为规律、项目知识下次自动应用。这就是本文要介绍的系统。二、系统架构总览整个系统由三个核心子系统构成行为观测层Observation Engine模式提炼层Instinct Engine记忆注入层Memory Engine通过各个子系统协作形成一个完整的自学习闭环三、行为观测层Observation Engine 通过 Hook 机制 100% 捕获每次工具调用写入 JSONL 观测流是整个系统的数据源。Hook 机制------确定性触发的关键早期版本用 Skill 来触发学习但 Skill 依赖模型主动调用触发率不稳定。v2 版本改用 Claude Code 原生 Hook 机制彻底解决了这个问题。Hook 是 Claude Code 在工具调用生命周期中的回调点可以通过 Claudecode CLI 执行 /hooks 命令获取。配置在 ~/.claude/settings.json{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: ~/.claude/hooks/observe.sh pre } ] } ], PostToolUse: [ { matcher: .*, hooks: [ { type: command, command: ~/.claude/hooks/observe.sh post } ] } ], Stop: [ { hooks: [ { type: command, command: ~/.claude/bin/auto-analyze-instincts.py ~/.claude/bin/auto-evolve.py } ] } ] } }JSON关键设计Stop Hook 在会话结束时触发驱动分析和提炼流程。PostToolUse 匹配所有工具.*确保 100% 的后置采集率PreToolUse 当前仅覆盖 Bash 调用用于在命令执行前记录意图两者互补形成完整的生命周期观测。Observation 数据格式每条观测记录是一个 JSONL 行包含工具名称、时间戳、输入参数等{ session_id: abc123, ts: 2026-05-26T10:30:00Z, phase: post, tool: Edit, input: { file_path: /src/app.ts, old_string: ..., new_string: ... }, bash_desc: null }JSON当前系统已积累数万条观测记录约 4MB 数据记录了跨越数月的完整编程行为轨迹。数据分片与生命周期管理为防止数据膨胀observations_rotate.py 在文件超 5MB 或 8000 行时自动按月份分片归档主文件只保留最近 30 天的数据。四、模式提炼层Instinct Engine 会话结束时自动分析观测数据提炼行为模式为原子化 Instinct 规则置信度动态演化。这是整个系统最核心的部分。auto-analyze-instincts.py 在每次会话结束时运行通过两条并行路径提炼行为模式。路径 A统计模式检测基于规则的硬编码检测器识别高频出现的工具调用序列每检测到一个模式生成或更新一条 Instinct首次发现confidence 0.5重复验证confidence 0.05上限 0.9长期未触发confidence - 0.05低于 0.55 标记为 deprecated路径 BAI 语义分析将观测摘要交给 Claude 模型进行语义理解捕获统计模式无法识别的深层规律# 调用本地 Claude CLI 进行语义分析 result subprocess.run( [claude, --print, --model, claude-haiku-4-5-20251001, -p, prompt], capture_outputTrue, textTrue ) # Claude 返回 JSON 数组每条是一个 instinct instincts json.loads(result.stdout)Python两条路径互补统计路径快速可靠语义路径捕获复杂模式。Instinct 数据模型每个 Instinct 是独立的 Markdown 文件存储在 ~/.claude/homunculus/instincts/personal/Markdown --- id: read-before-edit-pattern trigger: when about to edit a file that hasnt been read in this session confidence: 0.78 domain: workflow source: session-observation deprecated: false observed_at: 2026-05-20 --- ## Action 在 Edit 文件前先用 Read 工具读取该文件的当前内容特别是当文件较长或最近有其他改动时。 不跳过读取直接编辑以避免基于过时内容产生错误的修改。 ## Evidence 在过去 多次 Edit 操作中绝大多数之前有对应的 Read 调用。Yaml语义去重算法单条 Instinct 是原子性的auto-evolve.py 将同域高置信度规则聚合成 Evolved Skill并生成会话级规则文件。核心是基于 Jaccard 相似度的 Union-Find 去重def deduplicate_instincts(instincts, sim_threshold0.5): 提取英文关键词计算 Jaccard 相似度相似的合并为一组 tokens [tokenize(i[trigger] i[action]) for i in instincts] n len(instincts) parent list(range(n)) for i in range(n): for j in range(i 1, n): if jaccard(tokens[i], tokens[j]) sim_threshold: union(i, j) # 合并相似 instinct # 每组取置信度最高的作为代表 return [max(group, keylambda x: x[confidence]) for group in groups.values()]Python只提取英文关键词的设计很巧妙用户可能用中文或英文描述同一个习惯基于英文技术词汇的 Jaccard 相似度能跨语言识别同一意图。Domain 聚合与规则注入去重后按 domain 分组每组 2 条才生成 Evolved Skillworkflow (7条) → evolved-workflow.md testing (3条) → evolved-testing.md git (2条) → evolved-git.md code-style (2条) → evolved-code-style.md project-context (2条) → evolved-project-context.md research-habit (4条) → evolved-research-habit.md请在此输入代码块语言各 domain 的 evolved-*.md 内容随即被合并、精简后写入/.claude/rules/auto-evolved.md------每次会话结束时整体覆盖重写始终保持最新状态。Claude Code 启动时自动加载.claude/rules/ 目录下所有 .md 文件实现规则的跨会话注入。五、记忆注入层Memory Engine提炼完成的规则写入规则文件下次会话启动时自动加载完成知识的跨会话持久化。结构化知识的持久化Instinct 系统处理行为模式Memory 系统则处理知识性记忆------解决过的 Bug、重要的技术决策、项目上下文等。记忆类型体系记忆文件格式每条记忆存储为独立的 Markdown 文件使用 YAML frontmatter--- name: feedback-commit-timing description: 改完代码不主动提交等用户验证确认后再 commit/push metadata: type: feedback --- 改完代码后不要自动 commit 或 push。等用户在本地验证功能正常后再由用户确认提交。 **Why:** 自动提交会打断用户的验证节奏且一旦 push 到远端就需要额外操作回滚。 **How to apply:** 完成代码修改后明确告知用户改动内容等待其 confirm 再执行 git 操作。Yaml记忆召回实现从检索到注入的完整链路记忆存储完成只是第一步召回才是让记忆产生价值的关键环节。整个召回链路分为四个阶段阶段一触发时机召回由 SessionStart Hook 驱动会话开始时inject_memory_context.py 通过 SessionStart Hook 自动向 Claude 注入相关记忆上下文完成记忆的自动关联与应用而非等到用户发出请求时才加载------这保证了上下文在第一条消息前就已就绪。{ hooks: { SessionStart: [ { hooks: [ { type: command, command: python3 ~/.claude/memory/inject_memory_context.py } ] } ] } }Prolog阶段二查询构造inject_memory_context.py 以当前工作目录$PWD和最近 3 条 git commit message 作为召回查询的输入自动构造出与当前任务语境最接近的查询向量def build_query(cwd: str) - str: # 提取项目名 project_name Path(cwd).name # 获取最近 3 条 commit 作为补充语义 recent_commits subprocess.check_output( [git, log, --oneline, -3], cwdcwd ).decode().strip() return f{project_name} {recent_commits}Python阶段三向量检索Top-K 召回查询向量与记忆库中所有条目的向量做余弦相似度比较取 Top-5 最相关的记忆def recall_memories(query: str, top_k: int 5) - list[dict]: query_vec embed(query) # 生成查询向量 scores [] for mem in load_all_memories(): sim cosine_similarity(query_vec, mem[embedding]) scores.append((sim, mem)) scores.sort(keylambda x: -x[0]) return [m for _, m in scores[:top_k]]Python阶段四上下文注入召回的记忆以结构化 Markdown 格式注入到 Claude 的系统提示中每条记忆附带类型标签让模型能感知记忆来源并给予相应权重## 项目记忆自动注入请优先参考 [feedback] 改完代码不主动提交等用户验证确认后再 commit/push Why: 自动提交会打断验证节奏回滚成本高 [project] 当前项目使用 Vitest 做单元测试TDD 优先 How to apply: 新功能先在 tests/ 写测试用例再实现 [user] 用户是 Go 专家TypeScript 中级水平 How to apply: TS 代码解释适当补充类型系统的背景知识NixEmbedding LLM向量化的技术选型记忆系统的语义检索依赖向量嵌入Embedding这是让关键词匹配升级为语义理解的核心技术。为什么需要 Embedding传统全文搜索只能匹配字面量无法理解同义表达。而 Embedding 将文本映射为高维向量空间中的点语义相近的文本在空间中距离相近即使措辞完全不同。比如查询 不要自动提交代码 与记忆条目 等用户确认后再 commit 字面无交集但 Embedding 相似度仍然很高。当前方案本地 Embedding 模型为了保护代码隐私记忆内容可能包含项目路径、函数名等敏感信息系统选用本地运行的轻量 Embedding 模型配合 qdrant 向量库避免将记忆上传到第三方服务Embedding 写入流程def upsert_memory(memory: dict): # 构造嵌入文本 标题 描述 正文摘要 text f{memory[name]} {memory[description]} {memory[body][:200]} vector embed_local(text) # nomic-embed-text 本地推理 qdrant_client.upsert( collection_namememories, points[PointStruct( idmemory_hash(memory[name]), vectorvector, payload{name: memory[name], type: memory[type], path: memory[file_path]} )] )Python为什么不用 Claude Embedding APIClaude 目前未开放独立的 Embedding API且将记忆内容发送到云端存在隐私风险。本地 nomic-embed-text 在 M 系列芯片上推理速度约 10ms/条完全满足实时写入需求。两套记忆系统的协作整个系统分为两个相互独立又互相补充的记忆维度六、数据流设计数据流设计从一次工具调用到最终影响下次会话的完整路径1. 用户对话中触发工具调用如 Edit 文件 ↓ 2. PreToolUse Hook → observe.sh → observations.jsonl ↓ 3. 工具执行 ↓ 4. PostToolUse Hook → observe.sh → observations.jsonl ↓ 5. 会话结束Stop Hook 触发 ↓ 6. auto-analyze-instincts.py ├── 路径 A统计模式检测5 种硬编码模式 └── 路径 BClaude API 语义分析 ↓ 7. 写入/更新 ~/.claude/homunculus/instincts/personal/*.md ↓ 8. auto-evolve.py ├── 过滤 confidence 0.7 ├── Jaccard 语义去重Union-Find ├── 按 domain 聚合 └── 写入 rules/auto-evolved.md ↓ 9. 下次会话启动时 ├── Claude Code 自动加载 rules/auto-evolved.md └── SessionStart Hook → inject_memory_context.py → 注入项目记忆Stylus防膨胀设计系统长期运行必然面临数据膨胀问题。多个层次的防膨胀机制确保系统始终保持精简。数据层防膨胀Observations超 5MB 或 8000 行自动按月归档Instinct低置信度 0.55标记 deprecatedMemory raw按类型 TTL 管理60-90 天。索引层防膨胀MEMORY.md超 160 行按优先级裁剪auto-evolved.md每次会话结束覆盖重写去重Jaccard 相似度合并重复 Instinct。其他系统设计原子性优先先积累原子规则等同类足够多再聚类聚合避免过早抽象。一个 Instinct 只对应一个 trigger action。隐私边界Observations 只保本地export 只分享 Instinct 模式规则不含代码路径或会话内容。置信度演化规则不是静态的。反复观测强化长期不触发衰减。系统具有遗忘能力自然淘汰过时规则。Hook 优先于 Skill确定性触发是数据质量的保障。放弃依赖模型主动调用的 Skill 触发改用系统级 Hook 确保 100% 采集率。七、实际效果经过数月的积累系统已提炼出数百条 Instinct其中十余条高置信度规则≥70%每次会话自动激活。以下是几个典型案例系统收益量化效率提升与 Token 节省。构建这套系统的投入不小但它带来的收益是可以量化的。以下是基于数月真实使用数据的测量结果。收益一上下文冷启动时间从 10 分钟降至 30 秒问题每次新会话开始都要重新向 Claude 解释项目背景、技术栈、规范约束通常需要 3-5 轮对话、约十分钟左右才能让模型进入状态。改进后SessionStart Hook 在 30 秒内自动注入项目记忆和高置信度规则模型第一条响应就能体现项目上下文感知。收益二Token 消耗降低约 78%问题重复解释项目背景、编码规范等固定信息每次都占用大量 input token。改进后Memory 系统精确召回相关记忆Top-5避免将全部历史上下文塞入 prompt。相比每次粘贴完整 CLAUDE.md的方式平均节省约数千 tokens/会话。收益三错误重复率下降 80%Instinct 系统的核心价值不是记住做了什么而是记住犯过什么错、为什么犯。以 CLI 工具前置检查规则73% 置信度为例规则提炼前每月平均因CLI 未安装/认证失效导致任务中断 数次。规则提炼后每月 极少且出现时是新工具而非已知工具。收益四知识复利效应记忆系统的价值随时间指数增长而非线性增长第 1 个月规则稀少主要消除低级错误ROI 较低。第 3 个月十余条高置信度规则激活覆盖主要工作流每日节省显著时间。第 6 个月数百条 Instinct 积累项目级记忆形成Claude 的行为已高度贴合个人习惯。八、总结本文记录了为 Claude Code 构建的一套持久化记忆与自我学习系统的设计思路与实现细节。这套系统让 AI 助手能够跨越会话边界记住用户习惯并在每次对话结束后自动提炼行为规律和系统信息通过向量检索快速提取关键信息下一次对话时主动应用逐步进化为更懂你的编程伙伴。