news 2026/6/11 12:18:22

从 ChatCrystal 导出到 Obsidian 的工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 ChatCrystal 导出到 Obsidian 的工作流

本文面向:希望把 ChatCrystal 提取的 AI 对话知识同步到 Obsidian 个人笔记系统的用户。
预计阅读时间:9 分钟
最终效果:掌握用 ChatCrystal CLI 加一段 Node.js 脚本,把笔记自动导出为带标签、双向链接的 Obsidian Markdown 文件,并实现定时增量同步。


为什么要把 ChatCrystal 的笔记导出到 Obsidian

ChatCrystal 擅长做一件事:从 AI 对话中提取结构化知识。但它不是通用笔记工具。Obsidian 是。

你可能已经用 Obsidian 管理了项目文档、读书笔记、会议记录。如果 ChatCrystal 生成的笔记能自动同步到 Obsidian,就能把 AI 对话的知识和你的其他笔记连接起来,形成完整的知识网络。

这篇文章展示如何用 ChatCrystal CLI + 一个简单的脚本,实现笔记到 Obsidian 的自动同步。

核心思路

整个流程分三步:

ChatCrystal 数据库 → CLI 导出为 JSON → 转换脚本生成 Markdown 文件 → 写入 Obsidian Vault 目录

ChatCrystal 的笔记包含以下字段:

  • title— 标题
  • summary— 摘要
  • key_conclusions— 关键结论(数组)
  • code_snippets— 代码片段(数组,每个含 description + language + code)
  • tags— 标签(数组)
  • source_type— 来源(claude-code、cursor 等)
  • project_name— 项目名
  • created_at— 创建时间
  • relations— 关联笔记(数组)

这些字段可以自然映射到 Obsidian 的 Markdown 格式。

导出脚本

以下是一个 Node.js 脚本,读取 ChatCrystal 的笔记并生成 Obsidian 兼容的 Markdown 文件:

// export-to-obsidian.mjsimport{execSync}from'child_process';import{mkdirSync,writeFileSync}from'fs';import{join}from'path';// 配置constOBSIDIAN_VAULT=process.env.OBSIDIAN_VAULT||'/path/to/your/vault';constEXPORT_DIR=join(OBSIDIAN_VAULT,'ChatCrystal');constBASE_URL=process.env.CRYSTAL_BASE_URL||'http://localhost:3721';// 获取所有笔记(notes list --json 返回 { items, total, offset, limit })constnotesJson=execSync(`crystal notes list --json --base-url${BASE_URL}`,{encoding:'utf-8'});const{items:notes}=JSON.parse(notesJson);mkdirSync(EXPORT_DIR,{recursive:true});for(constnoteofnotes){// 获取笔记详情(包含关联关系)constdetailJson=execSync(`crystal notes get${note.id}--json --base-url${BASE_URL}`,{encoding:'utf-8'});constdetail=JSON.parse(detailJson);// 获取关联笔记constrelationsJson=execSync(`crystal notes relations${note.id}--json --base-url${BASE_URL}`,{encoding:'utf-8'}).toString().trim();constrelations=relationsJson?JSON.parse(relationsJson):[];// 构建 Markdown 内容constmd=buildMarkdown(detail,relations);// 文件名:去掉特殊字符,保留中文constsafeTitle=note.title.replace(/[\/\\:*?"<>|]/g,'-').substring(0,80);constfileName=`${safeTitle}.md`;constfilePath=join(EXPORT_DIR,fileName);writeFileSync(filePath,md,'utf-8');console.log(`导出:${fileName}`);}console.log(`\n完成! 共导出${notes.length}条笔记到${EXPORT_DIR}`);functionbuildMarkdown(note,relations){constlines=[];// YAML Frontmatter — Obsidian 用来索引和搜索lines.push('---');lines.push(`title: "${escapeYaml(note.title)}"`);lines.push(`source:${note.source_type||'unknown'}`);lines.push(`project:${escapeYaml(note.project_name||'')}`);lines.push(`created:${note.created_at||''}`);lines.push('tags:');for(consttagof(note.tags||[])){lines.push(`-${tag}`);}lines.push('---');lines.push('');// 标题lines.push(`#${note.title}`);lines.push('');// 元信息lines.push(`> 来源:${note.source_type||'未知'}| 项目:${note.project_name||'未知'}| 创建:${note.created_at||'未知'}`);lines.push('');// 摘要if(note.summary){lines.push('## 摘要');lines.push('');lines.push(note.summary);lines.push('');}// 关键结论if(note.key_conclusions&&note.key_conclusions.length>0){lines.push('## 关键结论');lines.push('');for(constconclusionofnote.key_conclusions){lines.push(`-${conclusion}`);}lines.push('');}// 代码片段if(note.code_snippets&&note.code_snippets.length>0){lines.push('## 代码片段');lines.push('');for(constsnippetofnote.code_snippets){if(snippet.description){lines.push(`###${snippet.description}`);lines.push('');}constlang=snippet.language||'';lines.push('```'+lang);lines.push(snippet.code||'');lines.push('```');lines.push('');}}// 关联笔记 — 使用 Obsidian 的 wikilink 语法if(relations&&relations.length>0){lines.push('## 关联笔记');lines.push('');for(constrelofrelations){consttargetTitle=rel.target_title||rel.title||`笔记 #${rel.target_note_id}`;constrelType=rel.relation_type||'related';constconfidence=rel.confidence?`(${Math.round(rel.confidence*100)}%)`:'';lines.push(`- [[${targetTitle}]] —${relType}${confidence}`);}lines.push('');}returnlines.join('\n');}functionescapeYaml(str){if(!str)return'';returnstr.replace(/"/g,'\\"');}

运行导出

# 设置 Obsidian Vault 路径exportOBSIDIAN_VAULT="$HOME/Documents/MyVault"# 运行导出nodeexport-to-obsidian.mjs

输出示例:

导出: SQLite WAL 模式下的并发写入问题.md 导出: JSONL 流式读取性能调优.md 导出: React useEffect 清理函数的常见陷阱.md ... 完成! 共导出 156 条笔记到 /home/user/Documents/MyVault/ChatCrystal

Obsidian 中的效果

导出后的文件在 Obsidian 中会自动获得以下特性:

1. 标签索引。YAML frontmatter 中的tags字段会被 Obsidian 识别为标签。你可以在 Obsidian 的标签面板中按#sqlite#react#性能等标签浏览。

2. 双向链接。[[笔记标题]]语法创建了 Obsidian 原生的 wikilink。在关系图谱视图中,你可以看到笔记之间的连接。

3. 全文搜索。摘要和关键结论都是纯文本,Obsidian 的全文搜索可以覆盖。

4. 代码高亮。代码块带有语言标记,Obsidian 会自动语法高亮。

增量同步

上面的脚本每次都会导出所有笔记。如果笔记量很大,每次全量导出会很慢。改进方案:只导出上次同步后新增或修改的笔记。

// incremental-export.mjsimport{execSync}from'child_process';import{mkdirSync,writeFileSync,readFileSync,existsSync}from'fs';import{join}from'path';constSTATE_FILE=join(process.env.HOME||'','.chatcrystal','export-state.json');constOBSIDIAN_VAULT=process.env.OBSIDIAN_VAULT||'/path/to/your/vault';constEXPORT_DIR=join(OBSIDIAN_VAULT,'ChatCrystal');mkdirSync(EXPORT_DIR,{recursive:true});// 读取上次同步状态letstate={};if(existsSync(STATE_FILE)){state=JSON.parse(readFileSync(STATE_FILE,'utf-8'));}constlastExportTime=state.lastExportTime||'1970-01-01T00:00:00Z';// 获取所有笔记(notes list --json 返回 { items, total, offset, limit })constnotesJson=execSync('crystal notes list --json',{encoding:'utf-8'});const{items:notes}=JSON.parse(notesJson);letexported=0;for(constnoteofnotes){// 只导出上次同步后更新的笔记if(note.updated_at&&note.updated_at<=lastExportTime){continue;}// ... 生成 Markdown 并写入(同上面的逻辑)exported++;}// 更新同步状态state.lastExportTime=newDate().toISOString();writeFileSync(STATE_FILE,JSON.stringify(state,null,2));console.log(`增量同步完成: 新增/更新${exported}条笔记`);

定时同步

用 cron(Linux/Mac)或任务计划程序(Windows)定期执行:

# 每小时同步一次0* * * *OBSIDIAN_VAULT="$HOME/Documents/MyVault"node/path/to/incremental-export.mjs>>~/.chatcrystal/export.log2>&1

Windows(PowerShell):

$action=New-ScheduledTaskAction-Execute"node"-Argument"C:\path\to\incremental-export.mjs"$trigger=New-ScheduledTaskTrigger-RepetitionInterval(New-TimeSpan-Hours 1)$env=New-ScheduledTaskSettingsSetRegister-ScheduledTask-TaskName"ChatCrystal-Obsidian-Sync"-Action$action-Trigger$trigger

反向工作流:从 Obsidian 搜索 ChatCrystal

除了导出,你还可以在 Obsidian 中直接搜索 ChatCrystal 的知识库。方法是利用 ChatCrystal 的 CLI:

在 Obsidian 中安装 “Shell Commands” 插件,配置一个命令:

crystal search "{{selection}}" --limit 5

选中一段文字,执行这个命令,就能在 ChatCrystal 的知识库中语义搜索相关内容。搜索结果会出现在 Obsidian 的输出面板中。

处理特殊情况

1. 标题冲突。不同对话可能生成相同标题的笔记。解决方案是在文件名中加入 ID 后缀:

constfileName=`${safeTitle}-${note.id}.md`;

2. 长摘要。某些笔记的摘要可能很长。Obsidian 对单个文件没有大小限制,但过长的内容会影响阅读体验。可以在脚本中截断摘要到 2000 字符。

3. 代码片段格式。ChatCrystal 的代码片段可能包含 Markdown 特殊字符(如 ` ````)。在导出时需要注意转义。

4. 标签规范化。ChatCrystal 的标签可能大小写不一致(SQLitevssqlite)。可以在导出时统一转为小写。

数据流全景

ChatCrystal Obsidian ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ SQLite 数据库 │ ──CLI──→ │ Markdown 文件 │ │ - 笔记 │ crystal notes │ - YAML 前置 │ │ - 标签 │ list/get │ - 标签 │ │ - 关联 │ relations │ - wikilinks │ │ │ │ │ │ vectra 索引 │ │ Obsidian 索引 │ │ - 向量嵌入 │ │ - 全文搜索 │ │ │ │ - 关系图谱 │ └─────────────────┘ └─────────────────┘

两个系统各自索引,各有所长。ChatCrystal 提供语义搜索(向量检索),Obsidian 提供可视化浏览和双向链接。通过定期同步,你可以在 Obsidian 中浏览和编辑笔记,同时保留 ChatCrystal 的语义搜索能力。


项目地址:github.com/ZengLiangYi/ChatCrystal

如有疑问欢迎在 GitHub Issues 或私信交流,很乐意解答。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 12:17:24

AI 驱动的进攻性与防御性自动化框架

工具介绍 CAI&#xff08;Cybersecurity AI&#xff09;是由西班牙 Alias Robotics 公司开发的轻量级开源框架&#xff0c;专注于帮助安全专业人士、研究人员和组织快速构建和部署 AI 驱动的进攻性与防御性自动化系统。它是目前 AI 安全领域的事实标准框架&#xff08;de fact…

作者头像 李华
网站建设 2026/6/11 12:15:25

MSC8154E DSP硬件设计:高速接口时序与电源系统实战解析

1. 项目概述与核心挑战在嵌入式DSP系统设计中&#xff0c;尤其是面对像MSC8154E这样的高性能多核数字信号处理器&#xff0c;硬件工程师面临的最大挑战往往不是功能实现&#xff0c;而是如何确保系统在高速运行下的稳定与可靠。我见过太多项目&#xff0c;原理图逻辑正确&#…

作者头像 李华
网站建设 2026/6/11 12:09:53

计算机毕业设计之django人脸识别的宿舍管理系统小程序

人脸识别的宿舍管理也是学校的核心&#xff0c;是必不可少的一个部分。在学校的整个服务行业中&#xff0c;学生担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类微信小程序也在不断改进。本课题所设计的人脸识别的宿舍管理系统&#xff0c;使用微信开发者与…

作者头像 李华
网站建设 2026/6/11 12:04:52

Paperxie 论文降 AIGC 降重工具,搞定知网维普双重检测难题

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/课程论文降重复率 - PaperXie智能写作PaperXie免费论文查重检测-首款免费论文检测软件,为毕业生提供专业的论文重复率检测、论文降重、Aigc检测、智能排版 、论文写作等一站式服务。https://www.paperxie.c…

作者头像 李华