目的:在纯本地、隐私优先的前提下,借鉴开源项目 ex-skill(前任.skill)的「关系记忆 + 人物人格」双层思路,使用 Python + Vue 3 + Vite 搭建可扩展的 Web 应用,对话由 DeepSeek(OpenAI 兼容 API)驱动,并配套 Agent Skill 规范以便在 Cursor / Claude Code 等环境中复用与演进。
文档版本:2026-04-02
规划文档;实现以后续迭代代码为准。
一、文档关系与适用范围
| 文档 | 职责(规划) |
|---|---|
| 本文 | 架构、技术栈、模块划分、Skill 扩展、UI 方向、API 草案、里程碑 |
README.md(待建) | 安装、环境变量、启动命令、数据目录说明 |
docs/交互与视觉规范.md(可选) | 日系动漫向组件级规范(色板、字体、动效时长) |
读者:全栈实现者、需要审阅隐私边界的产品/本人。
二、背景与目标
2.1 产品目标
- 回忆载体:将聊天记录、口述文本、可选图片元数据等,整理为结构化「记忆」与「人格」,用于本地对话与复盘(不替代真实人际关系与专业心理支持)。
- 技术对齐:概念上对齐 ex-skill 的 Part A — Relationship Memory 与 Part B — Persona(详见其 README 中的生成结构说明:ex-skill)。
- 模型:默认 DeepSeek(
base_url+api_key走 OpenAI 兼容协议);支持切换为其他兼容端点(仅配置层,业务代码不绑厂商)。
2.2 硬性约束
| 约束 | 实现要点 |
|---|---|
| 纯本地 | 浏览器只访问本机 localhost(或打包后的本地静态 + 本机 API);无内置云同步、无遥测上报。 |
| 隐私 | 用户数据目录默认在用户指定或应用数据路径(如 %APPDATA%/ex-memory-web);聊天记录原文、生成的 memory/persona 不落第三方。 |
| API Key | 仅通过环境变量或本地加密配置文件(可选)注入后端;永不下发给前端构建产物。 |
2.3 非目标(首版明确不做)
- 不提供对任何真实个人的骚扰、跟踪或隐私侵犯能力;不鼓励未授权数据抓取。
- 首版不要求与微信/QQ 官方 API 集成;仅 文件导入(适配 ex-skill 文档中提到的导出格式思路,解析器可渐进实现)。
三、总体架构
3.1 逻辑架构
flowchart TB
subgraph browser [浏览器 SPA]
UI[Vue 3 + Vite]
UI --> HTTP[fetch /api]
end
subgraph local [本机 Python 服务]
API[FastAPI]
SVC[业务服务层]
LLM[LLM 客户端 DeepSeek 兼容]
PARSER[导入解析器]
SKILL[Skill 装配与版本]
STORE[(本地存储)]
end
HTTP --> API
API --> SVC
SVC --> STORE
SVC --> LLM
SVC --> PARSER
SVC --> SKILL
- 前后端分离:Vue 构建静态资源;开发期 Vite 代理
/api到 FastAPI。 - 所有 LLM 调用经后端:前端只提交「当前会话 id、用户消息、可选检索片段」;避免 Key 暴露与绕过审计日志(本地日志可选)。
3.2 与 ex-skill 的对应关系(概念层)
| ex-skill 概念 | 本应用映射 |
|---|---|
memory.md / 关系记忆 | 本地库中每条「关系档案」的 Memory 文档(结构化 JSON + 可选 Markdown 导出) |
persona.md / 五层人格 | Persona 文档(规则层、身份、语言风格、情感模式、关系行为) |
| prompts 模板 | 后端 prompts/ 或打包资源目录;版本与 Skill 同步 |
| 版本管理 / 纠正 | 本地 版本快照 + Correction 层(用户反馈「不像」时写入补丁块,合并进生成逻辑) |
实现上不强制 fork ex-skill 仓库;可引用其 思路与文件结构,自研解析与装配,以降低许可证与依赖耦合风险(ex-skill 为 MIT,若直接复用代码需保留版权声明)。
四、技术栈
4.1 前端
| 类别 | 选型 | 说明 |
|---|---|---|
| 框架 | Vue 3 | Composition API、<script setup> |
| 语言 | TypeScript | vue-tsc 构建期检查 |
| 构建 | Vite | 与 Day6 狼人杀项目一致,便于学习路径统一 |
| 路由 | Vue Router 4 | 档案列表 / 档案详情 / 对话 / 设置 |
| 状态 | Pinia | 当前档案、会话列表、UI 主题状态 |
| 样式 | Tailwind CSS + 少量 CSS 变量 | 日系动漫向主题通过 CSS 变量与主题类 切换,避免魔法数散落 |
| HTTP | fetch 或 ofetch | 封装 api-base,统一错误与类型 |
4.2 后端
| 类别 | 选型 | 说明 |
|---|---|---|
| 运行时 | Python 3.11+ | 与 Day6 一致 |
| 框架 | FastAPI | REST + 可选 SSE 流式输出对话 |
| 配置 | pydantic-settings | DEEPSEEK_API_KEY、DEEPSEEK_BASE_URL、DATA_DIR 等 |
| LLM | openai SDK | base_url 指向 DeepSeek 兼容地址 |
| 存储 | SQLite + 文件系统 | 元数据、会话、版本索引存 SQLite;大块文本/Markdown 存文件便于备份与 Skill 导出 |
| 任务 | 同步 + asyncio | 长耗时解析可用 BackgroundTasks 或后续引入队列(首版同步即可) |
4.3 开发运维
- 一键启动:
uvicorn+ 前端vite双进程;或 Makefile /pnpmscripts 聚合。 - 测试:后端
pytest;前端Vitest+ 关键组件测试(按需)。
五、日系动漫向交互与 UI 要求
目标:情绪氛围像番剧 UI(柔和光感、留白、轻叙事),而非低幼贴纸堆叠。避免侵权:使用 自制渐变与几何装饰、可商用手写体/圆体字体(如 Google Fonts 中明确 OFL 的字体),角色立绘若使用须自有版权或 AI 生成并声明。
5.1 视觉基调
- 色彩:低饱和背景(浅灰蓝 / 米白 / 樱花粉偏灰);主色 1~2 个(青蓝或薰衣草),强调色用于按钮与焦点;暗色主题可选(深夜对话场景)。
- 形状:大圆角卡片、柔和阴影(多层淡阴影模拟「空气感」);分隔线细且半透明。
- 字体:标题用略具个性的圆体/准圆;正文用可读性高的无衬线;数字与代码保持等宽或系统 UI 字体。
- 背景:可选轻量 CSS 渐变 + 微粒/柔光动效(
prefers-reduced-motion时关闭)。
5.2 动效与反馈
- 页面切换:淡入 + 轻微位移动画(时长 200–320ms,easing 柔和)。
- 对话气泡:逐条出现可选打字机效果(流式 SSE 时自然对齐)。
- 按钮与输入:轻微 scale / glow,避免夸张弹跳。
5.3 信息架构(页面级)
| 路由(示例) | 内容 |
|---|---|
/ | 档案库(卡片栅格 + 搜索 + 「新建回忆」) |
/archive/:id | 档案概览:记忆时间线、人格标签、数据源、导出 Skill |
/archive/:id/chat | 对话主界面(记忆模式 / 日常模式 Tab) |
/settings | 数据目录、模型 endpoint、主题、关于与伦理声明 |
5.4 可访问性
- 对比度符合 WCAG AA 底线;键盘可操作;动效尊重系统「减少动态效果」。
六、数据模型与本地存储(草案)
6.1 核心实体
- Archive(档案):
id、slug(Skill 用)、展示名、创建时间、当前激活的 memory/persona 版本 id。 - MemoryVersion / PersonaVersion:版本号、源文件路径、摘要、生成时所用 prompt 版本。
- Session:会话 id、关联 archive、消息列表(或分表存储消息)。
- ImportJob:原始文件路径(导入后可删除或脱敏保留)、解析状态、错误信息。
- Correction:自然语言或结构化「纠正条」,合并顺序在 prompt 中定义。
6.2 目录布局(用户数据区示例)
DATA_DIR/
ex-memory.db # SQLite
archives/
{archive_id}/
raw/ # 用户上传的原始导出(可选加密)
memory_v{n}.md
persona_v{n}.md
versions.json # 或与 DB 重复时仅 DB
skills_export/ # 导出的 Agent Skill 目录(见 §七)
七、Skill 体系与扩展性
7.1 设计原则
- 双轨一致:应用内使用的
memory.md/persona.md与导出的 Cursor/Claude Skill 使用同一套模板,避免「应用一套、Skill 一套」漂移。 - 可扩展 Skill 包:除「前任对话」外,预留 Skill 类型 字段(如
ex-partner、memory-only、persona-only),对应不同SKILL.md模板与触发说明。
7.2 导出形态(建议)
在用户机器上生成目录(可与 Agent Skills 约定 对齐):
skills/ex-{slug}/
SKILL.md # frontmatter: name, description
memory.md # Part A
persona.md # Part B
prompts/ # 可选:与后端共用模板子集
reference.md # 可选:用户不可编辑的生成说明
用户可将 skills/ex-{slug} 复制到:
- 项目内:
.cursor/skills/ex-{slug}/ - 或全局:
~/.cursor/skills/ex-{slug}/
7.3 本仓库配套 Skill(开发用)
在 learn-agent 仓库中单独维护 「维护/使用 ex-memory-web」 的 Skill(与「生成的前任 Skill」区分):
| Skill | 作用 |
|---|---|
ex-memory-dev(示例名) | 描述 Day7 目录结构、API 约定、如何跑本地、如何导出档案;供 Agent 改代码时使用。 |
实现阶段在 code/Day7/ex-memory-web/.cursor/skills/ 或仓库根 .cursor/skills/ 落地(按团队习惯二选一,推荐项目级 便于随仓库版本走)。
7.4 扩展点(插件化)
- 解析器插件:约定接口
parse(source_type, file_path) -> RawConversation;首版内置plaintext、wechat_export(格式与 ex-skill 文档对齐的可选子集),后续增加 QQ 等。 - Prompt 插件:按
prompt_pack_id选择不同prompts/*.md组合(温柔/克制/辩论等风格包),仅配置与模板,不改核心代码。 - 导出插件:除 Cursor Skill 外,可扩展导出「单文件 JSON 备份」或「Obsidian 库」。
八、API 草案(REST)
路径前缀
/api;认证首版可省略(仅 localhost),若未来局域网访问再加简单 token。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/health | 健康检查 |
| GET/POST | /api/archives | 列表 / 创建 |
| GET/PATCH/DELETE | /api/archives/{id} | 详情 / 更新 / 删除 |
| POST | /api/archives/{id}/imports | 上传或注册本地路径 + 触发解析 |
| POST | /api/archives/{id}/generate | 根据原始材料生成或增量 merge memory/persona |
| GET | /api/archives/{id}/versions | 版本列表 |
| POST | /api/archives/{id}/rollback | 回滚到指定版本 |
| POST | /api/archives/{id}/corrections | 提交纠正 |
| POST | /api/archives/{id}/chat | 非流式对话 |
| POST | /api/archives/{id}/chat/stream | SSE 流式 token |
| GET | /api/archives/{id}/export/skill | 打包 zip 或返回目录树说明 |
错误体统一:{ "code": string, "message": string, "detail"?: unknown }。
九、关键流程
9.1 新建档案 → 导入 → 生成
- 用户创建 Archive,填写可选标签(MBTI、依恋类型等,与 ex-skill 标签表兼容)。
- 上传或选择本地导出文件;后端解析为中间结构。
- 调用 DeepSeek:分阶段跑 memory 提取、persona 提取(prompt 模板分文件,便于迭代)。
- 写入新版本文件 + DB;前端展示 diff 摘要(可选)。
9.2 对话
- 后端组装 system prompt:硬规则(伦理与安全边界)+ Persona + 检索到的 Memory 片段(简单实现:关键词/时间线;进阶:本地向量库 sqlite-vec 或 chromadb 嵌入式,仍为本地)。
- 调用 DeepSeek;流式返回给前端。
9.3 导出 Skill
- 将当前版本 memory/persona 填入模板,生成
SKILL.md(description写清「仅本地回忆用途」)。 - 打包下载或写入
DATA_DIR/skills_export/。
十、安全与伦理(实现层)
- System prompt 固定包含:不冒充真人决策、不鼓励骚扰、不提供违法建议;用户数据不出站。
- 敏感文件:上传目录默认不加入 git;
.gitignore覆盖DATA_DIR与上传临时目录。 - 日志:生产级关闭请求体日志;调试模式本地可选。
十一、分期里程碑(建议)
| 阶段 | 内容 |
|---|---|
| M1 | FastAPI 骨架 + SQLite 档案 CRUD + Vue 路由与日系主题壳 + DeepSeek 单次对话(无档案) |
| M2 | 档案绑定 memory/persona 文件、对话上下文装配、SSE |
| M3 | 文本导入 + 第一版 memory/persona 生成 pipeline、版本列表与回滚 |
| M4 | Skill 导出 + 仓库内 ex-memory-dev Skill;解析器插件接口 |
| M5 | 可选本地向量检索、Correction UI、暗色主题与动效打磨 |
十二、参考链接
- 开源灵感与结构说明:therealXiaomanChu/ex-skill
- 同仓库 Day6 工程参考:
code/Day6/werewolf-web/docs/前后端技术方案书.md(FastAPI + Vue3 + Vite + DeepSeek 兼容客户端模式可复用)
结语:本方案强调 本地优先、Skill 同源、可插拔扩展,UI 上用日系动漫感承载情绪,而不是弱化隐私与边界。实现时优先 M1–M2 打通「能私聊、能存档」,再迭代生成与导出,避免一次性范围过大。