Skip to main content
Deep Agents 通过 lsread_filewrite_fileedit_fileglobgrep 等工具向代理暴露文件系统接口。这些工具通过一个可插拔的后端运行。read_file 工具在所有后端中都原生支持图像文件(.png.jpg.jpeg.gif.webp),并将其作为多模态内容块返回。 read_file 工具在所有后端中都原生支持二进制文件(图像、PDF、音频、视频),返回一个带有类型化 contentmimeTypeReadResult 沙箱和 LocalShellBackend 还提供了一个 execute 工具。 本页解释了如何:

快速入门

以下是几个预构建的文件系统后端,您可以快速将其与您的 deep agent 一起使用:

内置后端

StateBackend(临时)

工作原理:
  • 通过 StateBackend 将文件存储在当前线程的 LangGraph 代理状态中。
  • 通过检查点在同一线程的多个代理轮次中持久化。
最适合:
  • 代理用于写入中间结果的临时记事本。
  • 自动清除大型工具输出,然后代理可以逐块读回。
请注意,此后端在主管代理和子代理之间共享,子代理写入的任何文件在子代理执行完成后仍会保留在 LangGraph 代理状态中。这些文件将继续对主管代理和其他子代理可用。

FilesystemBackend(本地磁盘)

FilesystemBackend 在可配置的根目录下读写真实文件。
此后端授予代理直接的文件系统读/写访问权限。 请谨慎使用,仅在适当的环境中使用。适当的用例:
  • 本地开发 CLI(编码助手、开发工具)
  • CI/CD 流水线(请参阅下面的安全注意事项)
不适当的用例:
  • Web 服务器或 HTTP API - 请改用 StateBackendStoreBackend沙箱后端
安全风险:
  • 代理可以读取任何可访问的文件,包括密钥(API 密钥、凭据、.env 文件)
  • 结合网络工具,密钥可能通过 SSRF 攻击被窃取
  • 文件修改是永久且不可逆的
推荐的安全措施:
  1. 启用人在回路 (HITL) 中间件以审查敏感操作。
  2. 将密钥排除在可访问的文件系统路径之外(尤其是在 CI/CD 中)。
  3. 对于需要文件系统交互的生产环境,请使用沙箱后端
  4. 始终使用 virtual_mode=Trueroot_dir 以启用基于路径的访问限制(阻止 ..~ 和根目录外的绝对路径)。 请注意,默认设置(virtual_mode=False)即使设置了 root_dir 也不提供安全性。
工作原理:
  • 在可配置的 root_dir 下读写真实文件。
  • 您可以选择设置 virtual_mode=True 以在 root_dir 下沙箱化并规范化路径。
  • 使用安全的路径解析,尽可能防止不安全的符号链接遍历,可以使用 ripgrep 进行快速 grep
最适合:
  • 您机器上的本地项目
  • CI 沙箱
  • 挂载的持久卷

LocalShellBackend(本地 shell)

此后端授予代理直接的文件系统读/写访问权限以及在您的主机上不受限制的 shell 执行权限。 请极其谨慎地使用,仅在适当的环境中使用。适当的用例:
  • 本地开发 CLI(编码助手、开发工具)
  • 您信任代理代码的个人开发环境
  • 具有适当密钥管理的 CI/CD 流水线
不适当的用例:
  • 生产环境(如 Web 服务器、API、多租户系统)
  • 处理不受信任的用户输入或执行不受信任的代码
安全风险:
  • 代理可以使用您的用户权限执行任意 shell 命令
  • 代理可以读取任何可访问的文件,包括密钥(API 密钥、凭据、.env 文件)
  • 密钥可能被暴露
  • 文件修改和命令执行是永久且不可逆的
  • 命令直接在您的主机系统上运行
  • 命令可以消耗无限的 CPU、内存、磁盘
推荐的安全措施:
  1. 启用人在回路 (HITL) 中间件以在执行前审查和批准操作。强烈推荐
  2. 仅在专用开发环境中运行。切勿在共享或生产系统上使用。
  3. 对于需要 shell 执行的生产环境,请使用沙箱后端
注意: 启用 shell 访问后,virtual_mode=True 不提供安全性,因为命令可以访问系统上的任何路径。
这段代码展示了如何使用 deepagents 库创建一个深度代理(Deep Agent)。首先,从 deepagents 中导入 createDeepAgent 函数和 LocalShellBackend 类。接着,创建一个 LocalShellBackend 实例,指定工作目录为当前目录(".")。最后,使用该后端实例调用 createDeepAgent 函数,生成一个代理对象。 工作原理:
  • 扩展 FilesystemBackend,添加 execute 工具以在主机上运行 shell 命令。
  • 命令直接在您的机器上使用 subprocess.run(shell=True) 运行,无沙箱化。
  • 支持 timeout(默认 120 秒)、max_output_bytes(默认 100,000)、envinherit_env 用于环境变量。
  • Shell 命令使用 root_dir 作为工作目录,但可以访问系统上的任何路径。
最适合:
  • 本地编码助手和开发工具
  • 在您信任代理时进行快速开发迭代

StoreBackend(LangGraph 存储)

部署到 LangSmith 部署 时,请省略 store 参数。平台会自动为您的代理配置一个存储。
namespace 参数控制数据隔离。对于多用户部署,始终设置命名空间工厂以按用户或租户隔离数据。
工作原理:
  • StoreBackend 将文件存储在运行时提供的 LangGraph BaseStore 中,实现跨线程的持久化存储。
最适合:
  • 当您已经使用配置好的 LangGraph 存储运行时(例如,Redis、Postgres 或 BaseStore 背后的云实现)。
  • 当您通过 LangSmith Deployment 部署代理时(会自动为您的代理配置存储)。

命名空间工厂

命名空间工厂控制 StoreBackend 读写数据的位置。它接收一个 LangGraph Runtime 并返回一个字符串元组,用作存储命名空间。使用命名空间工厂在用户、租户或助手之间隔离数据。 在构造 StoreBackend 时将命名空间工厂传递给 namespace 参数:
Runtime 提供:
  • rt.context — 通过 LangGraph 的上下文模式传递的用户提供的上下文(例如,user_id
  • rt.serverInfo — 在 LangGraph Server 上运行时的服务器特定元数据(助手 ID、图 ID、已认证用户)
  • rt.executionInfo — 执行身份信息(线程 ID、运行 ID、检查点 ID)
Runtime 参数在 deepagents>=1.9.1 中可用。早期的 1.9.x 版本传递的是 BackendContext — 请参阅下面的BackendContext 迁移rt.serverInfort.executionInfo 需要 deepagents>=1.9.0
常见的命名空间模式:
您可以组合多个组件以创建更具体的范围——例如,(user_id, thread_id) 用于按用户按对话隔离,或附加后缀如 "filesystem" 以在相同范围使用多个存储命名空间时消除歧义。 命名空间组件只能包含字母数字字符、连字符、下划线、点、@+、冒号和波浪号。通配符(*?)会被拒绝以防止 glob 注入。
namespace 参数在 v1.9.0 中将是必需的。对于新代码,请始终显式设置它。
当未提供命名空间工厂时,旧版默认使用 LangGraph 配置元数据中的 assistant_id。这意味着同一助手的所有用户共享相同的存储。对于多用户投入生产,请始终提供命名空间工厂。

CompositeBackend(路由器)

工作原理:
  • CompositeBackend 根据路径前缀将文件操作路由到不同的后端。
  • 在列表和搜索结果中保留原始路径前缀。
最适合:
  • 当您想为代理提供临时和跨线程存储时,CompositeBackend 允许您同时提供 StateBackendStoreBackend
  • 当您有多个信息源想要作为单个文件系统的一部分提供给代理时。
    • 例如,您在一个存储中将长期记忆存储在 /memories/ 下,同时还有一个自定义后端,其文档可在 /docs/ 访问。

指定一个后端

  • 将后端实例传递给 createDeepAgent({ backend: ... })。文件系统中间件将其用于所有工具。
  • 后端必须实现 AnyBackendProtocolBackendProtocolV1BackendProtocolV2)——例如,new StateBackend()new FilesystemBackend({ rootDir: "." })new StoreBackend()
  • 如果省略,默认为 new StateBackend()
在 1.9.0 版本之前,仅支持 BackendProtocol,现在它是 BackendProtocolV1。V1 后端在运行时通过 adaptBackendProtocol() 自动适配到 V2。无需更改代码即可继续使用现有的 V1 后端。要更新到 v2,请参阅将现有后端更新到 v2

路由到不同后端

将命名空间的部分路由到不同的后端。通常用于持久化 /memories/* 并保持其他所有内容为临时存储。
行为:
  • /workspace/plan.mdStateBackend(临时)
  • /memories/agent.mdFilesystemBackend/deepagents/myagent
  • lsglobgrep 聚合结果并显示原始路径前缀。
注意:
  • 更长的前缀优先(例如,路由 "/memories/projects/" 可以覆盖 "/memories/")。
  • 对于 StoreBackend 路由,请确保通过 create_deep_agent(model=..., store=...) 提供存储或由平台配置。

使用虚拟文件系统

构建自定义后端以将远程或数据库文件系统(例如 S3 或 Postgres)投影到工具命名空间中。 设计指南:
  • 路径是绝对的(/x/y.txt)。决定如何将它们映射到您的存储键/行。
  • 高效实现 lsglob(尽可能使用服务器端过滤,否则使用本地过滤)。
  • 对于外部持久化(S3、Postgres 等),在写入/编辑结果中返回 files_update=None(Python)或省略 filesUpdate(JS)——只有内存状态后端需要返回文件更新字典。
  • 使用 lsglob 作为方法名。
  • 所有查询方法(lsreadreadRawgrepglob)必须返回结构化的 Result 对象(例如,LsResultReadResult),其中包含可选的 error 字段。
  • read() 中支持二进制文件,返回带有适当 mimeTypeUint8Array 内容。
S3 风格大纲:
Postgres 风格大纲:
  • files(path text primary key, content text, mime_type text, created_at timestamptz, modified_at timestamptz)
  • 将工具操作映射到 SQL:
    • ls 使用 WHERE path LIKE $1 || '%' → 返回 LsResult
    • glob 在 SQL 中过滤或获取后在本地应用 glob → 返回 GlobResult
    • grep 可以按扩展名或最后修改时间获取候选行,然后扫描行(跳过 mime_type 为二进制的行)→ 返回 GrepResult

权限

使用权限来声明式地控制代理可以读取或写入哪些文件和目录。权限适用于内置的文件系统工具,并在调用后端之前进行评估。 有关完整选项集,包括规则排序、子代理权限和组合后端交互,请参阅权限指南

添加策略钩子

对于超出基于路径的允许/拒绝规则(速率限制、审计日志记录、内容检查)的自定义验证逻辑,通过子类化或包装后端来强制执行企业规则。 阻止在选定前缀下的写入/编辑(子类化):
通用包装器(适用于任何后端):

多模态和二进制文件

多模态文件支持(PDF、音频、视频)需要 deepagents>=1.9.0
V2 后端原生支持二进制文件。当 read() 遇到二进制文件(由文件扩展名的 MIME 类型确定)时,它返回一个带有 Uint8Array 内容和相应 mimeTypeReadResult。文本文件返回 string 内容。

支持的 MIME 类型

读取二进制文件

FileData 格式

FileData 是用于在状态和存储后端中存储文件内容的类型。
后端在从状态或存储读取时可能会遇到任一格式。框架透明地处理两者。新写入默认为 v2 格式。在滚动部署期间,如果旧版读取器需要旧版格式,请将 fileFormat: "v1" 传递给后端构造函数(例如,new StoreBackend({ fileFormat: "v1" }))。

从后端工厂迁移

deepagents 1.9.0 起,后端工厂模式已弃用。请直接传递预构建的后端实例,而不是工厂函数。
以前,像 StateBackendStoreBackend 这样的后端需要一个接收运行时对象的工厂函数,因为它们需要运行时上下文(状态、存储)来操作。现在后端通过 LangGraph 的 get_config()get_store()get_runtime() 辅助函数内部解析此上下文,因此您可以直接传递实例。

变更内容

已弃用的 API

工厂模式在运行时仍然有效,但会发出弃用警告。请在下一个主要版本之前更新您的代码以使用直接实例。

迁移示例

BackendContext 迁移

deepagents>=0.5.2(Python)和 deepagents>=1.9.1(TypeScript)中,命名空间工厂直接接收 LangGraph Runtime,而不是 BackendContext 包装器。旧的 BackendContext 形式仍然通过向后兼容的 .runtime.state 访问器工作,但这些访问器会发出弃用警告,并将在 deepagents>=0.7 中移除。 变更内容:
  • 工厂参数现在是 Runtime,而不是 BackendContext
  • 删除 .runtime 访问器——例如,ctx.runtime.context.user_id 变为 rt.server_info.user.identity
  • ctx.state 没有直接替代方案。命名空间信息应该是只读的,并且在运行生命周期内保持稳定,而状态是可变的并且会逐步变化——从中派生命名空间可能会导致数据最终位于不一致的键下。如果您有需要读取代理状态的用例,请提交 issue

协议参考

后端必须实现 BackendProtocol 必需方法:
  • ls(path: str) -> LsResult
    • 返回至少包含 path 的条目。在可用时包含 is_dirsizemodified_at。按 path 排序以获得确定性输出。
  • read(file_path: str, offset: int = 0, limit: int = 2000) -> ReadResult
    • 成功时返回文件数据。文件缺失时,返回 ReadResult(error="Error: File '/x' not found")
  • grep(pattern: str, path: Optional[str] = None, glob: Optional[str] = None) -> GrepResult
    • 返回结构化匹配项。出错时,返回 GrepResult(error="...")(不要引发异常)。
  • glob(pattern: str, path: str = "/") -> GlobResult
    • 将匹配的文件作为 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
    • 除非 replace_all=True,否则强制 old_string 的唯一性。如果未找到,返回错误。成功时包含 occurrences
支持类型:
  • LsResult(error, entries) — 成功时 entrieslist[FileInfo],失败时为 None
  • ReadResult(error, file_data) — 成功时 file_dataFileData 字典,失败时为 None
  • GrepResult(error, matches) — 成功时 matcheslist[GrepMatch],失败时为 None
  • GlobResult(error, matches) — 成功时 matcheslist[FileInfo],失败时为 None
  • WriteResult(error, path, files_update)
  • EditResult(error, path, files_update, occurrences)
  • FileInfo 字段:path(必需),可选 is_dirsizemodified_at
  • GrepMatch 字段:pathlinetext
  • FileData 字段:content(str)、encoding"utf-8""base64")、created_atmodified_at。 :::
后端实现 BackendProtocolV2。所有查询方法返回带有 { error?: string, ...data } 的结构化 Result 对象。

必需方法

  • ls(path: string) → LsResult
    • 列出指定目录中的文件和目录(非递归)。目录的路径以 / 结尾,is_dir=true。在可用时包含 is_dirsizemodified_at
  • read(filePath: string, offset?: number, limit?: number) → ReadResult
    • 读取文件内容。对于文本文件,内容按行偏移量/限制分页(默认偏移量 0,限制 500)。对于二进制文件,返回完整的原始 Uint8Array 内容,并设置 mimeType 字段。文件缺失时,返回 { error: "File '/x' not found" }
  • readRaw(filePath: string) → ReadRawResult
    • 将文件内容作为原始 FileData 读取。返回包含时间戳的完整文件数据。
  • grep(pattern: string, path?: string | null, glob?: string | null) → GrepResult
    • 搜索文件内容中的字面文本模式。二进制文件(由 MIME 类型确定)被跳过。失败时,返回 { error: "..." }
  • glob(pattern: string, path?: string) → GlobResult
    • 将匹配 glob 模式的文件作为 FileInfo 条目返回。
  • write(filePath: string, content: string) → WriteResult
    • 仅创建语义。冲突时,返回 { error: "..." }。成功时,设置 path,对于状态后端设置 filesUpdate={...};外部后端应使用 filesUpdate=null
  • edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean) → EditResult
    • 除非 replaceAll=true,否则强制 oldString 的唯一性。如果未找到,返回错误。成功时包含 occurrences

可选方法

  • uploadFiles(files: Array<[string, Uint8Array]>) → FileUploadResponse[] — 上传多个文件(用于沙箱后端)。
  • downloadFiles(paths: string[]) → FileDownloadResponse[] — 下载多个文件(用于沙箱后端)。

结果类型

支持类型

  • FileInfopath(必需),可选 is_dirsizemodified_at
  • GrepMatchpathline(从 1 开始)、text
  • FileData — 带时间戳的文件内容。请参阅 FileData 格式

沙箱扩展

SandboxBackendProtocolV2 扩展了 BackendProtocolV2,增加了:
  • execute(command: string) → ExecuteResponse — 在沙箱中运行 shell 命令。
  • readonly id: string — 沙箱实例的唯一标识符。

将现有后端更新到 V2

方法重命名

类型重命名

适配工具

如果您有需要与仅 V2 代码一起使用的现有 V1 后端,请使用适配函数:
框架会自动适配传递给 createDeepAgent() 的 V1 后端。仅在直接调用协议方法时才需要手动适配。