思源笔记迁移 Obsidian Markdown 实战:避免表格压平与链接丢失
思源笔记迁移 Obsidian Markdown 实战:避免表格压平与链接丢失
前言
思源笔记(SiYuan Note)是国内开发者常用的知识管理工具,其 .sy 格式文档提供了块引用、子文档层级、表格合并单元格等丰富功能。
我从本科时期开始使用思源笔记,用了四五年,一直用到工作第三年。期间积累了大量学习笔记、项目资料和刷题记录,但没有形成了比较完整的知识体系。今年开始尝试结合 AI Agent 梳理知识库维护流程,经过一番选型对比后,最终决定迁移到 Obsidian。
原因主要有三点:
- Obsidian 是 Markdown 优先的工具,文件格式开放,不依赖私有数据库
- Obsidian 支持 AI Agent 直接操作 Markdown 文件,便于自动化知识梳理
- Obsidian 的双链和图谱功能更适合长期知识库维护
但迁移过程中遇到了很多坑。本文将分享我从思源笔记迁移到 Obsidian Markdown 的实战经验,重点解决三个高频痛点:
- 表格被压平成一整段文本
- 思源块链接失效或变成无法解析的占位符
- 子文档层级关系丢失
一、迁移前的认知准备
1.1 Markdown 可读性优先
迁移的第一原则:Markdown 可读性优先,结构保留其次,思源私有语义最后。
这意味着:
- 如果思源表格可以转为标准 Markdown 表格,必须转为表格
- 如果思源块引用无法保留,至少要留下被引用的文本和追溯备注
- 如果思源子文档层级无法保留,通过目录或链接表达父子关系
1.2 迁移不是"搬运"
迁移不是把思源文件搬到 Obsidian 目录,而是:
- 识别源文档的语义
- 选择合适的目标目录
- 转换为 Markdown 可读格式
- 保留可追溯信息
1.3 迁移前必须做的事
1. 确认目录映射
迁移前先确认"源目录语义 → 目标目录结构"的映射关系,避免内容落到不合适的目录后又要整体挪动。
示例:
源目录:
- 刷题
- 数据结构
目标映射提案:
- 刷题 → 10-subjects/algorithms/刷题
- 数据结构 → 10-subjects/algorithms/数据结构
2. 建立源文档清单
递归枚举源目录中的全部 .sy 文档,建立清单并分类:
- 必迁:有正文内容、知识记录、题目记录、索引作用明确的文档
- 可忽略:仅承载挂件、空日记节点、纯层级容器、无正文导航壳的文档
- 待确认:是否有迁移价值无法仅凭标题判断的文档
迁移完成后,必须按清单回查,不允许凭感觉认定"已经迁完"。
二、表格迁移:避免被压平
2.1 现象:表格变成一整段文本
思源笔记中的表格,迁移后在 Obsidian 中显示成一长段文本,不再是表格。
错误示例:
方法描述[clear()](...)删除 hashMap 中的所有键值对[clone()](...)复制一份 hashMap[isEmpty()](...)判断 hashMap 是否为空
2.2 正确做法:转为 Markdown 表格
正确示例:
| 方法 | 描述 |
| --- | --- |
| [clear()](https://www.runoob.com/java/java-hashmap-clear.html) | 删除 hashMap 中的所有键值对 |
| [clone()](https://www.runoob.com/java/java-hashmap-clone.html) | 复制一份 hashMap |
| [isEmpty()](https://www.runoob.com/java/java-hashmap-isempty.html) | 判断 hashMap 是否为空 |
2.3 Markdown 表格迁移规则
如果源内容是表格,迁移结果必须满足:
- 保留表头行
- 保留列顺序
- 每一条逻辑记录仍然占一行
- 单元格内的链接仍保留在原单元格里
- 单元格文本里如果有
|,必须做转义 - 单元格内如果有换行,无法拆列时用
<br>保留
2.4 合并单元格的处理
标准 Markdown 表格不支持合并单元格,如果思源原表格包含合并单元格:
- 拆平成普通行
- 优先保证 Obsidian 中可读
- 在表格附近补一条迁移备注
示例:
| 分类 | 方法 | 描述 |
| --- | --- | --- |
| 基础操作 | clear() | 删除 hashMap 中的所有键值对 |
| 基础操作 | clone() | 复制一份 hashMap |
| 基础操作 | isEmpty() | 判断 hashMap 是否为空 |
> 迁移备注:原表格包含合并单元格,已按 Obsidian Markdown 表格能力拆平展示。
三、块引用与链接迁移
3.1 思源链接类型
思源笔记中存在多种专有链接:
siyuan://blocks/...:块链接- 嵌入块:动态引用其他块的内容
- 块引用:在正文中引用其他块的文本
这些链接在 Obsidian 中无法直接解析。
3.2 转换优先级
转换思源链接时遵循以下优先级:
- 能稳定映射到目标笔记:转换为普通 Markdown 链接或
[[双链]] - 不能稳定映射,但引用文本有阅读价值:保留文本并补原块 ID 备注
- 既不能映射,也没有阅读价值:删除思源专有链接壳,仅保留必要说明
3.3 禁止行为
- 把
siyuan://blocks/...原样保留到 Markdown - 把
LeetCode1、题1这类仅在源文脉中有意义的占位链接直接写入目标仓库 - 宣称"已转换为双链",但仓库里仍残留不可解析链接
3.4 块引用的处理
如果思源块引用无法原生保留:
- 保留被引用文本
- 能链接到目标笔记时保留链接
- 有必要时补充原块 ID
示例:
> 引用自 [[Java集合框架]]:ArrayList 是基于动态数组实现的 List 接口。
>
> 迁移备注:原块 ID `20220115143330-50zu2x3`
四、子文档层级迁移
4.1 思源子文档结构
思源笔记支持父子文档关系,父文档下可以有多个子文档,形成层级结构。
4.2 Markdown 中的处理方式
Markdown 本身不支持子文档概念,但可以通过以下方式保留层级关系:
方式 1:目录层级
10-subjects/algorithms/
├── algorithms.md ← 父文档摘要
├── 数据结构/
│ ├── 链表.md
│ ├── 数组.md
│ └── 哈希表.md
└── 刷题/
├── DFS.md
└── 滑动窗口.md
方式 2:链接索引
在父文档中创建子文档链接列表:
## 子文档索引
- [[数据结构/链表]]
- [[数据结构/数组]]
- [[数据结构/哈希表]]
- [[刷题/DFS]]
- [[刷题/滑动窗口]]
4.3 思源 ID 的处理
思源 ID 只作为追溯元数据保留,不作为主文件名。
示例 frontmatter:
---
siyuan_id: 20220115143330-50zu2x3
siyuan_title: 链表
siyuan_parent: 20220115143320-abc123
---
五、资源文件迁移
5.1 思源资源存储方式
思源笔记的图片和附件存储在 data/assets/ 目录,笔记中通过相对路径或思源专有路径引用。
5.2 Markdown 中的处理
- 图片和附件迁到 Obsidian 仓库资源目录(如
assets/) - 笔记中的引用改成相对路径
- 不把二进制内容直接塞进正文
示例:

六、迁移检查清单
6.1 迁移前检查
- 是否先完成了"源目录 → 目标目录"的映射确认?
- 是否已递归枚举全部源
.sy,并完成必迁 / 可忽略 / 待确认分类? - 是否确定了每个必迁文档的目标路径?
6.2 迁移后验收
必迁清单中的每个siyuan_id是否都有对应 Markdown?- 仓库中是否仍存在
siyuan://blocks/残留? - 是否仍存在无法解析的占位链接,如
[[LeetCode1]]、[[题1]]? - 是否存在文件名与其
siyuan_id对应源标题不一致、且未说明原因的文档?
6.3 表格专项检查
- 源表格是否仍然是表格?
- 输出里是否存在分隔行
| --- |? - 每一行源记录是否仍可识别为一行输出?
- 单元格链接是否还在原来的单元格中?
- 遇到合并单元格时,是否补了迁移备注?
七、常见错误与修正
错误 1:表格压平成段落
现象:Obsidian 中显示成一长段文本,不是表格。
修正:重新按源表格恢复行列,输出标准 Markdown 表格语法。
错误 2:内容还在,但展示语义丢了
现象:文字都保住了,但行列关系消失。
修正:把"在 Obsidian 中显示为表格"视为硬验收项,而不是样式优化。
错误 3:过度保留思源内部信息
现象:正文里充满 ID、元数据、编辑态信息,但还是不可读。
修正:可读 Markdown 优先,ID 只保留在 frontmatter 或迁移备注里。
错误 4:没确认目录映射就直接迁移
现象:内容先被落到了不合适的目录,后续又要整体挪动。
修正:迁移前先生成目录映射提案,先复用现有合适目录,经确认后再写入。
错误 5:漏迁非空源文档
现象:顶层索引、刷题正文已经生成,但某些有实际内容的子文档没有迁入。
修正:迁移前先递归建立源 .sy 清单,明确标注 必迁 / 可忽略 / 待确认,迁移后按 siyuan_id 逐项对账。
错误 6:文件名与源文档映射错位
现象:目标文件名看似合理,但 frontmatter 中的 siyuan_id 实际对应另一篇源文档。
修正:写入前核对"源标题 → 文件名 → siyuan_id",遇到重名时使用"标题 + 原 ID 备注"的保守命名。
八、实战案例:Java HashMap 表格迁移
原思源表格
思源笔记中有一篇"Java的HashMap"笔记,包含一个方法表格,每个方法有链接和描述。
迁移后的 Markdown
# Java的HashMap
## 常用方法
| 方法 | 描述 |
| --- | --- |
| [clear()](https://www.runoob.com/java/java-hashmap-clear.html) | 删除 hashMap 中的所有键值对 |
| [clone()](https://www.runoob.com/java/java-hashmap-clone.html) | 复制一份 hashMap |
| [isEmpty()](https://www.runoob.com/java/java-hashmap-isempty.html) | 判断 hashMap 是否为空 |
| [size()](https://www.runoob.com/java/java-hashmap-size.html) | 计算 hashMap 中键值对的数量 |
| [put()](https://www.runoob.com/java/java-hashmap-put.html) | 将键值对添加到 hashMap 中 |
| [get()](https://www.runoob.com/java/java-hashmap-get.html) | 获取指定键对应的值 |
---
siyuan_id: 20220115143330-50zu2x3
Obsidian 中显示效果
在 Obsidian 中,表格正常渲染,链接可点击,整体可读性良好。
九、AI Agent 协作迁移实践
这次迁移没有完全依赖单个 Agent 一口气完成,而是拆成了"读需求生成 spec → 按 spec 实施代码 → 回收经验沉淀 Skill"三个阶段。这样做的好处是:需求、执行和复盘相互隔离,后续发现问题时可以定位到底是 spec 不完整,还是执行偏离,还是验收规则缺失。
9.1 Codex GPT-5:先读需求,生成迁移 spec
第一阶段先让 Codex GPT-5 读取迁移需求、现有 Obsidian 目录结构、思源源文件目录和已有草稿,不直接写迁移代码,而是生成一份可执行 spec。
这份 spec 重点说明:
- 迁移目标:从思源
.sy转为 Obsidian 可读 Markdown - 目录映射:源目录应该落到哪个 Obsidian 目录
- 文档分类:哪些是
必迁 / 可忽略 / 待确认 - 内容转换规则:表格、块链接、子文档、资源文件分别怎么处理
- 元数据保留规则:
siyuan_id、源标题、父子关系放在哪里 - 验收标准:如何检查漏迁、链接残留、表格压平和目录错位
我会要求 spec 尽量写成"执行者可以照着做"的格式,而不是泛泛描述原则。尤其是表格和块链接这类容易出错的部分,spec 必须给出明确的禁止行为和合格示例。
示例要求可以写成:
请先不要迁移文件。先读取当前 Obsidian 仓库结构和思源源文件结构,生成一份迁移 spec。
spec 需要包含目录映射、必迁清单、转换规则、验收清单和风险点。
对表格、块链接、子文档层级、资源文件分别给出处理规则。
9.2 GLM-5 / DeepSeek 4 Flash:读取 spec,实施迁移代码
第二阶段再把 spec 交给 GLM-5 或 DeepSeek 4 Flash 这类执行型模型,让它们读取 spec 后实施代码。这里的重点不是让模型重新理解业务,而是让它严格按 spec 写脚本、跑转换、生成结果。
实际执行时,我会把任务约束得更窄:
- 先按 spec 枚举源
.sy文档并生成清单 - 再实现转换脚本或局部转换逻辑
- 每次只处理一类问题,例如先修表格,再处理链接,再处理子文档
- 输出变更文件、跳过原因和待确认项
- 不允许擅自修改已经确认的 Obsidian 目录结构
这样可以降低执行模型自由发挥的空间。GLM-5 / DeepSeek 4 Flash 更适合承担批量读取、规则执行、代码实现和重复修正;但目录语义、验收标准和取舍原则最好提前由 spec 固定下来。
示例要求可以写成:
请严格读取 migration-spec.md,不要重新设计迁移方案。
只实现 spec 中定义的转换脚本和校验逻辑。
完成后列出:新增文件、修改文件、跳过文件、待确认文件、仍然存在的风险。
9.3 Codex GPT-5:回看结果,总结为 Skill
第三阶段再用 Codex GPT-5 回看整个迁移过程,把已经验证过的经验总结成 siyuan-markdown-migration Skill。这个阶段关注的不是继续迁移更多文件,而是把可复用规则沉淀下来,方便以后遇到类似迁移任务时复用。
Skill 中保留的是稳定规则,而不是一次性的临时上下文:
- 什么时候触发这个 Skill
- 迁移前必须收集哪些上下文
.sy到 Markdown 的转换优先级- 表格、块链接、资源、子文档的处理规则
- 常见错误和禁止行为
- 验收清单和回查方式
我会特别要求 Codex GPT-5 区分"本次仓库特有信息"和"可复用迁移原则"。例如 10-subjects/algorithms/ 是本次仓库的目录约定,不应该写成所有迁移都必须使用的固定路径;但"迁移前必须确认源目录到目标目录的映射"就是可以复用的原则。
9.4 这套分工的关键点
这套流程最重要的是不要把 Agent 当成一次性文本生成器,而是把它们放到不同阶段:
| 阶段 | 使用模型 | 主要产物 | 关键要求 |
|---|---|---|---|
| 需求整理 | Codex GPT-5 | 迁移 spec | 先定规则,不急着写代码 |
| 代码实施 | GLM-5 / DeepSeek 4 Flash | 转换脚本、迁移结果、校验输出 | 严格按 spec 执行,减少自由发挥 |
| 经验沉淀 | Codex GPT-5 | siyuan-markdown-migration Skill |
提炼稳定规则,剥离一次性上下文 |
最终沉淀下来的不是某一次迁移结果,而是一套可复用的 Agent 协作流程:先让强推理模型把需求压成明确 spec,再让执行模型按规则批量实施,最后再由强推理模型做复盘和 Skill 总结。
十、总结
思源笔记迁移到 Obsidian Markdown 的核心原则:
- 可读性优先:Markdown 在 Obsidian 中必须能正常阅读,表格必须显示为表格。
- 结构其次:父子文档关系通过目录或链接表达,不强行保留思源私有结构。
- 追溯最后:思源 ID、块引用等私有语义通过 frontmatter 或迁移备注保留,不影响正文阅读。
- 清单验收:迁移前后都要有清单,按
siyuan_id逐项对账,不凭感觉认定完成。
迁移不是简单的文件搬运,而是从思源私有格式到 Markdown 标准格式的语义转换。把握好可读性、结构、追溯的优先级,才能避免表格压平、链接丢失、层级混乱等常见问题。
十一、迁移成果展示
经过约一周的迁移工作,最终形成的 Obsidian 仓库结构如下:
.
├── .obsidian/ ← Obsidian 配置目录
├── 00-inbox/ ← 收件箱(待处理内容)
│ ├── ai-drafts/ ← AI 生成草稿
│ ├── quick-notes/ ← 快速笔记
│ ├── todo-review/ ← 待复盘内容
│ └── web-clips/ ← 网页剪藏
├── 01-ideas/ ← 想法收集
├── 02-journal/ ← 日记与复盘
│ ├── daily/ ← 日记
│ └── weekly/ ← 周记
├── 03-tasks/ ← 任务管理
│ ├── inbox/ ← 任务收集
│ └── done/ ← 已完成任务
├── 10-subjects/ ← 主题知识库
│ ├── ai/ ← AI 相关
│ ├── algorithms/ ← 算法与刷题
│ ├── backend/ ← 后端开发
│ ├── frontend/ ← 前端开发
│ ├── engineering/ ← 工程实践
│ ├── electron/ ← Electron 开发
│ ├── nodejs/ ← Node.js
│ └── career/ ← 职业发展
├── 20-summaries/ ← 总结与复盘
├── 30-projects/ ← 项目资料
│ └── active/ ← 活跃项目
├── 40-templates/ ← 模板文件
├── 90-archive/ ← 归档区(原始资料)
│ ├── 2022-algorithms-study/ ← 2022 年算法学习原始记录
│ └── 2022-backend-study/ ← 2022 年后端学习原始记录
├── 90-assets/ ← 资源文件(图片、附件)
└── 首页导航.md ← 仓库入口导航
迁移成果统计:
- 迁移时间:约 7 天
- 源文档数量:约 50+ 篇
.sy文档(含子文档) - 迁移后文件数:约 80+ 篇 Markdown 文件
- 归档原始资料:约 30+ 篇(保留在
90-archive) - 沉淀迁移规范:形成
siyuan-markdown-migrationSkill
核心变化:
| 思源目录结构 | Obsidian 目录结构 | 说明 |
|---|---|---|
| 刷题 | 10-subjects/algorithms/ |
合并到算法主题 |
| 数据结构 | 10-subjects/algorithms/数据结构/ |
作为算法子目录 |
| Java后端 | 10-subjects/backend/ + 90-archive/2022-backend-study/ |
活跃内容归 subjects,原始记录归 archive |
| SpringBoot项目 | 90-archive/2022-backend-study/springboot-practice/ |
历史项目归档 |
| 项目笔记 | 30-projects/active/ |
按项目分类 |
后续维护策略:
10-subjects/只保留可继续维护的摘要和索引90-archive/保留原始资料,不做二次编辑- 新笔记直接写入
00-inbox/,定期整理到 subjects - 经验沉淀为 Skill 文件,便于 Agent 复用
参考资料
- 思源笔记官方文档:https://b3log.org/siyuan/
- Obsidian 官方文档:https://obsidian.md/
- 本文迁移规范源文件:
10-subjects/ai/skills/siyuan-markdown-migration/SKILL.md
本文基于实际迁移经验整理,如有问题欢迎留言交流。

浙公网安备 33010602011771号