主题
后端
为 Deep Agents 选择和配置文件系统后端。你可以为不同的后端指定路由、实现虚拟文件系统并强制执行策略。
Deep Agents 通过 ls、read_file、write_file、edit_file、delete、glob 和 grep 等工具向智能体暴露文件系统界面。这些工具通过可插拔的后端来操作。read_file 工具在所有后端上原生支持图像文件(.png、.jpg、.jpeg、.gif、.webp),并将它们作为多模态内容块返回。
沙箱和 LocalShellBackend 还提供一个 execute 工具。 本页介绍如何:
TIP
当你在 LangSmith Deployment 上部署时,会自动预置一个 store。使用 LangSmith 追踪来调试文件路径、权限拒绝和跨线程存储。按照可观测性快速入门完成设置。
我们还建议你设置 LangSmith Engine,它会监控你的追踪、检测问题并提出修复方案。
TIP
要生成智能体可通过文件系统工具读取的持久化仓库 wiki,请参见 OpenWiki。
快速开始
以下是一些预构建的文件系统后端,你可以将它们快速用于你的深度智能体:
| 内置后端 | 描述 |
|---|---|
| Default | agent = create_deep_agent(model="google_genai:gemini-3.6-flash") 线程范围。智能体默认的文件系统后端存储在 langgraph 状态中。文件在线程内跨轮次持久化(通过你的检查点器),且不会在线程之间共享。 |
| Local filesystem persistence | agent = create_deep_agent(model="google_genai:gemini-3.6-flash", backend=FilesystemBackend(root_dir="/Users/nh/Desktop/")) 这使深度智能体能够访问你本地机器的文件系统。你可以指定智能体有权访问的根目录。请注意,任何提供的 root_dir 都必须是绝对路径。通常应将其包装在 CompositeBackend 中,以使内部智能体数据(卸载的工具结果、对话历史)与你的项目文件保持分离。 |
| Durable store (LangGraph store) | agent = create_deep_agent(model="google_genai:gemini-3.6-flash", backend=StoreBackend()) 这使智能体能够访问跨线程持久化的长期存储。这非常适合存储适用于智能体多次执行的更长期记忆或指令。 |
| Context Hub | agent = create_deep_agent(model="google_genai:gemini-3.6-flash", backend=ContextHubBackend("my-agent")) 将文件持久地存储在 LangSmith Hub 仓库中,而无需单独预置 LangGraph store。 |
| Sandbox | agent = create_deep_agent(model="google_genai:gemini-3.6-flash", backend=sandbox) 在隔离环境中执行代码。沙箱提供文件系统工具以及用于运行 shell 命令的 execute 工具。可从 LangSmith、AgentCore、Daytona 或其他沙箱集成中选择。 |
| Local shell | agent = create_deep_agent(model="google_genai:gemini-3.6-flash", backend=LocalShellBackend(root_dir=".", env=""PATH": "/usr/bin:/bin"")) 直接在主机上进行文件系统操作和 shell 执行。没有隔离—仅在受控的开发环境中使用。请参阅下文的安全注意事项。 |
| Composite | 默认是线程范围的,/memories/ 跨线程持久化。Composite 后端具有最大程度的灵活性。你可以在文件系统中指定不同的路由以指向不同的后端。参见下文的 Composite 路由,了解可直接粘贴的示例。 |
graph TB
Tools[Filesystem Tools] --> Backend[Backend]
Backend --> State[State]
Backend --> Disk[Filesystem]
Backend --> Store[Store]
Backend --> ContextHub[Context Hub]
Backend --> Sandbox[Sandbox]
Backend --> LocalShell[Local Shell]
Backend --> Composite[Composite]
Backend --> Custom[Custom]
Composite --> Router{Routes}
Router --> State
Router --> Disk
Router --> Store
Router --> ContextHub
Sandbox --> Execute["#43; execute tool"]
LocalShell --> Execute["#43; execute tool"]
classDef trigger fill:#F6FFDB,stroke:#6E8900,stroke-width:2px,color:#2E3900
classDef process fill:#E5F4FF,stroke:#006DDD,stroke-width:2px,color:#030710
classDef decision fill:#FDF3FF,stroke:#7E65AE,stroke-width:2px,color:#504B5F
classDef output fill:#EBD0F0,stroke:#885270,stroke-width:2px,color:#441E33
class Tools trigger
class Backend,State,Disk,Store,ContextHub,Sandbox,LocalShell,Composite,Custom process
class Router decision
class Execute output
内置后端
StateBackend
python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="google_genai:gemini-3.6-flash")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="openai:gpt-5.5")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="openai:gpt-5.5",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="anthropic:claude-sonnet-5")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="openrouter:z-ai/glm-5.2")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="fireworks:accounts/fireworks/models/glm-5p2")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="baseten:zai-org/GLM-5.2")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=StateBackend(),
)python
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
# By default we provide a StateBackend
agent = create_deep_agent(model="ollama:north-mini-code-1.0")
# Under the hood, it looks like
agent2 = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=StateBackend(),
)工作原理:
- 通过
StateBackend将文件存储在当前线程的 LangGraph 智能体状态中。 - 通过检查点在同一线程的多次智能体轮次之间持久化。文件不会跨线程共享。
WARNING
设计为在图中使用。在图的运行之外调用后端方法(例如 state_backend.upload_files(...))不会生效,直到图执行。
最适合:
- 供智能体写入中间结果的暂存区。
- 自动驱逐大量工具输出,智能体随后可以逐块读回这些输出。
请注意,此后端在主管智能体和子智能体之间共享,子智能体写入的任何文件都将保留在 LangGraph 智能体状态中, 即使该子智能体的执行已经完成。这些文件将继续可供主管智能体和其他子智能体使用。
FilesystemBackend(本地磁盘)
FilesystemBackend 在可配置的根目录下读写真实文件。
WARNING
此后端授予智能体直接的文件系统读写访问权限。 请谨慎使用,仅在合适的环境中使用。
合适的用例:
- 本地开发 CLI(编码助手、开发工具)
- CI/CD 流水线(参见下文的安全注意事项)
不合适的用例:
- Web 服务器或 HTTP API - 请改用
StateBackend、StoreBackend或沙箱后端
安全风险:
- 智能体可以读取任何可访问的文件,包括密钥(API 密钥、凭证、
.env文件) - 与网络工具结合使用时,密钥可能通过 SSRF 攻击被窃取
- 文件修改是永久且不可逆的
推荐的防护措施:
启用人在回路 (HITL) 中间件以审查敏感操作。
将密钥排除在可访问的文件系统路径之外(尤其是在 CI/CD 中)。
对于需要文件系统交互的生产环境,使用沙箱后端。
始终将
virtual_mode=True与root_dir一起使用,以启用基于路径的访问限制(阻止..、~以及根目录之外的绝对路径)。请注意,默认值(
virtual_mode=False)即使设置了root_dir也不提供任何安全性。
python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="openai:gpt-5.5",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)python
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
)工作原理:
- 在可配置的
root_dir下读写真实文件。 - 你可以选择设置
virtual_mode=True,在root_dir下对路径进行沙箱隔离和规范化。 - 使用安全的路径解析,尽可能防止不安全的符号链接遍历,可以使用 ripgrep 进行快速
grep。
最适合:
- 你机器上的本地项目
- CI 沙箱
- 挂载的持久卷
对于智能体可以使用这些文件系统工具(来自 openwiki/)读取的持久化仓库 wiki,请参见 OpenWiki。
TIP
在大多数用例中,将 FilesystemBackend 包装在 CompositeBackend 中。Deep Agents 会自动将内部数据写入后端,包括卸载的大型工具结果(位于 /large_tool_results/ 下)和对话历史(位于 /conversation_history/ 下)。当你单独使用 FilesystemBackend 时,这些内部文件会被写入 root_dir 下的真实磁盘,将智能体产物与你的项目文件混在一起。
使用 CompositeBackend 将你的项目目录路由到 FilesystemBackend,同时将内部路径保留在临时的 StateBackend 存储中:
python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, FilesystemBackend
agent = create_deep_agent(
backend=CompositeBackend(
default=StateBackend(),
routes={
"/workspace/": FilesystemBackend(root_dir="/path/to/project", virtual_mode=True),
},
)
)这样,智能体在 /workspace/ 下的读写会写入真实磁盘,而卸载的工具结果和其他内部数据则保留在临时状态中。有关更多路由模式,请参见将不同路径路由到不同后端。
LocalShellBackend(本地 shell)
WARNING
此后端授予智能体直接的文件系统读写访问权限并在你的主机上拥有不受限制的 shell 执行权限。 请极其谨慎地使用,仅在合适的环境中使用。
合适的用例:
- 本地开发 CLI(编码助手、开发工具)
- 你信任智能体代码的个人开发环境
- 具有妥善密钥管理的 CI/CD 流水线
不合适的用例:
- 生产环境(例如 Web 服务器、API、多租户系统)
- 处理不受信任的用户输入或执行不受信任的代码
安全风险:
- 智能体可以以你的用户权限执行任意 shell 命令
- 智能体可以读取任何可访问的文件,包括密钥(API 密钥、凭证、
.env文件) - 密钥可能会被泄露
- 文件修改和命令执行是永久且不可逆的
- 命令直接在你的主机系统上运行
- 命令可以消耗无限的 CPU、内存、磁盘
推荐的防护措施:
- 启用人在回路 (HITL) 中间件以在执行前审查和批准操作。强烈建议这样做。
- 仅在专用的开发环境中运行。切勿在共享或生产系统上使用。
- 对于需要 shell 执行的生产环境,使用沙箱后端。
注意: 在启用 shell 访问的情况下,virtual_mode=True 不提供任何安全性,因为命令可以访问系统上的任何路径。
python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="openai:gpt-5.5",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)python
from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
)工作原理:
- 在
FilesystemBackend的基础上扩展了用于在主机上运行 shell 命令的execute工具。 - 命令使用
subprocess.run(shell=True)直接在你的机器上运行,没有沙箱隔离。 - 支持
timeout(默认 120s)、max_output_bytes(默认 100,000)、env和inherit_env环境变量。 - Shell 命令使用
root_dir作为工作目录,但可以访问系统上的任何路径。
最适合:
- 本地编码助手和开发工具
- 当你信任智能体时,在开发过程中快速迭代
StoreBackend(LangGraph store)
python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="openai:gpt-5.5",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)python
from deepagents import create_deep_agent
from deepagents.backends import StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
)NOTE
部署到 LangSmith Deployment 时,请省略 store 参数。平台会自动为你的智能体预置一个 store。
TIP
namespace 参数控制数据隔离。对于多用户部署,请始终设置一个命名空间工厂,以按用户或租户隔离数据。
工作原理:
StoreBackend将文件存储在运行时提供的 LangGraphBaseStore中,从而实现跨线程的持久化存储。
最适合:
- 当你已经在使用配置好的 LangGraph store 运行时(例如
BaseStore背后的 Redis、Postgres 或云端实现)。 - 当你通过 LangSmith Deployment 部署智能体时(会为你的智能体自动预置一个 store)。
命名空间工厂
命名空间工厂控制 StoreBackend 读写数据的位置。它接收一个 LangGraph Runtime,并返回一个用作 store 命名空间的字符串元组。使用命名空间工厂在用户、租户或助手之间隔离数据。
在构造 StoreBackend 时,将命名空间工厂传递给 namespace 参数:
python
NamespaceFactory = Callable[[Runtime], tuple[str, ...]]Runtime 提供:
rt.context—通过 LangGraph 的上下文模式传入的用户提供的上下文(例如user_id)rt.server_info—在 LangGraph Server 上运行时的服务器特定元数据(助手 ID、图 ID、已认证用户)rt.execution_info—执行身份信息(线程 ID、运行 ID、检查点 ID)
NOTE
Runtime 参数在 deepagents>=0.5.2 中可用。更早的 0.5.x 版本传入的是 BackendContext—请参见下文的从 BackendContext 迁移。rt.server_info 和 rt.execution_info 需要 deepagents>=0.5.0。
常见的命名空间模式:
python
from deepagents.backends import StoreBackend
# Per-user: each user gets their own isolated storage
backend = StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
)
# Per-assistant: all users of the same assistant share storage
backend = StoreBackend(
namespace=lambda rt: (
rt.server_info.assistant_id,
),
)
# Per-thread: storage scoped to a single conversation
backend = StoreBackend(
namespace=lambda rt: (
rt.execution_info.thread_id,
),
)你可以组合多个组件来创建更具体的范围—例如,用 (user_id, thread_id) 实现按用户、按对话的隔离,或在同一范围使用多个 store 命名空间时追加诸如 "filesystem" 的后缀来消除歧义。
命名空间组件只能包含字母数字字符、连字符、下划线、点、@、+、冒号和波浪号。通配符(*、?)会被拒绝,以防止 glob 注入。
WARNING
namespace 参数在 v0.5.0 中将变为必填。请始终为新代码显式设置它。
ContextHubBackend
NOTE
开始之前: ContextHubBackend 需要在 LangSmith 中设置一个 Context Hub 仓库。如果你不熟悉智能体仓库和技能仓库,请先阅读 Context Hub 概念页面。
ContextHubBackend 将你的智能体文件系统存储在 LangSmith Context Hub 仓库中。它可以使用独立仓库,也可以使用链接到技能仓库的智能体仓库。
仓库结构: 在 Context Hub 中,智能体仓库存放智能体的顶层指令和配置(例如 AGENTS.md、tools.json)。它可以链接到一个或多个技能仓库,每个技能仓库都打包为一项可复用的能力(例如包含邮件格式化或代码审查指令的 SKILL.md)。当你传入 ContextHubBackend("my-agent") 时,后端会将智能体仓库挂载到文件系统根目录;链接的技能仓库会作为 /skills/ 下的子目录出现。
这意味着你的智能体上下文被有意地分散到多个仓库中:每个智能体一个仓库,每项技能一个独立仓库。这种分离使技能可以独立地进行版本管理、共享,并在多个智能体之间复用。如果这让你觉得过于碎片化,请参见链接的仓库了解其理由。
python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="openai:gpt-5.5",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=ContextHubBackend("my-agent"),
)python
from deepagents import create_deep_agent
from deepagents.backends import ContextHubBackend
agent = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=ContextHubBackend("my-agent"),
)使用 owner/name 或 name 格式的仓库标识符来构造它。
NOTE
在使用 ContextHubBackend 之前,请设置 LANGSMITH_API_KEY。
工作原理:
- 首次使用时惰性地拉取 Hub 仓库树,随后从内存缓存中提供读取。
- 将写入和编辑作为 Hub 提交持久化,并在提交成功后更新缓存。
- 使用乐观的父提交写入(
parent_commit):每次推送都以最新已知的提交哈希为目标。
行为和限制:
- 如果仓库不存在,首次拉取会被视为空;第一次成功的写入可以创建该仓库。
- 如果另一个写入者先推进了仓库,你的过时父提交写入可能会失败。在冲突时重新拉取并重试。
upload_files()接受 UTF-8 文本。非 UTF-8 文件会按路径以invalid_path被拒绝。
最适合:
- 无需单独接入 LangGraph
BaseStore的 LangSmith 原生持久化文件系统存储。 - 能从 Hub 提交历史中受益的文件系统变更相关工作流。
CompositeBackend(路由)
python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="openai:gpt-5.5",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="anthropic:claude-sonnet-5",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="openrouter:z-ai/glm-5.2",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
model="ollama:north-mini-code-1.0",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(namespace=lambda _rt: ("memories",)),
},
),
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
)工作原理:
CompositeBackend根据路径前缀将文件操作路由到不同的后端。- 在列表和搜索结果中保留原始路径前缀。
最适合:
- 当你希望同时为智能体提供线程范围和跨线程存储时,
CompositeBackend允许你同时提供StateBackend和StoreBackend - 当你希望将多个信息来源作为单个文件系统提供给智能体时。
- 例如,你将长期记忆存储在一个 Store 的
/memories/下,同时还有一个自定义后端,其文档可通过 /docs/ 访问。
- 例如,你将长期记忆存储在一个 Store 的
指定后端
- 将后端实例传递给
create_deep_agent(model=..., backend=...)。文件系统中间件会将其用于所有工具。 - 后端必须实现
BackendProtocol(例如StateBackend()、FilesystemBackend(root_dir=".")、StoreBackend()、ContextHubBackend("my-agent"))。 - 如果省略,默认为
StateBackend()。
路由到不同的后端
将命名空间的部分路由到不同的后端。常用于让 /memories/* 跨线程持久化,同时让其他所有内容保持线程范围。
python
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, FilesystemBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": FilesystemBackend(root_dir="/deepagents/myagent", virtual_mode=True),
},
)
)行为:
/workspace/plan.md→StateBackend(线程范围)/memories/agent.md→/deepagents/myagent下的FilesystemBackendls、glob、grep聚合结果并显示原始路径前缀。
请注意:
- 更长前缀优先(例如,路由
"/memories/projects/"可以覆盖"/memories/")。 - 对于 StoreBackend 路由,请确保通过
create_deep_agent(model=..., store=...)提供 store,或由平台预置。 - Deep Agents 会将内部数据(卸载的工具结果、对话历史)写入默认后端。使用
StateBackend作为默认值,以保持这些产物是临时的,避免将它们写入磁盘或持久化存储。完整示例请参见 FilesystemBackend 提示。
自定义后端
实现自定义后端,将 Deep Agents 连接到数据库、对象存储和远程文件系统等存储系统。有关示例,请参见社区构建的后端。
实现后端协议
继承 BackendProtocol 并实现以下方法:
| 方法 | 签名 | 作用 | ||
|---|---|---|---|---|
ls | (path: str) -> LsResult | 列出给定路径下的文件和目录。 | ||
read | (file_path: str, offset: int, limit: int) -> ReadResult | 返回文件内容,可选择分页。 | ||
write | (file_path: str, content: str) -> WriteResult | 创建或覆盖文件。 | ||
edit | (file_path: str, old_string: str, new_string: str, replace_all: bool) -> EditResult | 在现有文件中进行查找替换。 | ||
glob | `(pattern: str, path: str | None) -> GlobResult` | 返回匹配 glob 模式的路径。 | |
grep | `(pattern: str, path: str | None, glob: str | None) -> GrepResult` | 在文件内容中搜索字面字符串。 |
delete | (file_path: str) -> DeleteResult | 可选。删除一个文件,或递归删除一个目录。如果后端不支持删除,则在请求时会自动对模型隐藏该工具。 |
要同时支持 execute 工具(运行 shell 命令),请改为实现 SandboxBackendProtocol,它在 BackendProtocol 的基础上扩展了一个 execute 方法。
对于失败情况,始终返回带有 error 字段的结构化结果类型。不要抛出异常。
示例:S3 风格后端骨架
此骨架将文件系统路径映射到对象键。用你存储客户端的 list、read、search、upload 以及读-改-写操作填充每个方法。
python
from deepagents.backends.protocol import (
BackendProtocol,
EditResult,
GlobResult,
GrepResult,
LsResult,
ReadResult,
WriteResult,
)
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(self, path: str) -> LsResult:
...
def read(self, file_path: str, offset: int = 0, limit: int = 2000) -> ReadResult:
...
def grep(self, pattern: str, path: str | None = None, glob: str | None = None) -> GrepResult:
...
def glob(self, pattern: str, path: str | None = None) -> GlobResult:
...
def write(self, file_path: str, content: str) -> WriteResult:
...
def edit(self, file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult:
...权限
使用权限以声明式方式控制智能体可以读取或写入哪些文件和目录。权限适用于内置文件系统工具,并在调用后端之前进行评估。
python
from deepagents import create_deep_agent, FilesystemPermission
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
"/policies/": StoreBackend(
namespace=lambda rt: (rt.context.org_id,),
),
},
),
permissions=[
FilesystemPermission(
operations=["write"],
paths=["/policies/**"],
mode="deny",
),
],
)有关完整选项(包括规则顺序、子智能体权限和复合后端交互),请参见权限指南。
添加策略钩子
对于基于路径的允许/拒绝规则之外的定制验证逻辑(速率限制、审计日志、内容检查),请通过继承或包装后端来强制执行企业规则。
阻止所选前缀下的写入/编辑(子类化):
python
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)通用包装器(适用于任何后端):
python
from deepagents.backends.protocol import (
BackendProtocol, WriteResult, EditResult, LsResult, ReadResult, GrepResult, GlobResult,
)
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(self, path: str) -> LsResult:
return self.inner.ls(path)
def read(self, file_path: str, offset: int = 0, limit: int = 2000) -> ReadResult:
return self.inner.read(file_path, offset=offset, limit=limit)
def grep(self, pattern: str, path: str | None = None, glob: str | None = None) -> GrepResult:
return self.inner.grep(pattern, path, glob)
def glob(self, pattern: str, path: str | None = None) -> GlobResult:
return self.inner.glob(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)从后端工厂迁移
WARNING
自 deepagents 0.5.0 起,后端工厂模式已被弃用。请直接传入预先构造好的后端实例,而不是工厂函数。
以前,像 StateBackend 和 StoreBackend 这样的后端需要一个接收运行时对象的工厂函数,因为它们需要运行时上下文(状态、store)才能工作。现在后端会通过 LangGraph 的 get_config()、get_store() 和 get_runtime() 辅助函数在内部解析这些上下文,因此你可以直接传入实例。
变化内容
| 之前(已弃用) | 之后 |
|---|---|
backend=lambda rt: StateBackend(rt) | backend=StateBackend() |
backend=lambda rt: StoreBackend(rt) | backend=StoreBackend() |
backend=lambda rt: CompositeBackend(default=StateBackend(rt), ...) | backend=CompositeBackend(default=StateBackend(), ...) |
backend: (config) => new StateBackend(config) | backend: new StateBackend() |
backend: (config) => new StoreBackend(config) | backend: new StoreBackend() |
已弃用的 API
| 已弃用 | 替代方案 |
|---|---|
在 create_deep_agent 中向 backend= 传入可调用对象 | 直接传入后端实例 |
StateBackend(runtime) 上的 runtime 构造参数 | StateBackend()(无需参数) |
StoreBackend(runtime) 上的 runtime 构造参数 | StoreBackend() 或 StoreBackend(namespace=..., store=...) |
WriteResult 和 EditResult 上的 files_update 字段 | 状态写入现在由后端在内部处理 |
中间件写入/编辑工具中的 Command 包装 | 工具返回纯字符串;不再需要 Command(update=...) |
NOTE
工厂模式在运行时仍然有效,但会发出弃用警告。请在下一个主要版本之前更新你的代码以使用直接实例。
迁移示例
python
# Before (deprecated)
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=lambda rt: CompositeBackend(
default=StateBackend(rt),
routes={"/memories/": StoreBackend(rt, namespace=lambda rt: (rt.server_info.user.identity,))},
),
)
# After
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
backend=CompositeBackend(
default=StateBackend(),
routes={"/memories/": StoreBackend(namespace=lambda rt: (rt.server_info.user.identity,))},
),
)从 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。
python
# Before (deprecated, removed in v0.7)
StoreBackend(
namespace=lambda ctx: (ctx.runtime.context.user_id,),
)
# After
StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
)协议参考
后端必须实现 BackendProtocol。
必需的方法:
ls(path: str) -> LsResult- 返回至少包含
path的条目。在可用时包含is_dir、size、modified_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: Optional[str] = None) -> 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)—成功时entries是list[FileInfo],失败时为None。ReadResult(error, file_data)—成功时file_data是FileData字典,失败时为None。GrepResult(error, matches)—成功时matches是list[GrepMatch],失败时为None。GlobResult(error, matches)—成功时matches是list[FileInfo],失败时为None。WriteResult(error, path, files_update)EditResult(error, path, files_update, occurrences)FileInfo包含字段:path(必填),可选is_dir、size、modified_at。GrepMatch包含字段:path、line、text。FileData包含字段:content(str)、encoding("utf-8"或"base64")、created_at、modified_at。 :::