ChatCrystal 用于从 AI 编程对话中整理知识,Obsidian 则可以把这些知识与项目文档、读书笔记和自己的思考放在一起。连接两者的方式不必复杂:读取结构化笔记,生成 Markdown 文件,放进一个 Vault。
本文介绍如何通过 CLI 读取笔记,并设计供 Obsidian 阅读的独立快照。下面的命令与片段说明转换方法,Markdown 文件的生成需要自行实现。命令与返回结构按 ChatCrystal 提交 7642768 修订于 2026 年 9 月 23 日。
先明确数据方向
ChatCrystal 笔记与关联
→ crystal --json notes list / get / relations
→ Markdown 快照目录
→ Obsidian 阅读、搜索和链接
这个流程不把 Obsidian 的修改写回 ChatCrystal,也不复制 embedding 索引。两边继续使用各自的检索能力。Markdown 是可阅读的导出结果,不是完整数据库备份。
要导出的核心内容包括标题、摘要、结论、代码片段、标签、项目和创建时间。关联关系另取,用于生成指向其他已导出笔记的 wikilink。
列表只是一页,不是整个知识库
先在已配置好连接的终端验证:
crystal --version
crystal --json notes list --page 1 --limit 100
当前列表的结构是:
{
"items": [{"id": 1, "title": "示例笔记"}],
"total": 1,
"offset": 0,
"limit": 100
}
这里的 items 才是当前页的数据,不能按 { notes } 解构。默认列表也不是全量导出,导出时需要继续请求后续页,直到收集到 total 指示的笔记。
随后逐条读取详情和关系:
crystal --json notes get 1
crystal --json notes relations 1
CLI 已经处理服务端响应封装,因此详情输出可直接作为笔记对象读取,关系输出是数组。连接地址与凭据沿用 CLI 的现有配置,远端连接方式参考项目 CLI 文档。
组织一次完整导出
本文参照的 ChatCrystal 版本要求 Node.js 24。先确认列表、详情和关系命令均能正常返回,再按以下顺序实现转换:
- 分页收集全部笔记 ID,核对总数与分页进度。
- 读取每条笔记的完整详情和关联关系。
- 将字段转换为 Markdown,检查代码块和关联链接。
- 写入 Vault 内一个新的目录,例如
ChatCrystal-2026-09-24,核对成功后再用于阅读。
导出期间应暂停导入、摘要和人工修改。多次 CLI 请求不是数据库事务快照,总数相同也不能证明内容未变。发生请求或磁盘写入错误时,应将本次输出视为未完成,保留旧快照并在新目录中重试。
用 ID 做文件名,用标题做展示
标题不是可靠的文件标识:两条笔记可能同名,标题可能变化,还可能包含路径分隔符。可以使用 note-<id>.md,并把标题写入 frontmatter 和正文:
---
title: "SQLite 事务与恢复"
chatcrystal_id: 42
tags: ["sqlite", "recovery"]
project: "ChatCrystal"
created: "2026-06-11T01:00:00Z"
---
上面是示意。可以使用 JSON 字符串序列化生成这些 YAML 值,处理引号和换行,而不是只替换双引号。created 复制源笔记的时间值;没有时间就保留为空,不替它推断时区。
同一个 ChatCrystal 实例中,标题变动不会改变输出文件名。来自不同实例的相同数字 ID 则不能直接混用,应分别输出到不同目录。
关联关系要处理两个方向
一条关系可能是当前笔记指向其他笔记,也可能是其他笔记指向当前笔记。目标不能永远取 target_note_id:
const other = relation.source_note_id === note.id
? relation.target_note_id
: relation.target_note_id === note.id
? relation.source_note_id
: null;
只应为本次导出集合内的目标生成链接,使用与文件名一致的 [[note-42]],并保留源 ID、目标 ID、关系类型和置信度。例如 [[note-2]] → [[note-1]] — DEPENDS_ON (80%) 表示笔记 2 依赖笔记 1;在任一端查看时,箭头方向都保持一致。置信度为 0 也应显示,而不是被真假判断误删。
Obsidian 支持 wikilink 和反向链接;关系是否有业务意义仍取决于源数据,不能把一条连线等同于经过验证的因果关系。内部链接说明
每个快照目录都可能包含 note-42.md。不要把很多完整快照同时长期放在同一个 Vault 里,否则短文件名链接可能产生歧义。可把历史快照移到 Vault 外,或在长期方案中改为明确的 Vault 相对路径链接。
代码围栏不能固定为三个反引号
导出的代码可能本身就是 Markdown,其中包含三个反引号。如果外层也用三个,后半段代码会意外变成正文。
生成代码块时,先寻找代码中最长的连续反引号,再生成更长的外层围栏;语言标记只保留安全的标识字符。这样能保留代码原文,而不是通过删除反引号“修好”格式。
转换时应保留完整摘要和标签原值;若希望规范大小写或适配特殊标签字符,应另外定义规则,而不是在导出时悄悄改变语义。
快照与增量同步是两个承诺
“只导出 updated_at 晚于上次运行的笔记”还不够实现可靠同步:正文没变但关系变了怎么办?删除如何传播?标题变动是否留下旧文件?用户已在 Obsidian 中修改的内容该保留哪一份?
当前 CLI 列表并没有在本文使用的返回契约中提供足够的同步版本信息。这里采用全量快照的设计,每次写入新的目录。这样可以先确认导出的准确性,再决定是否需要更复杂的同步系统。
如果之后实现增量同步,应至少维护稳定 ID 到文件的映射、内容与关系的哈希、删除策略和人工编辑冲突规则。一次失败不能把同步水位提前到当前时间,否则可能永久跳过未完成的笔记。
定时任务也应遵守这个边界:每次使用唯一目录、记录退出码、仅在成功后切换到新快照。不要直接每小时重写你正在编辑的 Vault 文件。
在 Obsidian 中怎样使用
打开新目录中的笔记,确认正文、代码块和相关笔记链接正常。你可以通过标题和正文搜索知识,通过标签浏览主题,再沿反向链接探索关系。建议把自己的补充写进独立笔记,通过链接引用导出内容,避免下一次导出与人工编辑争夺同一文件。
若需要 ChatCrystal 的语义搜索,可在终端执行:
crystal search "SQLite 事务恢复" --limit 5
也可以进一步集成到自己的工作流,但不要把未转义的选中文本直接插进 shell 命令。搜索与导出是两种入口,不需要把向量文件搬入 Obsidian。
如何检查导出是否可信
实现自动导出时,建议用构造的 CLI 响应验证分页、同名标题、关系方向、零置信度、嵌套围栏、请求失败和禁止覆盖,再对实际知识库做抽样检查。
首次运行后,至少核对笔记总数、一条长代码笔记、两条相互关联的笔记,以及包含引号的标题。确认满意后再把输出用于日常阅读。
这条流程的目标是让知识能够离开工具继续使用。导入端的结构差异见五种 AI 对话格式,检索层的取舍见本地向量数据库选型。