背景:为什么 AI 聊天工具需要"记忆"
用过 ChatGPT 做心理陪伴的人都知道一个痛点:每次对话都是从零开始。你今天跟它说了家庭情况、工作压力、情绪状态,关掉窗口再回来,它什么都不记得。
这不是 ChatGPT 的 bug,而是大模型对话的基本架构决定的------context window 是临时的,session 结束即清空。
我想解决这个问题,于是基于 Claude Code Agent Skill 开放标准 ,做了一个叫 Soul Guardian 的开源项目。核心思路很简单:用本地文件系统作为 AI 的持久记忆层。
本文主要聊技术实现,包括架构设计、文件读写策略、话题路由机制和安全协议。
GitHub: github.com/taohaowei/s... 协议: MIT | 安装:
npx skills add taohaowei/soul-guardian -g
整体架构:Agent Skill + 文件系统
什么是 Claude Code Agent Skill
Agent Skill 是 Claude Code 的扩展机制(也兼容 Copilot CLI、Gemini CLI 等)。一个 Skill 本质上就是一个 SKILL.md 文件,用 YAML frontmatter 声明元信息,Markdown 正文定义行为协议:
yaml
---
name: counselor
version: 0.3.0
description: |
心理咨询师技能。触发方式:/counselor 或自然语言描述心理相关需求。
---
当用户输入 /counselor 或匹配到 description 中的语义关键词时,Claude Code 会加载这个 SKILL.md,将其注入 system prompt,然后 AI 就在这个协议框架内工作。
关键点:Skill 本身不是代码,是结构化的 prompt engineering。 没有运行时、没有依赖、不需要 API key(Claude Code 自己的除外)。"智能"来自大模型,Skill 只是给它一个行为框架和记忆支架。
文件系统作为记忆层
所有持久数据存储在 ~/.counselor/ 目录下,纯 Markdown 文件:
bash
~/.counselor/
├── core/ # 核心状态(每次启动必读)
│ ├── PROFILE.md # 用户画像:基本信息、核心议题、咨询阶段
│ ├── STATE.md # 会话状态:最近情绪(1-10)、上次收获、下次方向
│ └── SAFETY.md # 安全评估:风险等级(低/中/高)、预警信号、保护因素
├── maps/ # 心理地图(按需加载)
│ ├── FAMILY.md # 三代家谱图、家庭角色、冲突模式、代际传递
│ ├── BELIEFS.md # 核心信念表(旧信念→新信念+置信度+证据)、思维日记
│ ├── STRENGTHS.md # 性格优势、成功应对经验、支持系统
│ ├── COMPASS.md # 八维生活满意度评分、价值观罗盘
│ ├── STORY.md # 生命故事线、转折点、问题外化(叙事疗法)
│ └── GOALS.md # 目标追踪、行为实验记录、情绪追踪
├── sessions/ # 会话归档(write-once)
├── journal/ # 日记条目(write-once)
├── toolkit/
│ └── EMERGENCY.md # 应急工具箱:呼吸法、落地技术、自我对话脚本
└── archive/ # 压缩归档
为什么选文件系统而不是 SQLite / 向量数据库?
- 零依赖 :不需要装任何东西,
~/.counselor/就是全部 - 可读可编辑 :用户可以
cat、vim、grep直接操作自己的心理档案 - 可版本控制 :想 git track 自己的心理变化?直接
git init - 隐私透明:没有二进制格式、没有加密黑箱,用户完全知道存了什么
- 与 LLM 天然兼容:Markdown 就是大模型最擅长读写的格式
核心机制一:分层文件读写策略
不同类型的文件有不同的读写语义,这是整个记忆系统最关键的设计决策:
| 文件类型 | 读取时机 | 写入策略 | 设计意图 |
|---|---|---|---|
core/STATE.md |
每次启动 | 覆盖写 | 永远只反映最新状态 |
core/PROFILE.md |
每次启动 | 增量更新 | 用户画像逐渐丰富 |
core/SAFETY.md |
每次启动 | 即时更新 | 风险变化零延迟 |
maps/*.md |
按需加载 | 增量追加 + 定期精炼 | 知识持续积累 |
sessions/*.md |
不主动读 | 只写不改 | 历史记录不可篡改 |
journal/*.md |
不主动读 | 只写不改 | 日记条目不可篡改 |
核心思路是写入策略的不对称性:
- STATE.md 覆盖写:每次会话结束时完整重写,保证下次启动读到的永远是最新快照。不做 append,因为状态不需要历史------那是 sessions 的职责。
- sessions/*.md 只写不改 :文件名为
YYYY-MM-DD.md,写入后永不修改。这保证了会话历史的完整性和不可篡改性,类似 append-only log。 - maps/*.md 增量 + 精炼:每次对话后追加新发现的信息(比如 FAMILY.md 中新提到的家庭成员),但不会无限膨胀------每 10 次会话触发一次精炼检查,合并重复信息、更新过时内容。
- SAFETY.md 即时更新:安全文件享有最高写入优先级。任何风险等级变化都在对话中立即写入,不等会话结束。
核心机制二:话题路由与按需加载
一个关键问题:用户的心理档案可能有几十 KB 的 Markdown 内容,全部塞进 context window 太浪费 token,也会稀释对话质量。
解决方案是话题路由表------根据用户当前聊的内容,动态加载对应的 map 文件:
用户话题关键词 → 加载文件
家庭/父母/伴侣/孩子 → maps/FAMILY.md
信念/想法/应该/必须 → maps/BELIEFS.md
优势/资源/擅长 → maps/STRENGTHS.md
满意度/方向/价值 → maps/COMPASS.md
故事/经历/回忆 → maps/STORY.md
目标/计划/练习 → maps/GOALS.md
焦虑/恐慌/呼吸 → toolkit/EMERGENCY.md
这本质上是一个简单的 keyword → file 映射,由 SKILL.md 中的协议定义,AI 在对话过程中自行执行路由判断。不需要 embedding、不需要 RAG pipeline,就是 prompt 里的一张规则表。
实际效果:用户说"今天又和我妈吵架了",AI 识别到家庭话题,通过 Bash 工具执行 cat ~/.counselor/maps/FAMILY.md,获取家庭关系上下文,然后在这个背景下继续对话。
相比全量加载,这种按需加载策略将每次对话的上下文消耗降低了约 60-70%。
核心机制三:渐进式建档
传统做法是让用户填表------姓名、年龄、困扰列表。这在心理咨询场景中非常糟糕,因为它破坏了对话的自然感。
Soul Guardian 采用前 4 次对话渐进建档:
| 会话 | 对话内容 | 档案产出 |
|---|---|---|
| 第 1 次 | 自然聊天,建立安全感 | PROFILE.md + STATE.md 初始化 |
| 第 2 次 | 触碰核心议题 | FAMILY.md 或 BELIEFS.md 开始填充 |
| 第 3 次 | 深入探索 | COMPASS.md + STRENGTHS.md |
| 第 4 次 | 档案成型 | 全部 map 文件基本就绪 |
技术上的实现是在 SKILL.md 中维护一个咨询阶段状态机 ,记录在 PROFILE.md 的 咨询阶段 字段中。AI 根据当前阶段决定对话策略------第 1 次不急着深挖,第 3 次可以开始挑战认知模式。
核心机制四:安全协议
心理场景有一条绝对红线:自杀/自伤/暴力风险检测。这不是可选功能,是必须设计到架构里的。
SKILL.md 中定义了四类风险信号:
- 自伤/自杀意念
- 伤害他人意图
- 严重暴力/虐待
- 精神病性症状
检测到任一信号后,系统行为:
markdown
1. 立即评估紧急程度
2. 写入 SAFETY.md(即时,不等会话结束)
3. 提供危机热线(全国24h:400-161-9995)
4. 声明 AI 局限性,建议寻求专业帮助
5. 如果风险等级从低→高,下次启动时优先处理
SAFETY.md 在每次启动时必检。如果上次记录的风险等级为"高",AI 会跳过常规对话流程,优先进行安全评估。
压缩机制:解决文件膨胀
长期使用后,sessions/ 目录会持续增长。解决方案:
- 每 10 次会话触发压缩检查
- 超过 3 个月的会话记录 :提取关键洞察,写入
archive/YYYY-QN.md - 原始 session 文件可以清理(用户决定)
archive 文件是季度级别的总结,保留了重要的模式发现和认知变化,但去除了对话细节。
$ARGUMENTS 占位符:支持即时触发
SKILL.md 末尾使用了 Agent Skill 标准的 $ARGUMENTS 占位符:
bash
$ARGUMENTS
这意味着用户可以在触发时直接带上内容:
bash
/counselor 今天工作被老板骂了,心情很差
AI 加载 SKILL.md 后,$ARGUMENTS 会被替换为用户输入的文本,直接基于这段内容开始对话,省去了寒暄环节。
实际效果:5 次对话后的文件变化
我自己作为第一个用户测试了 5 次对话(18 天)。~/.counselor/ 目录的变化:
| 文件 | 第 1 次后 | 第 5 次后 |
|---|---|---|
| PROFILE.md | 基本信息 + 1 个核心议题 | 5 个核心议题 + 3 个已发现优势 |
| FAMILY.md | 空模板 | 三代家谱 + 3 个冲突模式 + 代际传递分析 |
| BELIEFS.md | 空模板 | 4 条核心信念(含置信度变化追踪) |
| STATE.md | 情绪 6/10 | 情绪 3/10 |
| sessions/ | 1 个文件 | 5 个文件,共约 15KB |
最有价值的发现是第 5 次对话时,AI 基于 FAMILY.md 和 BELIEFS.md 的交叉信息,识别出了一个跨话题的行为模式------这是单次对话不可能做到的,持久记忆让"深度"成为可能。
总结:这个架构的适用场景
Soul Guardian 的技术方案------SKILL.md 行为协议 + 本地文件记忆 + 话题路由------并不局限于心理咨询场景。任何需要"跨会话记忆 + 结构化知识积累"的 AI 应用都可以参考:
- 个人知识管理助手:用 maps/ 存储不同领域的知识图谱
- 长期学习辅导:用 sessions/ 追踪学习进度,用 maps/ 记录知识掌握程度
- 项目管理 copilot:用 STATE.md 记录项目状态,用 maps/ 存储需求和决策记录
核心 takeaway:
- 文件系统是最简单的持久化方案,对于 Agent Skill 这种轻量级扩展,比引入数据库更合适
- 分层写入策略(覆盖 / 追加 / 只写)是记忆系统设计的关键
- 按需加载比全量加载更节省 token,也更聚焦
- 安全协议必须是架构级别的设计,不是事后补丁
开源地址 :github.com/taohaowei/s... 安装 :
npx skills add taohaowei/soul-guardian -g,在 Claude Code 中输入/counselor即可使用 协议:MIT欢迎 Star、Issue 和 PR。如果你对 Agent Skill 的架构设计感兴趣,项目里的 SKILL.md 和 templates.md 可以作为参考。