Skip to main content
ArcBlock Community

AFS 从入门到实战:理解 ArcBlock 面向 AI Agent 的资源世界

shenxiuqiang
Support

ChatGPT Image 2026年9月19日 18_18_24.jpg

AFS(Agentic File System)并不只是一个“给 AI 用的文件系统”。它真正解决的问题,是如何让 Agent 以统一、可寻址、可发现、可控制的方式访问文件、服务、数据以及正在运行的能力。 本文从一个刚接触 AFS 的开发者视角出发,从最简单的 arc afs 命令开始,逐步理解 Path、Mount、Provider、Capability,再深入到 Search、Query、Exec、权限边界以及 Agent 访问。读完之后,你应该能够理解 AFS 为什么存在,以及如何把它用于自己的 AI Agent 和 ARC 应用。

一、先别急着把 AFS 理解成“文件系统”

第一次看到 AFS,很容易产生一个直觉:它是不是类似 Linux 文件系统,只不过把文件提供给 AI Agent?

这个理解只能算对了一半。

传统文件系统解决的是一个相对明确的问题:如何把磁盘上的文件组织成目录和路径,并提供读取、写入、删除等操作。

AFS 的目标更大。

在 AFS 中,一个路径背后不一定是一块磁盘,也不一定是一份普通文件。它可能来自本地文件系统、数据库、远程服务、DID Space、Web Device,甚至可以代表某个可以被调用的动作。AFS 通过统一的路径和操作模型,把这些不同类型的资源放进一个可以被程序和 Agent 理解的资源空间。

所以,更准确的理解是:

AFS 是一个“路径可寻址的资源与能力抽象”。

官方文档也特别强调,路径是接口边界,而不是“所有数据都存储在同一个地方”的证明。真正负责资源访问的是 Provider;Provider 决定资源如何取得、保存以及支持哪些操作。

可以把传统文件系统与 AFS 做一个简单对比:

传统文件系统AFS
文件和目录资源和能力
磁盘是主要后端后端可以有很多种
路径指向文件路径指向 Provider 所拥有的资源
操作比较固定操作由 Provider 声明
主要面向程序和用户同时面向程序、应用和 Agent
权限主要由文件系统控制Provider、Mount、访问模式、调用方等共同决定

因此,如果只把 AFS 当成“AI 版文件系统”,很容易错过它真正有价值的地方。

二、先建立一个最重要的心智模型

理解 AFS 最简单的方法,是先记住下面这条链路:

javascript
调用方
  ↓
AFS Path
  ↓
Mount 路由
  ↓
Provider
  ↓
实际资源 / 后端系统

例如:

javascript
Agent
  ↓
/project/README.md
  ↓
匹配 /project
  ↓
FS Provider
  ↓
本地目录 /Users/me/project

也可以是:

javascript
Agent
  ↓
/knowledge/articles
  ↓
匹配某个 Mount
  ↓
Database / Knowledge Provider
  ↓
数据库、搜索服务或远程 API

这就是 AFS 最核心的设计。

调用方不需要知道底层究竟使用 SQLite、文件系统、HTTP API 还是其他存储系统。它只需要知道:

“我需要访问这个路径。”

然后由 ARC 根据 Mount 找到对应 Provider,再由 Provider 执行具体操作。

官方文档把这一过程描述为:调用方对 AFS Path 发起操作,运行时根据路径匹配 Mount,再把操作交给拥有该路径的 Provider;Provider 只执行自己声明并能够强制执行的操作。

三、为什么 AI Agent 特别需要 AFS?

传统应用通常是“应用调用 API”。

例如,一个聊天机器人需要读取用户文件,开发者可能需要写:

javascript
读取文件 API
↓
获取文件列表 API
↓
搜索 API
↓
数据库 API
↓
知识库 API
↓
对象存储 API

随着 Agent 能力越来越多,这种模式会变得非常复杂。

Agent 不只是“读取文件”。它可能需要:

  • 查看项目目录;
  • 读取代码;
  • 搜索文档;
  • 查询数据库;
  • 获取某个用户的数据;
  • 调用一个服务;
  • 执行某个任务;
  • 查看任务状态;
  • 修改某个资源;
  • 解释某个路径代表什么。

如果每一种能力都变成完全不同的 API,Agent 就必须理解大量不同的接口。

AFS 提供了另一种思路:

javascript
                     ┌─ 本地文件
                     ├─ 项目代码
Agent → AFS Path → Mount → Provider ─ 数据库
                     ├─ Web 服务
                     ├─ DID Space
                     └─ Agent Action

对于 Agent 来说,重要的不再是:“这个资源背后的 API 是什么?”

而变成:“这个资源在我的工作空间中叫什么?我对它有什么能力?”

这就是 AFS 与 Agent 结合之后最值得理解的地方。

四、AFS 中最重要的四个概念

刚开始学习 AFS,不需要一下子记住所有 API。

首先理解四个概念:

Path、Mount、Provider、Capability。

它们分别回答四个问题:

概念回答的问题
Path我要访问什么?
Mount这个路径应该交给谁?
Provider谁真正负责访问资源?
Capability这个资源到底允许我做什么?

把它们串起来就是:

javascript
Path
  ↓
“我要访问 /project”
  ↓
Mount
  ↓
“/project 属于这个 Provider”
  ↓
Provider
  ↓
“我负责访问这个资源”
  ↓
Capability
  ↓
“我支持 read / write / search ……”

这是理解 AFS 的第一道门槛。

五、Path:AFS 世界里的“地址”

Path 是 AFS 最容易理解的部分。

例如:

javascript
/project
/project/README.md
/project/src/index.ts
/knowledge/articles
/users/alice

它们看起来很像普通文件系统路径,但不要因此认为它们一定对应磁盘上的真实文件。

AFS Path 更接近:

“资源在当前 AFS 实例中的地址。”

官方文档把 Path 定义为实例命名空间中的虚拟地址,例如:

javascript
/modules/project/README.md

因此:

javascript
/project/README.md

并不意味着一定存在:

javascript
/Users/xxx/project/README.md

真正决定它指向什么的是 Mount。

六、Mount:把路径连接到 Provider

Mount 可以理解为 AFS 世界里的“路由”。

假设存在:

javascript
/project

这个路径可能通过 Mount 连接到:

javascript
fs:///Users/you/project

于是:

javascript
/project/README.md

最终可能被解析成:

javascript
/Users/you/project/README.md

整个关系可以画成:

javascript
AFS Path                 Mount                    Provider
/project/README.md  →  /project  →  fs://...  →  本地文件

这也是为什么:

同一个 AFS Path,在不同实例中可能完全不是同一个东西。

如果两个 ARC 实例拥有不同的 Mount 表,那么:

javascript
/project

在实例 A 和实例 B 中可以指向完全不同的 Provider。

官方的运行时边界文档明确指出,AFS 的行为是实例化的;同一个 CLI 二进制面对不同 daemon、不同数据目录或者不同 Mount 表,并不会自动产生相同的路径。

七、Provider:真正干活的人

如果说 Path 是地址,Mount 是路由,那么 Provider 就是真正干活的部分。

Provider 负责:

  1. 解析路径;
  2. 找到对应资源;
  3. 实现操作;
  4. 执行权限和能力限制;
  5. 与真正的后端系统交互。

例如,一个 FS Provider:

javascript
/project
    ↓
FS Provider
    ↓
本地文件系统

一个数据库 Provider:

javascript
/data/users
    ↓
Database Provider
    ↓
SQLite / PostgreSQL / ...

一个远程服务 Provider:

javascript
/services/weather
    ↓
Service Provider
    ↓
HTTP API

因此,AFS 本身并不需要知道:

“这个资源到底存在哪里?”

这属于 Provider 的职责。

八、Capability:AFS 最容易被忽略、却非常重要的一层

传统文件系统经常让人形成一个错误习惯:

既然是文件,就应该可以读、写、删除。

AFS 不是这样。

一个 Provider 可以只支持:

javascript
read
stat

也可以支持:

javascript
read
write
search

还可能支持:

javascript
read
write
delete
exec
search

所以:一个路径存在,并不意味着你可以对它执行所有操作。

官方 AFS Core Contract 明确规定,Provider 通过 OperationsDeclaration 声明自己的能力,AFS 不要求所有 Provider 都实现所有操作。

因此,在真正调用之前,应该先问:

javascript
这个 Path 是谁提供的?
这个 Provider 支持什么?
当前访问模式是什么?
我现在拥有的权限是什么?

这比直接尝试 writeexec 更可靠。

九、第一次运行 AFS:先看你自己的环境

如果你已经安装了 ARC,可以先执行:

javascript
arc --version

然后:

javascript
arc afs --help

当前官方文档以:

javascript
arc 2.0.0-beta.28

作为主要核验版本。

AFS CLI 的核心命令包括:

javascript
arc afs ls
arc afs read
arc afs write
arc afs delete
arc afs stat
arc afs exec
arc afs explain
arc afs search
arc afs mount

它们分别对应:

命令用途
ls查看目录 / 子资源
read读取资源
write写入或修改资源
delete删除资源
stat查看资源元数据
exec执行 Action
explain解释 AFS 概念和路径
search搜索资源
mount管理 Mount

第一次学习时,建议不要马上:

javascript
write
delete
exec

而是从:

javascript
explain
ls
stat
read
search

开始。

官方快速开始文档也建议先进行只读巡检,不要对未知路径直接进行写入、删除或者执行操作。

十、arc afs explain:学习 AFS 最值得掌握的命令

如果你刚开始接触 AFS,我非常建议先使用:

javascript
arc afs explain

它可以帮助你理解当前运行环境里的 AFS。

还可以继续:

javascript
arc afs explain mount

或者针对某个路径:

javascript
arc afs explain /project

它的价值在于:

不要猜 Path 是什么,而是让 AFS 告诉你 Path 是什么。

这是理解 AFS 与传统文件系统区别的一个很好的入口。

十一、ls:看看 AFS 世界里有什么

最简单的命令:

javascript
arc afs ls /

例如:

javascript
/
├── project
├── data
├── services
└── ...

然后可以继续:

javascript
arc afs ls /project

再继续:

javascript
arc afs ls /project/src

这和传统文件系统非常像。

但这里需要记住:

你看到的目录树不是操作系统磁盘目录树,而是当前 AFS Instance 通过 Mount 和 Provider 暴露出来的资源视图。

所以不要看到:

javascript
/data

就认为它一定对应:

javascript
/data

这个 Linux 目录。

十二、stat:不要猜,先问它是什么

stat 是 AFS 中非常重要的诊断工具:

javascript
arc afs stat /project

它可以帮助你了解资源的元数据以及相关能力。

尤其值得关注:

javascript
capabilities
accessMode
visibility

例如,一个 Provider 可能声明:

javascript
capabilities:
  list
  read
  stat
  search
  write

但当前访问模式可能是:

javascript
accessMode: readonly

这意味着:

Provider 理论上会 write,不代表当前调用方可以 write。

这是 AFS 权限模型里非常重要的一点。

官方 HTTP AFS 文档也专门用这个例子说明:capabilities 表示 Provider 实现了什么,而 accessMode 表示当前调用方实际获得什么访问能力,两者不能混为一谈。

十三、AFS 的核心操作

理解了 Path、Mount、Provider 和 Capability 后,再看 AFS API 就简单很多。

1. list

javascript
arc afs ls /project

解决的问题是:

“这里有什么?”

它主要用于枚举。

2. read

javascript
arc afs read /project/README.md

解决:

“把这个资源的内容给我。”

3. write

javascript
arc afs write /project/test.txt "Hello AFS"

解决:

“创建或修改这个资源。”

但是否允许写,必须看 Provider 和当前 access mode。

4. delete

javascript
arc afs delete /project/test.txt

解决:

“删除这个资源。”

同样不能因为命令存在,就认为所有 Provider 都支持删除。

5. stat

javascript
arc afs stat /project

解决:

“这个资源是什么?它有哪些能力?”

这是非常适合 Agent 在行动之前进行环境发现的操作。

javascript
arc afs search /project "AFS"

解决:

“在这个资源范围内查找相关内容。”

但它不是一个全局搜索引擎。

7. exec

javascript
arc afs exec <executable_path>

解决:

“调用这个路径对应的 Action。”

这也是 AFS 从“文件系统抽象”走向“Agent 能力空间”的关键一步。

8. explain

javascript
arc afs explain

解决:

“告诉我这个 AFS 世界是什么,以及某个路径如何被解析。”

十四、为什么 AFS 不只是 CRUD?

如果 AFS 只有:

javascript
list
read
write
delete

那么它与普通文件系统的差别并不大。

真正重要的是:

javascript
search
exec
explain
query

这些能力让 AFS 从“数据访问层”开始变成“Agent 工作空间”。

例如:

javascript
/project
    ├── README.md
    ├── package.json
    └── src/

这是数据。

而:

javascript
/project/build
/project/test
/project/deploy

则可能代表可执行能力。

于是 Agent 看到的世界就不再只是:

javascript
文件
文件
文件

而可以变成:

javascript
资源 + 数据 + 服务 + Action

这才是 Agentic File System 这个名字真正值得关注的地方。

十五、listsearchquery:千万不要混为一谈

这是深入 AFS 时必须理解的一个问题。三个操作分别解决不同问题。

javascript
list
  ↓
这里有什么?

search
  ↓
这里有没有包含某个文本?

query
  ↓
按照明确的结构化条件查询集合

官方文档明确指出,不能把三者理解为同一个功能的三个名字。

list

例如:

javascript
arc afs ls /project

回答:

/project 下面有哪些资源?

它是目录枚举。

例如:

javascript
arc afs search /project "RELEASING"

回答:

/project 范围内哪些资源匹配这个自由文本?

但是搜索的能力、索引方式、覆盖范围以及排序方式,由 Provider 自己定义。因此不能因为某一个 Provider 支持全文搜索,就认为所有 AFS Provider 都拥有同样的搜索能力。官方文档特别强调,AFS 并不承诺一个跨 Provider 的全局全文索引、统一语义搜索或者统一排序算法。

query

query 则是另外一种东西。

它对应:

javascript
/.actions/query

是一种严格类型化的集合查询能力。

因此:

javascript
list ≠ search ≠ query

这是设计 AFS 应用时非常重要的区别。

十六、理解 Access Mode:不是“有能力”就一定“能做”

AFS 的访问模式包括:

javascript
readonly
create
append
readwrite

例如:

javascript
Provider Capability
        ↓
支持 write
        ↓
当前 Mount
        ↓
readonly
        ↓
当前调用方
        ↓
不能 write

所以 AFS 实际上存在两层概念:**Provider 能做什么,**以及:当前调用方被允许做什么,这使得 AFS 更适合 Agent 环境。因为给 Agent 的并不是:“整个机器的访问权限。”而是:“给你一块明确的资源世界,以及这块世界里你可以执行的操作。”这也是 Agent 安全边界的重要基础。

十七、Visibility:Agent 有时候只需要知道“它存在”

AFS 还有一个容易被忽略的概念:

javascript
visibility

常见形式包括:

javascript
full
meta

如果是:

javascript
full

Agent 可以看到资源内容。如果是:

javascript
meta

则主要看到元数据,而不是完整内容。这对于构建大型 Agent 工作空间很有意义。Agent 不一定需要一开始就把所有内容读进上下文。它可以先:

javascript
发现资源
  ↓
读取 metadata
  ↓
判断是否相关
  ↓
再读取具体内容

这实际上与现代 Agent 的 Context 管理非常契合。

十八、AFS 与 Agent:真正的价值在哪里?

可以把传统 Agent 理解成:

javascript
Agent
 ↓
Tools
 ↓
各种 API
 ↓
各种数据源

而 AFS 更接近:

javascript
                         ┌─ 文件
                         ├─ 数据
Agent → AFS Resource View ├─ 服务
                         ├─ Action
                         └─ 工作状态

Agent 面对的是一个统一的资源世界。

例如一个软件开发 Agent:

javascript
/project
/project/src
/project/tests
/project/docs
/project/package.json
/project/build
/project/test

其中:

javascript
/project/src
/project/docs

主要是数据。

而:

javascript
/project/build
/project/test

可以代表操作。

于是 Agent 不再只是“调用工具”,而是在一个具有明确空间结构的环境中工作。

这就是 AFS 与传统 Tool Calling 一个很重要的区别。

十九、AFS 与 MCP 是什么关系?

如果你正在学习 AI Agent,可能会马上想到:

AFS 是不是 MCP?

不是。

两者解决的问题不同。

可以简单理解:

javascript
MCP
 ↓
Agent 与外部工具 / 资源之间的协议

AFS
 ↓
资源如何组织、寻址、发现和执行的抽象

因此,AFS 可以通过 MCP 暴露给 Agent。

同时也可以通过其他接口访问。

当前 ARC 文档中已经提供了 AFS over HTTP 的方式:客户端可以通过:

javascript
/api/afs/rpc

使用 JSON-RPC 调用 AFS 操作。

例如:

javascript
curl -s -X POST https://<host>/api/afs/rpc \
  -H 'Content-Type: application/json' \
  -d '{"type":"list","path":"/"}'

而对于支持 MCP 的客户端,则可以通过:

javascript
/mcp

访问相同的 AFS 数据面。

官方文档明确说明,两者使用不同的协议封装,但底层访问的数据面和访问规则是一致的。

可以理解为:

javascript
                 ┌─ MCP
Agent ───────────┤
                 ├─ HTTP JSON-RPC
                 ├─ CLI
                 └─ Application Code
                         ↓
                        AFS
                         ↓
                      Provider

这也是 AFS 很有意思的一点:AFS 是资源抽象,而不是绑定某一种 Agent 协议。

二十、Provider 才是 AFS 的真正扩展点

如果你想把 AFS 用在自己的项目中,最终一定会遇到 Provider。

Provider 的基本职责可以概括为:

javascript
定义资源
   ↓
定义路径
   ↓
定义操作
   ↓
声明能力
   ↓
连接后端

例如你有一个摄影项目:

javascript
/photos
/photos/2026
/photos/2026/yunnan
/photos/2026/yunnan/IMG_001.CR3

你完全可以设想一个摄影资源 Provider:

javascript
AFS
 ↓
/photos
 ↓
Photo Provider
 ↓
照片存储 / 元数据数据库 / 对象存储

对于 Agent 来说,它不需要知道:

javascript
照片究竟存在哪里?

只需要知道:

javascript
/photos/2026/yunnan

以及:

javascript
这个路径支持什么操作?

这就是 Provider 抽象的力量。

二十一、如何设计一个自己的 Provider?

如果进入 Provider 开发阶段,首先应该从最小能力集合开始。

不要一开始就声称支持:

javascript
list
read
write
delete
search
query
exec
batch
ifMatch

如果实际没有可靠实现,就不要声明。

官方 Provider 编写文档强调:

声明什么,就必须能够真正执行什么。

当前参考实现中的 Provider 通常基于:

javascript
AFSBaseProvider

并通过操作处理器实现:

javascript
List
Read
Write
Delete
Search
Stat
Explain

等能力。

Provider 还需要提供自己的 manifest / load 机制,并通过 capability declaration 告诉运行时自己支持什么。

二十二、为什么 Capability Declaration 如此重要?

假设 Agent 看到了:

javascript
/photos

它不能仅仅因为这是一个路径,就假定:

javascript
read
write
delete
search
exec

全部存在。

它应该先发现:

javascript
stat /photos

然后知道:

javascript
capabilities:
  list
  read
  search

于是 Agent 就知道:

javascript
可以浏览
可以读取
可以搜索
不能修改
不能删除
不能执行

这种设计非常适合 AI Agent。

因为 Agent 面对的是一个动态能力空间

它不需要把所有 Provider 的能力硬编码进去。

它可以:

javascript
发现
 ↓
理解
 ↓
选择操作
 ↓
执行

二十三、exec:AFS 从资源走向能力

这是我认为学习 AFS 时最值得重点理解的一部分。

普通文件系统里的对象主要是:

javascript
文件
目录

而 AFS 可以通过 exec 把“动作”纳入资源空间。

例如:

javascript
/project/build
/project/test
/project/deploy

这些路径未必对应文件。

它们可以代表:

javascript
Build Action
Test Action
Deploy Action

Agent 就可以通过统一的 AFS 路径模型发现这些能力。

因此:

javascript
Path

不再只是:

“某个文件在哪里?”

还可以表示:

“某个能力在哪里?”

这正是 AFS 从传统 File System 向 Agentic File System 转变的核心。

二十四、但不要把 exec 当成“任意执行命令”

这里一定要注意。

AFS 的 exec 并不是:

javascript
Agent → Shell → 随便执行命令

正确理解应该是:

javascript
Agent
 ↓
明确的 executable path
 ↓
Provider
 ↓
Provider 定义的 Action
 ↓
权限 / 策略 / 严重级别
 ↓
执行

官方核心合同明确指出,exec 需要明确的 Action 路径、参数以及权限 / 严重级别策略。

因此,对于 Agent 系统而言:

“可执行”不等于“可以执行任意代码”。

它更接近:

Provider 向 Agent 暴露了一组经过定义的能力。

二十五、Mount 是 AFS 与真实世界连接起来的地方

理解到这里,可以重新看 Mount。

Mount 并不是一个简单的“目录映射”。

它实际上是在告诉 ARC:

javascript
这个资源世界的一部分
应该通过哪个 Provider
以什么路径
暴露出来

例如:

javascript
/project
   ↓
FS Provider
   ↓
本地项目

或者:

javascript
/data
   ↓
Database Provider
   ↓
数据库

又或者:

javascript
/services
   ↓
Service Provider
   ↓
远程服务

最终 Agent 看到的是一个统一空间:

javascript
                    AFS
                     │
        ┌────────────┼────────────┐
        ↓            ↓            ↓
     /project      /data      /services
        ↓            ↓            ↓
      FS          Database      Service
        ↓            ↓            ↓
      Files        Records       APIs

这就是 AFS 最直观的架构图。

二十六、不要把源码里的 Provider 列表当成“官方产品目录”

这是开发者非常容易踩的坑。

ARC 源码中的:

javascript
providers/

可能存在很多 Provider package。

但是:

源码里存在一个 Provider,不等于它就是一个稳定公开支持的产品能力。

官方文档明确提醒,源码树中的 Provider package 是实现清单,而不是公开支持目录。真正使用某个 Provider 时,应当查看它是否有明确的产品级文档、支持范围和验证证据。

这对写教程尤其重要。

不要因为:

javascript
源码里有 xxx Provider

就直接写:

AFS 官方支持 xxx。

更准确的表达应该是:

当前 ARC 源码中存在 xxx Provider 实现;具体是否属于稳定公开能力,需要以对应版本和官方 Provider catalog 为准。

二十七、AFS 的运行时边界:为什么“我刚刚 Mount 成功了”还不代表能用?

这是实际开发中特别重要的一点。

假设执行:

javascript
arc afs mount add /project fs:///tmp/project

CLI 可能显示:

javascript
Mounted ...

但这并不意味着:

javascript
arc afs ls /project

一定马上能够正常工作。

官方当前文档在 2.0.0-beta.28 上记录了这种运行时现象:Mount 表可能已经出现新记录,但随后 explainlsread 仍可能无法正常访问。

因此,正确的验证方式不是:

javascript
mount add 成功
        ↓
认为完成

而应该是:

javascript
mount add
   ↓
mount list
   ↓
explain path
   ↓
stat / ls
   ↓
read
   ↓
确认真正可用

这也是为什么 AFS 文档非常强调:

配置成功 ≠ 运行时验收成功。

二十八、AFS 的错误处理也应该成为应用设计的一部分

AFS 不是简单返回:

javascript
true
false

开发应用时应该根据错误类型做不同处理。

例如:

javascript
AFS_NOT_FOUND
        ↓
资源不存在

AFS_UNSUPPORTED
        ↓
Provider 不支持该操作

AFS_VALIDATION_ERROR
        ↓
请求参数不合法

AFS_CONFLICT
        ↓
资源发生冲突

AFS_READONLY
        ↓
当前访问模式禁止修改

AFS_AUTH_REQUIRED
        ↓
需要认证

这些错误码可以让 Agent 或应用知道:

是资源不存在?

还是:

Provider 根本不支持?

还是:

当前用户没有权限?

这对于自动化 Agent 非常重要。

因为 Agent 不应该看到错误后简单地:

javascript
再试一次

而应该根据错误类型决定下一步。

二十九、一个真正的 Agent 应该如何使用 AFS?

假设我们开发一个代码 Agent。

传统方式可能是:

javascript
Agent
 ↓
list_files()
 ↓
read_file()
 ↓
search_code()
 ↓
run_tests()
 ↓
build()

而基于 AFS,可以抽象成:

javascript
Agent
 ↓
发现 AFS
 ↓
查看 /project
 ↓
stat /project
 ↓
发现 capabilities
 ↓
list /project
 ↓
search /project "TODO"
 ↓
read /project/src/index.ts
 ↓
exec /project/test

整个过程变成:

javascript
发现资源
   ↓
理解资源
   ↓
判断能力
   ↓
选择操作
   ↓
执行
   ↓
观察结果
   ↓
继续工作

这与 Agent 的自主工作方式非常匹配。

三十、从“工具调用”升级到“工作空间”

这是理解 AFS 最关键的一步。

传统 Tool Calling:

javascript
Agent
 ↓
工具 A
 ↓
工具 B
 ↓
工具 C
 ↓
工具 D

工具越来越多之后,Agent 面临的问题也越来越复杂:

javascript
这个工具做什么?
参数是什么?
它和哪个工具相关?
返回什么?
权限是什么?

而 AFS 提供了一种空间化的思路:

javascript
                 Agent
                   ↓
             Resource World
                   ↓
      ┌────────────┼────────────┐
      ↓            ↓            ↓
    Files        Data         Actions
      ↓            ↓            ↓
   /project      /data       /project/test

Agent 不只是“调用工具”。它开始:**在一个有结构、有边界、有名字、有能力声明的世界里工作。**这也是为什么 AFS 这个名字不是简单的:Agent File System;而是:Agentic File System;它强调的不是“文件属于 Agent”,而是:这个文件系统抽象是围绕 Agent 工作方式设计的。

三十一、一个实际开发场景:让 Agent 管理项目

假设我们有一个项目:

javascript
my-app
├── README.md
├── package.json
├── src/
├── tests/
└── docs/

传统 Agent 需要知道本地路径:

javascript
/Users/me/work/my-app

而通过 AFS,可以把它挂载为:

javascript
/project

于是 Agent 只需要面对:

javascript
/project

它可以:

javascript
list /project
       ↓
发现 README.md
       ↓
read /project/README.md
       ↓
search /project "TODO"
       ↓
发现代码问题
       ↓
read /project/src/...
       ↓
exec /project/test
       ↓
获取结果

Agent 不需要知道:

javascript
/Users/me/work/my-app

也不需要知道背后具体是哪一个文件系统。这就是 Path Abstraction 的价值。

三十二、如果把 AFS 用到知识库会怎么样?

假设你有一个知识库:

javascript
/knowledge

下面可能存在:

javascript
/knowledge/articles
/knowledge/docs
/knowledge/projects
/knowledge/users

Agent 可以先:

javascript
list /knowledge

再:

javascript
search /knowledge "ArcBlock"

找到相关资源后:

javascript
read /knowledge/articles/xxx

如果知识库 Provider 支持结构化 Query,则进一步:

javascript
query /knowledge

进行类型化查询。这意味着:**知识库不一定要专门包装成一个 Agent Tool。**它可以成为 Agent 工作空间中的一个资源区域。这就是 AFS 对 AI 应用架构可能产生的一个重要影响。

三十三、AFS 对应用开发者意味着什么?

如果你正在开发 AI Agent,可以把思考方式从:

“我要给 Agent 添加多少 Tools?”

逐渐转变为:

“我要给 Agent 构建怎样的 Resource World?”

两者的区别非常大。

传统思路:

javascript
增加功能
 ↓
增加 Tool
 ↓
增加 API
 ↓
增加 Tool Description

AFS 思路:

javascript
定义资源
 ↓
设计 Path
 ↓
Mount Provider
 ↓
声明 Capability
 ↓
让 Agent 自己发现和使用

这会让 Agent 架构更接近操作系统。操作系统并不需要为每一个应用专门发明:

javascript
open_file_tool
read_file_tool
write_file_tool

它提供的是:

javascript
文件系统
路径
权限
进程
设备

应用在这个世界里工作。AFS 正在探索类似的思路:给 Agent 一个可以工作的资源世界。

三十四、从开发者角度重新理解 ARC 与 AFS

如果继续学习 ArcBlock 当前 ARC 架构,最好把 ARC 和 AFS 分开理解。可以简单记成:

javascript
AFS
 ↓
资源、路径、Provider、Capability、操作

ARC
 ↓
运行时、Daemon、Blocklet、Session、CLI、宿主环境

官方架构文档把 AFS 描述为路径与能力层,而 ARC 更接近承载 Mount、Blocklet、CLI 等能力的运行时产品外壳。所以:

AFS 是模型,ARC 是运行环境。

当你研究:

javascript
Path
Mount
Provider
Capability
Search
Query
Exec

重点看 AFS。当你研究:

javascript
Daemon
Blocklet
Instance
Session
CLI
运行生命周期

重点看 ARC。这个区分可以避免很多概念混乱。

三十五、从这里开始进入 AFS 源码

如果你已经掌握前面的概念,可以开始阅读 ARC 源码。官方当前参考位置主要包括:

javascript
packages/core/src/type.ts

这里可以看到:

javascript
AFSModule
AFSRoot
Entry
Result

等核心类型。

然后:

javascript
packages/core/src/afs.ts

重点理解:

javascript
AFS 调度
路径路由
Provider 调用

接下来:

javascript
packages/core/src/capabilities/

理解:

javascript
OperationsDeclaration
Capability
Feature

再看:

javascript
packages/core/src/error.ts

理解统一错误体系。官方 AFS Reference 对这些源码位置提供了对应索引。

三十六、如果要自己实现 Provider,推荐的学习顺序

不要一开始就尝试做一个非常复杂的 Provider。

建议:

javascript
第一步:理解 AFSModule
        ↓
第二步:理解 AFSBaseProvider
        ↓
第三步:实现 list / stat
        ↓
第四步:实现 read
        ↓
第五步:实现 write
        ↓
第六步:实现 search
        ↓
第七步:增加 exec
        ↓
第八步:声明 capabilities
        ↓
第九步:运行 conformance tests

官方当前 Provider 开发文档推荐从 JSON Provider 及其 conformance 测试开始,因为它是相对紧凑、容易理解的参考实现。这样学习,比直接阅读整个 ARC 源码有效得多。

三十七、一个最小 Provider 应该遵循什么原则?

最重要的一条:

只声明你真正能够保证的能力。

如果 Provider 只能:

javascript
read
stat

那么就声明:

javascript
read
stat

不要为了看起来功能丰富而声明:

javascript
write
delete
search
query
exec

因为一旦声明,就意味着调用方可以把它当成合同的一部分。这也是 AFS 与很多“松散 API”设计最大的区别之一:Capability Declaration 本身就是 Contract。

三十八、Conformance:让 Provider 真正符合 AFS 合同

如果要写生产级 Provider,不能只测试:

javascript
read 能不能返回内容

还需要验证:

javascript
list
read
write
delete
stat
search
错误
权限
能力声明

等行为是否符合 AFS 合同。当前 ARC 使用:

javascript
@aigne/afs-testing

提供共享测试能力。官方 Provider 编写文档建议通过:

javascript
runProviderTests

运行 conformance 测试。因此,一个完整 Provider 的开发流程可以理解为:

javascript
实现 Provider
      ↓
声明 Capability
      ↓
运行 Conformance
      ↓
修复合同问题
      ↓
Mount
      ↓
CLI / Agent 实测
      ↓
形成正式 Provider

三十九、AFS 最值得注意的几个误区

误区一:AFS 就是虚拟文件系统

不完全正确。它虽然使用文件系统式 Path,但 Path 背后可以是各种 Provider 和资源。

误区二:所有 Path 都可以 read/write

错误。操作能力由 Provider 声明,并受到当前访问模式和权限影响。

错误。Search 是 Provider 定义的能力,不是所有 Provider 的必选能力。

误区四:search 就是全局语义搜索

错误。AFS 不承诺跨 Provider 的全局全文索引、语义搜索或者统一排序。

误区五:list、search、query 是同一件事

错误。三者分别对应:

javascript
list   → 枚举
search → 自由文本搜索
query  → 类型化集合查询

误区六:Mount 成功就意味着资源可用

错误。Mount 是配置状态,真正是否可用仍然需要通过:

javascript
explain
stat
ls
read

进行验证。

误区七:源码里有 Provider 就代表官方支持

错误。

源码 Provider 列表是实现清单,不等于稳定产品支持目录。

四十、用一句话理解 AFS

如果只能记住一句话,我建议记住:

AFS 不是把所有数据变成文件,而是把 Agent 需要工作的资源变成一个可以通过 Path 寻址、通过 Provider 提供、通过 Capability 发现和通过操作访问的统一资源世界。

于是:

javascript
Path       → 我在哪里?
Mount      → 交给谁?
Provider   → 谁负责?
Capability → 我能做什么?
Operation  → 我要做什么?
AccessMode → 我现在被允许做什么?

这几个概念一旦建立起来,AFS 后面的文档就会容易很多。

四十一、最后:为什么 AFS 值得关注?

AI Agent 正在从:

javascript
聊天

逐渐走向:

javascript
工作

而“工作”意味着 Agent 必须拥有一个工作环境。这个环境不能只是几十个散乱的 API。一个真正能够长期工作的 Agent,需要知道:

javascript
我在哪里?
我能看到什么?
哪些资源属于当前任务?
哪些资源可以读取?
哪些资源可以修改?
哪些动作可以执行?
这些资源之间有什么关系?
传统 API 很擅长回答:

“调用这个接口可以得到什么。”

而 AFS 尝试回答的是:

“Agent 在这个世界里有什么,以及它可以怎样工作。”

因此,AFS 最值得关注的地方,并不是它增加了几个类似文件系统的 CLI 命令,而是它提供了一种新的 Agent 基础设施抽象:

javascript
                         Agent
                           │
                           ▼
                 ┌─────────────────┐
                 │   AFS Resource  │
                 │      World      │
                 └────────┬────────┘
                          │
          ┌───────────────┼───────────────┐
          ▼               ▼               ▼
       Resources       Services         Actions
          │               │               │
          └───────────────┼───────────────┘
                          ▼
                      Providers
                          │
                          ▼
              Files / DB / Network / Data

从这个角度来看,AFS 可以被理解成 Agent 与真实计算世界之间的一层资源抽象

它把“文件、数据、服务、动作”放进一个具有路径和边界的世界里,再通过 Provider 和 Capability 控制这个世界到底能做什么。

对于正在构建 AI Agent、Agent Framework 或 AI 原生应用的开发者来说,这可能比“如何再增加一个 Tool”更值得研究。

附:建议的 AFS 学习路线

如果你是第一次学习,可以按照下面的顺序实践,而不要一上来就读源码:

javascript
① 了解 AFS 基本概念
        ↓
② 安装 / 确认 ARC
        ↓
③ arc afs --help
        ↓
④ arc afs explain
        ↓
⑤ arc afs ls /
        ↓
⑥ arc afs stat <path>
        ↓
⑦ arc afs read <path>
        ↓
⑧ 理解 Path / Mount / Provider
        ↓
⑨ 理解 Capability / AccessMode
        ↓
⑩ 理解 list / search / query
        ↓
⑪ 理解 exec
        ↓
⑫ 通过 HTTP / MCP 访问 AFS
        ↓
⑬ 阅读 Provider 实现
        ↓
⑭ 自己实现一个 Provider
        ↓
⑮ Conformance 测试
        ↓
⑯ 把 AFS 接入自己的 Agent

1 reply

shenxiuqiang4 days ago

官方资料

  • AFS 总览:https://www.arcblock.io/zh/docs/afs/
  • AFS 快速开始:https://www.arcblock.io/zh/docs/afs/getting-started/
  • 本地巡检:https://www.arcblock.io/zh/docs/afs/local-inspection/
  • 核心合同:https://www.arcblock.io/zh/docs/afs/core-contract/
  • Search 与 Query:https://www.arcblock.io/zh/docs/afs/search-and-query/
  • Providers:https://www.arcblock.io/zh/docs/afs/providers/
  • 编写 Provider:https://www.arcblock.io/zh/docs/afs/author-a-provider/
  • 运行时边界:https://www.arcblock.io/zh/docs/afs/runtime-boundaries/
  • AFS Reference:https://www.arcblock.io/zh/docs/afs/reference/

**版本提示:**本文涉及的 CLI 命令和部分运行时行为以 ArcBlock 当前文档核验的 arc 2.0.0-beta.28 为基准。AFS 正处于快速演进阶段,如果你使用其他 ARC 版本,建议先执行 arc --versionarc afs --help,再根据实际命令面调整本文示例。

Reply