












智能代理(AI Agent)を構築する際、私たちはAgentにファイルを読み取り、書き込み、検索、編集する能力を持たせる必要があることがよくあります。DeepAgentsフレームワークは、 Backend(バックエンド) 機構を通じてこの機能を実現しており、Agentに安全で制御可能なファイル操作環境を提供します。本稿では、Backendの概念や使用方法について深く掘り下げ、さらに4つの段階的に進むサンプルを通じてその強力な機能を示します。
BackendはDeepAgentsフレームワークの中核的な抽象概念であり、Agentがファイルシステムとどのようにやり取りするかを定義しています。Backendを通じて、Agentは以下のことが可能です:
ls_info)read)write)grep_raw)glob_info)edit)Backendの核心価値はセキュリティと柔軟性にあります:Agentのファイル操作を特定のディレクトリ内に制限し、権限の侵害を防ぎ、同時に複数のストレージメディア(ローカルファイルシステム、メモリ、クラウドストレージなど)をサポートします。
DeepAgentsフレームワークは、様々なバックエンド実装を提供し、異なるシナリオのニーズを満たします:
OpenSandboxBackend:OpenSandboxをベースとしたオープンソースサンドボックスソリューションDaytonaBackend:DaytonaをベースとしたクラウドサンドボックスソリューションBackendProtocolインターフェースを実装して、カスタムストレージロジックを定義DictBackend(メモリストレージ)、RedisBackend(Redisストレージ)など| バックエンドタイプ | ファイル操作 | コマンド実行 | 永続化 | セキュリティ分離 | 典型的なシナリオ |
|---|---|---|---|---|---|
| FilesystemBackend | ✅ | ❌ | ✅ | 中程度(virtual_mode) | ローカルファイル処理 |
| LocalShellBackend | ✅ | ✅(ローカル) | ✅ | 中(仮想モード) | ローカルスクリプト実行 |
| 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のメリット:
| シナリオ | 推奨バックエンド | 理由 |
|---|---|---|
| API呼び出しのみ、ファイル操作不要 | なし | シンプルで効率的 |
| 持続的なファイルストレージが必要 | FilesystemBackend | ディスクファイルを直接操作 |
| シェルコマンドを実行する必要がある | LocalShellBackend | コマンド実行+ファイル操作をサポート |
| 完全な隔離やカスタムストレージが必要 | カスタムバックエンド | 柔軟に制御可能で、特別なニーズに適しています |
Backendは、DeepAgentsフレームワークにおいてAI Agentとファイルシステムを接続する橋渡しです。Backendを柔軟に選択したりカスタマイズしたりすることで、Agentに安全で効率的で制御可能なファイル操作環境を提供できます。単純なBackendなしの設定から、機能豊富なLocalShellBackend、さらには完全にカスタマイズ可能なDictBackendまで、DeepAgentsはさまざまなアプリケーションシナリオに対応するための豊富な選択肢を提供しています。
。Backendの使用をマスターすることで、より強力で実用的なAI Agentを構築し、インテリジェントエージェントが本当に「手を動かす」能力を持つことができます!
このコンテンツは慣性聚合(RSSリーダー)によって自動集約されています。参考としてご覧ください。 原文出典 — 著作権は原著者に帰属します。