AI 分身(核心功能)
让 AI 学习联系人的聊天风格,模拟和 TA 对话——像真的在和 TA 聊天一样。
为什么做这个功能
聊天记录是一个人最真实的语言印记——用词习惯、语气特征、表情偏好,甚至说话的节奏。AI 分身从中学习这些特征,让你可以:
- 和已经失去联系的老友再聊一次 — 哪怕只是 AI 模拟的,也能找回当年的感觉
- 让远在天堂的亲人以 TA 熟悉的方式"回复"你 — 不是冰冷的机器,而是带着 TA 说话习惯的温暖文字。只要你们之间有过足够的聊天记录,AI 就能学到 TA 的表达方式
- 在做重要决定前,和最信任的人的 AI 分身聊聊 — TA 会用 TA 的方式给你回应
- 或者纯粹好奇 — 你最好的朋友如果看到你发的这句话,会怎么回?
关于还原度
AI 分身的表现取决于聊天记录的数量和质量。数百条消息就能捕捉基本风格,数千条以上则能还原出令人惊讶的细节——比如 TA 习惯用的语气词、TA 回复问题的方式、TA 在不同话题下的态度变化。
善意使用
AI 分身旨在帮助用户回忆和珍视人际关系中的美好时刻。所有模拟内容由 AI 生成,不代表真人的真实意愿或想法。
请勿将 AI 分身的输出用于冒充他人身份、误导或欺骗第三方,或任何可能侵害他人权益的用途。
使用本功能即表示您理解并同意:AI 分身仅供个人回忆与娱乐用途,项目作者不对因使用 AI 分身功能产生的任何直接或间接影响承担责任。
目录
功能概览
AI 分身是 WeLink 的核心 AI 功能之一,通过三层记忆 + 行为统计让 AI 深度模拟特定联系人的说话风格:
- 长期记忆:LLM 从全部聊天记录中提炼人物档案(性格、口头禅、兴趣、情感方式)
- 中期记忆:LLM 从最近对话中提炼近期状态(在忙什么、关注什么话题、当前情绪)
- 短期记忆:最近 100 条双向对话原文,保持话题连贯
- 行为特征:统计分析消息长度、emoji 频率、连发习惯、提问频率等量化指标
- 风格样本:均匀采样原始消息,让 AI 直接感受语感
关键特性:
- 学习一次,多轮对话复用(不重复加载数据库)
- 五步学习过程,SSE 实时推送进度(带动画)
- 支持选择学习消息数量:100 / 300 / 1000 / 2000 / 全部
- 支持从共同群聊中提取该联系人的发言作为额外学习材料
- 基于 Session 机制,不同配置互不干扰
- 流式响应,逐字显示
使用流程
┌─────────────────────────────────────────────────┐
│ 1. 打开联系人详情 → 点击「AI 分身」tab │
│ 2. 选择学习消息数量(100/300/1000/2000/全部) │
│ 3. 可选:勾选共同群聊(只提取 TA 的发言) │
│ 4. 可选:填写背景信息 │
│ 5. 点击「开始学习」 │
│ → SSE 实时推送 5 个步骤的进度 │
│ → Step 1: 加载聊天记录 │
│ → Step 2: 统计分析聊天特征 │
│ → Step 3: AI 提炼人物档案(需配置 LLM) │
│ → Step 4: AI 分析近期状态(需配置 LLM) │
│ → Step 5: 构建 AI 分身 │
│ → 返回学习结果 + 统计摘要 │
│ 6. 在聊天界面与 AI 分身对话 │
│ → 每轮只传 session_id + 对话历史 │
│ → 流式返回 AI 响应 │
│ 7. 可随时点击「重新学习」调整参数 │
└─────────────────────────────────────────────────┘三层记忆架构
AI 分身的核心创新在于三层记忆系统,让 AI 同时具备长期人格、中期状态感知和短期对话连贯性。
长期记忆:人物档案
LLM 从联系人全部聊天记录中均匀采样 200 条消息(sampleEvenly),提炼出:
- 性格特点
- 说话风格
- 常用口头禅 / 语气词
- 兴趣爱好
- 情感表达方式
- 价值观 / 态度倾向
- 幽默方式
均匀采样确保覆盖从早期到近期的完整时间跨度,避免只学到某个时期的风格。
中期记忆:近期状态
LLM 从最近 100 条双向对话中提炼出:
- 最近在忙什么
- 近期关注的话题
- 当前情绪 / 状态
- 近期生活事件
- 正在进行的计划
这让 AI 分身能自然地聊到对方最近的事情,而不只是泛泛模仿说话风格。
短期记忆:最近对话
最近 100 条双向消息原文(含双方),格式为 [日期 时间] 我/TA: 内容。
作用:保持对话连贯性,让 AI 知道你们当前在聊什么话题,避免话题断裂。
行为特征统计
从全部消息中自动统计以下量化指标,写入 prompt 约束 AI 行为:
| 指标 | 计算方式 | 约束作用 |
|---|---|---|
| 平均消息长度 | 所有文本消息字数均值 | 控制回复长度 |
| 短消息占比 | <10 字的消息百分比 | 判断是否偏爱短句 |
| 长消息占比 | >50 字的消息百分比 | 判断是否习惯长段 |
| emoji 使用率 | 含 emoji 的消息百分比 | 控制 emoji 频率 |
| 连发消息习惯 | 连续发送 ≥3 条的次数 | 反映消息节奏 |
| 提问频率 | 含 ? / ? 的消息百分比 | 控制提问习惯 |
学习流程
五步 SSE 进度推送
学习端点使用 Server-Sent Events 实时推送每个步骤的进度:
前端 后端
│ │
│ POST /ai/clone/learn │
│ {username, count, │
│ groups[], bio} │
├───────────────────────────→│
│ │
│ SSE: {step:"loading"} │ ← Step 1: 加载私聊 + 群聊消息
│←───────────────────────────┤ 过滤对方文本、取最近 N 条
│ │ 提取最近 100 条双向对话
│ │
│ SSE: {step:"analyzing"} │ ← Step 2: 统计分析
│←───────────────────────────┤ 消息长度、emoji、连发、提问
│ │
│ SSE: {step:"profile"} │ ← Step 3: LLM 提炼人物档案
│←───────────────────────────┤ 均匀采样 200 条 → CompleteLLM
│ │ (需配置 LLM 且消息 ≥ 20 条)
│ │
│ SSE: {step:"recent"} │ ← Step 4: LLM 分析近期状态
│←───────────────────────────┤ 最近对话 → CompleteLLM
│ │ (需配置 LLM 且对话 ≥ 10 条)
│ │
│ SSE: {step:"building"} │ ← Step 5: 组装分层 prompt
│←───────────────────────────┤ 缓存 session_id → prompt
│ │
│ SSE: {done:true, │ ← 最终结果
│ session_id, counts, │
│ has_profile, has_recent, │
│ avg_msg_len, emoji_pct} │
│←───────────────────────────┤前端显示动画效果:已完成步骤显示绿色勾,当前步骤显示紫色旋转动画,待执行步骤灰色。
降级机制:如果未配置 LLM(无 API Key),Step 3 和 Step 4 会自动跳过,仍可使用统计分析 + 风格样本进行基础模拟。
对话阶段
前端 后端
│ │
│ POST /ai/clone/chat │
│ {session_id, │
│ messages[], │
│ profile_id} │
├───────────────────────────→│
│ ├─ 从缓存取 system prompt
│ ├─ 拼接: [system] + messages
│ ├─ 调用 LLM(流式)
│ │
│ SSE: data: {delta} │
│ SSE: data: {delta} │
│ SSE: data: {done: true} │
│←───────────────────────────┤Session 管理
- 每次学习生成唯一的
session_id(格式:clone-{username}-{seq},递增序号) - session 仅存在于内存中,后端重启后需要重新学习
- 不同的参数组合(条数、群聊、背景信息)产生不同 session,互不干扰
- 前端重新学习时自动废弃旧 session
数据来源
私聊消息
从联系人的私聊记录中提取:
- 筛选条件:
is_mine = false(仅对方消息)且type = 1(纯文本) - 排序方式:按
create_time升序排列后取尾部 N 条(即最近 N 条) - 全部模式:不限条数,兜底上限 500 条
额外提取最近 100 条双向消息(含己方)用于短期记忆。
共同群聊发言
从用户选择的共同群聊中提取该联系人的发言:
- 筛选条件:SQL 层按
real_sender_id(联系人在 Name2Id 表中的 rowid)+local_type = 1过滤 - 排序方式:跨多个群聊 + 多个消息 DB 的结果按
create_time全局排序,取最近 N 条 - 内容解析:群聊文本格式为
wxid:\n内容,提取:\n之后的纯内容部分
背景信息
用户手动填写的自由文本,例如:
湖南人,在上海工作,我的大学同学,喜欢打篮球和摄影,说话比较直接
背景信息在 prompt 中置于最前,帮助 AI 建立人物画像基础。
System Prompt 结构
分层 prompt 按以下顺序组装,每层仅在有数据时出现:
你现在要扮演「{displayName}」,完全模拟 TA 的说话风格与我对话。
【TA 的背景】 ← 仅在用户填写时出现
{bio}
【人物档案】(AI 从全部聊天记录中提炼) ← 长期记忆,需配置 LLM
- 性格特点:...
- 说话风格:...
- 常用口头禅/语气词:...
- 兴趣爱好:...
- 情感表达方式:...
- 价值观/态度倾向:...
- 幽默方式:...
【近期状态】(AI 从最近对话中提炼) ← 中期记忆,需配置 LLM
- 最近在忙什么:...
- 近期关注的话题:...
- 当前情绪/状态:...
- 近期生活事件:...
- 正在进行的计划:...
【行为特征】(从消息数据统计) ← 始终存在
平均消息长度: X 字
短消息占比(<10字): X%
长消息占比(>50字): X%
emoji 使用率: X% 的消息含 emoji
连发消息习惯: X 次连续发送 3 条以上
提问频率: X% 的消息包含问号
【最近对话】(最近 N 条双向消息) ← 短期记忆
[日期 时间] 我/TA: 内容
...
【说话风格样本】(N 条原始消息) ← 均匀采样 100 条
原始消息文本...
【角色扮演规则】
1. 完全模仿 TA 的说话风格:用词习惯、口头禅、语气词、断句方式
2. 严格遵守行为特征中的消息长度——如果平均 12 字,就不要写 50 字的长段
3. 保持 TA 的 emoji / 表情符号使用频率和偏好
4. 保持人物档案中描述的性格和情感表达方式
5. 结合近期状态自然回应话题,但不要主动透露你掌握了这些信息
6. 参考最近对话的上下文,保持话题连贯性
7. 绝对不要暴露你是 AI,不要说"作为 AI"之类的话
8. 不要过度热情或客套,保持 TA 原本的交流温度API 端点
POST /api/ai/clone/learn
多步学习:加载联系人消息,统计分析,LLM 提炼记忆,构建并缓存分层 prompt。响应为 SSE 流。
请求体:
{
"username": "wxid_xxx",
"count": 300,
"groups": ["group_wxid_1", "group_wxid_2"],
"bio": "湖南人,在上海工作,我的大学同学"
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
username | string | 是 | 联系人的微信 username / wxid |
count | int | 是 | 学习的消息条数(100/300/1000/2000,0 表示全部) |
groups | string[] | 否 | 要包含的共同群聊 username 列表 |
bio | string | 否 | 联系人背景信息(自由文本) |
响应格式: Server-Sent Events (SSE)
进度事件(每步一条):
data: {"step": "loading", "detail": "正在加载聊天记录..."}
data: {"step": "analyzing", "detail": "正在分析聊天特征..."}
data: {"step": "profile", "detail": "AI 正在提炼人物档案..."}
data: {"step": "recent", "detail": "AI 正在分析近期状态..."}
data: {"step": "building", "detail": "正在构建 AI 分身..."}最终结果事件:
{
"done": true,
"session_id": "clone-wxid_xxx-1",
"sample_count": 450,
"private_count": 300,
"group_count": 150,
"has_profile": true,
"has_recent": true,
"avg_msg_len": 15,
"emoji_pct": 23
}| 字段 | 说明 |
|---|---|
has_profile | 是否成功提炼了长期人物档案 |
has_recent | 是否成功分析了中期近况 |
avg_msg_len | 对方平均消息长度(字) |
emoji_pct | 对方消息含 emoji 的百分比 |
POST /api/ai/clone/chat
对话:通过 session_id 复用已缓存的 system prompt,流式返回 AI 响应。
请求体:
{
"session_id": "clone-wxid_xxx-1",
"messages": [
{"role": "user", "content": "在干嘛呢"},
{"role": "assistant", "content": "刚下班,你呢"},
{"role": "user", "content": "周末一起打球?"}
],
"profile_id": "profile-1"
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
session_id | string | 是 | learn 返回的会话 ID |
messages | array | 是 | 完整对话历史(user/assistant 交替) |
profile_id | string | 否 | LLM 配置 profile ID(多配置切换) |
响应格式: Server-Sent Events (SSE)
data: {"delta": "刚"}
data: {"delta": "下班"}
data: {"delta": ","}
data: {"delta": "你呢"}
data: {"done": true}错误响应:
| HTTP 状态码 | 场景 |
|---|---|
| 400 | 未配置 AI 接口 / session_id 不存在或已过期 |
| 500 | 不支持流式响应 |
隐私与安全
- 数据不出本机:消息加载和 prompt 构建均在本地后端完成
- 按需发送:只有用户主动发送对话消息时,system prompt + 对话历史才会发送到 LLM 服务
- LLM 调用透明:学习过程中的两次 LLM 调用(人物档案 + 近期状态)仅在用户点击「开始学习」时触发,调用进度实时显示
- Session 内存态:缓存的 prompt 仅存在于后端进程内存中,不持久化到磁盘
- 隐私模式:前端支持隐私模式(privacy-blur),AI 分身界面中联系人姓名和 AI 回复均可模糊处理
- 无训练风险:消息仅作为 prompt context 发送给 LLM,不会被用于模型训练(取决于所选 LLM 提供商的数据政策)
使用责任
AI 分身功能仅供个人回忆、情感陪伴和娱乐用途。用户应当:
- 尊重他人:不将 AI 生成的内容冒充为真人发言,不用于误导、欺骗或伤害他人
- 理性看待:AI 模拟的是语言风格,不是真人的思想和意愿,不应作为重要决策的唯一依据
- 自行负责:使用本功能产生的一切后果由用户自行承担,项目作者不承担任何直接或间接责任