--- title: Obsidian CLI:AI 的外部记忆层 slug: obsidian-cli-ai-external-memory style: tech_blog audience: AI 从业者、知识管理爱好者 status: draft tags: - obsidian - ai-memory - cli - knowledge-management source_notes: - 01-topics/2026-03-02-obsidian-cli-ai-memory-layer.md - 00-inbox/2026-03-02-cli-is-all-you-need.md created_at: 2026-03-02T00:00:00+08:00 updated_at: 2026-03-02T00:00:00+08:00 id: 2026-03-02-obsidian-cli-ai-external-memory content_type: article channels: - wechat - x language: zh-CN source_urls: [] assets: [] cover_image: "" template: tech-blog owner: content-forge --- # Obsidian CLI:AI 的外部记忆层 ## 问题背景 AI Agent 有一个致命缺陷:会话结束,记忆清零。 每次对话都从零开始。你上周踩的坑、上个月做的架构决策、半年前的最佳实践——全没了。你得重复解释,Agent 重复犯错。 有人用 Notion,有人用 GitHub Issues,有人用外部数据库。但这些方案要么 API 臃肿,要么和 AI 的工作方式不匹配。 **Obsidian 1.12 给出了另一个答案:命令行工具。** ## 核心方案 Obsidian 1.12 新增的 CLI 让 AI 可以直接读写你的 vault——不用 API,不用 MCP server,就是普通的 shell 命令。 22 00-inbox/vin-obsidian-workflows.md 00-inbox/CLAUDE.md Best Practices.md Error: File "00-inbox/my-note.md" not found. 00-inbox/2026-03-02-cli-is-all-you-need.md 00-inbox/2026-03-02-lessons-from-building-claude-code.md 00-inbox/2026-03-02-obsidian-kanban-for-ai-tasks.md 00-inbox/2026-03-02-sync-test.md 00-inbox/vin-obsidian-workflows.md 01-topics/2026-03-02-cli-test.md 01-topics/2026-03-02-obsidian-cli-ai-memory-layer.md content-pipeline-v2.md templates/article.md templates/social-post.md templates/tech-blog.md 这套方案的核心逻辑是: **Obsidian 管存储,AI 管智能,CLI 把两边接上。** ### 为什么不用 MCP? Marco Franzon 在《CLI Is All You Need》里说得很直接: > "Bash is the ultimate MCP." > "Agents were trained on Unix pipes—they're ridiculously good at it." MCP server 需要你写 schema、维护 server、处理版本兼容。而 CLI?Agent 本来就会用。它被训练了几十年的 Unix 命令用法,、、 这些它比谁都熟。 Obsidian CLI 就是把这个原则用到了知识管理上。 ## 实现细节 ### 安装 1. 更新 Obsidian 到 1.12+ 2. 设置 → 通用 → 打开「命令行工具」 3. 验证:终端运行 name content-forge path /home/kang/apps/content-forge/content-forge files 22 folders 8 size 43687 ### 关键命令 | 命令 | 用途 | AI 场景 | |------|------|---------| | 22 | 统计笔记数量 | 快速了解 vault 规模 | | No matches found. | 全文搜索 | 找相关笔记 | | Error: File "..." not found. | 读取笔记内容 | 获取具体信息 | | 00-inbox/2026-03-02-cli-is-all-you-need.md 00-inbox/2026-03-02-lessons-from-building-claude-code.md 00-inbox/2026-03-02-obsidian-kanban-for-ai-tasks.md 00-inbox/2026-03-02-sync-test.md 00-inbox/vin-obsidian-workflows.md 01-topics/2026-03-02-cli-test.md 01-topics/2026-03-02-obsidian-cli-ai-memory-layer.md content-pipeline-v2.md templates/article.md templates/social-post.md templates/tech-blog.md | 查找孤儿笔记 | 发现知识孤岛 | | 00-inbox/2026-03-02-claude-code-overnight-work.md 00-inbox/2026-03-02-cli-is-all-you-need.md 00-inbox/2026-03-02-lessons-from-building-claude-code.md 00-inbox/2026-03-02-sync-test.md 00-inbox/vin-obsidian-workflows.md 01-topics/2026-03-02-cli-test.md 01-topics/2026-03-02-obsidian-cli-ai-memory-layer.md content-pipeline-v2.md templates/article.md templates/social-post.md templates/tech-blog.md | 查找死链 | 清理断裂链接 | | Error: No active file. Use file= or path= to specify a file. | 查看反向链接 | 顺藤摸瓜 | ### Token 节省 实测数据: | 操作 | 旧方案 | 新方案 | 节省 | |------|--------|--------|------| | 了解笔记库概况 | 遍历所有文件 (45KB) | 22 (351B) | **99.2%** | | 看一篇笔记结构 | 读取整个文件 (63KB) | Error: No active file. Use file= or path= to specify a file. 只看标题 (5KB) | **92%** | | 查找孤儿笔记 | 自己写脚本 | 00-inbox/2026-03-02-cli-is-all-you-need.md 00-inbox/2026-03-02-lessons-from-building-claude-code.md 00-inbox/2026-03-02-obsidian-kanban-for-ai-tasks.md 00-inbox/2026-03-02-sync-test.md 00-inbox/vin-obsidian-workflows.md 01-topics/2026-03-02-cli-test.md 01-topics/2026-03-02-obsidian-cli-ai-memory-layer.md content-pipeline-v2.md templates/article.md templates/social-post.md templates/tech-blog.md 一行命令 | N/A | ## 验证结果 ### 1. 省 Token 这是最直观的收益。AI 不再用 context window 存整个文件系统,而是用 CLI 按需查询。Context 窗口留给真正的推理,不是存文件列表。 ### 2. 多了一层图谱检索 这是更重要的收益。 向量搜索找的是「内容相似」的笔记。CLI 的反向链接找的是「你当初主动建立的知识连接」。 这两个「相关」不一样。 AI 搜到一篇笔记后,可以顺着 Error: No active file. Use file= or path= to specify a file. 拉出你当初链接它的所有笔记——这是传统搜索做不到的。它复活了你构建知识图谱时的意图。 ## 总结与扩展 **Obsidian CLI 把 AI 变成了你的长期记忆外挂。** - **省 token**:CLI 按需查询,不暴力遍历 - **图谱感知**:反向链接复活你的知识结构意图 - **零集成成本**:Agent 本来就会用 shell 如果你在用 Claude Code 或其他 CLI-native Agent,强烈建议把这个加进工作流。你的 vault 不再只是笔记库——它是 AI 的外部皮层。 --- **行动建议**: 1. 今天就更新 Obsidian 到 1.12,打开 CLI 2. 把 Obsidian CLI Usage: obsidian [options] Options: vault= Target a specific vault by name Notes: file resolves by name (like wikilinks), path is exact (folder/note.md) Most commands default to the active file when file/path is omitted Quote values with spaces: name="My Note" Use for newline, for tab in content values Commands: aliases List aliases in the vault file= - File name path= - File path total - Return alias count verbose - Include file paths active - Show aliases for active file append Append content to a file file= - File name path= - File path content= - Content to append (required) inline - Append without newline backlinks List backlinks to a file file= - Target file name path= - Target file path counts - Include link counts total - Return backlink count format=json|tsv|csv - Output format (default: tsv) base:create Create a new item in a base file= - Base file name path= - Base file path view= - View name name= - New file name content= - Initial content open - Open file after creating newtab - Open in new tab base:query Query a base and return results file= - Base file name path= - Base file path view= - View name to query format=json|csv|tsv|md|paths - Output format (default: json) base:views List views in the current base file bases List all base files in vault bookmark Add a bookmark file= - File to bookmark subpath= - Subpath (heading or block) within file folder= - Folder to bookmark search= - Search query to bookmark url= - URL to bookmark title= - Bookmark title bookmarks List bookmarks total - Return bookmark count verbose - Include bookmark types format=json|tsv|csv - Output format (default: tsv) command Execute an Obsidian command id=<command-id> - Command ID to execute (required) commands List available command IDs filter=<prefix> - Filter by ID prefix create Create a new file name=<name> - File name path=<path> - File path content=<text> - Initial content template=<name> - Template to use overwrite - Overwrite if file exists open - Open file after creating newtab - Open in new tab daily Open daily note paneType=tab|split|window - Pane type to open in daily:append Append content to daily note content=<text> - Content to append (required) inline - Append without newline open - Open file after adding paneType=tab|split|window - Pane type to open in daily:path Get daily note path daily:prepend Prepend content to daily note content=<text> - Content to prepend (required) inline - Prepend without newline open - Open file after adding paneType=tab|split|window - Pane type to open in daily:read Read daily note contents deadends List files with no outgoing links total - Return dead-end count all - Include non-markdown files delete Delete a file file=<name> - File name path=<path> - File path permanent - Skip trash, delete permanently diff List or diff local/sync versions file=<name> - File name path=<path> - File path from=<n> - Version number to diff from to=<n> - Version number to diff to filter=local|sync - Filter by version source file Show file info file=<name> - File name path=<path> - File path files List files in the vault folder=<path> - Filter by folder ext=<extension> - Filter by extension total - Return file count folder Show folder info path=<path> - Folder path (required) info=files|folders|size - Return specific info only folders List folders in the vault folder=<path> - Filter by parent folder total - Return folder count help Show list of all available commands <command> - Show help for a specific command history List file history versions file=<name> - File name path=<path> - File path history:list List files with history history:open Open file recovery file=<name> - File name path=<path> - File path history:read Read a file history version file=<name> - File name path=<path> - File path version=<n> - Version number (default: 1) history:restore Restore a file history version file=<name> - File name path=<path> - File path version=<n> - Version number (required) hotkey Get hotkey for a command id=<command-id> - Command ID (required) verbose - Show if custom or default hotkeys List hotkeys total - Return hotkey count verbose - Show if hotkey is custom format=json|tsv|csv - Output format (default: tsv) all - Include commands without hotkeys links List outgoing links from a file file=<name> - File name path=<path> - File path total - Return link count move Move or rename a file file=<name> - File name path=<path> - File path to=<path> - Destination folder or path (required) open Open a file file=<name> - File name path=<path> - File path newtab - Open in new tab orphans List files with no incoming links total - Return orphan count all - Include non-markdown files outline Show headings for the current file file=<name> - File name path=<path> - File path format=tree|md|json - Output format (default: tree) total - Return heading count plugin Get plugin info id=<plugin-id> - Plugin ID (required) plugin:disable Disable a plugin id=<id> - Plugin ID (required) filter=core|community - Plugin type plugin:enable Enable a plugin id=<id> - Plugin ID (required) filter=core|community - Plugin type plugin:install Install a community plugin id=<id> - Plugin ID (required) enable - Enable after install plugin:reload Reload a plugin (for developers) id=<id> - Plugin ID (required) plugin:uninstall Uninstall a community plugin id=<id> - Plugin ID (required) plugins List installed plugins filter=core|community - Filter by plugin type versions - Include version numbers format=json|tsv|csv - Output format (default: tsv) plugins:enabled List enabled plugins filter=core|community - Filter by plugin type versions - Include version numbers format=json|tsv|csv - Output format (default: tsv) plugins:restrict Toggle or check restricted mode on - Enable restricted mode off - Disable restricted mode prepend Prepend content to a file file=<name> - File name path=<path> - File path content=<text> - Content to prepend (required) inline - Prepend without newline properties List properties in the vault file=<name> - Show properties for file path=<path> - Show properties for path name=<name> - Get specific property count total - Return property count sort=count - Sort by count (default: name) counts - Include occurrence counts format=yaml|json|tsv - Output format (default: yaml) active - Show properties for active file property:read Read a property value from a file name=<name> - Property name (required) file=<name> - File name path=<path> - File path property:remove Remove a property from a file name=<name> - Property name (required) file=<name> - File name path=<path> - File path property:set Set a property on a file name=<name> - Property name (required) value=<value> - Property value (required) type=text|list|number|checkbox|date|datetime - Property type file=<name> - File name path=<path> - File path random Open a random note folder=<path> - Limit to folder newtab - Open in new tab random:read Read a random note folder=<path> - Limit to folder read Read file contents file=<name> - File name path=<path> - File path recents List recently opened files total - Return recent file count reload Reload the vault rename Rename a file file=<name> - File name path=<path> - File path name=<name> - New file name (required) restart Restart the app search Search vault for text query=<text> - Search query (required) path=<folder> - Limit to folder limit=<n> - Max files total - Return match count case - Case sensitive format=text|json - Output format (default: text) search:context Search with matching line context query=<text> - Search query (required) path=<folder> - Limit to folder limit=<n> - Max files case - Case sensitive format=text|json - Output format (default: text) search:open Open search view query=<text> - Initial search query snippet:disable Disable a CSS snippet name=<name> - Snippet name (required) snippet:enable Enable a CSS snippet name=<name> - Snippet name (required) snippets List installed CSS snippets snippets:enabled List enabled CSS snippets sync Pause or resume sync on - Resume sync off - Pause sync sync:deleted List deleted files in sync total - Return deleted file count sync:history List sync version history for a file file=<name> - File name path=<path> - File path total - Return version count sync:open Open sync history file=<name> - File name path=<path> - File path sync:read Read a sync version file=<name> - File name path=<path> - File path version=<n> - Version number (required) sync:restore Restore a sync version file=<name> - File name path=<path> - File path version=<n> - Version number (required) sync:status Show sync status tab:open Open a new tab group=<id> - Tab group ID file=<path> - File to open view=<type> - View type to open tabs List open tabs ids - Include tab IDs tag Get tag info name=<tag> - Tag name (required) total - Return occurrence count verbose - Include file list and count tags List tags in the vault file=<name> - File name path=<path> - File path total - Return tag count counts - Include tag counts sort=count - Sort by count (default: name) format=json|tsv|csv - Output format (default: tsv) active - Show tags for active file task Show or update a task ref=<path:line> - Task reference (path:line) file=<name> - File name path=<path> - File path line=<n> - Line number toggle - Toggle task status done - Mark as done todo - Mark as todo daily - Use daily note status="<char>" - Set status character tasks List tasks in the vault file=<name> - Filter by file name path=<path> - Filter by file path total - Return task count done - Show completed tasks todo - Show incomplete tasks status="<char>" - Filter by status character verbose - Group by file with line numbers format=json|tsv|csv - Output format (default: text) active - Show tasks for active file daily - Show tasks from daily note template:insert Insert template into active file name=<template> - Template name (required) template:read Read template content name=<template> - Template name (required) resolve - Resolve template variables title=<title> - Title for variable resolution templates List templates total - Return template count theme Show active theme or get info name=<name> - Theme name for details theme:install Install a community theme name=<name> - Theme name (required) enable - Activate after install theme:set Set active theme name=<name> - Theme name (empty for default) (required) theme:uninstall Uninstall a theme name=<name> - Theme name (required) themes List installed themes versions - Include version numbers unresolved List unresolved links in vault total - Return unresolved link count counts - Include link counts verbose - Include source files format=json|tsv|csv - Output format (default: tsv) vault Show vault info info=name|path|files|folders|size - Return specific info only vaults List known vaults total - Return vault count verbose - Include vault paths version Show Obsidian version wordcount Count words and characters file=<name> - File name path=<path> - File path words - Return word count only characters - Return character count only workspace Show workspace tree ids - Include workspace item IDs Developer: dev:cdp Run a Chrome DevTools Protocol command method=<CDP.method> - CDP method to call (required) params=<json> - Method parameters as JSON dev:console Show captured console messages clear - Clear the console buffer limit=<n> - Max messages to show (default 50) level=log|warn|error|info|debug - Filter by log level dev:css Inspect CSS with source locations selector=<css> - CSS selector (required) prop=<name> - Filter by property name dev:debug Attach/detach Chrome DevTools Protocol debugger on - Attach debugger off - Detach debugger dev:dom Query DOM elements selector=<css> - CSS selector (required) total - Return element count text - Return text content inner - Return innerHTML instead of outerHTML all - Return all matches instead of first attr=<name> - Get attribute value css=<prop> - Get CSS property value dev:errors Show captured errors clear - Clear the error buffer dev:mobile Toggle mobile emulation on - Enable mobile emulation off - Disable mobile emulation dev:screenshot Take a screenshot path=<filename> - Output file path devtools Toggle Electron dev tools eval Execute JavaScript and return result code=<javascript> - JavaScript code to execute (required) 命令加到你的 Agent 可用工具列表 3. 试着让 Agent 帮你清理一次孤儿笔记 --- > 参考: > - [[2026-03-02-obsidian-cli-ai-memory-layer]] 原始思考 > - [[2026-03-02-cli-is-all-you-need]] CLI vs MCP 的深度分析