Tarquin note
Tarquin note
本文迁移自 wl.do 原文,已按本站 2024 归档规则保留原文结构。

讲完LLM Wiki 编译层之后,知识库内部的 AI 已经能"读"自己的笔记了。但还有一个外部世界的问题没解决:别人家的 AI 怎么也能动我的知识库?
具体场景是这样的:
这些事情如果没有接入层,每一件都得人肉操作。Petrichor 这次做的就是把整个知识库开放给任意 Agent,让"AI 知道你写了什么 / AI 帮你写一点东西"这件事,可以发生在你打开知识库之外的任何工具里。
这篇文章讲清楚它能做什么、为什么这么设计,以及为什么没有选择直接做一个 MCP Server。
动手前先扫了一圈现在的"AI 文档接入"市场:
| 平台 | 给 Agent 的入口 | 鉴权 |
|---|---|---|
| GitBook | 公开站点 URL 后追加固定后缀,自动生成只读 MCP Server | 公开文档不需要鉴权 |
| Mintlify | 只读 MCP(公开)+ 可写 MCP(带 Token)+ 分支 PR 合并 | OAuth / API Token |
| ReadMe | MCP Server + 可下载 SKILL.md,让编辑器按固定流程调用 | API Token |
| Notion | Hosted MCP + OAuth,能力随连接权限走 | OAuth |
| Claude Code / Codex | Skills(SKILL.md)+ MCP,前者描述"何时调用 / 如何鉴权 / 危险操作如何确认" | 视后端实现而定 |
两个观察:
Petrichor 最终选择的方向是:HTTP 在底 + Skill 在面。HTTP 是任何 Agent 都能发的请求,Skill 是给 Agent 看的"使用说明"。这两层都不需要常驻进程,跟一键部署的形态天然契合;以后真要包一层 streaming HTTP MCP Server,也只是在能力层上再加一个适配,不会推翻现有形态。
Petrichor 的 Agent 接入由四块组成,彼此独立又互相配合。
最底层是统一的 HTTP 能力层:所有读写都走 Bearer Token 鉴权的 HTTP 调用,再额外强制带一个"Agent 来源"请求头。任何能发 HTTP 的工具都能直接用,不需要常驻进程、不需要 SDK。
中间是API Key 与权限粒度:Key 在用户的账号页生成,只显示一次明文、入库只存哈希;颁发时按四类 scope 勾选,控制这把 Key 能做的事情上限。
最上面是完整的调用审计:每一次请求,不管成功还是失败,都会留下"谁、用哪个 Agent、调了哪个工具、入参、出参、状态、耗时",用户在后台可以随时回看。
最外层还有一个可下载的SKILL.md 包——给 Agent 看的工作流说明文档,按"环境自检 / 文章读写 / 文档检索 / 文档问答"切成 4 个子 Skill,按需加载。
下面把每一块拆开讲。
整套能力都挂在统一的命名空间下,请求统一带 Bearer Token 鉴权。最重要的入口是一份公开的 manifest 接口——它不需要 Key,Agent 拿到一个域名就能 GET 一下、自我发现整个清单。
这份 manifest 里写清楚了:鉴权用什么 Header、强制要带哪个 Agent 来源头、当前系统支持哪些 scope、所有能力端点的路径、方法、所需权限。
这一步看着平平无奇,但很关键:Agent 不再需要"猜"接口路径。它只要被告诉根域名,就能自己读 manifest、自己拼请求、自己决定调用哪些能力。这就是为什么任何能发 HTTP 的 Agent(包括完全自己写的)都能上手——它不需要预先知道 Petrichor 的存在。
紧接着用capabilities接口查"当前这把 Key 能做什么",返回当前持有的 scope 集合和可访问的知识库列表。Agent 看完就知道"我能写文章但不能删,能读两个知识库"。
主要能力包括:
Key 在登录用户的"Agent Key 管理"页面生成。流程很轻:点"新建 Key",勾选要的 scopes;服务端生成随机 Key,入库只存哈希,原文用一次性弹窗显示,关掉就不会再有;每次请求带进来,服务端再哈希一遍跟库里对比。
为什么不做"可解密的存储"?因为只要服务端能解密,就有人能解密。哈希一去不复返,丢 Key 就重新建一个,没有任何余地,这正是想要的安全模型。
Key 还有几个可选字段:人类可读标签(比如 "claude-code-laptop")、过期时间、撤销时间。撤销后下一次调用立即 401,不用等任何缓存过期。
总共只有四类 scope,刻意保持简单:
| Scope | 包含动作 |
|---|---|
| doc:read | 知识库列表、目录树、文档搜索、文档查看 |
| article:write | 新建文章、更新文章、创建文件夹 |
| article:delete | 删除文章(单独一类,比 write 更危险) |
| qa:read | 文档问答(消耗 LLM Token,单独控制是否允许) |
权限不够直接 403,并且这一次 403 也会被写进审计日志——所以你能在调用记录里看到"某个 Agent 试图删除文章但被拒绝了"。
刻意没有做"按知识库授权"或"按文件夹授权",因为这套设计的目标用户是个人/小团队,而不是企业级多租户。多一层粒度就多一层 UX 复杂度,不如把"想接外部 Agent 又不想给它全部权限"做成"再开一个 Key、只勾它需要的 scope"。
这是做下来最满意的一块。所有外部 Agent 调用都强制带一个"Agent 来源"请求头,否则直接 400,连鉴权阶段都进不去。
为什么要强制这个头?因为 Bearer Key 只告诉服务端"是谁的 Key",不能告诉你"是哪个 Agent 在用"。同一把 Key 可能同时被 Claude Code、Cursor、自己写的 cron 调用,没有这个头你根本不知道是谁在写文章。
每一次请求,不管成功还是失败,都会留下一条记录:哪个 Key、哪个 Agent 来源、调了哪个工具、走的哪个路径、来源 IP、User-Agent、入参快照、出参快照、状态码、耗时、错误信息。登录用户在"Agent 调用日志"页面可以随时翻这些记录,按 Agent / 工具 / 状态码筛。
为什么连入参出参都存?因为没有这两段,"AI 帮我写过什么"就是个黑箱。我希望任何外部 Agent 对知识库的所有改动都是可追溯的——这不是"防 AI 作恶",而是"AI 不可避免地会出错或者会被滥用,得能知道发生了什么"。
HTTP 解决"能不能调",SKILL.md 解决"该不该调、怎么调"。
最朴素的做法是给一份 SKILL.md 把所有能力一股脑塞进去。但 Anthropic 的 Skill 设计哲学其实更倾向职责分离——一个 Skill 描述一件事,Agent 按需加载,避免把 prompt 撑爆。
所以 Petrichor 输出的是一个 zip 包,含4 个独立 Skill 文件夹:
每份 SKILL.md 都按 Claude Code 的规范来,主要写四件事:什么时候用(用户说什么话该把这个 Skill 调起来)、怎么鉴权(用哪个环境变量做 Bearer、必传哪个 Agent 来源头)、调用顺序(先查 capabilities → 再列知识库 → 视情况建文件夹 → 最后写入)、危险操作的护栏(比如删除文章前必须复述标题路径并得到用户明确确认,一次会话不许批量删除超过 3 篇)。
Claude Code 用户拿到 zip 解压,把 4 个文件夹塞进自己的 Skills 目录,重启就能直接被调起。Cursor / Codex 还没标准化 Skill 协议,可以把 SKILL.md 当成 system prompt 的一部分塞进去,效果是等价的——这也是为什么选 SKILL.md 而不是某个 IDE 私有格式。
另外还提供单文件版的 SKILL.md,兼容那些只认一个文件的客户端。
这是被问得最多的问题。简单回答:还没必要,但留好了升级口。
MCP 的优势是协议层标准化——一旦实现,所有支持 MCP 的客户端都能直接接入。但它的代价是:
所以现在的形态是:底层 HTTP 已经是稳定能力,未来想要 MCP,只需要在能力层之外再挂一层适配把它转成 MCP 协议即可,业务能力零改动。
回到一开始那几个场景,现在每一个都能跑通:
场景 1:从 IDE 把笔记同步到知识库
Claude Code 装好 petrichor-articles 这个 Skill,在终端里说:
把刚刚那段调试 Pooler 6543 的笔记整理成一篇文章,放到我"工程记录"知识库下的"Postgres"文件夹
Agent 自动完成"找知识库 → 必要时建文件夹 → 写入文章"的链路,全程不切窗口。
场景 2:让 Cursor 先去知识库找答案
petrichor-docs 描述了搜索与查看的用法。Cursor 看到代码注释里有"这个函数的设计在我们之前的笔记里",会主动调搜索接口而不是凭空生成。
场景 3:定时把外部内容写进知识库
写个 cron,每天拉 GitHub Issue / Slack 消息,调写入接口落进"日报"文件夹。Bearer Key + Agent 来源头,调用记录全都能在后台翻到。
场景 4:在团队内审计 AI 行为
任何人接了你的 Key,所有改动都留痕。哪个 Agent 在哪个 IP 用哪个 UA 改了什么文章,都能查。一旦发现异常,撤销 Key 即可——下一次调用立刻 401。
这些都不是协议层缺陷,是有意先压在 v1 之外的功能。等到有真实需求驱动再加。
整个过程不到 5 分钟。
知识库从前是个封闭的资产:你写进去的东西只有打开它的时候才看得到。
接上 Agent 之后,知识库变成了操作系统级的服务:任何工具都能查它、写它、问它。你不必再"切过去用知识库",知识库会跟着你的工作流走。
这不是要把所有 AI 工具都拉进自己的生态——恰恰相反,它是让你的知识库成为别人 AI 生态里的一份公民。Claude Code 在写代码时能知道你笔记里有过的判断,Cursor 在补全时能引用你的前任设计,cron 在凌晨把当天的日报存进来——你不必为每一个工具单独适配,一份 Skill 包 + 一个 Key 就够了。