> 关键工具:Claude Code(终端自主 Agent)+ Node.js
> 技术栈阶:高阶——直接操作本地文件系统
> 完整演示:构思 → 创建项目 → 提示词编写 → AI 制作 → 项目检验 → 落地
> 预计耗时:跑通第一版约 1~2 小时;之后日常运行 1~2 秒
这一篇怎么读
这是一个跑在你本机、改你真实笔记的命令行工具,落地形态不是网址,而是"融进你每天的笔记工作流"。本篇完整走一遍从想法到日用的过程,重点演示高阶 Agent 必须有的"安全笼子"。
阶段一 · 构思:想清楚它改什么、怎么不出事
- 痛点:用了几年的 Obsidian 库里堆着大量"孤岛笔记",本该互联却没人手动连。
- 核心流程:扫描整库 → 理解每篇语义 → 为孤岛笔记推荐
双链和#标签。 - MVP:只做"推荐",先不自动写回;产出一份建议报告供人审。
- 成功标准:跑一次能得到一份靠谱的建议清单(不是噪声),且绝不破坏原笔记。
构思阶段就要定的安全底线
这个工具会批量碰你的真实笔记。第一性原则:先出报告、人审、再执行、可回滚。 这条底线决定了后面整个提示词的写法。动手前先 git init 或整库复制一份备份。
阶段二 · 创建项目:装好 Agent、备好退路
这一步把"在终端里能干活的 Agent"和"项目骨架"准备好。
- 装 Claude Code(终端自主 Agent):
npm install -g @anthropic-ai/claude-code # 安装
claude --version # 确认可用
- 进你的 vault 并建项目骨架(在库根目录操作,这样 Agent 默认就能看到所有笔记):
cd ~/path/to/your-vault
git init && git add -A && git commit -m "backup before link-tool" # 关键:先备份
npm init -y # 建 node 项目
- 在 vault 根目录启动 Agent:
claude
为什么先 git 备份
高阶 Agent 能直接改你磁盘上的文件。git commit 一份当前状态,等于给自己买了"后悔药"——万一工具跑偏,git checkout . 一键还原。任何会动真实数据的工具,第一步永远是留退路。
阶段三 · 具体提示词编写:给会动手的 Agent 下工单
高阶提示词不是描述界面,而是给 Agent 立规矩:目标、产出形态、安全边界、步长,全要写死。
起手提示词(在 vault 里启动 claude 后输入)
在当前 Obsidian vault 里做一个 Node.js 工具,为孤立笔记推荐双链和标签。
严格按规格,分步实现,每步先说计划再动手。
【输入】递归扫描当前目录所有 .md(忽略 .obsidian/ 等隐藏目录)。
【解析】每篇读出 标题、正文、已有的 #标签 和 [[双链]]。
【核心】算笔记间语义相似度,为每篇找最相关的 3 篇;
"孤立笔记"=出入链都少的笔记,优先推荐。
【安全约束——最重要】
- 绝不直接修改任何 .md。
- 把所有建议写进 suggestions.md 报告,每篇待改进笔记一节,
列"建议链接到哪几篇(附理由)"和"建议加哪些标签"。
- 让我审完报告后,再单独提供 apply 命令执行。
【步长】先只做"扫描+解析+生成 suggestions.md",不要碰相似度算法。
跑通后再加语义相似度。先把要扫描的文件数和计划告诉我。"先只做扫描、不碰算法"是在给 Agent 划步长——逼它分步交付,错了你能立刻发现。
阶段四 · AI 制作:看 Agent 产出了什么(关键片段)
Agent 先报告:"扫描到 1240 个 md 文件",然后生成了第一版脚手架。关键产出:
项目结构:
link-suggest.js # 主入口
lib/
scan.js # 扫描与解析
similarity.js # 相似度(第二步才加)
report.js # 生成 suggestions.md
.link-cache.json # 缓存(后面加,已 gitignore)
解析笔记的关键片段(提取标题、标签、双链):
// lib/scan.js(关键片段)
function parseNote(content, path) {
const tags = [...content.matchAll(/#([\w一-鿿/-]+)/g)].map(m => m[1]);
const links = [...content.matchAll(/\[\[([^\]]+)\]\]/g)].map(m => m[1]);
const title = (content.match(/^#\s+(.+)/m)?.[1]) || basename(path, '.md');
return { path, title, tags, links, body: stripFrontmatter(content) };
}
此时第一版 suggestions.md 已能生成。但一翻就发现问题——见下一步。
阶段五 · 项目检验(上):把"想太多"和"性能"两个坑填掉
5.1 坑①:性能——1240 篇不能两两硬比
1240 篇两两比较是 ~150 万次,朴素实现会很慢。人要介入做架构决策,而不是让 AI 闷头算:
性能策略提示词
两两比较太慢。改用 TF-IDF 把每篇转成关键词向量(不依赖外部 API,
离线、免费、快),用向量算余弦相似度。整个过程打印进度。特意选 TF-IDF 而非云端 embedding——处理私人笔记,离线不外泄是更优解。"用够用的方案而非最炫的方案",是工程品味。
5.2 坑②:噪声——给流水账也硬推链接
第一版报告给《今天买了牛奶》这种流水账也硬凑了 3 个双链:
降噪提示词
报告噪声太多,加两个过滤:
1. 跳过正文 < 100 字的笔记。
2. 相似度低于 SIMILARITY_THRESHOLD(先 0.35) 就不推荐,宁缺毋滥。
报告顶部打印"共扫描 X 篇,其中 Y 篇生成了建议"。"宁可不推荐也不硬凑"——又一个只有人会拍板的取舍。
5.3 核心难点:增量扫描(这个案例真正的 30%)
不可能每次都全量扫 1240 篇。要做到"今天改了 5 篇就只算这 5 篇":
增量扫描提示词
加增量能力:维护 .link-cache.json 记录每篇的 路径/修改时间/内容哈希/向量。
每次只重算"修改时间或哈希变了"的笔记,未变的复用缓存向量。
把 .link-cache.json 加进 .gitignore。运行前先做"缓存对账":
清掉缓存里已不存在于磁盘的笔记(防止推荐指向已删除的死链)。调试时撞到一个隐蔽 bug:删掉一篇笔记后,缓存里它的向量还在,于是工具还推荐链接到它。修法正是上面那句"缓存对账"。"状态与现实不一致"是所有增量缓存系统的典型陷阱。
阶段五 · 项目检验(下):按高阶工具的风险清单验收
| 检验项 | 操作 | 期望 |
|---|---|---|
| 幂等 | 连跑两次 apply | 第二次不重复加已有链接/标签 |
| 增量正确 | 改 1 篇后运行 | 只重算这 1 篇相关部分,1~2 秒完成 |
| 删除鲁棒 | 删掉一篇被推荐的笔记后运行 | 不再推荐指向它的死链 |
| 可回滚 | apply 后从 .link-backup/ 恢复 | 能完整还原原状 |
| 不污染 | 查 git status | 缓存与备份目录都被 gitignore |
阶段六 · 落地:让它融进你每天的笔记工作流
这个工具的"上线"不是部署到云,而是变成你顺手能用的日常命令。
6.1 先把 apply 做得可逆
apply 命令提示词
实现 apply:按 suggestions.md 写回笔记,但要:
- 改每个文件前先备份到 .link-backup/(可回滚)。
- 双链追加到笔记末尾的"## 相关笔记"小节,不插进正文打乱结构。
- 标签追加到 frontmatter 的 tags,不重复添加。
- 执行完打印"本次修改 N 篇,备份在 .link-backup/"。6.2 装成顺手的命令
在 package.json 加脚本,并设一个 shell 别名,日后一个词就能跑:
// package.json
"scripts": {
"suggest": "node link-suggest.js",
"apply": "node link-suggest.js apply"
}
# ~/.zshrc 加别名,以后在库里直接 notelink / notelink-apply
alias notelink='cd ~/path/to/your-vault && npm run suggest'
alias notelink-apply='cd ~/path/to/your-vault && npm run apply'
6.3(可选)定时自动跑
让它每周日自动生成一份建议报告,你周一审一眼:
# crontab -e 加一行:每周日 9:00 生成建议(只生成报告,不自动 apply)
0 9 * * 0 cd ~/path/to/your-vault && /usr/local/bin/node link-suggest.js
落地的分寸
即便"自动化",也只自动到"生成报告"为止,apply 永远留给人手动确认。这正是高阶工具落地的关键分寸:让 AI 帮你发现,让你自己决定。
30% 复盘:人类到底守住了什么
AI 能很快写出"扫描+推荐"主体(70%)。让它"敢在你真实笔记库天天跑"的 30%,全是人类的工程纪律:
| 30% 工程点 | 人类做了什么 | 不做会怎样 |
|---|---|---|
| 安全边界 | 先报告后 apply、改前备份、可回滚 | 一次跑偏,1240 篇笔记被搞乱 |
| 性能 | TF-IDF 离线向量、避免两两比对 | 全量比对慢到不可用 |
| 增量 | 缓存 + 修改时间/哈希判断变化 | 每次全量,沦为"只能用一次" |
| 状态一致 | 缓存对账,清理已删笔记 | 推荐指向不存在的死链 |
| 质量取舍 | 阈值过滤、宁缺毋滥 | 报告全是噪声 |
核心教训:高阶 Agent 越强,"把它关进笼子"的设计越重要。 最值钱的不是相似度算法,而是"先报告后执行、改前必备份、增量不全量"这套让你始终掌控的纪律。
可复用心法与提示词模板
带得走的三条
- 改文件先 dry-run 再 apply:批量改真实数据的工具都要"先建议、人审、执行、可回滚"。
- 强制 Agent 分步交付:提示词写死"先只做 X,跑通再做 Y"。
- 增量化是本地批处理的命门:缓存 + 变化检测 + 状态对账,三件套缺一不可。
通用"本地文件批处理 Agent"提示词骨架:
在当前目录做一个 <语言> 脚本,对本地 <文件类型> 做 <任务>。严格遵守:
1. 分步实现,先做"扫描+生成报告",不碰核心算法;先报文件数和计划。
2. 【安全】绝不覆盖原文件;先出 dry-run 报告供我审;apply 前自动备份、可回滚。
3. 【性能】优先离线/免费方案;大批量避免 O(n²);打印进度。
4. 【增量】缓存记录修改时间/哈希,只处理变化文件;运行前缓存对账。
5. 缓存与备份目录加入 .gitignore。