导入聊天记录
导入前请确认你有权处理双方共同产生的聊天内容,并阅读 负责任使用与数据隐私。不要把未脱敏的真实导出文件提交到 GitHub、Issue 或 PR。
还没有导出文件?先看各平台导出教程。
支持格式
| 来源 | 格式 | 内置 plugin |
|---|---|---|
| Afterglow Chat v1 | JSON、typed/bare JSONL | afterglow_v1 |
| QQChatExporter | JSON、chunked JSONL | qqexporter_v5 |
| WeFlow | arkme-json、ChatLab JSONL | wechat_weflow |
| Douyin Chat Export | ChatLab JSON、JSONL | douyin_chat_export |
| TXT、Markdown | whatsapp | |
| Telegram Desktop | HTML | telegram_html |
| DiscordChatExporter | JSON | discord_chat_exporter |
微信导入使用第三方开源工具 WeFlow。支持导出 arkme-json 或 ChatLab JSONL 格式。请在评估权限与隐私风险后导入,并优先在隔离、离线环境中操作。
其它平台可转换为 Afterglow Chat v1,或实现独立 ingestion plugin。 长期维护、公开使用以及需要完整保留源平台语义时,独立 plugin 更合适。
WhatsApp 和 Telegram 导入
WhatsApp 选择导出目录中的 chat.txt,也支持样本中的 chat.md。两者是同一份聊天记录,选择其中一个即可;Markdown 的时间只有分钟精度。TXT 支持方括号和 Android 的日期加短横线格式、12/24 小时制、多行消息和 Unicode 方向控制字符。点分隔日期按日/月解释;斜杠日期默认月/日,若有首项大于 12 的日期则整份文件按日/月解释。没有时区的时间使用 APP_TIMEZONE(默认 Asia/Shanghai)。
Telegram Desktop 选择导出目录中的 messages.html;分页导出时一起选择 messages2.html 等所有聊天页。解析依赖 HTML 的结构与时间属性,不依赖日期分隔符的显示语言、导出目录名或文件名。保留连续发言的发送者、引用目标、媒体说明及占位符;没有时间的日期分隔符和通知不计入聊天消息。
uv run xuwen import 路径/到/WhatsAppAelura/chat.txt --language zh-CN
uv run xuwen import 路径/到/TGChatExport_2026-10-13/messages.html --language zh-CN
uv run xuwen import-images 路径/到/TGChatExport_2026-10-13 --plugin telegram_html --language zh-CN这两类导出没有提供发送者账号 UID,插件用昵称生成带 whatsapp: / telegram: 前缀的身份标识。请在配置向导确认谁是“我”、谁是“朋友”;昵称更改或同名账号需要手动检查身份。消息正文可包含任何语言,当前 WhatsApp 媒体占位符识别覆盖中文和英文;其它语言的媒体描述会作为原文保留。
Telegram 图片导入读取导出目录内的原图与静态贴纸;动画、语音、视频保留占位符。WhatsApp 样本没有媒体文件,只保留占位符。Telegram HTML 上传只导入文本,图片导入需要保留完整导出目录后单独运行 import-images。
DiscordChatExporter 导入
使用 DiscordChatExporter 导出的 JSON 聊天文件,包含发送者账号 ID、消息时间和引用回复。插件不依赖文件名或界面语言,中文与英文文件名都可以导入;导入前在向导中分配“我”和“朋友”。Discord 官方 package 个人数据包不是此格式,且没有对方回复。
uv run xuwen import "路径/到/Direct Messages - Friend [频道ID].json" --language zh-CN附件和贴纸保留媒体占位符,正文和附件说明保留原文。只有指向导出目录内图片的相对路径可用于 import-images;远程 CDN URL 不会自动下载。
配置向导导入
配置向导允许一次上传一个或多个 .json、.jsonl、.ndjson、.txt、.md、.html 或 .htm 文件。它会分别识别每个文件的格式 和候选 UID。跨平台或多账号时,把自己的全部 UID 标为“我”,目标人物的全部 UID 标为“朋友”。
所有同时上传的文件必须属于同一个目标人物。WebUI 会合并本次任务中的全部文件生成 persona、 风格和作息画像。
CLI 文本导入
cd backend
# 单文件
uv run python -m xuwen.ingestion.cli import chat.json --language zh-CN
# 多文件,可混合 JSON / JSONL 和不同内置格式
uv run python -m xuwen.ingestion.cli import qq.json wechat.json douyin.json chunks/*.jsonl --language zh-CN
# 强制指定格式;混合格式时不要指定
uv run python -m xuwen.ingestion.cli import chat.jsonl --plugin afterglow_v1 --language zh-CN多文件文本导入会复用数据库连接和 Embedding 客户端,但每个文件仍独立完成清洗、会话切分和 chunk 构建。因此向量窗口与 response pair 不跨文件边界。导入完成后,作息画像会使用本次传入的全部文件 去重重建,主动开聊画像则从全部已入库窗口重建。
CLI 的 --language zh-CN / --language en 指定本次命令的输出语言;省略时读取进程环境或选定 .env 中的 XUWEN_LANGUAGE,未设置则默认英文。聊天原文不会被翻译,界面语言也不会替 CLI 选择语言。
QQChatExporter JSONL
选择导出目录中的 chunks/*.jsonl,不要选择只含索引信息的 manifest.json:
uv run python -m xuwen.ingestion.cli import 路径/到/chunks/*.jsonl --language zh-CNchunked JSONL 通常不包含 manifest 中的当前账号身份。首次使用向导时需要手动确认双方 UID。
只做文本导入时,可以在 QQChatExporter 高级选项中选择仅保留文件元数据;需要历史图片检索时, 必须另外保留实际图片资源目录。
WeFlow ChatLab JSONL
uv run python -m xuwen.ingestion.cli import 路径/到/微信聊天.jsonl --language zh-CNChatLab member 记录不可靠地标注哪个账号是自己,因此同样需要在向导中分配身份。
Douyin Chat Export
使用 Douyin Chat Export 导出的 ChatLab JSON 或 JSONL:
uv run python -m xuwen.ingestion.cli import 路径/到/抖音聊天.jsonl --language zh-CNplugin 使用 meta.ownerId 标记自己,并把消息中最活跃的非 owner 成员作为朋友候选;导入前仍应在 配置向导确认身份。文本、分享链接和引用关系会保留。纯图片、表情、语音、视频和无正文分享只作为 对话窗口中的占位符,不会成为朋友单条回复或 response pair。
抖音导出的图片内容是带有效期的 CDN URL 或 data URL。文本导入只保存 [图片] 占位符,当前 import-images 不会下载这些远程内容,也不会把 URL 或 base64 数据送入向量库。
表情占位符模式
默认 raw 模式会归一化常见 QQ/微信方括号表情。若中间件已把文字表情统一为 [/表情]:
uv run python -m xuwen.ingestion.cli import chat.json \
--json-emoji-mode normalized --language zh-CN导入与 persona 分析必须使用相同的 --json-emoji-mode。
多文件 persona
# 单文件
uv run python scripts/analyze_persona.py chat.json
# 多文件,必须属于同一个目标人物
uv run python scripts/analyze_persona.py qq.json wechat.json chunks/*.jsonlscripts/analyze_persona.py 和 scripts/check_proactive_quality.py 是独立辅助脚本,目前没有 --language 参数,部分控制台提示仍为中文。不要给它们追加该参数;需要选择语言的导入或分析任务请使用主 CLI 的 --language zh-CN / --language en。
persona 聚合器会跨文件去重,并按 ingestion plugin 分组。在每个 plugin 的时间线内统一排序和重新切分 会话,因此同格式 chunk 边界两侧可以形成回复样本;不同 plugin 都参与总体语言与作息统计,但不会组成 跨平台问答对。
产物写入 PERSONA_DATA_DIR:
persona_card.mdpersona_report.jsonpersona_style_profile.jsoncircadian_profile.json
历史图片
文本导入只保留媒体占位和图片引用。需要图片检索时,保留完整导出目录:
export-dir/
chat.json 或 chat.jsonl
resources/ 或 media/
任意子目录/
image.jpg配置 VISION_ENABLED=true 及 VISION_API_* 后运行:
uv run python -m xuwen.ingestion.cli import-images export-dir --language zh-CN命令会递归发现多个 JSON/JSONL 和图片,按文件内容 SHA-256 去重,调用视觉模型生成摘要并写入 history_images。原图不会在每次聊天时重复发送给主模型。
中断续跑
文本 chunk ID 是确定性的;导入或 Embedding 中断后重新执行同一命令,已入库部分会被跳过。开启打标后, 可单独继续未完成的标签:
uv run python -m xuwen.ingestion.cli label --language zh-CN部分 Embedding 请求失败时,配置向导会显示未入库的 chunk 数量,并提供重试入口。重新导入相同文件可补齐缺失记录;正常续跑时跳过已入库记录不算失败。
Discord、Telegram 和 WhatsApp 的消息与应答对 ID 不再依赖消息在导出文件中的序号,因此导出范围变化后,相同消息与应答对仍可复用 ID。旧版本 ID 对应的数据库记录不会自动迁移;此前已入库的正文损坏、图片错配或重复记录,需要另行清理,或使用原始导出文件重建。