note-to-blog
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNote to Blog
笔记转博客
从 Obsidian Note 仓库中筛选适合发布的笔记,评估适配性,批量选题,双通道处理(快速转换 / 深度研究),并行 Agent 派发。
从 Obsidian Note 仓库中筛选适合发布的笔记,评估适配性,批量选题,双通道处理(快速转换 / 深度研究),并行 Agent 派发。
Prerequisites
前置条件
| Tool | Type | Required | Install |
|---|---|---|---|
| Python 3 | cli | Yes | Pre-installed on macOS |
| PyYAML | pip | Yes | |
| writing-proofreading | skill | No | Included in |
Do NOT proactively verify these tools on skill load. If a command fails due to a missing tool, directly guide the user through installation and configuration step by step.
| 工具 | 类型 | 是否必需 | 安装方式 |
|---|---|---|---|
| Python 3 | cli | 是 | macOS系统预装 |
| PyYAML | pip | 是 | |
| writing-proofreading | skill | 否 | 包含在 |
请勿在技能加载时主动验证这些工具。如果因工具缺失导致命令执行失败,请直接逐步引导用户完成安装和配置。
Script Location
脚本位置
All deterministic operations are handled by the Python script:
text
scripts/note-to-blog.py (collect / convert / state subcommands)Path configuration is in user-config.md.
所有确定性操作均由Python脚本处理:
text
scripts/note-to-blog.py (包含 collect / convert / state 子命令)路径配置在user-config.md中。
Workflow Overview
工作流概述
text
Phase 1 Phase 2 Phase 3 Phase 4 Phase 5
Collect ──▶ Evaluate ──▶ Interact ──▶ Execute ──▶ Summary
(script) (LLM) (user) (Agent Teams) (report)
├─ select ├─ Fast track
├─ skip └─ Deep track
└─ assign tracktext
阶段1 阶段2 阶段3 阶段4 阶段5
收集 ──▶ 评估 ──▶ 交互 ──▶ 执行 ──▶ 总结
(脚本) (LLM) (用户) (Agent团队) (报告)
├─ 选择 ├─ 快速轨道
├─ 跳过 └─ 深度轨道
└─ 分配轨道Phase 1: Collect
阶段1:收集
Run the script to gather all data in one call:
collectbash
python3 scripts/note-to-blog.py collect \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/" \
--blog-content "repos/bokushi/src/content/" \
--project-paths \
"~/.claude/projects/-Users-sueharakyoko-code-nini-dev" \
"~/.claude/projects/-Users-sueharakyoko-code-nini-dev-repos-bokushi" \
--history-file "~/.claude/history.jsonl"The script outputs a single JSON object to stdout containing:
- : all eligible notes with title, summary, char_count, outgoing_links
candidates - : wikilink hub nodes (3+ inbound links) with related notes
clusters - : existing blog posts with title, tags, collection
published_posts - : recent Claude Code session activity signals
session_keywords - : total_scanned, filtered_out, candidates_count
stats
Read the JSON output and proceed to Phase 2.
运行脚本一次性收集所有数据:
collectbash
python3 scripts/note-to-blog.py collect \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/" \
--blog-content "repos/bokushi/src/content/" \
--project-paths \
"~/.claude/projects/-Users-sueharakyoko-code-nini-dev" \
"~/.claude/projects/-Users-sueharakyoko-code-nini-dev-repos-bokushi" \
--history-file "~/.claude/history.jsonl"脚本会向标准输出输出一个JSON对象,包含以下内容:
- : 所有符合条件的笔记,包含标题、摘要、字符数、外链
candidates - : 维基链接枢纽节点(入站链接≥3个)及其关联笔记
clusters - : 已发布的博客文章,包含标题、标签、分类
published_posts - : 近期Claude Code会话的活动信号
session_keywords - : 扫描总数、过滤数量、候选笔记数量
stats
读取JSON输出后进入阶段2。
Phase 2: Evaluate
阶段2:评估
Make a single LLM evaluation using the prompt template from scoring-criteria.md.
使用scoring-criteria.md中的提示模板,调用LLM进行一次评估。
Input
输入
Construct the evaluation prompt with the JSON data:
collect- : title + summary + char_count for each
candidates - : hub_title + related count + link_count for each
clusters - : title + tags for deduplication
published_posts - : for timeliness scoring
session_keywords
结合脚本输出的JSON数据构建评估提示:
collect- : 每条笔记的标题 + 摘要 + 字符数
candidates - : 枢纽标题 + 关联笔记数 + 链接数
clusters - : 标题 + 标签(用于查重)
published_posts - : 用于时效性评分
session_keywords
Output
输出
The LLM SHALL return a JSON array of 5~8 recommendations, mixing individual notes and topic clusters:
json
[
{
"type": "single",
"path": "Areas/大模型(LLM)/关于后LLM时代的代码Review.md",
"title": "关于后 LLM 时代的代码 Review 的看法",
"score": 92,
"collection": "blog",
"effort": "小",
"session_activity": "★★★",
"duplicate_risk": "none",
"reason": "结构完整、有真实案例、观点独特"
},
{
"type": "cluster",
"hub_title": "优雅的哲学",
"hub_path": "Areas/生活(Life)/优雅的哲学-v2.0.md",
"related_count": 9,
"score": 88,
"collection": "blog",
"effort": "大",
"theme_summary": "关于如何优雅地生活的哲学思考,散落在多篇笔记中",
"reason": "主题深度足够,需要整合多篇笔记"
}
]If the LLM response is not valid JSON, retry once with explicit format instructions.
LLM需返回一个包含5~8条推荐的JSON数组,混合单篇笔记和主题簇:
json
[
{
"type": "single",
"path": "Areas/大模型(LLM)/关于后LLM时代的代码Review.md",
"title": "关于后 LLM 时代的代码 Review 的看法",
"score": 92,
"collection": "blog",
"effort": "小",
"session_activity": "★★★",
"duplicate_risk": "none",
"reason": "结构完整、有真实案例、观点独特"
},
{
"type": "cluster",
"hub_title": "优雅的哲学",
"hub_path": "Areas/生活(Life)/优雅的哲学-v2.0.md",
"related_count": 9,
"score": 88,
"collection": "blog",
"effort": "大",
"theme_summary": "关于如何优雅地生活的哲学思考,散落在多篇笔记中",
"reason": "主题深度足够,需要整合多篇笔记"
}
]如果LLM返回的不是有效JSON,需使用明确的格式说明重试一次。
Phase 3: Interact
阶段3:交互
Step 3.1: Present recommendations
步骤3.1:展示推荐结果
Display the recommendation list as a mixed table:
text
undefined以混合表格形式展示推荐列表:
text
undefined类型 标题 适配分 目标 工作量 活跃 重复风险
类型 标题 适配分 目标 工作量 活跃 重复风险
1 单篇 后LLM时代代码Review 92 blog 小 ★★★ 无
2 主题簇 优雅的哲学 (9篇关联) 88 blog 大 ★ 无
3 单篇 SSH私钥加密 85 til 小 ─ 无
4 单篇 Feed内容阅读姿势 82 blog 小 ★ 无
...
For cluster entries, show the hub title and related note count.1 单篇 后LLM时代代码Review 92 blog 小 ★★★ 无
2 主题簇 优雅的哲学 (9篇关联) 88 blog 大 ★ 无
3 单篇 SSH私钥加密 85 til 小 ─ 无
4 单篇 Feed内容阅读姿势 82 blog 小 ★ 无
...
对于主题簇条目,需显示枢纽标题和关联笔记数量。Step 3.2: User actions
步骤3.2:用户操作
The user can perform batch operations:
| Action | Example | Effect |
|---|---|---|
| Select + assign track | "1 和 3 快速转换,2 走深度" | Queue items with track assignment |
| Override collection | "1 放 til" | Change target collection |
| Batch skip | "4~6 跳过,reason: private" | Mark as skipped via |
| See more | "还有别的吗" | Request additional recommendations (exclude previously shown items) |
| Check status | "状态" | Run |
On skip: run the state script immediately for each skipped item:
bash
python3 scripts/note-to-blog.py state skip "<path>" --reason "<reason>" \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/"用户可执行批量操作:
| 操作 | 示例 | 效果 |
|---|---|---|
| 选择并分配轨道 | "1 和 3 快速转换,2 走深度" | 将条目加入队列并分配处理轨道 |
| 覆盖目标分类 | "1 放 til" | 修改目标分类 |
| 批量跳过 | "4~6 跳过,原因:私密内容" | 通过 |
| 查看更多 | "还有别的吗" | 请求更多推荐(排除已展示的条目) |
| 查看状态 | "状态" | 运行 |
跳过操作:立即为每个跳过的条目运行状态脚本:
bash
python3 scripts/note-to-blog.py state skip "<path>" --reason "<reason>" \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/"Step 3.3: Track assignment
步骤3.3:处理轨道分配
Each selected item must be assigned a track:
| Track | When to use | What happens |
|---|---|---|
| Fast (快速) | Independent, mostly complete notes | Script converts → Agent reviews → draft |
| Deep (深度) | Topic clusters or rough notes needing research | Agent reads all related notes → research report |
Default suggestions:
- with
type: "single"→ suggest fast trackeffort: "小" - or
type: "cluster"→ suggest deep trackeffort: "大" - User always makes the final decision
每个选中的条目必须分配一个处理轨道:
| 轨道 | 使用场景 | 处理流程 |
|---|---|---|
| 快速轨道 | 独立完整的笔记 | 脚本转换 → Agent审核 → 生成草稿 |
| 深度轨道 | 主题簇或需要补充研究的粗糙笔记 | Agent读取所有关联笔记 → 生成研究报告 |
默认建议:
- 且
type: "single"→ 建议使用快速轨道effort: "小" - 或
type: "cluster"→ 建议使用深度轨道effort: "大" - 最终决定权在用户手中
Step 3.4: Confirm selections
步骤3.4:确认选择
Before proceeding, display a summary:
text
确认选择:
Fast track:
1. 后LLM时代代码Review → blog/
3. SSH私钥加密 → til/
Deep track:
2. 优雅的哲学 (9篇关联) → blog/
开始处理?Wait for user confirmation.
在执行前展示选择摘要:
text
确认选择:
快速轨道:
1. 后LLM时代代码Review → blog/
3. SSH私钥加密 → til/
深度轨道:
2. 优雅的哲学 (9篇关联) → blog/
开始处理?等待用户确认。
Phase 4: Execute (Agent Teams)
阶段4:执行(Agent团队)
Dispatch N parallel Agents using the Task tool, one per selected item. Each Agent operates independently.
使用Task工具调度N个并行Agent,每个选中的条目对应一个Agent,各Agent独立运行。
Parallel dispatch
并行调度
text
总编 (Main Agent)
├── Task Agent 1: 文章 A (fast track)
├── Task Agent 2: 文章 B (fast track)
└── Task Agent 3: 主题簇 C (deep track)Use the Task tool to launch all Agents in a single message (parallel execution). Each Agent should be a subagent with a detailed prompt containing all the information it needs (note path, script path, target collection, etc.).
general-purposetext
总编 (主Agent)
├── 任务Agent 1: 文章A(快速轨道)
├── 任务Agent 2: 文章B(快速轨道)
└── 任务Agent 3: 主题簇C(深度轨道)在一条消息中使用Task工具启动所有Agent(并行执行)。每个Agent应为子Agent,提示信息中需包含其所需的全部信息(笔记路径、脚本路径、目标分类等)。
general-purposeFast Track Agent Instructions
快速轨道Agent说明
Each fast track Agent receives these instructions:
Step 1 — Run the convert script (use the absolute path to the script in the Agent prompt):
bash
python3 "<absolute-path-to-skill>/scripts/note-to-blog.py" convert "<full-path-to-note>"Step 2 — Review the converted output (the script automatically handles):
- Obsidian fields stripped (aliases, date, modified, etc.)
- Frontmatter set to: title, pubDate (today), tags (merged from frontmatter + inline #tags), hidden: true
- Wikilinks → plain text, image embeds → standard markdown, callouts → bold, highlights → bold, comments → removed
- Verify no conversion artifacts or TODO comments from unrecognized syntax
Step 3 — Generate a description: Write a one-sentence description for the blog post frontmatter (in the same language as the article content).
Step 4 — Write the draft: Add the field to the converted frontmatter, then write to where is a kebab-case version of the title.
descriptionrepos/bokushi/src/content/<collection>/<slug>.md<slug>Step 5 — Return a result object:
json
{
"status": "done",
"note_path": "<relative note path>",
"draft_path": "<collection>/<slug>.md",
"description": "<generated description>",
"issues": ["<any issues found>"],
"suggestions": ["<improvement suggestions>"]
}每个快速轨道Agent需执行以下步骤:
步骤1 — 运行转换脚本(在Agent提示中使用脚本的绝对路径):
bash
python3 "<技能的绝对路径>/scripts/note-to-blog.py" convert "<笔记的完整路径>"步骤2 — 审核转换输出(脚本自动处理以下内容):
- 移除Obsidian字段(别名、日期、修改时间等)
- 设置前置元数据:标题、发布日期(今日)、标签(合并前置元数据标签和行内#标签)、hidden: true
- 维基链接转为纯文本,图片嵌入转为标准Markdown格式,提示框转为粗体,高亮内容转为粗体,注释移除
- 检查是否存在转换残留或无法识别语法导致的TODO注释
步骤3 — 生成描述:为博客文章的前置元数据写一句描述(语言与文章内容一致)。
步骤4 — 生成草稿:将字段添加到转换后的前置元数据中,然后写入,其中是标题的短横线分隔形式。
descriptionrepos/bokushi/src/content/<collection>/<slug>.md<slug>步骤5 — 返回结果对象:
json
{
"status": "done",
"note_path": "<笔记相对路径>",
"draft_path": "<collection>/<slug>.md",
"description": "<生成的描述>",
"issues": ["<发现的问题>"],
"suggestions": ["<改进建议>"]
}Deep Track Agent Instructions
深度轨道Agent说明
Each deep track Agent receives these instructions:
Step 1 — Read all related notes: Read the hub note and all related notes listed in the cluster.
Step 2 — Produce a structured research report:
markdown
undefined每个深度轨道Agent需执行以下步骤:
步骤1 — 读取所有关联笔记:读取枢纽笔记和主题簇中的所有关联笔记。
步骤2 — 生成结构化研究报告:
markdown
undefined主题报告:<hub_title>
主题报告:<hub_title>
涉及笔记 (N 篇)
涉及笔记(N篇)
- <title> (hub, <char_count>字)
- <title> (<char_count>字)
- ...
- <标题>(枢纽,<字符数>字)
- <标题>(<字符数>字)
- ...
主题地图
主题地图
- 核心论点:...
- 子话题 A:...(涉及 N 篇)
- 子话题 B:...(涉及 N 篇)
- 核心论点:...
- 子话题A:...(涉及N篇笔记)
- 子话题B:...(涉及N篇笔记)
重叠与矛盾
重叠与矛盾
- <specific overlaps or contradictions found>
- <发现的具体重叠或矛盾点>
缺口
内容缺口
- <missing arguments, incomplete sections>
- <缺失的论点、不完整的章节>
建议大纲
建议大纲
- 引言:...
- 第一部分:...(来源:笔记 A、B)
- 第二部分:...(来源:笔记 C、需要补充)
- 结论:...
**Step 3 — Return a result object**:
```json
{
"status": "done",
"note_path": "<hub note path>",
"related_paths": ["<related note paths>"],
"report": "<full research report markdown>",
"suggested_collection": "<blog/til/monthly>"
}- 引言:...
- 第一部分:...(来源:笔记A、B)
- 第二部分:...(来源:笔记C、需补充内容)
- 结论:...
**步骤3 — 返回结果对象**:
```json
{
"status": "done",
"note_path": "<枢纽笔记路径>",
"related_paths": ["<关联笔记路径>"],
"report": "<完整的研究报告Markdown>",
"suggested_collection": "<blog/til/monthly>"
}Important: State updates
注意:状态更新
Individual Agents do NOT update directly. After all Agents complete, the main agent collects results and runs state updates sequentially:
.note-to-blog.jsonFor each fast track result:
bash
python3 scripts/note-to-blog.py state draft "<note_path>" \
--target "<collection>/<slug>.md" \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/"Deep track items are NOT marked as drafted (they need further user decision).
单个Agent不得直接更新。所有Agent完成后,主Agent收集结果并依次运行状态更新:
.note-to-blog.json对于每个快速轨道结果:
bash
python3 scripts/note-to-blog.py state draft "<note_path>" \
--target "<collection>/<slug>.md" \
--note-repo "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/"深度轨道条目不会标记为草稿(需要用户进一步决策)。
Phase 5: Summary
阶段5:总结
After all Agents complete, present a unified summary:
所有Agent完成后,展示统一总结:
Fast track results
快速轨道结果
text
Fast Track 完成:
✓ 后LLM时代代码Review → repos/bokushi/src/content/blog/llm-code-review.md
- 转换正常,无问题
- 建议:可补充最新的 AI code review 工具对比
✓ SSH私钥加密 → repos/bokushi/src/content/til/ssh-key-encryption.md
- 发现 1 个 TODO 标记需要手动处理text
快速轨道完成:
✓ 后LLM时代代码Review → repos/bokushi/src/content/blog/llm-code-review.md
- 转换正常,无问题
- 建议:可补充最新的AI代码审核工具对比
✓ SSH私钥加密 → repos/bokushi/src/content/til/ssh-key-encryption.md
- 发现1个TODO标记需要手动处理Deep track results
深度轨道结果
text
Deep Track 完成:
📋 优雅的哲学 (9篇关联)
- 研究报告已生成
- 建议大纲:4 部分,来源涵盖 7 篇笔记
- 下一步?
a) 按大纲写作(调用 Agent 生成初稿)
b) 修改大纲
c) 暂不处理text
深度轨道完成:
📋 优雅的哲学 (9篇关联)
- 研究报告已生成
- 建议大纲:4部分,来源涵盖7篇笔记
- 下一步?
a) 按大纲写作(调用Agent生成初稿)
b) 修改大纲
c) 暂不处理State update confirmation
状态更新确认
text
状态更新:
drafted: 2 篇
下次 collect 时这些笔记将不再出现在候选列表中。
草稿均为 hidden: true,需要手动 review 后改为 false 发布。
建议使用 /writing-proofreading 进行审校。
发布后运行 state publish 更新状态:
python3 scripts/note-to-blog.py state publish "<note_path>" --note-repo "..."text
状态更新:
草稿:2篇
下次执行collect时这些笔记将不再出现在候选列表中。
所有草稿均设置为hidden: true,需要手动审核后改为false才能发布。
建议使用/writing-proofreading进行审校。
发布后运行state publish更新状态:
python3 scripts/note-to-blog.py state publish "<note_path>" --note-repo "..."Detailed References
详细参考文档
- Path configuration: user-config.md
- LLM evaluation prompt and scoring: scoring-criteria.md
- 路径配置:user-config.md
- LLM评估提示与评分标准:scoring-criteria.md