DeepAgents In Action学习(Third)
传统的 Agent 开发有一个致命问题:所有信息都直接塞进 prompt。文件内容、搜索结果、中间计算------全部挤在一个不断膨胀的对话历史里。
DeepAgents给我出的答案是:给Agent一个文件系统(或者换句话说给了一本书,需要什么就翻到哪儿去查)
内置的文件系统工具
| 工具 | 用途 | 类比 |
|---|---|---|
ls |
列出目录中的文件和元信息(大小、修改时间) | 打开文件夹看看有什么 |
read_file |
读取文件内容,支持偏移量和限制条数;原生支持多模态格式(图片、视频、音频、PDF/PPT) | 翻开某份资料阅读 |
write_file |
创建新文件 | 写一份新的备忘录 |
edit_file |
对已有文件做精确字符串替换 | 用红笔修改文档 |
delete |
删除文件或目录 | 清理不再需要的资料 |
glob |
按模式匹配查找文件(如 **/*.py) |
在文件柜中按标签找 |
grep |
搜索文件内容,按字面量匹配;支持内容输出和计数 | 全文检索 |

-
read_file
特性:分片读取 、原生多模态支持
-
分片读取,对于大文件,
read_file支持按偏移量和行数读取,避免一次性把整个文件塞进上下文python# 默认最多读取前 100 行 read_file("/workspace/report.md") # 从第 100 行开始,读取 50 行 read_file("/workspace/report.md", offset=100, limit=50) -
原生多模态支持,
read_file不只能读文本------它原生支持多种多媒体格式,直接返回多模态内容块,让 Agent 能"看到"图片、"听到"音频、"读懂"文档类型 支持格式 图片 .png.jpg.jpeg.gif.webp.heic.heif视频 .mp4.mpeg.mov.avi.flv.mpg.webm.wmv.3gpp音频 .wav.mp3.aiff.aac.ogg.flac文档 .pdf.ppt.pptx
-
-
grep
支持三种输出模式:
files_with_matches:只返回匹配的文件路径(快速定位)content:返回匹配行及上下文(深入查看)count:返回匹配数量(概览统计)
python# 找到所有包含 "TODO" 的 Python 文件 grep("TODO", glob="**/*.py", output_mode="files_with_matches") # 查看匹配内容 grep("def create_agent", output_mode="content")
上下文自动管理
虚拟文件系统与Deep Agents的上下文自动管理机制紧密配合
-
大结果自动转存,只保留部分内容预览
当工具调用的输入或输出超过 20,000 tokens 时(可通过
tool_token_limit_before_evict配置),Deep Agents 会自动:
-
将完整内容写入虚拟文件系统
-
在对话历史中替换为文件路径引用 + 前 10 行预览
-
Agent 需要时可以按需读回
示例如下:
原始结果:50000 tokens 的搜索结果
自动存储后:
"结果已保存到 /workspace/search_results_001.md,
前 10 行预览:
1 # Search Results for 'LangGraph'
2
3 ## Result 1: Official Documentation
4 ..."
这个机制是完全自动的------Agent 不需要手动管理,但可以随时通过 read_file 或 grep 重新访问完整内容
* 历史对话内容总结
当上下文大小达到模型窗口的 85% 时,如果没有更多可卸载的内容,Deep Agents 会启动**自动总结**:
1. 用 LLM 生成对话的结构化摘要(意图、产出物、下一步)
2. 将完整的原始对话**写入文件系统**保存
3. 用摘要**替换**对话历史中的旧消息
这种"双保险"设计意味着:Agent 既有精炼的工作记忆(摘要),又能在需要时回溯细节(文件系统中的完整记录)。

* 可插拔的存储后端
> "虚拟文件系统"是一个抽象概念,具体的文件存到哪里,由**后端(Backend)**决定。
>
> Deep Agents 的方案是你可以根据场景选择不同的存储策略

* StateBackend(默认):临时存储
> 文件存在 LangGraph 的 Agent State 中。特点:
>
> - 同一个对话线程内**持久化**(多轮对话不丢失)
> - 对话结束后**丢失**(换一个 thread 就没了)
> - 主 Agent 和子 Agent **共享**文件
>
> 适合场景:大多数情况下的默认选择,Agent 的"草稿纸"。
```python
from deepagents import create_deep_agent
# 默认就是 StateBackend,不需要显式指定
agent = create_deep_agent(model=model)
# 显式配置
agent = create_deep_agent(model=model,backend=StateBackend())
```
* FilesystemBackend:本地磁盘
> 文件直接读写**本地文件系统**。特点:
>
> - `root_dir` 指定 Agent 可访问的根目录;相对路径会被解析为绝对路径(`Path(root_dir).resolve()`),`"."` 即当前工作目录
> - `virtual_mode=True` 启用路径沙箱(阻止 `..`、`~` 及越界的绝对路径),**强烈建议开启**;若为默认的 `virtual_mode=False`,即使设了 `root_dir` 也不提供任何越界保护
> - 文件修改是**永久的、不可逆的**
>
> 适合场景:本地开发 CLI(编程助手)、CI/CD 流水线。
>
> 💡 `virtual_mode` 从 0.5.0 起不显式声明会有弃用警告,0.6.0 起变为必填。建议直接写 `virtual_mode=True` 开启路径沙箱。
>
> ⚠️ 安全提示:Agent 可以读取 `root_dir` 下所有文件,包括 `.env`、密钥等敏感文件。Web 服务或 API 场景中切勿使用此后端,应改用沙箱后端。建议配合 Human-in-the-Loop 使用。
```python
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
model=model,
backend=FilesystemBackend(root_dir=".", virtual_mode=True)
)
```
* LocalShellBackend:本地 Shell 执行'
> `LocalShellBackend` 是 `FilesystemBackend` 的扩展,在文件系统工具之外**额外提供 `execute` 工具**,可直接在宿主机运行 Shell 命令。特点:
>
> - 命令通过 `subprocess.run(shell=True)` 执行,**无任何沙箱隔离**
> - 支持 `timeout`(默认 120 秒)、`max_output_bytes`(默认 100,000)、`env` 等参数
> - `root_dir` 作为命令的工作目录,但命令可访问系统上任意路径
>
> 适合场景:本地开发环境的编程助手、你完全信任 Agent 行为的个人开发机。
>
> ⚠️ 极高风险警告:Agent 可执行任意 Shell 命令,包括删除文件、外传数据、消耗资源。**绝对不要在生产环境或多用户系统中使用。** 沙箱后端是生产环境的安全替代方案。
>
> 如果确实要在个人开发机中临时使用,至少做几层防护:
>
> - 将 `root_dir` 指向一个专门的临时工作区,而不是用户主目录或整个仓库上级目录
> - 显式设置 `virtual_mode=True`,并用最小化的 `env` / `PATH` 降低命令可见范围
> - 不把 `.env`、私钥、云凭证、生产配置文件放进 Agent 可访问目录
> - 对 `rm`、`mv`、安装依赖、修改配置、访问网络等高风险操作增加 Human-in-the-Loop 审批
> - 需要运行不可信代码、处理用户上传文件或对外提供服务时,直接换用沙箱后端,不要用 `LocalShellBackend`
```python
from deepagents.backends import LocalShellBackend
agent = create_deep_agent(
model=model,
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"})
)
```
* StoreBackend:跨会话持久化
> 文件存在 LangGraph 的 Store 中。特点:
>
> - **跨线程持久化**------不同对话都能访问同一份文件
> - `namespace` 参数控制数据隔离:`lambda rt: (rt.server_info.user.identity,)` 按用户隔离,防止数据混用
> - 开发用 `InMemoryStore`,部署到 LangSmith 时省略 `store` 参数(平台自动配置)
>
> 适合场景:长期记忆、跨会话的用户偏好、累积的知识库。
>
> 💡 `namespace` 从 v0.5.0 起是必填参数。`rt.server_info.user.identity` 部署到 LangSmith 时能自动拿到用户身份,但本地 `invoke()` 时 `rt.server_info` 是 `None`,直接访问会报错。
>
> 💡 `namespace` 本地需要加 `if rt.server_info else ("local-user",)` 兜底。
```python
from langgraph.store.memory import InMemoryStore
from deepagents.backends import StoreBackend
agent = create_deep_agent(
model=model,
backend=StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,), # 按用户隔离数据
),
store=InMemoryStore() # 开发用;部署到 LangSmith 时可省略,平台自动提供
)
```
* CompositeBackend:混合路由
> 这个模式最灵活的方案------**不同路径走不同后端**
>
> - Agent 写入 `/workspace/plan.md` → StateBackend(临时)
> - Agent 写入 `/memories/preferences.txt` → StoreBackend(持久化,按用户隔离)
> - `ls`、`glob`、`grep` 自动聚合所有后端的结果,路径前缀保留
>
> 这种设计让 Agent 既有快速的"草稿纸"(State),又有持久的"记忆库"(Store),通过路径前缀自然隔离。
```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=model,
backend=CompositeBackend(
default=StateBackend(), # 默认:临时存储
routes={
"/memories/": StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
}
),
store=InMemoryStore()
)
```
* 沙箱后端:安全代码执行
> 除了文件系统工具外,Agent 还会获得一个额外的 `execute` 工具,可以在隔离环境中执行 Shell 命令
>
> 当前支持的沙箱服务有Modal、Daytona、Runloop 等
```python
# 沙箱后端自动提供 execute 工具
agent = create_deep_agent(
model=model,
backend=sandbox # 沙箱实例
)
# Agent 现在可以运行: execute("pip install pandas && python analyze.py")
```
### backend策略选择指南
| 场景 | 推荐backend | 理由 |
| -------------- | -------------------------------- | ----------------- |
| 学习和实验 | StateBackend(默认) | 零配置,自动清理 |
| 本地编程助手 | FilesystemBackend | 直接操作项目文件 |
| 需要跨会话记忆 | CompositeBackend | 混合临时 + 持久化 |
| 需要执行代码 | 沙箱后端 | 安全隔离 |
| 生产部署 | StoreBackend 或 CompositeBackend | 持久化 + 可伸缩 |