












在構建智能代理(AI Agent)時,我們經常需要讓Agent具備讀取、寫入、搜索和編輯文件的能力。DeepAgents框架通過Backend(後端)機制實現了這一功能,為Agent提供了一個安全、可控的文件操作環境。本文將深入探討Backend的概念、使用方法,並通過四個漸進式的示例來展示其強大功能。
Backend是DeepAgents框架中的一個核心抽象,它定義了Agent如何與文件系統進行交互。通過Backend,Agent可以:
ls_info)read)write)grep_raw)glob_info)edit)Backend的核心價值在於安全性和靈活性:它可以將Agent的文件操作限制在特定目錄內,防止越權訪問,同時支持多種存儲介質(本地文件系統、內存、雲存儲等)。
DeepAgents框架提供了多種Backend實現,滿足不同場景的需求:
OpenSandboxBackend:基於OpenSandbox的開源沙箱方案DaytonaBackend:基於Daytona的雲沙箱方案BackendProtocol接口自定義存儲邏輯DictBackend(內存存儲)、RedisBackend(Redis存儲)等| Backend類型 | 文件操作 | 命令執行 | 持久化 | 安全隔離 | 典型場景 |
|---|---|---|---|---|---|
| FilesystemBackend | ✅ | ❌ | ✅ | 中等(virtual_mode) | 本地文件處理 |
| LocalShellBackend | ✅ | ✅(本地) | ✅ | 中等(virtual_mode) | 本地腳本執行 |
| SandboxBackend | ✅ | ✅(沙箱) | 可選 | 高(完全隔離) | 雲端安全執行 |
| 自定義Backend | 自定義 | 自定義 | 自定義 | 自定義 | 特殊需求 |
最簡單的Agent配置不使用Backend,僅依賴工具調用完成任務:
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver
# 創建內存檢查點保存器
checkpointer = InMemorySaver()
# 創建基礎Agent
agent = create_deep_agent(
model=llm,
tools=[web_search],
#checkpointer=checkpointer,
system_prompt='你是一個助手,請根據用戶輸入的指令,進行相應的操作。'
)
特點:
當需要Agent操作文件時,FilesystemBackend是最常用的選擇:
import os
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
# 創建Agent工作目錄
temp_workspace = "./agent_workspace"
os.makedirs(temp_workspace, exist_ok=True)
agent = create_deep_agent(
model=llm,
tools=[web_search],
checkpointer=checkpointer,
backend=FilesystemBackend(
root_dir=temp_workspace,
virtual_mode=True, # 防止Agent通過`../../`跳出根目錄
),
system_prompt='你是一個助手,請根據用戶輸入的指令,進行相應的操作。'
)
關鍵參數:
root_dir:指定Agent的工作根目錄virtual_mode=True:啟用虛擬模式,防止路徑穿越攻擊(如../../etc/passwd)適用場景:
如果Agent不僅需要操作文件,還需要執行shell命令,LocalShellBackend是更好的選擇:
import os
import sys
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend, LocalShellBackend
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
temp_workspace = "./agent_workspace"
os.makedirs(temp_workspace, exist_ok=True)
agent = create_deep_agent(
model=llm,
tools=[web_search],
checkpointer=checkpointer,
backend=LocalShellBackend(
root_dir=temp_workspace,
virtual_mode=True,
timeout=30, # 命令執行超時時間(秒)
max_output_bytes=50000, # 命令輸出最大字節數
env={
"PATH": f"{os.path.dirname(sys.executable)};{os.environ.get('PATH', '')}",
},
),
system_prompt='你是一個助手,請根據用戶輸入的指令,進行相應的操作。'
)
新增功能:
python script.py、ls -la)適用場景:
DeepAgents的強大之處在於其可擴展性。通過實現BackendProtocol接口,我們可以創建完全自定義的Backend:
from deepagents.backends.protocol import BackendProtocol, WriteResult, EditResult
from deepagents.backends.utils import FileInfo, GrepMatch
from datetime import datetime
import re
class DictBackend(BackendProtocol):
"""將文件存儲在內存字典中的自定義後端"""
def __init__(self):
self.files = {} # 路徑 -> 內容
self.metadata = {} # 路徑 -> 元數據
def ls_info(self, path: str) -> list[FileInfo]:
"""列出文件和目錄信息"""
result = []
seen_dirs = set()
for file_path in self.files.keys():
if file_path.startswith(path):
remaining = file_path[len(path):]
if '/' in remaining:
dir_name = path + remaining.split('/')[0] + '/'
if dir_name not in seen_dirs:
seen_dirs.add(dir_name)
result.append(FileInfo(path=dir_name, is_dir=True))
else:
meta = self.metadata.get(file_path, {})
result.append(FileInfo(
path=file_path,
is_dir=False,
size=meta.get('size', 0),
modified_at=meta.get('modified_at')
))
return result
def read(self, file_path: str, offset: int = 0, limit: int = 2000) -> str:
"""讀取文件內容,支持分頁"""
if file_path not in self.files:
return f"Error: File '{file_path}' not found"
content = self.files[file_path]
lines = content.splitlines(keepends=True)
start_line = offset
end_line = start_line + limit if limit > 0 else len(lines)
selected_lines = lines[start_line:end_line]
result = ''.join(f"{start_line + i + 1}: {line}" for i, line in enumerate(selected_lines))
return result if result else "(end of file)"
def write(self, file_path: str, content: str) -> WriteResult:
"""寫入新文件(僅創建,不覆蓋)"""
if file_path in self.files:
return WriteResult(error=f"File '{file_path}' already exists (create-only).")
self.files[file_path] = content
self.metadata[file_path] = {
'size': len(content),
'modified_at': datetime.now().isoformat()
}
return WriteResult(path=file_path, files_update=None)
def grep_raw(self, pattern: str, path: str | None = None, glob: str | None = None) -> list[GrepMatch] | str:
"""正則表達式搜索文件內容"""
try:
re.compile(pattern)
except re.error as e:
return f"Invalid regex pattern: {e}"
matches = []
for file_path, content in self.files.items():
for i, line in enumerate(content.splitlines()):
if re.search(pattern, line):
matches.append(GrepMatch(path=file_path, line=i+1, text=line))
return matches
def glob_info(self, pattern: str, path: str = "/") -> list[FileInfo]:
"""通配符匹配文件"""
import fnmatch
all_files = [
FileInfo(path=p, is_dir=False, size=self.metadata[p]['size'],
modified_at=self.metadata[p]['modified_at'])
for p in self.files.keys() if p.startswith(path)
]
matched = [fi for fi in all_files if fnmatch.fnmatch(fi.path, path.rstrip('/') + '/' + pattern)]
return matched
def edit(self, file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> EditResult:
"""編輯文件內容"""
if file_path not in self.files:
return EditResult(error=f"File '{file_path}' not found")
content = self.files[file_path]
if replace_all:
new_content = content.replace(old_string, new_string)
occurrences = content.count(old_string)
else:
if content.count(old_string) != 1:
return EditResult(error=f"Found {content.count(old_string)} occurrences. For safety, edit requires exactly one match unless replace_all=True.")
new_content = content.replace(old_string, new_string, 1)
occurrences = 1
if new_content == content:
return EditResult(error=f"String '{old_string}' not found.")
self.files[file_path] = new_content
self.metadata[file_path]['size'] = len(new_content)
self.metadata[file_path]['modified_at'] = datetime.now().isoformat()
return EditResult(path=file_path, files_update=None, occurrences=occurrences)
使用自定義Backend:
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend, LocalShellBackend
from langgraph.checkpoint.memory import InMemorySaver
from my_backend import DictBackend
checkpointer = InMemorySaver()
agent = create_deep_agent(
model=llm,
tools=[web_search],
checkpointer=checkpointer,
backend=DictBackend(),
system_prompt='你是一個助手,請根據用戶輸入的指令,進行相應的操作。'
)
自定義Backend的優勢:
| 場景 | 推薦Backend | 原因 |
|---|---|---|
| 僅需API調用,無需文件操作 | 無Backend | 簡單高效 |
| 需要持久化文件存儲 | FilesystemBackend | 直接操作磁盤文件 |
| 需要執行shell命令 | LocalShellBackend | 支持命令執行+文件操作 |
| 需要完全隔離或自定義存儲 | 自定義Backend | 靈活可控,適合特殊需求 |
Backend是DeepAgents框架中連接AI Agent與文件系統的橋樑。通過靈活選擇或自定義Backend,我們可以為Agent打造安全、高效、可控的文件操作環境。從簡單的無Backend配置,到功能強大的LocalShellBackend,再到完全自定義的DictBackend,DeepAgents提供了豐富的選項來滿足各種應用場景。
掌握Backend的使用,將幫助你構建更加強大和實用的AI Agent,讓智能代理真正具備"動手"能力!
此內容由慣性聚合(RSS閱讀器)自動聚合整理,僅供閱讀參考。 原文來自 — 版權歸原作者所有。