Software 2.0 落地:把 Obsidian 仓库改造成本地 Agent 工作台

44 阅读6分钟

Software 2.0 落地:把 Obsidian 仓库改造成本地 Agent 工作台

前阵子我一直在想一件事:我已经在用 Obsidian,平常会写博客,也开始学 Agent,那我真正缺的到底是什么?

后来越来越清楚——不是一个更会聊天的 AI,也不是更花哨的笔记插件。我缺的是一个能长期运转的本地工作系统。不只是记笔记,也不只是对话,而是能把原始资料、知识沉淀、项目推进、写作输出和 Agent 记忆连起来的东西。

先说明一点,这套做法不是我凭空想出来的。比较直接的启发来自两边:一边是 Karpathy 关于 LLM Knowledge Bases 的方法论,另一边是 yanhua1010 那篇把这套东西落到 Obsidian 的实践文章。我做的事更像是在这个基础上,结合自己的后端开发、博客写作和 Agent 学习场景,把仓库结构真正搭起来。

不是发明新理论,是把已有的东西工程化。


Karpathy 那个比喻

Karpathy 原帖最打动我的不是某个具体工具,而是这么一句话:把知识库当代码仓库,把 LLM 当编译器。

原始资料不是最终知识,就像源码不是可以直接跑的程序。它需要经过整理、抽取、索引,才能变成真正可用的东西。

这个比喻一旦接受了,很多设计决策就会变得自然。比如 raw/ 放原始输入、wiki/ 放提炼后的知识条目,不是为了目录好看,而是因为"未编译的源码"和"编译产物"本来就不应该混在一起。

yanhua1010 那篇文章则把这件事说得更接地气。它不停留在"理念很酷",而是把目录分层、Output 落文件、健康检查、增量整理这些东西翻成了贴近 Obsidian 的实际动作。

我参考的就是这两层。然后再往前走一步:把它变成一个我能实际日常使用、Agent 也能直接调用工具的本地仓库。

--

我想要什么

我的场景其实挺具体的:后端开发,平常写博客,最近在学 Agent,希望每次和 Agent 的有效协作都能沉淀下来,不想每次重开会话都从头解释一遍我的习惯和目标。

这意味着我需要的不是一个通用 Agent,而是一个能在本地仓库里持续积累上下文的工作台。

后来我对这件事的理解有个转变:不是"我在用一个 Agent",而是"我在维护一个更大的 Agent 系统"。

这个系统里,我负责提出问题、做判断;Agent 负责分析、生成、协助执行;仓库负责保存长期资产;脚本负责把高频动作稳定下来。有了 Claude Code、Codex 这类工具,到处都可以是 Agent 系统,发挥想象就好。

系统全貌


image.png

为什么要分层

最后落下来的 V1 结构是这样的:

raw/        # 原始输入
wiki/       # 知识编译层
projects/   # 研究/专题/实验推进层
writing/    # 稳定输出层
outputs/    # 运行时产物
agent/      # 记忆、会话、QA、prompt、playbook
scripts/    # Agent 直接可调用的本地工具

这里最重要的不是目录多,而是每一层只回答一个问题。wiki/ 回答"我知道了什么",projects/ 回答"我正在推进什么",writing/ 回答"我准备输出什么",agent/ 回答"我是谁、最近在做什么、该怎么协作"。

如果用 Karpathy 那个比喻来对应:raw/ 是源码,wiki/ 是编译产物,scripts/ 是构建工具,agent/ 是运行时环境。这么看的话,分层就不是强迫症,而是编译流程本来就该有的样子。

这些问题混在一个目录里,系统后面一定越长越乱。这不是经验之谈,是我自己混过一段时间之后得出来的。


AGENTS.md 是导航,不是记忆

很多人第一反应是:新会话会丢上下文,那就把所有东西都堆进 AGENTS.md

我最后的结论是别这样。

AGENTS.md 适合做的事是:解释这个仓库是什么,告诉 Agent 有哪些层,告诉它新会话先读什么、先跑什么,告诉它不同任务该先查哪里。它是启动导航页。

真正的长期记忆在 agent/memory/,会话历史在 agent/sessions/,高价值问答在 agent/qa/,项目上下文在 projects/,通用知识在 wiki/

把这些全塞进 AGENTS.md,它很快就会变成另一个腐烂的大杂烩。腐烂的大杂烩应该在 raw/,不该在入口文件里。


脚本是运行层,不是附属品

一开始我也觉得脚本只是辅助自己手动跑的东西。后来发现这个定位不对。

更合理的方式是:这些脚本应该直接成为 Agent 的本地工具箱。

  • recall.py:新会话开始时读取本地记忆
  • capture_session.py:把一次有价值的会话落成 session
  • archive_qa.py:把高价值问答沉淀成 QA 卡片
  • search_qa.py:先检索已有经验,不是每次重答
  • compile_note.py:把 raw 编译成 summary,这是"编译"那一步真正发生的地方
  • refresh_indexes.py:刷新知识索引
  • consolidate_memory.py:把短期和事件记忆压缩进长期记忆
  • health_check.py / weekly_review.py:定期体检和回顾

这件事的意义不在于自动化本身,而在于稳定性。Agent 单次能力很强,但每次重开会话,如果没有稳定的本地入口,做事层次和上下文恢复会明显波动。脚本的作用是把高频动作固化下来,让一次会话能力逐步沉淀成仓库能力。

所以脚本在这套系统里不是装饰,是运行层。

脚本结构


projects/writing/ 是后来补的

一开始只有 raw / wiki / outputs / agent / scripts,跑了一段时间发现还是不够。

知识积累和项目推进不是一回事。研究一个主题时,我会有目标、假设、实验记录、阶段性结论,这些塞进 wiki/ 不合适,所以补了 projects/。写文章时,选题池、草稿、已发布归档需要一个独立的地方,所以补了 writing/

这两个目录补上之后,wiki/ 不再承担项目推进,projects/ 不再承担长期知识,writing/ 不再承担研究过程。各归各位,后面维护起来省事很多。


V1 停在哪里

这次我没有让系统无限生长,而是刻意停在了一个稳定版本。

当前 V1 里已经有:架构说明、启动导航、记忆读取与会话归档、QA 归档与检索、raw → wiki 的最小编译闭环、索引刷新、记忆整合、健康检查与周回顾、项目推进层、写作层。

没有继续往下扩脚本,停在一个可用、可读、可维护的状态。

很多系统死的不是能力不够,是永远做不完。这套东西我不想让它死在这里。


结语

这次最大的收获不是"搭了一个更复杂的笔记库",而是终于把一件事想通了:

Agent 很强,但会话会结束。真正有价值的,是让它参与到一个能持续积累资产的系统里——而仓库本身,才是长期存在的东西。

当原始输入放哪里、知识放哪里、项目推进放哪里、写作输出放哪里、记忆放哪里、Agent 用什么工具恢复上下文,这些边界都清楚之后,Obsidian 才不只是笔记库,而更像一个真正能长期工作的本地工作台。