
作为一个经常用 Obsidian 整理小说设定和剧本资料的效率党我最头疼的事情就是人物一多关系就乱。刚开始可能只有三五个人物还能靠记忆撑住等到世界观铺开、角色超过二十个的时候谁是谁的师父、谁和谁有仇、谁在暗中帮谁全乱成一团。更麻烦的是这些关系分散在十几篇笔记里每次想回顾剧情都要来回翻。后来我搭了一套 Obsidian 自动生成人物关系白板的方案用模板统一管理人物笔记然后用 Templater 插件一键解析所有 Markdown 笔记自动生成一张 Mermaid 关系图甚至可以直接在 Canvas 白板里手动微调布局。整个过程不需要复制粘贴、不需要手动画线改完人物笔记后重新运行一次脚本关系图就会自动更新。这篇文章就把完整思路和可复制的模板代码分享出来适合小说作者、剧本创作者、跑团玩家以及所有在 Obsidian 里管理复杂实体关系的人。1. 为什么要自动生成人物关系白板1.1 人物关系图的痛点如果你亲手画过人物关系图应该能理解那种“画到一半就想放弃”的感觉。最开始我用的还是思维导图软件后来换成了在线白板工具。工具本身不差但真正的痛点不在画图而在“关系变了之后怎么同步”。今天新增一个角色明天把两个角色的关系从“盟友”改成“敌对”每一次修改都要回到白板里手动移动节点、重画连线、修改标签。一旦人物超过二十个白板就会变得极其拥挤连线交叉得根本看不清。更糟糕的是关系往往不是单一维度的。师徒关系、血缘关系、阵营关系、利益关系、仇恨关系可能同时存在。如果全画在一张图上视觉上就是一团乱麻。1.2 为什么选择 Obsidian MarkdownObsidian 本质上是一个本地 Markdown 笔记软件但它不只用来记笔记。它有很完整的双链系统比如你用[[林晚]]这种语法就能把两篇笔记连起来它还有非常强大的插件生态可以让你用 Dataview、Templater 这样的工具去读取、处理、批量生成笔记内容。因为所有笔记都是纯 Markdown 文本所以数据非常规整。我们完全可以把人物关系的“描述”和“可视化”分开人物关系的数据写在 Markdown 笔记的 frontmatter 里可视化结果由脚本自动读取数据并生成。这样维护的就是数据本身而不是画布上那些线。只要数据正确关系图就可以无限次重新生成永远跟笔记内容保持一致。1.3 自动生成方案的整体思路这套方案的核心不是某个单一插件而是“模板 脚本 渲染”的组合用统一的 Markdown 模板维护每个人物笔记人物笔记的 frontmatter 里声明relationships数组用来表示“这个人物和谁有关系、是什么关系”用 Templater 写一段 JavaScript 脚本遍历笔记库中所有人物笔记脚本把人物关系数据拼装成 Mermaid 语法的图表代码脚本自动写入或者更新一个独立的关系图.md文件Obsidian 天然支持 Mermaid 渲染打开这个文件就能看到一张可交互的关系图。整个过程只需要按一次快捷键所以叫它“一键解析”。2. 环境准备Obsidian 安装与插件生态2.1 Obsidian 的安装如果你还没有安装 Obsidian直接去官网下载即可。由于 Obsidian 安装包是从海外服务器分发的部分地区下载速度确实很慢有时候还会卡在“正在准备下载”很久。如果你遇到 Obsidian 下载太慢的情况可以尝试以下方式去官网选择 Windows / macOS / Linux 对应的安装包优先使用官方稳定版如果官网下载缓慢可以尝试使用 GitHub Releases 页面下载使用支持断点续传的下载工具避免下载到一半中断下载完成后如果发现安装包损坏重新下载即可不要勉强安装。Obsidian 本身是本地笔记软件个人使用是免费的。安装完成后会要求你打开一个“库”文件夹也就是你的笔记目录这个目录里全部是 Markdown 文件没有复杂的数据库结构后期迁移和备份都很方便。2.2 需要安装的插件本文核心依赖两个社区插件请提前安装插件作用Templater模板引擎可以运行 JavaScript 脚本用于自动解析笔记并生成新的 Markdown 文件Dataview查询和展示笔记元数据用于辅助排查数据是否写对打开 Obsidian 的设置界面进入“第三方插件”关闭“安全模式”然后点击“浏览”进入社区插件市场搜索并安装上述插件。如果社区插件市场打不开通常是因为网络问题。此时可以手动安装插件先下载插件的 release 文件解压后把整个文件夹放到你笔记库根目录下的.obsidian/plugins/文件夹中然后在 Obsidian 里重新加载或重启再到“第三方插件”里启用它。由于插件版本更新较快某些插件的配置界面可能会有变化但 Templater 的核心模板语法和 Dataview 的查询逻辑都比较稳定可以放心使用。2.3 建议的笔记库目录结构为了让脚本扫描时不至于把无关文件也纳入统计建议给笔记库一个清晰的目录结构。我的项目结构长这样我的小说库/ ├─ .obsidian/ │ ├─ plugins/ │ │ ├─ templater-obsidian/ │ │ └─ dataview/ ├─ 人物/ │ ├─ 林晚.md │ ├─ 沈砚.md │ └─ 苏念.md ├─ templates/ │ ├─ 人物模板.md │ └─ 生成人物关系图.md ├─ 关系图.md └─ 设定总览.md人物/文件夹存放所有人物笔记templates/存放模板和自动生成脚本关系图.md是最终生成的关系白板会自动更新不需要手动编辑。3. 人物笔记建模用 Markdown 描述关系3.1 用 frontmatter 存储结构化数据Markdown 文件除了正文之外还可以在文件头部写一段 YAML 格式的 frontmatter。Obsidian 和 Dataview、Templater 插件都能读取这段内容。frontmatter 的基本格式是--- key: value ---放在文件最顶部注意开头和结尾都要有三条短横线。比如一篇基本的人物笔记可以这样写--- type: 人物 姓名: 林晚 身份: 天机阁阁主 阵营: 中立 --- 林晚是这篇小说里比较特殊的角色……type: 人物是给所有人物笔记打上的统一标记。这样脚本在遍历全库的时候不用猜哪些笔记是人物只需要找type 人物的文件即可。3.2 如何表示人物关系人物关系最直观的表达方式是“谁和谁是关系”。我选择在 frontmatter 里维护一个relationships数组每个数组项包含两个字段target关联目标的文件名type关系类型比如“师徒”“盟友”“前任”“仇敌”。示例--- type: 人物 姓名: 林晚 身份: 天机阁阁主 阵营: 中立 relationships: - target: 沈砚 type: 师徒 - target: 苏念 type: 盟友 ---这里target: 沈砚对应的是人物/沈砚.md这篇笔记。后续脚本在生成关系图时会读取目标名字然后与库内的人物文件进行匹配。要注意target必须写中文名并且要和你的人物笔记文件名保持一致。如果文件名是“沈砚”但target写成了“沈砚陆家养子”脚本就会匹配不上导致连线缺失。3.3 正文中的双链仍然很重要frontmatter 里的relationships负责给脚本提供结构化数据而笔记正文里的双链[[沈砚]]也很重要原因有两个Obsidian 内置的 Graph View 关系图谱会读取双链并自动形成一张无向网络图双链能让你在阅读人物笔记时直接点击跳转到关联角色阅读体验更好。所以建议在人物笔记的正文里也保留双链描述形成“正文可读、frontmatter 可算”的双层结构。例如林晚是 [[沈砚]] 的师父多年来一直在暗中保护他。 她与 [[苏念]] 虽然立场不同但为了共同的目标暂时结盟。这样既不会破坏 Markdown 文本的阅读感又方便之后用内置 Graph View 快速预览整张网络。3.4 关系方向问题在 Mermaid 图中连线是由方向性的。关系是“林晚 是 沈砚 的师父”还是“沈砚 是 林晚 的师父”这两者完全不一样。我建议统一使用“从当前人物指向目标人物”的语义。也就是说在“林晚”的笔记中写target: 沈砚, type: 师徒表达的含义是“林晚 → 沈砚师徒”。如果你后续写了“沈砚”的笔记也写了target: 林晚, type: 师徒那就会出现一条重复的且反向的连线。为了避免这种问题最简单的方法是统一约定只在一方维护关系字段。比如默认在“长辈/上级/主动方”的笔记中写关系另一方不再重复写。这样能减少很多重复数据。4. 核心原理Templater 如何“一键解析”4.1 Templater 能做什么Templater 是一个比 Obsidian 内置模板功能强大得多的插件。它允许你在模板里写 JavaScript 脚本当模板被执行时脚本会运行并把结果插入当前文件或者新文件。我们正好可以利用这一点写一个 Templater 模板让模板在被执行时去扫描全库的人物笔记然后生成 Mermaid 代码并把代码写入一个新的 Markdown 文件。这个过程相当于把“读取数据 → 组装视图 → 写文件”三个步骤封装在一个模板里每次运行都是全自动的。4.2 用到的 Obsidian API在 Templater 脚本中我们可以通过app对象访问 Obsidian 的 API。本方案主要用到两个接口app.vault.getMarkdownFiles()返回仓库中所有 Markdown 文件的TFile对象列表。app.metadataCache.getFileCache(file)读取指定文件解析后的缓存信息其中.frontmatter就是文件的 frontmatter 数据。示例const files app.vault.getMarkdownFiles(); for (const file of files) { const cache app.metadataCache.getFileCache(file); const frontmatter cache cache.frontmatter; if (frontmatter frontmatter.type 人物) { // 这就是一个人物文件 } }注意getFileCache返回的是 Obsidian 的内部缓存对象字段名可能随着 Obsidian 版本而变化。在多数版本中frontmatter就是一个普通的键值对象可以直接访问。如果你发现frontmatter里的值是 undefined可以先打开一篇笔记让 Obsidian 读取一次缓存再重新运行脚本。4.3 为什么生成 Mermaid 而不是直接生成 Canvas也许有人会问为什么不直接生成 Obsidian 的 Canvas 白板文件因为 Canvas 文件的本质是 JSON结构比 Markdown 复杂很多自动生成的难度也更高。而 Mermaid 是一种基于文本的图表描述语言Obsidian 原生支持渲染只需在 Markdown 文件里写mermaid graph LR A[林晚] --|师徒| B[沈砚] Obsidian 就会自动渲染成关系图。这种方式非常简单、稳定而且修改之后立即重新渲染。所以本文先把 Mermaid 作为主方案。如果你确实需要 Canvas 白板那种手动拖拽的体验可以参考第 6 章的做法把 Mermaid 图作为草稿再手动补充到 Canvas 中。4.4 生成 Mermaid 代码的拼接规则生成 Mermaid 代码其实就是拼字符串但需要小心两点节点不能重名中文节点名最好使用英文 ID 加显示名避免解析异常。所以我用P1、P2这样的编号作为 Mermaid 节点 ID再通过[中文名]设置节点显示名。这样 Mermaid 解析器不会因为中文字符产生兼容性问题。生成后的 Mermaid 代码大致像下面这样graph TD P1[林晚] P2[沈砚] P3[苏念] P1 --|师徒| P2 P1 --|盟友| P35. 完整实战从零搭建一键关系白板5.1 建立目录和模板文件在开始写代码之前先把目录结构搭好。在 Obsidian 中你可以直接在文件管理器里新建文件夹也可以直接在你的笔记库目录中创建文件夹。建议先手动创建两个文件夹人物/templates/然后打开 Obsidian 设置找到 Templater 插件的配置界面设置模板文件夹为templates/这样后续只需通过命令面板就能一键运行模板。5.2 创建人物笔记模板首先创建一个统一的人物笔记模板路径是templates/人物模板.md内容如下--- type: 人物 姓名: % tp.file.title % 身份: 阵营: relationships: - target: type: --- ## 角色简介 在这里填写人物的基本信息、性格、外貌等。 ## 核心关系 - [[沈砚]]师徒 - [[苏念]]盟友 ## 剧情目标 在这里填写人物在故事中的目标、冲突和成长线。这个模板用到了 Templater 的变量% tp.file.title %在执行“当前笔记应用模板”时它会自动把当前笔记的文件名作为姓名填入 frontmatter。5.3 创建示例人物笔记接下来我创建三个示例人物用来演示效果。你可以直接在 Obsidian 中新建笔记也可以手动创建 Markdown 文件。第一个例子人物/林晚.md--- type: 人物 姓名: 林晚 身份: 天机阁阁主 阵营: 中立 relationships: - target: 沈砚 type: 师徒 - target: 苏念 type: 盟友 --- 林晚是 [[沈砚]] 的师父多年来一直在暗中保护他。 她与 [[苏念]] 虽然立场不同但为了共同的目标暂时结盟。第二个例子人物/沈砚.md--- type: 人物 姓名: 沈砚 身份: 剑客 阵营: 天机阁 relationships: - target: 林晚 type: 师父 --- 沈砚是 [[林晚]] 的弟子性格孤傲剑术天赋极高。 他与 [[苏念]] 有过一段旧情但如今已形同陌路。第三个例子人物/苏念.md--- type: 人物 姓名: 苏念 身份: 江湖医师 阵营: 中立 relationships: - target: 林晚 type: 盟友 - target: 沈砚 type: 旧情 --- 苏念是江湖上有名的医师与 [[林晚]] 是盟友关系。 她和 [[沈砚]] 之间有着一段说不清道不明的旧情。注意为了演示效果我故意让三个角色之间的relationships有重复和反向。你可以观察最后生成的关系图是怎样的再决定要不要按第 3 章建议的“单向维护”方式精简。5.4 创建自动生成关系图的 Templater 脚本这是整套方案的核心文件。创建一个新模板路径为templates/生成人物关系图.md内容如下这是一个完整的 Templater 模板文件。请注意最外层围栏是四个反引号因为内部需要包含一个 Mermaid 代码块的字符串--- 类型: 关系图 生成时间: % tp.date.now(YYYY-MM-DD HH:mm) % --- %* // 1. 遍历全库找出所有 type 为“人物”的笔记 const files app.vault.getMarkdownFiles(); const persons []; for (const file of files) { const cache app.metadataCache.getFileCache(file); const fm cache cache.frontmatter; if (fm fm.type 人物) { persons.push({ name: file.basename, relations: fm.relationships || [] }); } } // 2. 生成 Mermaid 节点代码使用 P1、P2 作为节点 ID const lines []; lines.push(mermaid); lines.push(graph TD); const idMap {}; persons.forEach((p, index) { const id P (index 1); idMap[p.name] id; lines.push( ${id}[${p.name}]); }); // 3. 生成 Mermaid 连线代码 persons.forEach(p { const fromId idMap[p.name]; if (Array.isArray(p.relations)) { p.relations.forEach(rel { if (rel rel.target rel.type idMap[rel.target]) { lines.push( ${fromId} --|${rel.type}| ${idMap[rel.target]}); } }); } }); lines.push(); // 4. 把拼接好的内容输出到当前模板生成的文件中 tR lines.join(\n); %下面逐段解释这段脚本第 1 步通过app.vault.getMarkdownFiles()拿到所有 Markdown 文件然后通过app.metadataCache.getFileCache(file)读取 frontmatter。只有type 人物的文件才会进入persons数组。第 2 步遍历persons为每个人物分配一个P1、P2这样的唯一 ID然后生成一行 Mermaid 节点代码。第 3 步再次遍历persons把每个节点的relationships数组里的关系对象转成连线。idMap[rel.target]用来把目标中文名映射成节点 ID这样即使中文名相同也不会冲突。第 4 步用tR ...把生成的字符串写入当前文件。Templater 在执行模板时tR表示最终输出内容。5.5 运行生成脚本打开任意一篇笔记或者处于文件管理器中按 Templater 默认快捷键通常是Alt N打开模板选择器然后选择“生成人物关系图”。执行之后Obsidian 会创建一个新标签页里面就是自动生成的关系图 notebook。因为模板里已经写好了 frontmatter你可以先把它保存成关系图.md再打开预览。如果你希望每次运行后强制覆盖同一个关系图.md可以再配合tp.file.move()把生成的文件移动到指定路径。不过更简单的做法是第一次生成后把该文件命名为关系图.md之后每次运行模板再手动删除旧文件重新生成。为了避免繁琐你可以后续用 Templater 的tp.file.include或者自定义命令去封装不过初版方案已经足够日常使用。5.6 预期效果打开最新生成的关系图.md你应该能看到一个 Mermaid 关系图。因为三个示例人物之间有互相连线所以图中会显示林晚 → 沈砚师徒林晚 → 苏念盟友沈砚 → 林晚师父苏念 → 林晚盟友苏念 → 沈砚旧情可以发现因为我在示例中重复维护了关系所以会出现多条连线和反向连线。这正好说明了一个问题关系方向字段需要约定清楚否则图上会有冗余内容。你可以在脚本里加一个去重逻辑只保留第一次出现的“A → B 关系类型”。具体实现方式可以是维护一个 Set判断from - to - type是否已经存在。我放在后面“最佳实践”里详细说明。5.7 如果页面没有渲染关系图如果打开关系图.md后只看到 Mermaid 源码而没有渲染出图原因一般是文件的后缀不是.mdObsidian 没有开启 Mermaid 支持。正常情况下 Obsidian 原生支持 Mermaid但如果你安装了主题或插件冲突可能需要检查脚本生成的 Mermaid 语法有错误。可以先手动测试一下新建一个笔记写入最简单的一段 Mermaid 代码看看能不能渲染。mermaid graph LR A[测试] -- B[成功] 如果这条笔记能正常渲染说明 Obsidian 本身没问题问题出在脚本生成的代码上。此时可以打开“阅读视图”查看生成的 Mermaid 源码对照 Mermaid 语法检查是否有漏掉空格、引号未闭合等问题。6. 白板进阶从 Mermaid 到 Canvas6.1 Obsidian Canvas 是什么Obsidian 的新版本中内置了 Canvas 功能它就是一个可以自由拖拽节点、画连线、写便签、嵌入笔记卡片的“白板”工具。Canvas 文件的后缀是.canvas本质上是一个 JSON 文件。Canvas 非常适合做最终排版你可以把人物卡片摆开手动调整位置给连线加上颜色和说明。相比之下Mermaid 适合快速查看关系结构但布局是自动的不能手动调整。所以合理的工作流是先用 Templater 自动生成 Mermaid 关系图打开 Canvas新建一块白板把人物笔记作为卡片拖进去在卡片之间画连线如果需要自动生成 Canvas可以用脚本生成.canvas文件。6.2 手动 Canvas 制作步骤新建 Canvas 的入口在左侧工具栏点击之后会生成一个空白画布。然后在左侧文件列表中把人物/林晚.md、人物/沈砚.md、人物/苏念.md三篇笔记拖入画布。Obsidian 会把它们变成可移动的卡片。接着用画布上的连线工具从一个卡片边缘拖到另一个卡片边缘即可创建一条连线。选中连线后可以给连线修改文字标签和颜色。这种方法虽然不是“一键自动生成”但胜在可以直接手动微调。比较适合需要最终交付给他人查看、或者需要精细控制版面风格的场景。6.3 尝试用脚本生成 Canvas JSON如果你对自动生成 Canvas 文件感兴趣核心思路是先分析一个手动画好的.canvas文件看它的 JSON 结构写 Templater 脚本遍历人物笔记生成对应的节点数组和连线数组把 JSON 写入一个.canvas文件。不过 Canvas JSON 的字段在不同版本中可能会有调整我在这里不展开写具体的生成代码避免因为版本差异导致误导。建议你先手动创建一个简单的 Canvas然后用文本编辑器打开它观察里面节点的坐标、尺寸、颜色、连线字段的组织方式再照着生成。如果你已经对 Canvas JSON 格式有把握那思路与生成 Mermaid 是完全一样的只是最后拼装的代码结构不同。6.4 备选可视化插件除了 Mermaid 和 CanvasObsidian 社区还有一些可视化插件例如 Juggl 等可以基于双链生成可交互的思维网络图。不过这类插件的更新频率参差不齐安装前建议看一下插件主页的状态和维护情况。如果只是想快速看关系网络Obsidian 内置的 Graph View 其实也够用。你只需要在人物笔记正文中保留双链Graph View 就会自动展示节点之间的连线。它的优点是零成本、自动更新缺点是无法显示关系类型也没有白板排版的自由度。所以在实际使用中我的建议是快速回顾剧情用 Graph View对外展示或深度排版用 Canvas自动生成关系图用本文的 Templater Mermaid 方案。7. 常见问题与排查思路7.1 Obsidian 下载太慢无法安装这是很多人入门 Obsidian 时遇到的第一道坎。如果官网下载速度很慢可以尝试从 GitHub Releases 页面下载安装包或者使用带有断点续传功能的下载工具。下载完成之后建议先校验一下安装包大小是否正常如果压缩包只有几百 KB通常是不完整的需要重新下载。7.2 社区插件市场打不开Obsidian 的社区插件市场基于 GitHub 分发部分地区网络连接不稳定导致插件市场加载不出来。解决办法有两种一是多刷新几次或者稍后再试二是手动安装插件。手动安装时去插件对应的 GitHub Releases 页面下载 zip 文件解压后放入.obsidian/plugins/插件名/目录下然后在 Obsidian 设置里启用。需要注意手动安装插件时要确保解压后的文件夹名称与main.js、manifest.json所在的位置匹配否则 Obsidian 可能识别不到插件。7.3 Templater 脚本没有输出内容如果运行“生成人物关系图”模板后页面上什么都没有请检查以下几点问题现象常见原因解决思路输出内容为空脚本没有进入人物列表遍历检查笔记是否设置了type: 人物输出内容为空frontmatter 字段没读出来先打开任意人物笔记刷新缓存再运行脚本输出内容为空relationships字段名写错统一使用relationships不要写relations只输出了 Mermaid 源码脚本拼装的代码缩进或引号有问题打开阅读视图对比 Mermaid 语法中文人物连线缺失target与文件名不一致让target严格等于文件名7.4 生成的图没有渲染只有代码块如果生成的代码块顶部是mermaid graph TD P1[林晚] 但页面没有渲染成图可以先排除是否 Obsidian 没有启用 Mermaid。Obsidian 在较新的版本中默认支持 Mermaid但如果你开启了一些深色主题或者代码块插件可能会有干扰。可以在设置里搜索“代码块”查看是否有与 Mermaid 冲突的插件。如果排查不出可以先禁用最近安装的插件再测试。7.5 人物笔记多了之后生成速度变慢脚本每次都会遍历所有 Markdown 文件。如果你的库里有上千篇笔记而人物笔记只有几十篇仍然会对所有文件执行一次缓存读取这会让生成速度变慢。优化方式是在脚本里先根据文件夹过滤。如果人物笔记都在人物/文件夹可以只在file.path.startsWith(人物/)时读取 frontmatter这样可以减少大量无效 IOconst files app.vault.getMarkdownFiles(); for (const file of files) { if (!file.path.startsWith(人物/)) continue; const cache app.metadataCache.getFileCache(file); // ... }7.6 Mermaid 图中出现大量重复连线前面说到如果每篇人物笔记都维护了关系就很容易出现重复或者反向连线。解决思路有两个一种是在数据维护阶段统一约定关系只写在一方笔记中。另一种是在脚本生成阶段做去重例如const seen new Set(); // ... const key fromId - targetId - type; if (seen.has(key)) return; seen.add(key); lines.push( ${fromId} --|${type}| ${idMap[rel.target]});这样可以避免同一对“A → B 关系类型”出现多次。8. 最佳实践与工程建议8.1 统一人物文件命名人物文件名一旦确定就不要随意修改。因为target字段和正文双链都依赖文件名改文件名会导致旧链接失效脚本也匹配不上人物。如果确实需要改名建议在 Obsidian 中重命名Obsidian 会自动更新仓库内的双链。但relationships数组里的target字符串不会自动更新需要手动检查。8.2 用受控词表维护关系类型关系类型如果太自由比如“师徒”“是师父”“师傅”“弟子”混用会导致最终生成的关系图很乱。建议建立一个“关系类型词表”比如师父弟子盟友仇敌夫妻旧情上级下属在创建人物笔记时尽量从词表里选择关系类型避免同一种关系出现多个版本的叫法。8.3 注意关系的方向语义关系图是有向图还是无向图取决于你的语义定义。本文使用的 Mermaid 连线是--表示“由当前人物指向目标人物”。如果你要表达“林晚是沈砚的师父”最佳实践是只在“林晚”的笔记中写一条target: 沈砚, type: 师徒不要同时在“沈砚”的笔记中反向写一条target: 林晚, type: 师父。如果确实需要双向关系也可以把它们视为两条语义不同的关系但生成图时要注意视觉上的交织。8.4 定期清理插件生态Obsidian 社区插件非常多装得越多启动越慢潜在的脚本冲突也越多。建议每个季度做一次插件体检查看哪些插件已经超过一年没有使用关闭或卸载不必要的插件将核心的脚本模板单独维护利用 Obsidian 自带的“核心插件”减少依赖。8.5 使用 Git 备份笔记人物关系脚本在运行时会覆盖关系图.md。如果你在脚本改造过程中出现了覆盖错误之前的关系图可能就丢了。建议对笔记库启用 Git 版本管理每次脚本修改和运行后都能快速回滚。Obsidian 本身不内置 Git 功能但你可以把笔记库目录初始化为 Git 仓库然后定期提交。这样改动任何模板或笔记都有据可查。8.6 脚本去重与排序为了得到一张干净的关系图生成脚本最好加上两个处理人物节点按文件名排序保证每次生成的图节点顺序一致连线按照fromId toId type去重并排序。这样可以避免每次运行脚本后界面布局和连线顺序发生不稳定的跳变方便后续配合 Canvas 进行二次调整。9. 总结与下一步探索这篇文章从小说场景下的人物关系维护痛点出发介绍了如何用 Obsidian 的 Markdown 笔记体系配合 Templater 插件自动解析人物笔记中的 frontmatter 数据并生成一张可以随时更新的 Mermaid 人物关系白板。你不仅学会了模板脚本的写法也理解了关系数据建模的基本思路先确定数据结构再选择可视化形式最后用脚本把二者串起来。如果后续想继续深入可以从三个方向入手扩展脚本让它可以生成势力分布图、时间线、剧情脉络等更多类型的图表学习 Canvas JSON 格式尝试把 Mermaid 自动生成的节点和连线直接写入.canvas文件结合 Dataview 做一个关系查询面板比如“显示某个角色的所有关联对象”这样就不需要在笔记和关系图之间反复切换。这套方法不限于小说创作写资料库、管理项目团队、梳理知识体系时只要把“人物”换成“项目”“成员”“知识点”再调整一下字段语义就能直接复用。如果你正在用 Obsidian 搭知识库建议先把人物笔记模板建好再往里面填内容最后运行一次生成脚本看看关系图是否符合你的预期。数据越规范自动化脚本越省心。