2026年4月,GitHub Trending 上出现了一个令人眼前一亮的名字——Obsidian Agent Skills。这个项目以每日 217 星的增速成为当周增长最快的开源项目之一,核心价值在于:让 AI Agent 能够原生理解 Obsidian 独特的 Markdown 扩展语法和双链笔记格式,将碎片化的个人知识库升级为可被 AI 自动化编排的「第二大脑」执行底座。
然而,市面上关于 Obsidian Agent Skills 的报道大多停留在「它是干什么的」层面,对它的工程架构、与 MCP 的关系与边界、以及如何在实际项目中落地缺乏系统性的深度解析。本文从工程师视角出发,对这些问题逐一拆解。
Obsidian 与其他笔记软件最本质的区别有两点:
- 本地优先,数据完全归用户所有:所有笔记以
.md文件存储在本地 Vault 目录,数据库是文件系统。 - 双链与 MOC(Map of Content):通过
[[wikilink]]构建知识图谱,通过 MOC 文件组织主题索引,形成网状知识结构而非线性文档。
但这套系统在 AI 时代暴露了一个根本矛盾:Obsidian 拥有极强的知识组织能力,却没有原生的执行能力。你可以用 Dataview 查询笔记,用 Templater 模板生成内容,用 QuickAdd 快速捕获——但这些都是规则驱动的自动化,缺少真正的智能决策层。
这就是 Agent Skills 要填补的空白。
传统知识管理的范式是:人组织知识,AI 检索知识。Agent Skills 带来的是:AI 理解知识结构后,自主规划、执行和管理知识工作流。
这意味着:
- AI 可以理解你的笔记目录结构和 MOC 关系
- AI 可以在 Obsidian Vault 中创建、更新和链接笔记
- AI 可以根据笔记中的 TODO 和项目进度自动生成报告
- AI 可以在你写一篇论文时,自动从 Vault 中检索相关概念并生成文献综述草稿
要理解 Agent Skills,需要回顾大模型工具调用能力的演进历程:
第一阶段:ReAct(Reason + Act)
大模型通过「思考→行动→观察」的循环调用外部工具(Tool)。这是 ChatGPT Plugins、GPTs 时代的主流范式。
# ReAct 的核心循环伪代码 while not completed:
thought = model.think(task, context) action = model.select_action(thought, available_tools) observation = execute(action) context += (thought, action, observation) 第二阶段:MCP(Model Context Protocol)
Anthropic 在 2024 年末提出的标准化协议,目标是解决「每个 AI 应用各自定义一套 Tool 接口」的碎片化问题。MCP 提供了:
- 统一的工具发现机制
- 标准化的工具描述格式
- 安全沙箱化的工具执行环境
// MCP 工具定义示例 { "name": "filesystem_read", "description": "Read contents from a file", "inputSchema": { "type": "object", "properties": { "path": { "type": "string" }, "encoding": { "type": "string", "default": "utf-8" } } } }
第三阶段:Agent Skills
Skill 是比 Tool 更高层次的抽象。如果说 Tool 是「原子操作」(读文件、执行命令),那么 Skill 是面向场景的 SOP(Standard Operating Procedure)——它将多个原子操作、指令模板和工作流程组合成一个可复用的技能单元。
一个 Skill 的典型结构:
my-skill/ ├── SKILL.md # 技能定义文件(核心) ├── scripts/ # 辅助脚本 ├── prompts/ # 提示词模板 └── config.yaml # 技能配置
My Project Skill
Description
这个 Skill 帮我管理项目文档的完整生命周期。
Trigger Keywords
项目文档, 新建文档, 更新文档, 生成报告
Capabilities
- 在
projects/目录下创建项目笔记 - 更新目录索引(MOC)
- 生成项目周报
Instructions
当用户提到以上触发词时,按以下步骤执行:
- 理解用户需求(新建/更新/生成)
- 确定目标路径
- 读取现有索引文件
- 执行对应操作
- 更新 MOC 索引
Code Templates
创建项目笔记
--- title: {{project_name}} created: {{date}} status: active tags: [project] --- # {{project_name}} 目标 {{goals}} 进度 - [ ] 任务1 - [ ] 任务2 Obsidian Agent Skills 的核心创新在于:它不只是一个 Skill,而是一整套 Obsidian 原生的 Skill 框架。它的设计目标是让任何 AI Agent(Claude Code、OpenCode、Cursor AI 等)都能:
- 理解 Obsidian 的 Vault 结构:目录树、标签体系、链接关系
- 操作 Obsidian 的核心实体:笔记、标签、链接、嵌入块
- 与 Obsidian 插件系统交互:Dataview 查询、Templater 模板、QuickAdd 捕获
Obsidian Agent Skills 采用分层架构,每层职责清晰:
┌─────────────────────────────────────────────────────┐ │ Agent Core(智能体核心) │ │ 负责任务理解、决策编排、上下文管理 │ ├─────────────────────────────────────────────────────┤ │ Skill Registry(技能注册中心) │ │ 管理所有可用 Skill 的元数据与触发规则 │ ├─────────────────────────────────────────────────────┤ │ Execution Engine(执行引擎) │ │ 处理 Skill 调用、错误重试、资源限制 │ ├─────────────────────────────────────────────────────┤ │ Skill Implementations(技能实现层) │ │ ObsidianVault、Dataview、Templater 等具体实现 │ └─────────────────────────────────────────────────────┘
Agent Core 是整个系统的决策中枢。它维护一个技能路由表,根据用户意图匹配最合适的 Skill:
// Agent Core 核心接口定义 interface Agent
interface Skill { id: string; name: string; description: string; triggerKeywords: string[]; instructions: string; codeTemplates?: Record
interface ExecutionContext { vaultPath: string; currentNote?: string; userIntent: string; history: ConversationTurn[]; variables: Record
interface ResourceLimits { maxExecutionTime: number; // 毫秒 maxMemoryMB: number; maxFileSizeMB: number; maxCPUCores: number; }
Skill Registry 采用了多级匹配策略:
class SkillRegistry:
def __init__(self): self.skills: Dict[str, Skill] = {} self.keyword_index: Dict[str, List[str]] = {} # 关键词倒排索引 def register(self, skill: Skill): self.skills[skill.id] = skill # 建立关键词倒排索引 for keyword in skill.triggerKeywords: if keyword not in self.keyword_index: self.keyword_index[keyword] = [] self.keyword_index[keyword].append(skill.id) def match(self, user_input: str) -> Optional[Skill]: """ 多级匹配策略: 1. 精确关键词匹配 2. 模糊语义匹配 3. 默认降级策略 """ # 第一轮:关键词精确匹配 for keyword, skill_ids in self.keyword_index.items(): if keyword in user_input: # 返回匹配度最高的 Skill return self._select_best_match(skill_ids, user_input) # 第二轮:语义相似度匹配 embedding = self._compute_embedding(user_input) best_score = 0 best_skill = None for skill_id, skill in self.skills.items(): score = cosine_similarity(embedding, skill.embedding) if score > best_score and score > 0.7: best_score = score best_skill = skill return best_skill
Execution Engine 负责 Skill 的实际运行,它的核心设计理念是「安全第一,渐进增强」:
class ExecutionEngine:
def __init__(self, vault_path: str, config: VaultConfig): self.vault_path = vault_path self.config = config self.resource_limits = config.get_resource_limits() self.execution_history = [] async def execute(self, skill: Skill, context: ExecutionContext) -> SkillResult: """带资源限制和安全检查的执行""" # 第一步:资源检查 if not self._check_resources(skill): raise ResourceExhaustedError( f"Skill {skill.id} exceeds resource limits" ) # 第二步:安全扫描 security_result = self._security_scan(skill, context) if not security_result.safe: raise SecurityError(security_result.reason) # 第三步:执行前的快照 snapshot = self._create_snapshot() try: # 第四步:执行技能 result = await self._run_skill(skill, context) # 第五步:验证执行结果 if not self._validate_result(result, skill.expected_outputs): raise ValidationError("Output validation failed") return result except Exception as e: # 第六步:失败时回滚 self._rollback(snapshot) raise def _security_scan(self, skill: Skill, context: ExecutionContext) -> SecurityResult: """安全扫描:防止 Skill 执行破坏性操作""" blocked_domains = self.config.blocked_domains blocked_operations = ['rm -rf', 'format', 'delete_all'] # 检查文件操作是否超出 vault 范围 vault_real = os.path.realpath(self.vault_path) for file_op in skill.fileOperations: op_real = os.path.realpath(file_op.path) if not op_real.startswith(vault_real): return SecurityResult(safe=False, reason=f"Path escape attempt: {op_real}") # 检查是否包含危险操作 for blocked in blocked_operations: if blocked in skill.instructions: return SecurityResult(safe=False, reason=f"Blocked operation: {blocked}") return SecurityResult(safe=True)
很多人把 Agent Skills 和 MCP 看作同类产品,这是一个常见误解。它们的本质区别在于抽象层次和设计目标:
一个典型的协作模式:
# ObsidianVault.skill 定义 name: ObsidianVault description: 管理 Obsidian 笔记库的完整操作 uses_mcp_tools:
- filesystem_read
- filesystem_write
- shell_command # 用于执行 obsidian-cli
instructions: | 当需要操作 Obsidian Vault 时:
- 使用 filesystem_read 读取笔记内容
- 使用 Dataview 查询笔记关系(通过 shell 执行 dv query)
- 使用 filesystem_write 创建或更新笔记
- 如果涉及复杂模板,使用 shell_command 执行 Templater
注意:
- 所有文件操作必须在 vault_path 内
- 创建笔记时自动添加 YAML frontmatter
- 更新 MOC 索引时保持链接一致性
这种分工让 MCP 负责「如何安全地读写文件」,让 Skill 负责「如何正确地组织 Obsidian 知识」。
下面演示如何使用 Obsidian Agent Skills 构建一个完整的论文写作自动化流程。
第一步:定义 Skill
# research-paper-workflow
Description
自动化论文写作工作流:从文献收集到结构化输出的完整流程。
Trigger Keywords
写论文, 文献综述, 研究报告, 论文大纲, 整理文献
Vault Structure
Execution Steps
Phase 1: 文献收集与整理
- 在
literature/中创建文献卡片 - 提取论文摘要、方法和结论
- 建立文献之间的引用关系
Phase 2: 概念提取
- 使用 Dataview 查询所有文献笔记
- 提取高频概念和关键术语
- 生成概念笔记并链接到相关文献
Phase 3: 大纲生成
- 分析 MOC 文件中的主题结构
- 生成论文大纲模板
- 将大纲写入
drafts/目录
Phase 4: 内容填充
- 根据大纲逐节生成内容
- 引用 Vault 中的具体文献笔记
- 保持双链关系的一致性
Code Templates
文献笔记模板
--- title: "{{paper_title}}" authors: ["{{authors}}"] year: {{year}} journal: "{{journal}}" doi: "{{doi}}" tags: [literature, {{topic}}] created: {{date}} status: raw reading_status: {{status}} --- # {{paper_title}} 核心贡献 > 一句话总结这篇论文的主要贡献 方法 {{method_summary}} 关键发现 1. 发现1 2. 发现2 相关概念 - [[概念1]] - [[概念2]] 我的想法 > 阅读过程中的思考和启发 引用 {{citation}} 论文大纲模板
--- title: "{{thesis_title}}" created: {{date}} status: draft word_target: } --- # {{thesis_title}} 摘要 1. 引言 - 1.1 研究背景 - 1.2 研究问题 - 1.3 研究意义 2. 文献综述 > 由 Agent 自动从 literature/ 中提取关键文献 3. 理论框架 > 由 Agent 从 concepts/ 中整合相关理论 4. 研究方法 - 4.1 数据来源 - 4.2 分析框架 5. 核心论证 > 由 Agent 基于 Vault 中的笔记内容填充 6. 结论与展望 参考文献 > 由 Agent 自动生成格式化引用列表 第二步:实现核心执行逻辑
import os import re import subprocess from pathlib import Path from datetime import datetime from typing import Dict, List, Optional class ObsidianVault:
"""Obsidian Vault 操作封装""" def __init__(self, vault_path: str): self.vault_path = Path(vault_path) self.literature_dir = self.vault_path / "02-Projects" / "research-2026" / "00-Literature" self.concepts_dir = self.vault_path / "03-Knowledge" / "Concepts" self.drafts_dir = self.vault_path / "02-Projects" / "research-2026" / "03-Drafts" def create_literature_note(self, paper_info: Dict) -> str: """创建文献笔记""" content = self._render_literature_template(paper_info) filename = self._sanitize_filename(paper_info['title']) + ".md" filepath = self.literature_dir / filename filepath.parent.mkdir(parents=True, exist_ok=True) filepath.write_text(content, encoding='utf-8') # 自动建立双向链接 self._update_backlinks(filepath, paper_info) return str(filepath) def _render_literature_template(self, paper: Dict) -> str: """渲染文献笔记模板""" template = """--- title: "{title}" authors: [{authors}] year: {year} journal: "{journal}" doi: "{doi}" tags: [literature, {topic}] created: {date}
reading_status: unread
{title}
核心贡献
> 一句话总结
方法
待填写
关键发现
- 待填写
相关概念
待链接
我的想法
>
引用
{papers} """
return template.format( title=paper['title'], authors=', '.join(f'"{a}"' for a in paper.get('authors', [])), year=paper.get('year', ''), journal=paper.get('journal', ''), doi=paper.get('doi', ''), topic=paper.get('topic', ''), date=datetime.now().strftime('%Y-%m-%d'), papers=paper.get('citation', '') ) def query_dataview(self, query: str) -> List[Dict]: """执行 Dataview 查询""" dv_script = f''' dv.pages('"02-Projects/research-2026/00-Literature"') .where(p => p.reading_status === "read") .sort(p => p.year, 'desc') ''' # 通过 Obsidian 的本地 API 或 dataviewjs 执行 result = subprocess.run( ['obsidian-cli', 'dataview', '--query', dv_script], capture_output=True, text=True, cwd=self.vault_path ) if result.returncode == 0: return json.loads(result.stdout) return [] def generate_draft_outline(self, topic: str, target_words: int) -> str: """基于 Vault 内容生成论文大纲""" # 1. 从 Vault 中检索相关文献 relevant_papers = self.query_by_tag(topic) # 2. 提取核心概念 concepts = self._extract_core_concepts(relevant_papers) # 3. 生成大纲 outline = self._build_outline(topic, concepts, target_words) # 4. 写入草稿目录 draft_file = self.drafts_dir / f"{self._sanitize_filename(topic)}_outline.md" draft_file.parent.mkdir(parents=True, exist_ok=True) draft_file.write_text(outline, encoding='utf-8') return str(draft_file) def _extract_core_concepts(self, papers: List[Dict]) -> List[str]: """从文献中提取核心概念""" # 使用 NLP 技术提取关键词 all_text = ' '.join(p.get('content', '') for p in papers) # 简单实现:基于词频 + 停用词过滤 words = re.findall(r'b[a-zA-Z一-龥]{3,}b', all_text) stopwords = {'the', 'a', 'an', 'and', 'or', 'but', 'of', 'in', 'on', 'at', 'to', 'for', 'is', 'are', 'was', 'were', '这个', '那个', '以及', '通过', '可以', '使用'} word_freq = {} for word in words: word_lower = word.lower() if word_lower not in stopwords: word_freq[word_lower] = word_freq.get(word_lower, 0) + 1 # 返回 Top 20 高频词作为核心概念候选 return [w for w, _ in sorted(word_freq.items(), key=lambda x: x[1], reverse=True)[:20]] 第三步:与 Agent Core 集成
class ResearchPaperWorkflow: """论文写作工作流 Skill 实现""" def __init__(self, vault: ObsidianVault, llm_client): self.vault = vault self.llm = llm_client async def execute(self, user_request: str) -> WorkflowResult: """执行完整的论文写作工作流""" # 解析用户意图 intent = self._parse_intent(user_request) if intent['action'] == 'collect_literature': return await self._collect_literature(intent) elif intent['action'] == 'generate_outline': return await self._generate_outline(intent) elif intent['action'] == 'write_section': return await self._write_section(intent) else: return WorkflowResult( success=False, message=f"未知操作: {intent['action']}" ) async def _generate_outline(self, intent: Dict) -> WorkflowResult: """生成论文大纲""" topic = intent['topic'] target_words = intent.get('target_words', 10000) # 从 Vault 检索相关材料 relevant_notes = self.vault.query_by_keyword(topic) literature_notes = [n for n in relevant_notes if 'literature' in n.get('tags', [])] if len(literature_notes) < 3: return WorkflowResult( success=False, message=f"文献不足,当前仅有 {len(literature_notes)} 篇,建议至少收集 5 篇" ) # 构建上下文 context = " ".join([
f" 文献: {n['title']} "
for n in literature_notes[:10] ]) # 调用 LLM 生成大纲 prompt = f""" 基于以下文献材料,为「{topic}」生成一篇学术论文的大纲。
文献材料: {context}
要求:
- 大纲结构符合学术论文规范
- 每章需要说明该部分的核心论点
- 引用 Vault 中的具体文献
- 总字数目标: 字
请直接输出 Markdown 格式的大纲。 """
outline = await self.llm.complete(prompt) # 写入 Vault filepath = self.vault.generate_draft_outline(topic, target_words) return WorkflowResult( success=True, message=f"大纲已生成并保存至 {filepath}", output={'outline': outline, 'file': filepath} ) # research-paper-workflow/skill.yaml version: "1.0.0" name: research-paper-workflow description: AI 辅助学术论文写作完整工作流 author: developer created: 2026-04-01 triggers: keywords:
- 写论文 - 文献综述 - 研究报告 - 论文大纲 - 整理文献 - 学术写作 patterns:
- "帮我写一篇关于*的论文" - "整理*相关的文献" vault: required_structure:
- "02-Projects/research-*/00-Literature/" - "03-Knowledge/Concepts/" - "02-Projects/research-*/03-Drafts/" dependencies: plugins:
- dataview - templater - quickadd cli_tools:
- obsidian-cli resource_limits: max_execution_time: # 5分钟 max_memory_mb: 2048 max_file_operations: 50
outputs:
- type: file path: "02-Projects/research-*/03-Drafts/" format: markdown
- type: log path: "01-DailyNotes/"
当 Obsidian Vault 包含数千篇笔记时,Agent 操作会遇到显著的性能瓶颈。以下是经过验证的优化策略:
策略一:Dataview 索引缓存
class DataviewCache: """Dataview 查询结果缓存,避免重复索引"""def init(self, ttl_seconds: int = 300):
self.cache: Dict[str, CacheEntry] = {} self.ttl = ttl_secondsdef get(self, query: str) -> Optional[List[Dict]]:
entry = self.cache.get(query) if entry and not entry.is_expired(): return entry.data return Nonedef set(self, query: str, data: List[Dict]):
self.cache[query] = CacheEntry( data=data, created_at=time.time() )def invalidate_pattern(self, pattern: str):
"""当文件变更时使疾相关缓存""" for key in list(self.cache.keys()): if pattern in key: del self.cache[key]策略二:增量操作而非全量扫描
class IncrementalVaultScanner: """增量扫描:只处理变更的文件"""def init(self, vault: ObsidianVault):
self.vault = vault self.last_scan_file = vault.vault_path / ".agent" / "last_scan.json" self.last_scan = self._load_last_scan()def scan_changes(self) -> List[Path]:
"""返回自上次扫描以来变更的文件""" current_files = changes = [] for path, mtime in current_files.items(): last_mtime = self.last_scan.get(path, 0) if mtime > last_mtime: changes.append(Path(path)) self._save_scan(current_files) return changesdef _should_ignore(self, path: Path) -> bool:
"""忽略系统文件和临时文件""" ignore_patterns = [ '.obsidian/', '.trash/', '.agent/', '.cache/', '00-Inbox/', # 草稿不纳入索引 ] path_str = str(path) return any(p in path_str for p in ignore_patterns)策略三:并发安全的文件操作
import asyncio from filelock import FileLock
class ConcurrentVaultWriter:
"""并发安全的 Vault 写入器""" def __init__(self, vault: ObsidianVault): self.vault = vault self.write_lock = asyncio.Lock() async def write_note(self, path: Path, content: str): """带锁的文件写入""" async with self.write_lock: # 文件级别的锁,防止并发写冲突 lock_path = str(path) + ".lock" with FileLock(lock_path, timeout=10): path.write_text(content, encoding='utf-8') async def batch_write(self, operations: List[Tuple[Path, str]]): """批量写入,使用信号量控制并发度""" semaphore = asyncio.Semaphore(3) # 最多 3 个并发写 async def write_with_limit(path: Path, content: str): async with semaphore: await self.write_note(path, content) await asyncio.gather(*[ write_with_limit(path, content) for path, content in operations ]) # vault_security_policy.yaml security: # 路径隔离:禁止跳出 Vault 目录 path_isolation: enabled: true vault_root: "${VAULT_PATH}" allowed_subdirs: - "00-Inbox/" - "01-DailyNotes/" - "02-Projects/" - "03-Knowledge/" - "04-Archive/" blocked_patterns: - ".obsidian/" - "*.vault" - "../" # 操作速率限制 rate_limiting:
max_writes_per_minute: 20 max_reads_per_minute: 100 burst_allowance: 5 # 危险操作黑名单 blocked_operations:
- pattern: "rm -rf" action: block - pattern: "del /f /s /q" action: block - pattern: "format" action: block # 审计日志 audit:
enabled: true log_file: ".agent/audit.log" log_operations: - write - delete - move retention_days: 30
回顾全文,Obsidian Agent Skills 解决了一个根本问题:让知识管理从「人找知识」进化到「知识找知识、AI 驱动知识工作流」。
它的核心贡献可以归结为三点:
- 原生理解 Obsidian 语法:AI 能理解
[[wikilink]]、#tag、Dataview 查询、Templater 模板,而不是把它们当作普通文本 - Skill 抽象的统一性:通过 SKILL.md 标准,任何人都可以定义面向特定场景的工作流,而不需要重新发明轮子
- 安全与可扩展的架构:四层架构分离了决策、注册、执行和实现,天然支持 MCP 生态的集成
需要客观指出的是,Obsidian Agent Skills 目前仍处于早期阶段:
- Vault 规模限制:超过 5000 篇笔记时,性能会出现明显下降
- 多语言支持:中文 Obsidian 社区的一些特有插件(如 Longform)尚未完全兼容
- 实时协作:多人同时编辑 Vault 时的冲突解决机制尚不完善
从技术趋势来看,Obsidian Agent Skills 可能的演进方向:
- 多 Agent 协作:一个 Agent 负责文献收集,一个负责概念提取,一个负责写作执行
- 跨 Vault 知识图谱:打通多个 Obsidian Vault 之间的知识孤岛
- 自适应学习:Agent 通过观察用户的写作习惯和知识组织偏好,自动优化工作流
- Obsidian Agent Skills 项目
- OpenClaw Skill 标准文档
- MCP 协议规范
- Dataview 文档
- claude-obsidian Skill
本文首发于 程序员茄子,如需转载,请保留出处。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/258824.html