深度智能体通过 lsread_filewrite_fileedit_fileglobgrep 等工具向智能体暴露文件系统接口。这些工具基于可插拔的后端运行。 本页将介绍如何选择后端将不同路径路由到不同后端实现自定义虚拟文件系统(例如 S3 或 Postgres)、添加策略钩子以及遵循后端协议

快速入门

以下是几种可直接用于深度智能体的预构建文件系统后端:
内置后端说明
默认agent = create_deep_agent()
在状态中短暂存储。默认文件系统后端存储于 langgraph 状态,仅在单个线程内持久。
本地文件系统持久化agent = create_deep_agent(backend=FilesystemBackend(root_dir="/Users/nh/Desktop/"))
让深度智能体访问本地机器文件系统。可以指定智能体可访问的根目录,必须使用绝对路径。
持久 Store(LangGraph Store)agent = create_deep_agent(backend=lambda rt: StoreBackend(rt))
为智能体提供跨线程持久化的存储,非常适合保存长期记忆或多次执行都需要的指令。
组合后端默认短暂存储,/memories/ 路径持久化。Composite 后端灵活性最高,可以为不同路径配置不同后端。下文提供可直接复制的路由示例。

内置后端

StateBackend(短暂存储)

# 默认情况下会提供 StateBackend
agent = create_deep_agent()

# 内部实现类似如下
from deepagents.backends import StateBackend

aagent = create_deep_agent(
    backend=(lambda rt: StateBackend(rt))  # 工具通过 runtime.state 访问状态
)
工作原理:
  • 将文件存储在当前线程的 LangGraph 智能体状态中。
  • 通过检查点跨同一线程的多次调用持久化。
适用场景:
  • 作为智能体的草稿空间,用于写入中间结果。
  • 自动驱逐体积较大的工具输出,智能体可按需逐段读取。

FilesystemBackend(本地磁盘)

from deepagents.backends import FilesystemBackend

agent = create_deep_agent(
    backend=FilesystemBackend(root_dir="/Users/nh/Desktop/")
)
工作原理:
  • 在指定的 root_dir 下读取/写入真实文件。
  • root_dir 必须是绝对路径。
  • 可选 virtual_mode=True,在 root_dir 内进行沙箱隔离和路径规范化。
  • 使用安全的路径解析,尽可能阻止危险的符号链接遍历;支持使用 ripgrep 加速 grep
适用场景:
  • 本地项目开发
  • CI 沙箱环境
  • 挂载的持久卷

StoreBackend(LangGraph Store)

from deepagents.backends import StoreBackend

agent = create_deep_agent(
    backend=(lambda rt: StoreBackend(rt))  # 工具通过 runtime.store 访问 Store
)
工作原理:
  • 将文件存储在运行时提供的 LangGraph BaseStore 中,实现跨线程的持久化。
适用场景:
  • 已经配置 LangGraph Store 的环境(例如 Redis、Postgres 或基于 BaseStore 的云实现)。
  • 使用 LangSmith Deployments 部署智能体(平台会自动为智能体提供 Store)。

CompositeBackend(路由器)

from deepagents import create_deep_agent
from deepagents.backends import StateBackend, StoreBackend
from deepagents.backends.composite import CompositeBackend

composite_backend = lambda rt: CompositeBackend(
    default=StateBackend(rt),
    routes={
        "/memories/": StoreBackend(rt),
        "/docs/": CustomBackend(),
    }
)

agent = create_deep_agent(backend=composite_backend)
工作原理:
  • 根据路径前缀将文件操作路由到不同后端。
  • 在列表与搜索结果中保留原始路径前缀。
适用场景:
  • 同时提供短暂存储与跨线程持久存储,例如将 StateBackend 与 StoreBackend 结合。
  • 当需要将多个信息源以统一文件系统形式提供给智能体时。
    • 例如 /memories/ 下使用 Store 保存长期记忆,同时 /docs/ 下使用自定义后端提供文档。

指定后端

  • 通过 create_deep_agent(backend=...) 传入后端,文件系统中间件会使用该后端提供所有工具。
  • 可传入以下任意一种:
    • 实现 BackendProtocol 的实例(如 FilesystemBackend(root_dir="."))。
    • 工厂函数 BackendFactory = Callable[[ToolRuntime], BackendProtocol](适用于需要运行时的后端,如 StateBackendStoreBackend)。
  • 如果未指定,默认使用 lambda rt: StateBackend(rt)

路由到不同的后端

可以将命名空间的不同部分路由到不同后端,常见做法是让 /memories/* 持久化,而其他路径保持短暂。
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
from deepagents.backends.composite import CompositeBackend

composite_backend = lambda rt: CompositeBackend(
    routes={
        "/memories/": FilesystemBackend(root_dir="/deepagents/myagent"),
    },
)

agent = create_deep_agent(backend=composite_backend)
行为:
  • /workspace/plan.md → 使用 StateBackend(短暂存储)
  • /memories/agent.md → 使用 FilesystemBackend,在 /deepagents/myagent 下持久化
  • lsglobgrep 会聚合结果并保留原始路径前缀
注意事项:
  • 更长的前缀优先匹配(例如 "/memories/projects/" 会覆盖 "/memories/")。
  • 如果路由到 StoreBackend,请确保运行时提供了 store(即 runtime.store)。

使用虚拟文件系统

可构建自定义后端,将远程存储或数据库(如 S3、Postgres)映射为工具可访问的文件系统。 设计指南:
  • 路径均为绝对路径(如 /x/y.txt)。需要决定如何映射到存储键或数据库行。
  • 高效实现 ls_infoglob_info(优先使用服务端列表;若不可行,则本地过滤)。
  • 对缺失文件或非法正则表达式返回用户可读的错误字符串。
  • 若为外部持久化存储,请在结果中返回 files_update=None;仅状态内后端应返回 files_update 字典。
S3 风格示例:
from deepagents.backends.protocol import BackendProtocol, WriteResult, EditResult
from deepagents.backends.utils import FileInfo, GrepMatch

class S3Backend(BackendProtocol):
    def __init__(self, bucket: str, prefix: str = ""):
        self.bucket = bucket
        self.prefix = prefix.rstrip("/")

    def _key(self, path: str) -> str:
        return f"{self.prefix}{path}"

    def ls_info(self, path: str) -> list[FileInfo]:
        # 列出 _key(path) 下的对象,构建 FileInfo(path、size、modified_at)
        ...

    def read(self, file_path: str, offset: int = 0, limit: int = 2000) -> str:
        # 读取对象,返回带行号的内容或错误信息
        ...

    def grep_raw(self, pattern: str, path: str | None = None, glob: str | None = None) -> list[GrepMatch] | str:
        # 可选服务端过滤,否则列出对象后本地扫描
        ...

    def glob_info(self, pattern: str, path: str = "/") -> list[FileInfo]:
        # 按照模式在所有键上匹配
        ...

    def write(self, file_path: str, content: str) -> WriteResult:
        # 仅允许创建新文件;成功返回 WriteResult(path=file_path, files_update=None)
        ...

    def edit(self, file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult:
        # 读 → 替换(根据 replace_all 决定替换策略)→ 写入 → 返回匹配次数
        ...
Postgres 风格示例:
  • 建表:files(path text primary key, content text, created_at timestamptz, modified_at timestamptz)
  • 将工具操作映射到 SQL:
    • ls_info 使用 WHERE path LIKE $1 || '%'
    • glob_info 可在 SQL 中过滤或先查询再本地 glob
    • grep_raw 可以按扩展名或修改时间筛选候选行,再逐行扫描

添加策略钩子

通过继承或包装后端,可以实现企业级策略管控。 禁止特定前缀写入/编辑(继承方式):
from deepagents.backends.filesystem import FilesystemBackend
from deepagents.backends.protocol import WriteResult, EditResult

class GuardedBackend(FilesystemBackend):
    def __init__(self, *, deny_prefixes: list[str], **kwargs):
        super().__init__(**kwargs)
        self.deny_prefixes = [p if p.endswith("/") else p + "/" for p in deny_prefixes]

    def write(self, file_path: str, content: str) -> WriteResult:
        if any(file_path.startswith(p) for p in self.deny_prefixes):
            return WriteResult(error=f"Writes are not allowed under {file_path}")
        return super().write(file_path, content)

    def edit(self, file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult:
        if any(file_path.startswith(p) for p in self.deny_prefixes):
            return EditResult(error=f"Edits are not allowed under {file_path}")
        return super().edit(file_path, old_string, new_string, replace_all)
通用包装器(适用于任意后端):
from deepagents.backends.protocol import BackendProtocol, WriteResult, EditResult
from deepagents.backends.utils import FileInfo, GrepMatch

class PolicyWrapper(BackendProtocol):
    def __init__(self, inner: BackendProtocol, deny_prefixes: list[str] | None = None):
        self.inner = inner
        self.deny_prefixes = [p if p.endswith("/") else p + "/" for p in (deny_prefixes or [])]

    def _deny(self, path: str) -> bool:
        return any(path.startswith(p) for p in self.deny_prefixes)

    def ls_info(self, path: str) -> list[FileInfo]:
        return self.inner.ls_info(path)

    def read(self, file_path: str, offset: int = 0, limit: int = 2000) -> str:
        return self.inner.read(file_path, offset=offset, limit=limit)

    def grep_raw(self, pattern: str, path: str | None = None, glob: str | None = None) -> list[GrepMatch] | str:
        return self.inner.grep_raw(pattern, path, glob)

    def glob_info(self, pattern: str, path: str = "/") -> list[FileInfo]:
        return self.inner.glob_info(pattern, path)

    def write(self, file_path: str, content: str) -> WriteResult:
        if self._deny(file_path):
            return WriteResult(error=f"Writes are not allowed under {file_path}")
        return self.inner.write(file_path, content)

    def edit(self, file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult:
        if self._deny(file_path):
            return EditResult(error=f"Edits are not allowed under {file_path}")
        return self.inner.edit(file_path, old_string, new_string, replace_all)

协议参考

所有后端都必须实现 BackendProtocol 必选接口:
  • ls_info(path: str) -> list[FileInfo]
    • 返回的条目至少包含 path。如有可能,补充 is_dirsizemodified_at。建议按 path 排序,保证输出确定性。
  • read(file_path: str, offset: int = 0, limit: int = 2000) -> str
    • 返回带行号的内容。若文件不存在,返回字符串:"Error: File '/x' not found"
  • grep_raw(pattern: str, path: Optional[str] = None, glob: Optional[str] = None) -> list[GrepMatch] | str
    • 返回结构化匹配结果。若正则无效,返回类似 "Invalid regex pattern: ..." 的字符串(不要抛异常)。
  • glob_info(pattern: str, path: str = "/") -> list[FileInfo]
    • 返回匹配到的文件列表(若无则返回空列表)。
  • write(file_path: str, content: str) -> WriteResult
    • 仅允许创建新文件。若文件已存在,返回 WriteResult(error=...)。成功时设置 path,状态型后端还应返回 files_update={...};外部持久化后端应返回 files_update=None
  • edit(file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult
    • 默认要求 old_string 仅出现一次;若设置 replace_all=True 则替换全部匹配。未找到时返回错误。成功时包含 occurrences
相关类型:
  • WriteResult(error, path, files_update)
  • EditResult(error, path, files_update, occurrences)
  • FileInfo 字段:必填 path,可选 is_dirsizemodified_at
  • GrepMatch 字段:pathlinetext

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.