文件系统(Filesystem)¶
作用¶
HarnessAgent 把 agent 对工作区的访问从”一定是本机磁盘”抽象成统一接口。所有文件工具(read_file / write_file / edit_file / grep_files / glob_files / list_files)和可选的 execute(shell)都从这个抽象走。
这样做让你能在三种部署模式之间切换,而不改 agent 代码:
本机 + shell —— 单进程、本地、信任环境;
共享存储 —— 多副本 / 多 pod 共享同一份长期记忆;
沙箱 —— 文件与命令都在隔离容器里执行,跨调用恢复同一份工作区。
三种声明式模式¶
在 HarnessAgent.Builder 上用 filesystem(...) 三选一(不调就是默认模式 3):
模式 |
配置 |
提供 shell? |
适用场景 |
|---|---|---|---|
1 · 共享存储 |
|
❌ |
多副本要共享 |
2 · 沙箱 |
|
✅(在沙箱内) |
隔离执行、跨调用恢复同一份工作区、可选快照 + 分布式 |
3 · 本机 + shell(默认) |
|
✅(宿主 |
单进程 / 本机 / 信任环境 / 简单脚本与测试 |
filesystem(...)与abstractFilesystem(...)互斥;后者是给完全自管文件系统的逃生口,正常用法不需要。
模式 1:共享存储¶
适合”多副本,但用户的长期记忆要一致”。把一个 KV 存储(Redis / JDBC / 自定义)传进去,框架自动把 MEMORY.md、memory/、会话日志、子任务记录等路由到这个存储:
HarnessAgent agent = HarnessAgent.builder()
.name("store")
.model(model)
.workspace(workspace)
.filesystem(new RemoteFilesystemSpec(redisStore)
.isolationScope(IsolationScope.USER)) // 按 userId 分命名空间
.build();
这种模式不提供 shell——故意的:要 shell 请用模式 2(沙箱)或 3(本机)。
模式 2:沙箱¶
适合”代码会执行不可信操作、或要隔离生产环境”。所有文件操作和 shell 命令都发到沙箱里执行,宿主完全不受影响。沙箱可以做快照,下次 call() 时连同 node_modules、pip install 都能恢复回来:
HarnessAgent agent = HarnessAgent.builder()
.name("sandbox")
.model(model)
.workspace(workspace)
.filesystem(new DockerFilesystemSpec()
.image("ubuntu:24.04")
.isolationScope(IsolationScope.SESSION))
.build();
详细见 沙箱。可选后端:Docker / Kubernetes / Daytona / E2B / AgentRun(阿里云)。
模式 3:本机 + shell(默认)¶
什么都不写就是这个:工作区落到 ${cwd}/.agentscope/workspace/,shell 在宿主上跑:
HarnessAgent agent = HarnessAgent.builder()
.name("local")
.model(model)
.workspace(workspace)
// .filesystem(...) 不写 = 本机 + shell
.build();
需要调整超时、环境变量等:
.filesystem(new LocalFilesystemSpec()
.executeTimeoutSeconds(120)
.env("MY_VAR", "value")
.inheritEnv(false))
IsolationScope —— 多用户与多副本怎么分桶¶
模式 1(共享存储)和模式 2(沙箱)都用同一个 IsolationScope 概念,决定谁和谁共享同一份状态:
Scope |
含义 |
典型场景 |
|---|---|---|
|
每个 sessionId 独立 |
多用户 SaaS,每段对话各跑各的 |
|
同一 |
同一用户的多个会话共享长期记忆(分布式部署) |
|
这个 agent 的所有用户/会话共享 |
公共知识库型 agent |
|
全局共享一份 |
谨慎使用 |
例子:要让 alice 在不同设备上的多个对话共享同一份长期记忆——选 USER,再把 userId="alice" 放进 RuntimeContext。
多用户隔离怎么实现¶
RuntimeContext.userId 是切多用户的钥匙:
本机模式:用户级文件落在
workspace/<userId>/...,例如workspace/alice/skills/code-reviewer/SKILL.md只对 alice 可见;共享存储模式:作为 KV 命名空间前缀,分布式副本天然共享;
沙箱模式:作为沙箱状态的 slot key(搭配
IsolationScope.USER)。
userId 不传的情况下走单租户默认,所有人共享一个根。
工作区里的两层读取¶
AGENTS.md、MEMORY.md、KNOWLEDGE.md 等关键文件在读取时有”两层兜底”:先看你配的文件系统后端,没有再退回本地磁盘。这对模式 1(共享存储)下的”模板文件” 很有用:第一个副本启动时本地有 AGENTS.md 模板,立刻可用;后续副本会从共享存储读出最新版本。
写永远走配置的文件系统后端。
完全自管:abstractFilesystem(...)¶
如果三种模式都不合适,可以传一个完全自己实现的文件系统:
HarnessAgent.builder()
...
.abstractFilesystem(myCustomFilesystem) // 与上面的 filesystem(...) 互斥
.build();
通常不需要——三种模式覆盖了 95% 的场景。