关于 obs-memory
obs-memory 是面向编码 Agent 的 Obsidian 持久记忆技能,可在会话间保存项目知识。它通过图结构笔记支持项目导览、按需查找和记录发现。
主要功能
- 01会话开始时读取待办和项目概览
- 02通过 Obsidian CLI 查询笔记关系
- 03按项目、组件和领域组织知识
- 04提供初始化及项目分析命令
适用场景
- 01开始编码前查看待办与项目背景
- 02查找组件依赖或相关架构决策
- 03将新发现和架构决策写入知识库
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ adamtylerlynch/ obsidian-agent-memory-skills --skill obs-memory安装后在 Claude Code 中输入/obs-memory确认已加载。
详细介绍
Obsidian Agent Memory
你可以访问一个持久化的 Obsidian 知识库——一个跨会话持久保存、采用图结构的记忆库。使用它来了解方向、查询架构和组件知识,并记录新的发现。
发现知识库
按以下顺序确定知识库路径(以第一个匹配项为准):
- 环境变量:
$OBSIDIAN_VAULT_PATH - Agent 配置引用:从 Agent 的项目或全局配置中解析知识库路径(查找带有类似
~/Documents/SomeName/路径的 "Obsidian Knowledge Vault" 部分) - 默认路径:
~/Documents/AgentMemory
将解析出的路径存储为 $VAULT,供后续所有操作使用。为 CLI 调用设置 $VAULT_NAME,其值为 basename "$VAULT"。
检查 $VAULT/Home.md,确认知识库存在。如果知识库不存在,请告知用户,并建议运行 init 命令,通过捆绑模板初始化新知识库。
会话开始 — 熟悉项目
每次会话开始时,最多执行 2 项操作来熟悉项目:
步骤 1:读取 TODO
优先使用 CLI:
obsidian vault=$VAULT_NAME tasks path="todos" todo verbose
备用方案:读取 $VAULT/todos/Active TODOs.md 文件。
了解待处理、进行中和近期已完成的事项。
步骤 2:检测当前项目并阅读其概览
从当前工作目录自动检测项目:
basename $(git rev-parse --show-toplevel 2>/dev/null) 2>/dev/null || basename $(pwd)
然后列出 $VAULT/projects/*/ 中的文件,检查是否存在匹配的项目。将 Git 仓库名称(或目录名称)与项目文件夹名称进行匹配。如果找到匹配项,读取项目概览:$VAULT/projects/{matched-name}/{matched-name}.md。
此项目概览包含指向所有组件、模式、架构决策和领域的维基链接。暂时不要读取这些链接指向的笔记——只有在当前任务需要相关上下文时,才按需查看。
会话开始时不要读取的内容
Home.md(仅在迷失方向且找不到项目时读取)sessions/(仅在用户提及之前的工作时读取)- 领域索引(仅在需要跨项目知识时读取)
- 组件笔记(仅在处理相应组件时读取)
自动行为
这些行为适用于使用此技能的所有 Agent,无需明确命令。
会话开始时
按照上述会话开始流程,在未收到请求的情况下自动熟悉项目(TODO 和项目概览)。如果知识库在解析出的路径下不存在,请告知用户,并建议运行 init。
会话结束信号
当用户说“完成了”“收尾中”“就这样”“我们停下吧”或类似的会话结束语时,提出撰写会话摘要。不要自动执行;先询问:“结束之前,要我把会话摘要写入知识库吗?”
发现组件时
如果你深入分析了一个在知识库中尚无笔记的组件,且该项目已启用知识库,请提议创建组件笔记,并根据导入项和依赖关系推断其关联。例如:“我注意到知识库中没有 AuthMiddleware 组件的笔记。要我创建一份并梳理它的依赖关系吗?”
首次运行时
如果所有解析出的路径下都不存在知识库,请引导用户运行 init,然后在当前目录位于 Git 仓库内时,自动为当前项目搭建初始结构。
工作期间 — 图谱导航
原则:优先使用 CLI 查询,其次读取文件。 Obsidian CLI 可结构化访问属性、链接、反向链接、标签和搜索功能——优先使用这些功能,而不是读取整个文件。
优先使用 CLI 查询
使用以下 CLI 命令进行定向查询,避免消耗文件读取令牌:
# Query a component's dependencies
obsidian vault=$VAULT_NAME property:read file="Component Name" name="depends-on"
# Find what depends on a component
obsidian vault=$VAULT_NAME property:read file="Component Name" name="depended-on-by"
obsidian vault=$VAULT_NAME backlinks file="Component Name"
# Find all outgoing links from a note
obsidian vault=$VAULT_NAME links file="Component Name"
# Find all notes of a type
obsidian vault=$VAULT_NAME tag verbose name="component"
# Search vault content
obsidian vault=$VAULT_NAME search format=json query="search term" matches limit=10
# Get note structure without full read
obsidian vault=$VAULT_NAME outline file="Component Name"
# Read a specific property
obsidian vault=$VAULT_NAME property:read file="Component Name" name="key-files"
其中 $VAULT_NAME 是知识库文件夹名称(即 $VAULT 的 basename)。
文件读取回退方案(CLI 不可用时)
如果 Obsidian CLI 不可用,则回退到读取文件:
- 需要了解某个组件?项目概览中有指向它的链接。阅读对应笔记即可。
- 需要了解某项架构决策?组件笔记或项目概览中有指向它的链接。跟随链接即可。
- 需要了解跨项目知识?组件/模式笔记中有指向领域笔记的链接。跟随链接即可。
- 需要查看会话历史?只有在遇到困难或用户提及之前的工作时才阅读。
优先扫描 Frontmatter
需要扫描多篇笔记以找到合适内容时,只读取每个文件开头约 10 行。Frontmatter 中的 tags、project、type 和 status 字段能让你在阅读全文前判断笔记是否相关。
读取前先列出目录
读取文件前先列出目录内容——了解有哪些文件,而无需消耗 token:
$VAULT/projects/{name}/**/*.md— 某个项目的所有笔记$VAULT/domains/{tech}/*.md— 领域知识文件
写入 Vault
简洁地写。笔记是为你未来的上下文准备的,而不是面向人类的文档。优先采用:
- 用项目符号列表代替散文
- 用 Wikilink 代替重复解释(链接到相关内容,而不是重述)
- 用 Frontmatter 标签提高可发现性,而不是写冗长描述
何时写入
- 发现新组件:深入了解代码库某个部分时,创建组件笔记
- 做出架构决策:做出重要设计选择时,记录 ADR
- 发现模式:记录未来会话应遵循的重复模式
- 学到领域知识:发现跨项目知识时,写入领域笔记
范围规则
| 知识类型 | 位置 | 示例 |
|---|---|---|
| 仅限一个项目 | projects/{name}/ | 此 API 如何处理身份验证 |
| 多个项目共享 | domains/{tech}/ | Go 接口的工作方式 |
| 通用且与技术无关 | patterns/ | SOLID 原则 |
| 会话摘要 | sessions/ | 已完成和发现的内容 |
| TODO | todos/Active TODOs.md | 按项目分组 |
Frontmatter 约定
新建笔记时务必包含:
---
tags: [category, project/short-name]
type: <component|adr|session|project>
project: "[[projects/{name}/{name}]]"
created: YYYY-MM-DD
---
Wikilink 约定
- 链接到相关笔记:
[[projects/{name}/components/Component Name|Component Name]] - 链接到领域:
[[domains/{tech}/{Tech Name}|Tech Name]] - 链接回项目:
[[projects/{name}/{name}|project-name]]
笔记模板
组件笔记:
---
tags: [components, project/{short-name}]
type: component
project: "[[projects/{name}/{name}]]"
created: {date}
status: active
layer: ""
depends-on: []
depended-on-by: []
key-files: []
---
章节:用途、注意事项
架构决策:
---
tags: [architecture, decision, project/{short-name}]
type: adr
project: "[[projects/{name}/{name}]]"
status: proposed | accepted | superseded
created: {date}
---
章节:背景、决策、考虑过的替代方案、后果
会话笔记:
---
tags: [sessions]
type: session
projects:
- "[[projects/{name}/{name}]]"
created: {date}
branch: {branch-name}
---
章节:背景、已完成的工作、发现、决策、后续步骤
命令
init — 初始化 Vault
使用随附模板引导创建新的 Obsidian Agent Memory Vault。
用法:init [path]
步骤:
-
确定知识库路径:如果提供了第一个参数,则使用该参数;否则使用知识库路径解析链(默认值:
~/Documents/AgentMemory)。 -
检查知识库是否已存在:检查
$VAULT/Home.md。如果存在,告知用户知识库已位于该路径,并询问是否要打开。 -
定位内置模板:模板位于相对于 skill 包根目录的
vault-template/。搜索 skill 包的安装目录——它可能位于 Agent 的插件/skill 缓存中,也可能位于本地检出目录中。查找vault-template/Home.md文件以确认正确路径。 -
创建知识库:
mkdir -p "$VAULT" cp -r "$TEMPLATE_DIR/vault-template/"* "$VAULT/" -
创建 Obsidian 配置目录:
mkdir -p "$VAULT/.obsidian"将以下内容写入
$VAULT/.obsidian/app.json:{ "alwaysUpdateLinks": true, "newFileLocation": "folder", "newFileFolderPath": "inbox", "attachmentFolderPath": "attachments" } -
创建空目录:
mkdir -p "$VAULT/inbox" mkdir -p "$VAULT/attachments"在每个空目录中创建
.gitkeep文件。 -
报告已创建的知识库并提供后续步骤:
- 在 Obsidian 中打开:知识库切换器 → 将文件夹作为知识库打开 →
$VAULT - 通过
OBSIDIAN_VAULT_PATH环境变量或 Agent 配置设置知识库路径 - 开始工作——Agent 会在工作过程中构建知识图谱
- 在 Obsidian 中打开:知识库切换器 → 将文件夹作为知识库打开 →
-
生成 Agent 配置片段:输出适用于用户 Agent 的知识库路径片段。对于 Claude Code,输出
CLAUDE.md片段:## Obsidian Knowledge Vault Persistent knowledge vault at `$VAULT`.对于其他 Agent,输出通用说明:“将
OBSIDIAN_VAULT_PATH=$VAULT添加到环境变量或 Agent 配置中。” -
自动搭建当前项目:如果位于 git 仓库中,则自动运行
project命令,在知识库中搭建当前项目。 -
简洁输出:最终输出最多 5–8 行:已创建的知识库路径、已搭建的项目(如适用)、如何在 Obsidian 中打开,以及如何设置知识库路径。
analyze — 分析项目并填充知识库
分析当前代码库,并使用相互关联、内容丰富的笔记填充知识库。
用法:analyze(不带参数——使用当前仓库)
阶段 1:发现——扫描知识来源
扫描仓库中包含已有知识的文件:
| 类别 | 要扫描的文件 |
|---|---|
| Agent 配置 | CLAUDE.md、.claude/CLAUDE.md、.cursorrules、.windsurfrules、.clinerules、AGENTS.md、Agents.md |
| 文档 | README.md、CONTRIBUTING.md、ARCHITECTURE.md、docs/architecture.md、docs/ARCHITECTURE.md |
| 现有 ADR | docs/adr/ADR-*.md、architecture/ADR-*.md、adr/*.md、docs/decisions/*.md |
| 项目元数据 | package.json、go.mod、Cargo.toml、pyproject.toml、setup.py、Gemfile、pom.xml、build.gradle、*.csproj |
| 构建/CI | Makefile、Dockerfile、docker-compose.yml、.github/workflows/*.yml、.gitlab-ci.yml |
| 配置 | tsconfig.json、.eslintrc.*、jest.config.*、.goreleaser.yml |
读取发现的每个文件。对于较大的文件(README、Agent 配置),完整读取。对于元数据文件,提取关键字段(名称、版本、依赖项)。
还要收集:
- 仓库 URL:使用
git remote get-url origin获取 - 仓库根目录路径:使用
git rev-parse --show-toplevel获取 - 当前分支:使用
git branch --show-current获取 - 目录树(源码目录的前 2 层,排除隐藏目录、vendor 和 node_modules)
- 文件扩展名频率(用于检测编程语言)
Phase 2:分析 — 提取与综合
根据发现的内容,综合整理:
- 项目元数据:名称、语言、框架、仓库 URL、本地路径
- 架构摘要:入口点、分层组织(例如,
internal/→ Go 服务层,src/components/→ React 应用)、构建系统 - 组件清单:主要功能模块——每个代表独立单元的顶层源代码目录或逻辑分组。对每项说明:用途(根据 README/Agent 配置上下文)、关键文件及其关系
- 模式清单:编码规范、错误处理策略、测试方法——从 Agent 配置文件(如 CLAUDE.md 中的“Coding Guidelines”“Testing”等章节)提取
- 领域映射:检测到的技术 → 知识库领域笔记(例如,Go、TypeScript、Terraform、React)
- 现有决策:在仓库中找到的 ADR 文件 → 导入为知识库 ADR 笔记
- 依赖项摘要:package 清单中的关键依赖项(列在项目概览中,不单独创建笔记)
Phase 3:填充 — 编写知识库笔记
幂等性规则:
- 如果项目目录不存在 → 创建所有内容(脚手架 + 填充)
- 如果项目目录存在,但概览只是一个骨架 → 替换为已填充的版本
- 如果单个组件/模式/ADR 笔记已存在 → 跳过并报告(不要覆盖手动编写的内容)
- 领域笔记:不存在时创建;已存在时,追加项目链接
要编写的笔记:
-
项目概览(
$VAULT/projects/{name}/{name}.md)——完整填充:--- aliases: [] tags: [project/{short-name}] type: project repo: {git remote url} path: {repo root path} language: {detected language(s)} framework: {detected framework(s)} created: {YYYY-MM-DD} status: active ---章节:
- 架构:分析得出的实际描述
- 组件:包含指向组件笔记的维基链接的表格
- 项目模式:包含指向模式笔记的维基链接的表格
- 架构决策:包含指向 ADR 笔记的维基链接的列表
- 关键依赖项:来自 package 清单
- 领域:指向领域笔记的维基链接
-
组件笔记(
$VAULT/projects/{name}/components/{Component}.md)——每个主要模块一份:--- tags: [components, project/{short-name}] type: component project: "[[projects/{name}/{name}]]" created: {YYYY-MM-DD} status: active layer: {detected layer} depends-on: [] depended-on-by: [] key-files: [{key files list}] ---章节:用途、注意事项
-
模式笔记(
$VAULT/projects/{name}/patterns/{Pattern}.md)——根据 Agent 配置中的规范编写:--- tags: [patterns, project/{short-name}] type: pattern project: "[[projects/{name}/{name}]]" created: {YYYY-MM-DD} ---章节:模式、适用场景、实现方式
-
ADR 导入(
$VAULT/projects/{name}/architecture/ADR-{NNNN} {title}.md)——来自仓库中现有的 ADR:--- tags: [architecture, decision, project/{short-name}] type: adr project: "[[projects/{name}/{name}]]" status: accepted created: {YYYY-MM-DD} ---保留原始内容,并添加知识库 frontmatter。
-
领域笔记(
$VAULT/domains/{tech}/{Tech}.md):- 如果是新的:创建并添加项目链接
- 如果已存在:将此项目添加到“使用此领域的项目”章节
-
更新索引:
$VAULT/projects/Projects.md— 添加/更新行$VAULT/domains/Domains.md— 为新领域添加/更新行
Phase 4:报告
打印摘要:
Analyzed: {project-name}
Sources read: {N} knowledge files
Created: project overview (populated)
Created: {N} component notes
Created: {N} pattern notes
Imported: {N} architecture decisions
Linked: {N} domain notes
Skipped: {N} existing notes (preserved)
recap — 编写会话摘要
编写会话摘要笔记并更新 TODO。
用法:recap
步骤:
-
收集会话上下文,运行:
git log --oneline -20 git diff --stat HEAD~5..HEAD 2>/dev/null || git diff --stat git branch --show-current -
读取当前 TODO — 优先使用 CLI:
obsidian vault=$VAULT_NAME tasks path="todos" todo verbose回退方案:读取
$VAULT/todos/Active TODOs.md。 -
读取项目概览:从
$VAULT/projects/$PROJECT/$PROJECT.md读取(用于了解维基链接和上下文)。 -
编写会话笔记 — 优先使用 CLI:
obsidian vault=$VAULT_NAME create path="sessions/{YYYY-MM-DD} - {title}" template="Session Note" silent obsidian vault=$VAULT_NAME property:set path="sessions/{YYYY-MM-DD} - {title}" name="type" value="session" type="text" obsidian vault=$VAULT_NAME property:set path="sessions/{YYYY-MM-DD} - {title}" name="branch" value="{current-branch}" type="text" obsidian vault=$VAULT_NAME property:set path="sessions/{YYYY-MM-DD} - {title}" name="projects" value="[[projects/$PROJECT/$PROJECT]]" type="list"然后追加正文内容:
obsidian vault=$VAULT_NAME append path="sessions/{YYYY-MM-DD} - {title}" content="..."回退方案:直接在
$VAULT/sessions/{YYYY-MM-DD} - {title}.md创建文件:--- tags: [sessions] type: session projects: - "[[projects/$PROJECT/$PROJECT]]" created: {YYYY-MM-DD} branch: {current-branch} ---需要填写的部分:
- 上下文:正在处理的内容(根据 git log 上下文)
- 已完成工作:按编号列出完成事项(根据提交和差异)
- 发现:值得记录的技术发现
- 决策:本次会话中作出的设计选择
- 后续步骤:接下来应该做什么(使用复选框)
-
更新 TODO:编辑
$VAULT/todos/Active TODOs.md:- 从 Active TODOs 中移除已完成的
[x]项目,并将其追加到$VAULT/todos/Completed TODOs Archive.md中带日期的## $PROJECT (YYYY-MM-DD)标题下(如果文件不存在,则创建该文件) - 添加本次会话中发现的新项目
- 按项目对项目进行分组
- 不要在 Active TODOs 中留下
[x]项目——这些项目会不断累积,并在每次会话开始时浪费上下文窗口
- 从 Active TODOs 中移除已完成的
-
更新会话日志:在
$VAULT/sessions/Session Log.md中添加一条记录,包含日期、项目、分支和一行摘要。 -
报告写入的内容。
project — 搭建新项目
在知识库中搭建新项目。使用第一个参数作为项目名称;如果未提供,则使用 $PROJECT。
用法:project [name]
步骤:
-
确定项目名称:如果提供了参数,则使用该参数;否则使用
$PROJECT。 -
检查项目是否存在:查找
$VAULT/projects/{name}/{name}.md。如果文件存在,告知用户并询问是否改为打开该文件。 -
创建目录结构:
$VAULT/projects/{name}/$VAULT/projects/{name}/architecture/$VAULT/projects/{name}/components/$VAULT/projects/{name}/patterns/
-
创建项目概览,路径为
$VAULT/projects/{name}/{name}.md:--- aliases: [] tags: [project/{short-name}] type: project repo: {git remote url if available} path: {working directory} language: {detected from files} framework: created: {YYYY-MM-DD} status: active ---各部分:架构、组件、项目模式、架构决策、领域
自动检测并填入:
- 根据仓库中的文件扩展名确定语言
- 通过
git remote get-url origin获取仓库 URL - 链接到
$VAULT/domains/中存在的相关领域
-
更新 Projects.md:在
$VAULT/projects/Projects.md的项目表中添加一行。 -
报告搭建的结构。
note — 使用模板创建笔记
使用模板创建笔记。第一个参数指定类型:component、adr 或 pattern。
用法:note <component|adr|pattern> [name]
note component [name]
创建文件:$VAULT/projects/$PROJECT/components/{name}.md:
---
tags: [components, project/{short-name}]
type: component
project: "[[projects/$PROJECT/$PROJECT]]"
created: {YYYY-MM-DD}
status: active
layer: ""
depends-on: []
depended-on-by: []
key-files: []
---
各部分:用途、注意事项
如果提供了名称参数,则将其用作组件名称;否则,询问用户。
note adr [title]
通过列出 $VAULT/projects/$PROJECT/architecture/ADR-*.md 中已有的 ADR,确定下一个 ADR 编号。
创建文件:$VAULT/projects/$PROJECT/architecture/ADR-{NNNN} {title}.md:
---
tags: [architecture, decision, project/{short-name}]
type: adr
project: "[[projects/$PROJECT/$PROJECT]]"
status: proposed
created: {YYYY-MM-DD}
---
各部分:背景、决策、考虑过的替代方案、影响
note pattern [name]
创建文件:$VAULT/projects/$PROJECT/patterns/{name}.md:
---
tags: [patterns, project/{short-name}]
project: "[[projects/$PROJECT/$PROJECT]]"
created: {YYYY-MM-DD}
---
各部分:模式、适用场景、实现、示例
创建任何笔记后,都要在项目概览中添加指向该笔记的维基链接。
todo — 管理 TODO
查看并更新当前项目的 Active TODOs。
用法:todo [action]
步骤:
-
读取当前 TODO,来源为
$VAULT/todos/Active TODOs.md。 -
如果没有额外参数:显示
$PROJECT的当前 TODO,并询问要更新什么。 -
如果提供了参数:解析为 TODO 操作:
- 纯文本 → 在
$PROJECT下添加为新的待办事项 done: <text>→ 将事项标记为已完成:从 Active TODOs 中移除,并追加到$VAULT/todos/Completed TODOs Archive.md中日期标题## $PROJECT (YYYY-MM-DD)下(如果文件不存在,则创建该文件)remove: <text>→ 移除匹配的事项
- 纯文本 → 在
-
写回 Active TODOs(如果有事项完成,也要写回归档文件)。
lookup — 搜索 Vault
在 Vault 中搜索知识。支持定向子命令和自由文本搜索。
用法:lookup <subcommand|freetext>
lookup deps <name>
查询某个组件依赖什么。
obsidian vault=$VAULT_NAME property:read file="<name>" name="depends-on"
回退方案:读取组件笔记,并解析 depends-on frontmatter 列表。
lookup consumers <name>
查询哪些内容依赖某个组件(反向依赖)。
obsidian vault=$VAULT_NAME property:read file="<name>" name="depended-on-by"
obsidian vault=$VAULT_NAME backlinks file="<name>"
合并结果 — depended-on-by 提供显式关系,backlinks 则捕获隐式引用。回退方案:读取组件笔记,并通过 Grep 搜索反向链接。
lookup related <name>
查询与指定笔记相关的所有笔记(两个方向)。
obsidian vault=$VAULT_NAME links file="<name>"
obsidian vault=$VAULT_NAME backlinks file="<name>"
回退方案:读取笔记并提取 wikilinks,然后在整个 Vault 中通过 Grep 搜索 [[<name>。
lookup type <type> [project]
查找指定类型的所有笔记(component、adr、session、project)。
obsidian vault=$VAULT_NAME tag verbose name="<type>"
如果指定了 [project],则筛选出同时标记为 project/<short-name> 的笔记:
obsidian vault=$VAULT_NAME search query="type: <type>" path="projects/<project>"
回退方案:在 $VAULT 中通过 Grep 搜索 type: <type>。
lookup layer <layer> [project]
查找特定层中的所有组件。
obsidian vault=$VAULT_NAME search query="layer: <layer>" path="projects/<project>"
如果未指定项目,则搜索所有项目:
obsidian vault=$VAULT_NAME search query="layer: <layer>" path="projects"
回退方案:在 $VAULT/projects/ 中通过 Grep 搜索 layer: <layer>。
lookup files <component>
查询组件的关键文件。
obsidian vault=$VAULT_NAME property:read file="<component>" name="key-files"
回退方案:读取组件笔记,并解析 key-files frontmatter 列表。
lookup <freetext>
在整个 Vault 中进行常规搜索。
obsidian vault=$VAULT_NAME search format=json query="<freetext>" matches limit=10
回退方案:在 $VAULT 中的所有 .md 文件里搜索查询内容。
如果查询看起来像标签(以 # 或 project/ 开头):
obsidian vault=$VAULT_NAME tags name="<query>"
如果查询与笔记名称匹配:
obsidian vault=$VAULT_NAME backlinks file="<query>"
呈现结果:显示匹配笔记的 frontmatter(前约 10 行),以便用户决定要完整阅读哪些笔记。
relate — 管理关系
通过 frontmatter 属性创建和查询笔记之间的双向关系。
用法:relate <subcommand> [args]
支持的关系类型
| 正向属性 | 反向属性 |
|---|---|
depends-on | depended-on-by |
extends | extended-by |
implements | implemented-by |
consumes | consumed-by |
relate <source> <target> [type]
在两个笔记之间创建双向关系。默认类型为 depends-on/depended-on-by。
步骤:
-
解析笔记名称:使用
file=参数指定笔记显示名称。如果可能存在歧义(名称相同但文件夹不同),请使用包含相对于 Vault 的完整路径的path=。 -
读取 source 上的当前属性(正向):
obsidian vault=$VAULT_NAME property:read file="<source>" name="<forward-property>"回退方案:读取 source 笔记的 frontmatter。
-
检查关系是否已存在:如果列表中已包含
<target>(作为 wikilink),则跳过并报告“已存在关系”。 -
追加到 source(正向): 在本地将
[[<target>]]追加到当前值,以构建新列表,然后设置:obsidian vault=$VAULT_NAME property:set file="<source>" name="<forward-property>" value="<full-list>" type="list"回退方案:直接编辑 source 笔记的 frontmatter。
-
读取 target 上的当前属性(反向):
obsidian vault=$VAULT_NAME property:read file="<target>" name="<inverse-property>" -
追加到 target(反向):
obsidian vault=$VAULT_NAME property:set file="<target>" name="<inverse-property>" value="<full-list>" type="list" -
报告已创建的关系。
安全性:始终先读取再设置。切勿盲目追加。应在本地构建完整列表,并以原子方式设置。
relate show <name>
显示某篇笔记的所有关系。
步骤:
-
查询全部 8 个关系属性:
obsidian vault=$VAULT_NAME property:read file="<name>" name="depends-on" obsidian vault=$VAULT_NAME property:read file="<name>" name="depended-on-by" obsidian vault=$VAULT_NAME property:read file="<name>" name="extends" obsidian vault=$VAULT_NAME property:read file="<name>" name="extended-by" obsidian vault=$VAULT_NAME property:read file="<name>" name="implements" obsidian vault=$VAULT_NAME property:read file="<name>" name="implemented-by" obsidian vault=$VAULT_NAME property:read file="<name>" name="consumes" obsidian vault=$VAULT_NAME property:read file="<name>" name="consumed-by"回退方案:读取笔记的 frontmatter 并解析所有关系属性。
-
查询结构链接:
obsidian vault=$VAULT_NAME links file="<name>" obsidian vault=$VAULT_NAME backlinks file="<name>" -
按关系类型呈现结果。先显示显式(属性)关系,再显示尚未涵盖的结构性(wikilink)关系。
relate tree <name> [depth]
通过 BFS 遍历依赖树。默认深度为 2。
步骤:
-
初始化 BFS:以
<name>为深度 0 的起点。维护已访问集合和队列。 -
处理队列中的每个节点:
obsidian vault=$VAULT_NAME property:read file="<current>" name="depends-on"回退方案:读取笔记并从 frontmatter 中解析
depends-on。 -
将未访问的依赖项以
current_depth + 1的深度加入队列。达到depth限制时停止。 -
呈现树形结构,以缩进列表展示依赖链。
Token 预算规则
- 优先使用 CLI,而非读取文件:使用
obsidianCLI 查询属性、反向链接、链接、标签和搜索——这些命令会返回定向数据,无需读取完整文件 - 会话开始时:最多执行 2 项操作(TODO + 项目概览)
- 工作期间:读取完整笔记前,先使用
lookup子命令和relate show - 先读 frontmatter:扫描时,先读取约 10 行,再决定是否读取完整文件
- 先列出,再读取:读取文件前,先列出目录内容
- 简洁书写:使用项目符号、链接和标签——能用项目符号表达时,不写散文
错误处理
- 如果知识库不存在 → 建议运行
/obs init进行初始化 - 如果知识库中不存在该项目 → 提议运行
/obs project为其创建框架 - 如果笔记已存在 → 显示笔记而不是覆盖,并提议进行编辑
- 如果未检测到 git 仓库 → 使用当前目录名作为项目名称
- 如果 CLI 命令失败 → 回退到读取文件以获取相同数据
知识库结构参考
$VAULT/
├── Home.md # Dashboard (read only if lost)
├── projects/{name}/
│ ├── {name}.md # Project overview — START HERE
│ ├── architecture/ # ADRs and design decisions
│ ├── components/ # Per-component notes
│ └── patterns/ # Project-specific patterns
├── domains/{tech}/ # Cross-project knowledge
├── patterns/ # Universal patterns
├── sessions/ # Session logs (read only when needed)
├── todos/Active TODOs.md # Pending work (read at session start)
├── templates/ # Note templates
└── inbox/ # Unsorted