---
title: "导入"
description: "导入 Claude 和 ChatGPT 对话、MCP 记忆（memory.json）、Claude 的项目与记忆，以及普通 Markdown——格式按内容识别。"
---

# 导入

导入让你一次上传，就把已有的知识库整个搬进空间：claude.ai 和 ChatGPT 的导出包、MCP 记忆服务器（memory-server）、Claude 的项目与记忆，以及普通的 Markdown 和文本文件。格式**按内容**识别，而不看文件名，所以你不必事先手工准备什么——引擎会自己解析归档，并分门别类放进文件夹。

导入是[导出](/docs/import-export/export/)的镜像：导出从磁盘读取作为事实来源的文件，导入则解析源数据，再走常规写入路径写出笔记。每条笔记进入空间的方式，和真人在编辑器里亲手创建它别无二致——同样有版本管理、溯源和索引。

## 能识别哪些格式

一份 Claude 或 ChatGPT 归档里通常同时装着好几类数据；凡是导入认得的，它都会识别出来并一并搬过去：

| 来源 | 导出包中的文件 | 会变成怎样的笔记 |
|---|---|---|
| Claude 对话 | `conversations.json` | 每段对话一条笔记，消息呈现为 `### Human/Assistant` |
| ChatGPT 对话 | `conversations.json`（含分片形式 `conversations-000.json…`） | 每段对话一条笔记，按时间顺序的完整记录 |
| MCP 记忆 | `memory.json`（JSONL） | 每个实体一条笔记；关系 → `[[wikilinks]]` |
| Claude 项目 | `projects.json` 或 `projects/<uuid>.json` | 一个项目文件夹：文档 + 指令 |
| Claude 记忆 | `memories.json` | 账号记忆的每个块各一条笔记 |
| Claude 设计对话 | `design_chats/<uuid>.json` | 每段对话一条笔记 |
| Markdown / 文本 | `.md`、`.txt` | 一条笔记，文件正文即笔记正文 |

格式靠分析内容来判定（每家服务都会给出一个叫 `conversations.json` 的文件，所以文件名靠不住）。空消息，以及没有一段实质内容的对话，不会留下「孤儿」笔记——跳过了多少，会写在导入摘要里。归档里若混有无法识别的 JSON，它同样会作为 `unsupported` 计入摘要——数据的丢失始终摆在摘要里，而不会悄无声息地发生。

## 如何导入

导入位于空间设置的 **Import** 标签页（`/s/<space>/management/import`）中。每个选项各占一节：

- **File**——选择导出文件（`conversations.json`、整个 ZIP 导出包，或 `memory.json`）。单个 `.md`/`.txt` 文件走拖放导入（见下文），不经由这个对话框。
- **Skip existing notes**——重复导入时如何处理（见下文）。
- **Memory entries**——记忆实体往哪里放（见下文）。

耗时长的导入会作为**持久任务**运行：进度条带实时刷新的已写入笔记计数、当前阶段，以及一个 **Cancel** 按钮。你可以离开这个标签页再回来——导入会在后台继续跑，回来时你会重新看到进度，或是最终的摘要。

> [!tip] 把文件拖进窗口
> 那个单独的上传对话框并非必需：把 `.md` 或 `.txt` 文件直接拖进应用窗口，它就成了一条笔记。拖到树里的某个文件夹上，笔记就落在那个文件夹里；拖进内容区，则落在当前打开笔记所在的文件夹，或者落在根目录。这是同一条导入流水线，只是多开了一个入口。

### 「Skip existing notes」选项

笔记的文件名是确定性的，且与来源的身份绑定。正因如此，重新导入同一份导出包会**覆盖同一批文件**，而不是繁殖出一堆重复——五十段都叫「Untitled」的对话也不会互相打架。

- **关闭（重复上传时的默认值——upsert）**——已有笔记按路径覆盖，幂等。
- **开启**——路径已存在的笔记会被**跳过**。这对应的场景是：「我把更新过的历史又导了一遍——别把我手工改好的东西覆盖掉。」

### 「Memory entries」选项

`memory.json` 里的实体可以送往三个去处之一：

- **folder**——放在导入根文件夹下，作为用户可见的普通笔记。
- **space**——放进空间隐藏的智能体记忆挂载点（`.notarium/memory`）：这些条目不出现在树、文档流和搜索里，但智能体能通过 `recall` 取到。
- **skip**——干脆不导入记忆。

> [!note] 是空间的记忆，不是全局个人域
> **space** 选项放进的是该空间自己的智能体记忆。空间内部没有单独的 UI 界面来浏览这份记忆——智能体通过 `recall` 看到它。这是某一个具体空间的记忆，而不是全局的个人记忆域（后者在资源管理器树中以 **Memory** 透镜打开）——本次导入不会写到那里。

## 数据如何摆放

导入会在所选根目录下建出一棵可预期的文件夹树：

```md
conversations/claude/     — Claude 对话
conversations/chatgpt/    — ChatGPT 对话
projects/<project>/       — Claude 项目（+ docs/、prompt-template.md）
memory/claude/            — Claude 账号记忆
memory/<entity-type>/     — memory.json 中的实体
design-chats/<project>/   — Claude 设计对话
```

## 日期作为数据保留下来

天真的导入会把整段历史都打上「今天」的日期，文档流于是把几百段对话堆成一堆。Notarium 的做法相反：**把创建日期当作数据一路传下来**——每条笔记的 frontmatter 里都会写入 `created:`，取值是那段对话真正发生的时间。文档流会把导入的历史铺回它们各自的真实日期上；而「导出 → 导入」这一来一回也保留日期，搬家不掉东西。

「Created」字段也可以在编辑器里手动改（就在笔记的元数据里）——比如做迁移时，或者要订正一条笔记的日期。最后修改时间（`modified`）则始终如实反映文件被编辑的时刻，改不了。

## 底层如何运作

导入的设计要经得起两件事：GB 级的归档，和半路断掉的连接。

- **流式处理。** 上传边收边写入磁盘，ZIP 一个成员一个成员地解包，对话的 JSON 数组逐元素解析——一次只处理一段对话。峰值内存与归档大小无关，所以 600 MB 的导出包不会把服务器压垮。
- **持久任务。** 主机有元数据库时（自托管的常态），导入默认走持久任务：上传先存进暂存区，再由后台工作进程在请求之外把笔记写出来。关掉标签页、连接断开、甚至服务器重启——进度都不会丢。
- **协作式调度。** 批量导入不会独占服务器：写入会给交互请求让路，后台索引在流处理期间暂停、事后再补上。哪怕正在写入成千上万条笔记，搜索和导航依旧灵敏。

```mermaid
flowchart LR
  src([归档 / 文件]) -->|上传| stage[磁盘上的暂存区]
  stage -->|导入任务| worker[后台工作进程]
  worker -->|写入路径| notes[(Markdown 笔记)]
  worker -.->|进度| ui([Import 标签页])
```

> [!note] 没有元数据库时的导入
> 主机上没有元数据库时（只有 `AUTH_MODE=none` 模式才会没有），就没有任务层：导入在单个请求内走同步的流式路径，核心相同，实时计数器照旧。进度和摘要看上去一模一样；唯一的差别是，这样的导入扛不过服务器重启。

## 边界

- **能取消，不能暂停。** 任务可以（协作式地）取消，但不能暂停之后再恢复。
- **进度是不确定型的。** 归档里有多少笔记事先无从得知，所以进度显示的是阶段和已写入笔记的实时计数，而不是百分比和剩余时间。
- **上传一旦中断就得重来。** 持久性要等字节抵达之后才生效：大归档传到一半断了，就得从头再来。
- **二进制附件不会被导入。** 附件里的文本会嵌进笔记正文，但二进制文件本身不会（和导出一样）。
- **导入落在空间根目录。** 导入对话框不提供目标文件夹的选择——笔记进入根目录；用拖放时，根目录由落点区域决定。

## 下一步

- [导出](/docs/import-export/export/)——把空间或文件夹作为 Markdown 归档取回来。
- [智能体与 MCP](/docs/agents/)——智能体如何通过 `recall` 使用导入进来的记忆。
