在这里插入图片描述

一、为什么程序员需要"第二大脑"?

作为程序员,你是否遇到过这些痛点:

  • 📚 知识碎片化:Stack Overflow、GitHub Issues、技术博客看了一堆,需要时却想不起来
  • 🔍 重复搜索:同一个问题解决过,过段时间又要重新 Google
  • 📝 笔记混乱:Notion、印象笔记、本地 Markdown 散落各处,找不到想要的
  • 🧠 认知负担:大脑装着太多技术细节,影响深度思考

核心矛盾:信息爆炸时代,"记录"变得越来越容易,但"检索"和"复用"依然是瓶颈。

解决方案不是更努力地记笔记,而是建立一套让 AI 帮你管理知识的自动化系统:用 Obsidian 做结构化存储,用 Claude Code 做智能写入与检索。


二、技术选型:为什么是 Claude Code + Obsidian?

2.1 Obsidian 的核心优势

特性 说明
本地优先 数据完全自主,永不丢失,无订阅绑架
Markdown 原生 纯文本格式,可纳入 Git 版本控制
双向链接 构建知识网络,自动发现隐藏关联
REST API 插件 支持外部程序读写笔记,这是集成的关键
插件生态 Dataview、Templater 等扩展可实现动态索引

2.2 Claude Code 的核心优势

⚠️ 重要说明:Claude Code 是 Anthropic 的终端 AI 编码代理,并非通用的知识管理工具。本文通过 CLAUDE.md 指令 + Bash 脚本 + MCP 集成三种方式,将其扩展为知识管理助手。

特性 说明
终端原生 在任何有 Shell 的环境运行,无需 IDE
CLAUDE.md 指令系统 项目/用户级别的持久化指令,定义 AI 行为
MCP 服务器集成 通过标准协议连接外部服务
Hooks 机制 工具调用前后自动触发脚本
全代码库感知 理解整个项目结构,不只是单文件

2.3 完整集成架构

工具层

读取行为指令

HTTP PUT/GET

知识检索

图谱渲染

动态查询

调用工具

👤 用户输入
(终端自然语言)

Claude Code CLI
~/.claude/settings.json

CLAUDE.md
用户级 / 项目级

Bash 脚本
obsidian-write.sh

MCP 服务器
(可选扩展)

Hooks
preToolUse / postToolUse

Local REST API
端口 27124
Obsidian 插件

Obsidian Vault
本地 Markdown 文件

知识图谱视图

Dataview 插件


三、环境准备与安装

3.1 安装 Obsidian

# macOS(推荐 Homebrew)
brew install --cask obsidian

# Windows
winget install Obsidian.Obsidian

# Linux:从官网下载 AppImage
# https://obsidian.md/download

3.2 安装 Claude Code

Claude Code 当前(2026 年 4 月)推荐使用原生安装脚本,不再需要 Node.js:

# macOS / Linux(推荐,无需 Node.js)
curl -fsSL https://claude.ai/install.sh | sh

# Windows PowerShell(管理员权限)
irm https://claude.ai/install.ps1 | iex

# npm 方式(需要 Node.js 18+,适合固定版本场景)
npm install -g @anthropic-ai/claude-code

# 验证安装
claude --version

认证方式:首次运行 claude 后,终端会引导打开浏览器完成 OAuth 登录(适合 Pro/Max/Team 账户)。CI/CD 环境可通过环境变量 ANTHROPIC_API_KEY 直接认证。

3.3 安装 Obsidian Local REST API 插件

  1. 打开 Obsidian → 设置 → 社区插件 → 关闭安全模式
  2. 搜索并安装 “Local REST API”
  3. 在插件设置中:
    • 启用 HTTPS,端口保持 27124
    • 点击 Generate new API key,复制保存备用
    • 勾选 Enable non-encrypted (HTTP) server(可选,用于本地调试)

验证 API 是否正常:

# 替换 YOUR_TOKEN 为实际 token
curl -sk -H "Authorization: Bearer YOUR_TOKEN" \
  https://127.0.0.1:27124/vault/ | python3 -m json.tool

四、Obsidian 目录结构设计

4.1 基于 PARA 方法的目录结构

📁 Obsidian Vault/
├── 📁 00-Inbox/          # 📥 快速捕获区(Claude 自动写入此处)
├── 📁 01-Notes/          # 📝 日常笔记与日记
├── 📁 02-Knowledge/      # 📚 沉淀后的技术知识
├── 📁 03-Projects/       # 🚀 项目相关笔记
├── 📁 04-Areas/          # 🎯 长期关注领域
├── 📁 05-Archives/       # 📦 已完成/过期内容
├── 📁 06-Attachments/    # 📎 图片、PDF 等附件
└── 📁 Templates/         # 📋 笔记模板

设计原则:Claude Code 写入笔记统一落入 00-Inbox/,经人工整理后再移至对应目录。这避免了 AI 误分类导致的混乱。

4.2 标准笔记 Frontmatter 规范

所有由 Claude 自动创建的笔记应包含以下元数据,便于 Dataview 查询:

---
title: "React 18 Concurrent Mode 学习笔记"
date: 2026-04-20
tags:
  - 前端
  - React
  - 学习笔记
type: note          # note | bug | meeting | project | idea
status: inbox       # inbox | processed | archived
source: claude      # 标记由 Claude 自动生成
related:
  - "[[React Hooks 总结]]"
  - "[[前端性能优化]]"
---

4.3 每日笔记模板(Templates/daily-note.md

---
title: "{{date:YYYY-MM-DD}} 日记"
date: {{date:YYYY-MM-DD}}
tags:
  - 日记
type: daily
---

## ✅ 今日完成

- 

## 💡 今日收获

- 

## 🔗 相关笔记

- 

## 📅 明日计划

- 

五、配置 Claude Code 与 Obsidian 集成

5.1 配置架构说明

⚠️ 重要澄清:Claude Code 的配置文件是 ~/.claude/settings.json(JSON 格式)。Obsidian 集成不是 Claude Code 的原生配置项,而是通过以下方式实现:

  1. CLAUDE.md — 告诉 Claude 如何使用 Obsidian
  2. Bash 脚本 — 实际执行 API 调用
  3. 环境变量 — 存储 token 等敏感信息

5.2 存储 Obsidian API Token

不要将 token 硬编码在脚本中,使用环境变量:

# 添加到 ~/.zshrc 或 ~/.bashrc
export OBSIDIAN_API_TOKEN="your_token_here"
export OBSIDIAN_VAULT_PATH="$HOME/Documents/Obsidian Vault"
export OBSIDIAN_API_PORT="27124"

# 使配置生效
source ~/.zshrc

5.3 用户级 CLAUDE.md 配置

创建 ~/.claude/CLAUDE.md,让 Claude Code 在所有项目中都知道如何操作 Obsidian:

# 用户全局指令

## Obsidian 笔记操作

当用户要求保存笔记、记录想法或整理信息时,使用以下工具:

### 写入笔记
调用脚本:`~/.claude/scripts/obsidian-write.sh "<文件名>" "<内容>"`

脚本会将笔记保存到 Obsidian Vault 的 `00-Inbox/` 目录。

### 笔记格式规范
- 所有笔记必须包含 YAML frontmatter(date、tags、type、status: inbox、source: claude)
- 技术笔记包含:背景、核心内容、代码示例、相关链接
- Bug 记录包含:问题描述、根本原因、解决方案、防止复现措施
- 会议纪要包含:参会人、主题、决议、待办事项

### 文件命名规范
格式:`{类型}-{简短描述}-{YYYYMMDD}.md`
示例:`tech-react18-concurrent-mode-20260420.md`

5.4 Claude Code 设置文件

~/.claude/settings.json 中可以配置全局行为(此为实际生效的配置文件):

{
  "env": {
    "OBSIDIAN_API_PORT": "27124"
  },
  "permissions": {
    "allow": [
      "Bash(~/.claude/scripts/*)"
    ]
  }
}

六、核心脚本:obsidian-write.sh

6.1 创建脚本目录

mkdir -p ~/.claude/scripts

6.2 完整脚本代码

创建 ~/.claude/scripts/obsidian-write.sh

#!/usr/bin/env bash
# ============================================================
# obsidian-write.sh — 向 Obsidian 写入笔记
# 使用方式: ./obsidian-write.sh <文件名(不含路径)> <笔记内容>
# ============================================================

set -euo pipefail

# ── 参数检查 ────────────────────────────────────────────────
if [ $# -lt 2 ]; then
    echo "❌ 用法: $0 <文件名> <内容>" >&2
    exit 1
fi

FILENAME="$1"
CONTENT="$2"

# ── 读取配置(优先环境变量,fallback 默认值) ────────────────
API_TOKEN="${OBSIDIAN_API_TOKEN:-}"
API_PORT="${OBSIDIAN_API_PORT:-27124}"
API_BASE="https://127.0.0.1:${API_PORT}"
INBOX_DIR="00-Inbox"

if [ -z "$API_TOKEN" ]; then
    echo "❌ 错误: 环境变量 OBSIDIAN_API_TOKEN 未设置" >&2
    echo "   请在 ~/.zshrc 中添加: export OBSIDIAN_API_TOKEN='your_token'" >&2
    exit 1
fi

# ── 自动补全文件名 ────────────────────────────────────────────
# 如文件名不含日期后缀,自动添加今日日期
if [[ ! "$FILENAME" =~ [0-9]{8}\.md$ ]]; then
    DATE=$(date +%Y%m%d)
    # 移除已有 .md 后缀再拼接
    BASENAME="${FILENAME%.md}"
    FILENAME="${BASENAME}-${DATE}.md"
fi

TARGET_PATH="${INBOX_DIR}/${FILENAME}"

# ── URL 编码(处理中文文件名) ────────────────────────────────
# 使用 Python 进行可靠的 URL 编码
ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$TARGET_PATH', safe='/'))")

# ── 执行写入请求 ──────────────────────────────────────────────
HTTP_RESPONSE=$(curl -sk \
    -w "\n%{http_code}" \
    -X PUT "${API_BASE}/vault/${ENCODED_PATH}" \
    -H "Authorization: Bearer ${API_TOKEN}" \
    -H "Content-Type: text/markdown; charset=UTF-8" \
    --data-binary "${CONTENT}")

HTTP_CODE=$(echo "$HTTP_RESPONSE" | tail -n1)
RESPONSE_BODY=$(echo "$HTTP_RESPONSE" | head -n-1)

# ── 结果判断 ──────────────────────────────────────────────────
if [[ "$HTTP_CODE" == "200" || "$HTTP_CODE" == "204" ]]; then
    echo "✅ 笔记已保存: ${TARGET_PATH}"
    exit 0
else
    echo "❌ 保存失败 (HTTP ${HTTP_CODE})" >&2
    echo "   响应体: ${RESPONSE_BODY}" >&2
    echo "   请确认 Obsidian 正在运行且 Local REST API 插件已启用" >&2
    exit 1
fi
# 添加执行权限
chmod +x ~/.claude/scripts/obsidian-write.sh

# 验证脚本可用
~/.claude/scripts/obsidian-write.sh "test-hello-world" "# 测试笔记\n\n这是一条测试。"

6.3 读取笔记脚本

创建 ~/.claude/scripts/obsidian-read.sh

#!/usr/bin/env bash
# 读取 Obsidian 笔记内容
# 用法: ./obsidian-read.sh <文件路径(相对于 Vault 根目录)>

set -euo pipefail

FILE_PATH="${1:-}"
API_TOKEN="${OBSIDIAN_API_TOKEN:-}"
API_PORT="${OBSIDIAN_API_PORT:-27124}"

if [ -z "$FILE_PATH" ] || [ -z "$API_TOKEN" ]; then
    echo "❌ 用法: $0 <文件路径>" >&2
    exit 1
fi

ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$FILE_PATH', safe='/'))")

curl -sk \
    -H "Authorization: Bearer ${API_TOKEN}" \
    "https://127.0.0.1:${API_PORT}/vault/${ENCODED}"

6.4 搜索笔记脚本

#!/usr/bin/env bash
# 搜索 Obsidian 笔记
# 用法: ./obsidian-search.sh <关键词>

QUERY="${1:-}"
API_TOKEN="${OBSIDIAN_API_TOKEN:-}"
API_PORT="${OBSIDIAN_API_PORT:-27124}"

ENCODED_QUERY=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$QUERY'))")

curl -sk \
    -H "Authorization: Bearer ${API_TOKEN}" \
    "https://127.0.0.1:${API_PORT}/search/simple/?query=${ENCODED_QUERY}&contextLength=200"
chmod +x ~/.claude/scripts/obsidian-read.sh ~/.claude/scripts/obsidian-search.sh

七、实战工作流演示

工作流总览

Obsidian Local REST API Bash 脚本 Claude Code 👤 用户 Obsidian Local REST API Bash 脚本 Claude Code 👤 用户 "记录笔记:React 18 Concurrent Mode..." 解析意图,生成结构化 Markdown 调用 obsidian-write.sh HTTP PUT /vault/00-Inbox/xxx.md 写入文件到磁盘 204 No Content HTTP 200/204 ✅ 笔记已保存 "已保存到 00-Inbox/tech-react18..."

7.1 场景一:快速记录技术要点

用户输入

请记录笔记:今天学习了 React 18 的 Concurrent Mode,核心概念包括:
1. Suspense 边界
2. useTransition Hook
3. 自动批处理(Automatic Batching)

Claude 生成并保存的笔记00-Inbox/tech-react18-concurrent-mode-20260420.md):

---
title: "React 18 Concurrent Mode 学习笔记"
date: 2026-04-20
tags:
  - 前端
  - React
  - React18
  - Concurrent
type: note
status: inbox
source: claude
---

# React 18 Concurrent Mode 学习笔记

## 背景

React 18 引入并发模式(Concurrent Mode),允许 React 同时准备多个版本的 UI,从而避免长时间渲染阻塞用户交互。

## 核心概念

### 1. Suspense 边界
用于处理异步加载状态,配合 `React.lazy` 或数据获取库(如 React Query)使用。

```jsx
<Suspense fallback={<Loading />}>
  <AsyncComponent />
</Suspense>

2. useTransition Hook

将非紧急的状态更新标记为"过渡",避免阻塞高优先级交互(如输入响应)。

const [isPending, startTransition] = useTransition();
startTransition(() => {
  setSearchResults(filterData(input));
});

3. 自动批处理(Automatic Batching)

React 18 将异步事件中的多次 setState 自动合并为一次渲染,减少不必要的重新渲染。

相关笔记

  • [[React Hooks 最佳实践]]
  • [[前端性能优化]]

---

**Claude 终端输出**:

✅ 笔记已保存: 00-Inbox/tech-react18-concurrent-mode-20260420.md


### 7.2 场景二:Bug 记录与追踪

**用户输入**:

记录一个 Bug:生产环境 Redis 连接池耗尽, 原因是 finally 块缺失导致连接未释放, 解决方案是使用 try-finally 确保 conn.close()


**生成笔记**(`00-Inbox/bug-redis-connection-leak-20260420.md`):

```markdown
---
title: "Bug: Redis 连接池耗尽"
date: 2026-04-20
tags:
  - Bug
  - Redis
  - 后端
  - Python
type: bug
status: inbox
source: claude
severity: P0
environment: production
---

# Bug:Redis 连接池耗尽

## 问题描述
生产环境 Redis 连接池耗尽,导致新请求无法获取连接,服务降级。

## 根本原因
异常场景下 `conn.close()` 未被执行,连接泄漏累积导致连接池耗尽。

## 解决方案

### ❌ 错误写法
```python
def get_data(key: str):
    conn = redis_pool.get_connection()
    result = conn.get(key)
    conn.close()  # 抛出异常后此行不会执行!
    return result

✅ 正确写法

def get_data(key: str):
    conn = redis_pool.get_connection()
    try:
        result = conn.get(key)
        return result
    finally:
        conn.close()  # 无论是否异常,始终执行

防止复现

  • 添加连接池监控告警(阈值 80%)
  • Code Review checklist 增加"资源释放"检查项
  • 考虑使用 Context Manager 封装连接操作

相关笔记

  • [[Redis 最佳实践]]
  • [[Python 异常处理规范]]

### 7.3 场景三:会议纪要自动整理

**用户输入**:

整理会议纪要: 参会人:张三、李四、王五 主题:Q2 技术规划 决议:

  1. 迁移到 Kubernetes(负责人:李四,截止 6 月底)
  2. 引入 GraphQL(负责人:张三,截止 5 月底)
  3. 重构用户服务(负责人:王五,截止 7 月底)

**生成笔记**(`00-Inbox/meeting-q2-tech-planning-20260420.md`):

```markdown
---
title: "会议纪要:Q2 技术规划"
date: 2026-04-20
tags:
  - 会议纪要
  - Q2
  - 技术规划
type: meeting
status: inbox
source: claude
attendees:
  - 张三
  - 李四
  - 王五
---

# 会议纪要:Q2 技术规划

**时间**:2026-04-20  
**参会人**:张三、李四、王五

## 决议事项

| # | 事项 | 负责人 | 截止时间 | 状态 |
|---|------|--------|----------|------|
| 1 | 迁移到 Kubernetes | 李四 | 2026-06-30 | 🟡 进行中 |
| 2 | 引入 GraphQL | 张三 | 2026-05-31 | 🟡 进行中 |
| 3 | 重构用户服务 | 王五 | 2026-07-31 | ⬜ 待开始 |

## 后续行动
- [ ] 李四:下周提交 Kubernetes 迁移方案
- [ ] 张三:调研 GraphQL 框架选型
- [ ] 王五:梳理用户服务现有依赖

## 相关笔记
- [[Q2 项目计划]]
- [[Kubernetes 迁移调研]]

八、高级功能:Dataview 动态索引

安装 Dataview 插件后,可以创建动态查询视图,这是 Obsidian 知识管理的核心能力。

8.1 收件箱视图(待处理笔记一览)

TABLE
  title as "标题",
  date as "日期",
  type as "类型",
  tags as "标签"
FROM "00-Inbox"
WHERE source = "claude" AND status = "inbox"
SORT date DESC

8.2 本周 Bug 汇总

TABLE
  title as "Bug",
  date as "记录时间",
  severity as "严重程度"
FROM ""
WHERE type = "bug"
  AND date >= date(today) - dur(7 days)
SORT severity ASC, date DESC

8.3 待办事项追踪

TASK
FROM "00-Inbox" OR "03-Projects"
WHERE !completed
  AND file.mtime >= date(today) - dur(14 days)
GROUP BY file.link

九、定时任务:让知识管理自动运转

手动记录笔记是一种模式,但真正的"第二大脑"应该能在你不主动操作时也在后台运作——定期生成周报、自动归档、提醒待办。以下提供三套方案,覆盖 macOS / Linux / 无 GUI 服务器场景。

9.1 方案架构总览

执行层

脚本层

调度层

0 9 * * 5

0 2 1 * *

0 8 * * 1-5

生成内容

⏰ cron / launchd
系统定时触发

📝 weekly-review.sh
每周五生成周报

📦 obsidian-archive.sh
每月归档旧笔记

🔔 daily-remind.sh
每天推送待办提醒

🤖 claude -p
无头模式调用 Claude

📡 Local REST API
Obsidian 读写

关键点:定时脚本分两类——纯脚本操作(直接读写 Obsidian API,速度快、无 AI 调用费用)和AI 增强操作(调用 claude -p 无头模式让 Claude 生成内容,质量高但消耗 token)。根据需求选择合适类型。


9.2 核心脚本:每周知识周报(AI 增强型)

这是最有价值的定时任务:每周五自动读取本周写入的笔记,让 Claude 提炼总结,再写回 Obsidian。

创建 ~/.claude/scripts/weekly-review.sh

#!/usr/bin/env bash
# ============================================================
# weekly-review.sh — 每周五自动生成知识周报
# 触发方式:cron 定时 或 手动执行
# ============================================================

set -euo pipefail

# ── 配置 ─────────────────────────────────────────────────────
API_TOKEN="${OBSIDIAN_API_TOKEN:-}"
API_PORT="${OBSIDIAN_API_PORT:-27124}"
API_BASE="https://127.0.0.1:${API_PORT}"
VAULT_PATH="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}"
LOG_FILE="$HOME/.claude/logs/weekly-review.log"

# ── 前置检查 ──────────────────────────────────────────────────
mkdir -p "$(dirname "$LOG_FILE")"
exec >> "$LOG_FILE" 2>&1
echo "===== $(date '+%Y-%m-%d %H:%M:%S') 开始执行周报任务 ====="

if [ -z "$API_TOKEN" ]; then
    echo "❌ OBSIDIAN_API_TOKEN 未设置,任务终止"
    exit 1
fi

# 检查 Obsidian 是否在运行(Local REST API 必须 Obsidian 开着才能工作)
if ! curl -sk -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $API_TOKEN" \
    "${API_BASE}/vault/" | grep -q "^200"; then
    echo "⚠️  Obsidian 未运行或 API 不可达,任务终止"
    exit 0  # 用 0 避免 cron 发送错误邮件
fi

# ── 收集本周笔记 ──────────────────────────────────────────────
WEEK_START=$(date -v-6d '+%Y-%m-%d' 2>/dev/null || date -d '6 days ago' '+%Y-%m-%d')
TODAY=$(date '+%Y-%m-%d')
YEAR_WEEK=$(date '+%Y-W%V')

echo "📅 收集周期:${WEEK_START} ~ ${TODAY}"

# 查找本周新增的 md 文件(从文件系统查,比 API 更可靠)
RECENT_NOTES=$(find "${VAULT_PATH}/00-Inbox" \
    -name "*.md" \
    -newer "${VAULT_PATH}/.last-review-marker" \
    2>/dev/null || \
    find "${VAULT_PATH}/00-Inbox" -name "*.md" -mtime -7)

NOTE_COUNT=$(echo "$RECENT_NOTES" | grep -c '.md' || echo 0)
echo "📊 本周新增笔记:${NOTE_COUNT} 篇"

if [ "$NOTE_COUNT" -eq 0 ]; then
    echo "ℹ️  本周无新增笔记,跳过周报生成"
    touch "${VAULT_PATH}/.last-review-marker"
    exit 0
fi

# ── 读取笔记内容 ──────────────────────────────────────────────
NOTES_CONTENT=""
while IFS= read -r NOTE_FILE; do
    [ -z "$NOTE_FILE" ] && continue
    BASENAME=$(basename "$NOTE_FILE")
    CONTENT=$(head -50 "$NOTE_FILE")  # 每篇只取前 50 行,控制 token 量
    NOTES_CONTENT="${NOTES_CONTENT}\n\n### 📄 ${BASENAME}\n${CONTENT}"
done <<< "$RECENT_NOTES"

# ── 调用 Claude 生成周报(无头模式) ──────────────────────────
echo "🤖 调用 Claude 生成周报摘要..."

PROMPT="你是一个知识管理助手。以下是我本周(${WEEK_START}${TODAY})写入 Obsidian 的笔记内容:

${NOTES_CONTENT}

请生成一份简洁的**知识周报**,格式如下(使用 Markdown):

## 本周亮点
(2-3句话总结本周最重要的收获)

## 知识分类统计
(按 type 分类统计笔记数量)

## 核心知识点
(列出最值得记忆的 3-5 个知识点,每条一句话)

## 待跟进事项
(从笔记中提取未完成的 TODO 和待解决的问题)

## 下周建议
(基于本周内容,建议下周可以深入研究的方向)

要求:简洁实用,避免废话,总字数控制在 500 字以内。"

REVIEW_CONTENT=$(echo "$PROMPT" | claude -p --output-format text 2>/dev/null)

if [ -z "$REVIEW_CONTENT" ]; then
    echo "❌ Claude 返回内容为空,可能是认证问题或 token 不足"
    exit 1
fi

# ── 写入周报到 Obsidian ───────────────────────────────────────
REPORT_FILENAME="weekly-review-${YEAR_WEEK}.md"
REPORT_PATH="01-Notes/${REPORT_FILENAME}"

FULL_CONTENT="---
title: \"知识周报 ${YEAR_WEEK}\"
date: ${TODAY}
tags:
  - 周报
  - 知识总结
type: weekly-review
status: processed
source: claude-auto
week: \"${YEAR_WEEK}\"
note_count: ${NOTE_COUNT}
---

# 知识周报 ${YEAR_WEEK}

> 自动生成时间:$(date '+%Y-%m-%d %H:%M')  
> 本周笔记数量:${NOTE_COUNT} 篇  
> 覆盖周期:${WEEK_START} ~ ${TODAY}

${REVIEW_CONTENT}

---

## 原始笔记列表

$(echo "$RECENT_NOTES" | xargs -I{} basename {} | sed 's/^/- /')"

# URL 编码路径
ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${REPORT_PATH}', safe='/'))")

HTTP_CODE=$(curl -sk -o /dev/null -w "%{http_code}" \
    -X PUT "${API_BASE}/vault/${ENCODED_PATH}" \
    -H "Authorization: Bearer ${API_TOKEN}" \
    -H "Content-Type: text/markdown; charset=UTF-8" \
    --data-binary "${FULL_CONTENT}")

if [[ "$HTTP_CODE" == "200" || "$HTTP_CODE" == "204" ]]; then
    echo "✅ 周报已保存:${REPORT_PATH}"
    touch "${VAULT_PATH}/.last-review-marker"
else
    echo "❌ 周报保存失败(HTTP ${HTTP_CODE})"
    exit 1
fi

echo "===== 周报任务完成 ====="
chmod +x ~/.claude/scripts/weekly-review.sh

9.3 核心脚本:自动归档旧笔记(纯脚本型)

创建 ~/.claude/scripts/obsidian-archive.sh

#!/usr/bin/env bash
# ============================================================
# obsidian-archive.sh — 自动归档 90 天前的 Inbox 笔记
# 触发方式:每月 1 日凌晨执行
# ============================================================

set -euo pipefail

VAULT_PATH="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}"
LOG_FILE="$HOME/.claude/logs/archive.log"
ARCHIVE_DIR="${VAULT_PATH}/05-Archives"
INBOX_DIR="${VAULT_PATH}/00-Inbox"
YEAR_MONTH=$(date '+%Y-%m')

mkdir -p "$(dirname "$LOG_FILE")" "$ARCHIVE_DIR"
exec >> "$LOG_FILE" 2>&1
echo "===== $(date '+%Y-%m-%d %H:%M:%S') 开始归档任务 ====="

# 按年月创建子目录,避免归档目录混乱
TARGET_DIR="${ARCHIVE_DIR}/${YEAR_MONTH}"
mkdir -p "$TARGET_DIR"

COUNT=0
while IFS= read -r -d '' FILE; do
    BASENAME=$(basename "$FILE")
    mv "$FILE" "${TARGET_DIR}/${BASENAME}"
    echo "📦 已归档: ${BASENAME} → 05-Archives/${YEAR_MONTH}/"
    COUNT=$((COUNT + 1))
done < <(find "$INBOX_DIR" -name "*.md" -mtime +90 -print0)

echo "✅ 归档完成,共处理 ${COUNT} 篇笔记"
echo "===== 归档任务结束 ====="
chmod +x ~/.claude/scripts/obsidian-archive.sh

9.4 核心脚本:每日待办提醒(AI 增强型)

创建 ~/.claude/scripts/daily-remind.sh

#!/usr/bin/env bash
# ============================================================
# daily-remind.sh — 每天早上提取待办,写入今日提醒笔记
# ============================================================

set -euo pipefail

API_TOKEN="${OBSIDIAN_API_TOKEN:-}"
API_PORT="${OBSIDIAN_API_PORT:-27124}"
API_BASE="https://127.0.0.1:${API_PORT}"
VAULT_PATH="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}"
TODAY=$(date '+%Y-%m-%d')
LOG_FILE="$HOME/.claude/logs/daily-remind.log"

mkdir -p "$(dirname "$LOG_FILE")"
exec >> "$LOG_FILE" 2>&1

# 检查 API 可达性
if ! curl -sk -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $API_TOKEN" \
    "${API_BASE}/vault/" | grep -q "^200"; then
    echo "$(date) ⚠️ Obsidian 未运行,跳过提醒任务"
    exit 0
fi

# 从所有笔记中提取未完成的 TODO(直接读文件系统,不走 API)
TODOS=$(grep -r "- \[ \]" \
    "${VAULT_PATH}/00-Inbox" \
    "${VAULT_PATH}/03-Projects" \
    --include="*.md" \
    -h 2>/dev/null | \
    sed 's/- \[ \] //' | \
    sort -u | head -20)  # 最多取 20 条

TODO_COUNT=$(echo "$TODOS" | grep -c . || echo 0)

if [ "$TODO_COUNT" -eq 0 ]; then
    echo "$(date) ℹ️ 今日无待办事项"
    exit 0
fi

# 生成今日提醒笔记
REMIND_CONTENT="---
title: \"${TODAY} 每日提醒\"
date: ${TODAY}
tags:
  - 每日提醒
  - 待办
type: daily-remind
status: inbox
source: claude-auto
---

# ${TODAY} 每日提醒

> 自动生成时间:$(date '+%H:%M')

## 📋 待处理事项(共 ${TODO_COUNT} 条)

$(echo "$TODOS" | sed 's/^/- [ ] /')

---

*来源:自动扫描 00-Inbox 和 03-Projects 中的未完成事项*"

ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('01-Notes/daily-remind-${TODAY}.md', safe='/'))")

curl -sk -o /dev/null -w "%{http_code}" \
    -X PUT "${API_BASE}/vault/${ENCODED}" \
    -H "Authorization: Bearer $API_TOKEN" \
    -H "Content-Type: text/markdown; charset=UTF-8" \
    --data-binary "$REMIND_CONTENT"

echo "$(date) ✅ 每日提醒已写入,共 ${TODO_COUNT} 条待办"
chmod +x ~/.claude/scripts/daily-remind.sh

9.5 注册定时任务

macOS:使用 launchd(推荐)

launchd 是 macOS 原生的任务调度器,比 cron 更可靠,支持唤醒机器执行。

步骤 1:创建 plist 配置文件

创建 ~/Library/LaunchAgents/com.obsidian.weekly-review.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.obsidian.weekly-review</string>

    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/YOUR_USERNAME/.claude/scripts/weekly-review.sh</string>
    </array>

    <!-- 每周五早上 9:00 执行 -->
    <key>StartCalendarInterval</key>
    <dict>
        <key>Weekday</key>
        <integer>5</integer>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>

    <!-- 环境变量(launchd 不继承 shell 环境变量) -->
    <key>EnvironmentVariables</key>
    <dict>
        <key>OBSIDIAN_API_TOKEN</key>
        <string>YOUR_TOKEN_HERE</string>
        <key>OBSIDIAN_VAULT_PATH</key>
        <string>/Users/YOUR_USERNAME/Documents/Obsidian Vault</string>
        <key>OBSIDIAN_API_PORT</key>
        <string>27124</string>
        <key>HOME</key>
        <string>/Users/YOUR_USERNAME</string>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/YOUR_USERNAME/.claude/logs/launchd-weekly.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/YOUR_USERNAME/.claude/logs/launchd-weekly-err.log</string>

    <!-- 错过执行时间(如机器关机),下次登录后补执行 -->
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>

同样方式创建归档和每日提醒的 plist(修改 Label、脚本路径和时间)。

步骤 2:注册并启动

# 替换用户名
PLIST=~/Library/LaunchAgents/com.obsidian.weekly-review.plist

# 注册
launchctl load "$PLIST"

# 验证注册状态
launchctl list | grep obsidian

# 立即手动触发一次测试(不等下周五)
launchctl start com.obsidian.weekly-review

# 查看日志
tail -f ~/.claude/logs/launchd-weekly.log

⚠️ 重要:plist 中的 EnvironmentVariables 必须写死 token,因为 launchd 不读取 ~/.zshrc。建议将 token 存入 macOS Keychain 后通过脚本读取(见附录 C)。


Linux / 服务器:使用 cron
# 编辑当前用户的 crontab
crontab -e

添加以下三行:

# ── 环境变量(cron 不继承 shell 环境)────────────────────────
OBSIDIAN_API_TOKEN=your_token_here
OBSIDIAN_VAULT_PATH=/home/yourname/Documents/Obsidian Vault
OBSIDIAN_API_PORT=27124
HOME=/home/yourname

# 每天工作日早上 8:00 生成每日提醒
0 8 * * 1-5 /home/yourname/.claude/scripts/daily-remind.sh

# 每周五早上 9:00 生成知识周报
0 9 * * 5 /home/yourname/.claude/scripts/weekly-review.sh

# 每月 1 日凌晨 2:00 归档旧笔记
0 2 1 * * /home/yourname/.claude/scripts/obsidian-archive.sh

验证 cron 是否生效:

# 查看当前 crontab
crontab -l

# 查看 cron 执行日志(Linux)
grep CRON /var/log/syslog | tail -20

# 手动测试脚本(先在终端跑通再交给 cron)
bash ~/.claude/scripts/weekly-review.sh

9.6 Cron 表达式速查

┌──────── 分钟 (0-59)
│ ┌────── 小时 (0-23)
│ │ ┌──── 日   (1-31)
│ │ │ ┌── 月   (1-12)
│ │ │ │ ┌ 星期 (0-6, 0=周日)
│ │ │ │ │
0 9 * * 5     每周五 09:00
0 8 * * 1-5   工作日每天 08:00
0 2 1 * *     每月 1 日 02:00
*/30 * * * *  每 30 分钟
0 0 * * 0     每周日午夜

9.7 定时任务监控与告警

定时任务最大的风险是静默失败——脚本报错但没人知道。添加简单的告警机制:

#!/usr/bin/env bash
# ~/.claude/scripts/check-tasks.sh
# 检查所有定时任务的执行状态,手动运行或每天检查一次

LOG_DIR="$HOME/.claude/logs"
ALERT=0

check_log() {
    local LOG="$1"
    local TASK_NAME="$2"
    local MAX_HOURS="${3:-25}"  # 超过多少小时未执行视为异常

    if [ ! -f "$LOG" ]; then
        echo "⚠️  ${TASK_NAME}:日志文件不存在(任务可能从未执行)"
        ALERT=1
        return
    fi

    LAST_RUN=$(stat -f "%m" "$LOG" 2>/dev/null || stat -c "%Y" "$LOG")
    NOW=$(date +%s)
    HOURS_AGO=$(( (NOW - LAST_RUN) / 3600 ))

    if [ $HOURS_AGO -gt $MAX_HOURS ]; then
        echo "⚠️  ${TASK_NAME}:最后执行于 ${HOURS_AGO} 小时前(超过 ${MAX_HOURS}h 阈值)"
        ALERT=1
    else
        echo "✅ ${TASK_NAME}:正常(${HOURS_AGO}h 前执行)"
    fi

    # 检查最后一次是否有错误
    if tail -5 "$LOG" | grep -q "❌\|失败\|ERROR"; then
        echo "   └─ ⚠️  最后一次执行有错误,请查看:${LOG}"
        ALERT=1
    fi
}

echo "=== 定时任务健康检查 $(date '+%Y-%m-%d %H:%M') ==="
check_log "${LOG_DIR}/weekly-review.log"  "知识周报"   200  # 约 8 天
check_log "${LOG_DIR}/archive.log"        "笔记归档"   750  # 约 31 天
check_log "${LOG_DIR}/daily-remind.log"   "每日提醒"   25   # 约 1 天

if [ $ALERT -eq 1 ]; then
    echo ""
    echo "发现异常,建议手动执行对应脚本排查。"
    exit 1
else
    echo ""
    echo "所有任务运行正常。"
fi
chmod +x ~/.claude/scripts/check-tasks.sh

# 手动检查
~/.claude/scripts/check-tasks.sh

十、使用技巧与最佳实践

10.1 触发短语设计

在与 Claude Code 交互时,使用一致的触发短语可以避免歧义:

触发短语 Claude 的动作
记录笔记:... 写入 note 类型笔记到 Inbox
记录 Bug:... 写入 bug 类型笔记
整理会议纪要:... 写入 meeting 类型笔记
搜索笔记:... 调用搜索脚本返回结果
读取笔记 [文件名] 读取并展示笔记内容

10.2 标签体系设计

建议使用两级分层标签

技术领域:前端 / 后端 / DevOps / 数据库 / AI
内容类型:学习笔记 / Bug / 方案设计 / 教程 / 会议纪要
项目标识:项目名称(如 user-service / payment-refactor)
优先级:P0 / P1 / P2(仅用于 Bug 和待办)

10.3 每周整理工作流

每周五整理

技术知识

项目相关

已过时

保持原位

📥 00-Inbox
(新增内容)

人工审查

📚 02-Knowledge

🚀 03-Projects

📦 05-Archives


十一、常见问题与排查

Q1:API 连接失败(Connection Refused)

curl: (7) Failed to connect to 127.0.0.1 port 27124

排查步骤:

  1. 确认 Obsidian 正在运行(插件仅在 Obsidian 打开时工作)
  2. 在 Obsidian 插件设置中确认 Local REST API 已启用
  3. 检查端口冲突:lsof -i :27124

Q2:认证失败(401 Unauthorized)

{"error": "Unauthorized", "code": 40101}

解决方案:

  1. 在 Obsidian 插件设置中重新生成 API Key
  2. 更新环境变量:export OBSIDIAN_API_TOKEN="new_token"
  3. 验证:echo $OBSIDIAN_API_TOKEN

Q3:中文文件名导致 404

原因是 URL 编码问题,脚本中已通过 Python 的 urllib.parse.quote 处理。如仍有问题,检查:

# 验证编码是否正确
python3 -c "import urllib.parse; print(urllib.parse.quote('00-Inbox/测试笔记.md', safe='/'))"
# 预期输出:00-Inbox/%E6%B5%8B%E8%AF%95%E7%AC%94%E8%AE%B0.md

Q4:Claude 无法找到脚本

确认 ~/.claude/CLAUDE.md 中的脚本路径使用绝对路径,而非 ~ 或相对路径:

# 正确
调用脚本:`/Users/yourname/.claude/scripts/obsidian-write.sh`

# 可能有问题
调用脚本:`~/.claude/scripts/obsidian-write.sh`

十二、进阶扩展

12.1 纳入 Git 版本控制

cd "$OBSIDIAN_VAULT_PATH"
git init
echo ".obsidian/workspace.json" >> .gitignore
echo ".obsidian/cache" >> .gitignore
git add .
git commit -m "init: 初始化 Obsidian 知识库"

# 推送到私有仓库(强烈建议私有)
git remote add origin git@github.com:yourname/obsidian-vault.git
git push -u origin main

自动提交钩子:

# .git/hooks/post-commit
#!/bin/bash
git push origin main --quiet && echo "☁️ 已同步到远端"
chmod +x .git/hooks/post-commit

12.2 多设备同步方案对比

方案 优点 缺点 适合场景
iCloud Drive 配置简单,iOS 原生支持 仅 Apple 生态 全 Apple 用户
Git + GitHub 版本历史,私有仓库 需手动或 Hook 触发 开发者
Obsidian Sync 官方支持,端对端加密 付费($10/月) 需要跨平台且不想折腾
Syncthing 开源,P2P 无云服务 需同时在线 追求数据自主

12.3 MCP 服务器扩展(进阶)

Claude Code 支持通过 MCP(Model Context Protocol)服务器扩展能力。未来可以基于此构建专属的 Obsidian MCP 服务器,实现比 REST API 更丰富的操作(如批量重组、图谱分析等)。

项目参考:搜索 GitHub 上的 obsidian-mcp 开源实现。


十三、总结:系统的核心价值

通过 Claude Code + Obsidian 的深度集成,本文构建了一个三层知识管理系统:

🔵 捕获层
Claude 终端交互
自然语言输入

🟡 存储层
Obsidian Vault
结构化 Markdown

🟣 检索层
Dataview 动态查询
双向链接图谱

系统的核心价值不在于技术复杂性,而在于三个改变:

  • 降低记录门槛:用自然语言说出来,Claude 负责结构化
  • 提升检索效率:Dataview + 双向链接,知识自动关联
  • 减少认知负担:知道"有地方存",大脑才能专注于思考

“第二大脑的目的不是替代你思考,而是让你从记忆负担中解放出来,把认知资源留给真正需要创造力的工作。”


附录 A:完整文件清单

~/.claude/
├── CLAUDE.md              # 用户级全局指令(定义 Claude 的 Obsidian 操作方式)
├── settings.json          # Claude Code 配置(权限、环境变量)
└── scripts/
    ├── obsidian-write.sh  # 写入笔记
    ├── obsidian-read.sh   # 读取笔记
    └── obsidian-search.sh # 搜索笔记

$OBSIDIAN_VAULT_PATH/
├── 00-Inbox/              # Claude 自动写入区
├── 01-Notes/
├── 02-Knowledge/
├── 03-Projects/
├── 04-Areas/
├── 05-Archives/
├── 06-Attachments/
└── Templates/
    └── daily-note.md

附录 B:环境变量速查

# ~/.zshrc 或 ~/.bashrc 中添加以下内容

# Obsidian 集成配置
export OBSIDIAN_API_TOKEN="在 Obsidian 插件设置中生成"
export OBSIDIAN_VAULT_PATH="$HOME/Documents/Obsidian Vault"
export OBSIDIAN_API_PORT="27124"

标签#ClaudeCode #Obsidian #知识管理 #AI工具 #效率提升 #程序员工具 #第二大脑

最后更新:2026-04-20

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐