深度代理通过工具向代理暴露文件系统界面,例如 ls, read_file, write_file, edit_file, glob和 grep。这些工具通过可插拔后端运行。 read_file 工具原生支持图像文件(.png, .jpg, .jpeg, .gif, .webp)跨所有后端,返回它们为多模态内容块。
read_file 工具原生支持二进制文件(图像、PDF、音频、视频)跨所有后端,返回 ReadResult ,包含类型化的 content 和 mimeType.
沙箱和LocalShellBackend也提供了一个 execute tool. 本页说明如何:
- - 选择后端
- - 将不同路径路由到不同后端
- - 实现自定义后端
- - 设置权限 对文件系统访问
- - 添加策略钩子
- - 处理二进制和多模态文件
- - 符合后端协议
- - 将现有后端更新到v2
快速入门
以下是几个预构建的文件系统后端,您可以使用它们与深度代理快速配合:
| 内置后端 | 描述 |
|---|---|
| 默认 | agent = create_deep_agent(model="google_genai:gemini-3.5-flash") <br></br> 线程作用域。代理的默认文件系统后端存储在 langgraph 状态中。文件在单个线程内跨轮次持久化(通过您的检查点),不会在线程间共享。 |
| 本地文件系统持久化 | agent = create_deep_agent(model="google_genai:gemini-3.5-flash", backend=FilesystemBackend(root_dir="/Users/nh/Desktop/")) <br></br>这使深度代理可以访问您本地机器的文件系统。您可以指定代理有权访问的根目录。请注意,任何提供的 root_dir 必须是绝对路径。通常,包装在 CompositeBackend中 ,以将内部代理数据(卸载的工具结果、对话历史)与您的项目文件分开。 |
| 持久存储(LangGraph存储) | agent = create_deep_agent(model="google_genai:gemini-3.5-flash", backend=StoreBackend()) <br></br>这使代理可以访问长期存储,该存储 _跨线程持久化_。这非常适合存储更长期的记忆或适用于代理在多次执行中的指令。 |
| 上下文中心 | agent = create_deep_agent(model="google_genai:gemini-3.5-flash", backend=ContextHubBackend("my-agent")) <br></br>将文件持久化存储在 LangSmith Hub 仓库中,无需配置单独的 LangGraph 存储。 |
| 沙箱 | agent = create_deep_agent(model="google_genai:gemini-3.5-flash", backend=sandbox) <br></br>在隔离环境中执行代码。沙箱提供文件系统工具以及 execute 用于运行 shell 命令的工具。可选择 LangSmith、AgentCore、Daytona、Deno、E2B、Modal、Runloop 或本地 VFS。 |
| 本地 shell | agent = create_deep_agent(model="google_genai:gemini-3.5-flash", backend=LocalShellBackend(root_dir=".", env={"PATH": "/usr/bin:/bin"})) <br></br>直接在主机上执行文件系统和 shell 操作。无隔离——仅在受控的开发环境中使用。见 安全注意事项 下方。 |
| 组合 | 默认线程作用域, /memories/ 跨线程持久化。组合后端具有最大的灵活性。您可以在文件系统中指定不同的路由指向不同的后端。请参阅下方的组合路由获取可直接粘贴的示例。 |
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
内置后端
状态后端
工作原理: - 通过 @[ 将文件存储在当前线程的 LangGraph 代理状态中StateBackend]. - 通过检查点跨同一线程的多个代理轮次持久化。文件不在线程之间共享。
最适合: - 供代理写入中间结果的草稿板。 - 自动清除大型工具输出,然后代理可以逐块读回。
请注意,此后端在主管代理和子代理之间共享,子代理写入的任何文件都将保留在 LangGraph 代理状态中 即使该子代理的执行完成。这些文件将继续对主管代理和其他子代理可用。
文件系统后端(本地磁盘)
FilesystemBackend 在可配置的根目录下读取和写入真实文件。
工作原理: - Reads/writes real files under a configurable root_dir. - 您可以选择设置 virtual_mode=True 来沙箱化并规范化 root_dir. - 使用安全路径解析,尽可能防止不安全的符号链接遍历,可使用 ripgrep 进行快速 grep.
最适合: - 本地项目 - CI 沙箱 - 挂载的持久卷
LocalShellBackend(本地 shell)
工作原理: - 扩展 FilesystemBackend 并配合 execute 工具在主机上运行 shell 命令。 - 命令使用 subprocess.run(shell=True) 直接在你的机器上运行,无沙盒隔离。 - 支持 timeout (默认 120 秒), max_output_bytes (默认 100,000), env和 inherit_env 用于环境变量。 - Shell 命令使用 root_dir 作为工作目录,但可以访问系统上的任何路径。
最佳用途: - 本地编码助手和开发工具 - 在开发过程中需要快速迭代且信任代理时
StoreBackend (LangGraph 存储)
工作原理: - StoreBackend 将文件存储在运行时提供的 LangGraph BaseStore 中,实现跨线程持久化存储。
最佳用途: - 当你已经使用配置的 LangGraph 存储运行时(例如 Redis、Postgres 或 BaseStore). - 当你通过 LangSmith 部署 部署你的代理时(系统会自动为你的代理配置存储)。
命名空间工厂
命名空间工厂控制 StoreBackend 读取和写入数据的位置。它接收一个 LangGraph Runtime 并返回一个字符串元组,用作存储命名空间。使用命名空间工厂来隔离用户、租户或助手之间的数据。
在构造 namespace 时将命名空间工厂传递给 StoreBackend:
NamespaceFactory = Callable[[Runtime], tuple[str, ...]]
Runtime provides: - rt.context — 通过 LangGraph 的 上下文 schema 传递的用户提供上下文(例如, user_id)
- -
rt.serverInfo— 在 LangGraph Server 上运行时的服务器特定元数据(assistant ID、graph ID、已认证用户) - -
rt.executionInfo— 执行身份信息(thread ID、run ID、checkpoint ID)
常见的命名空间模式:
// Per-user: each user gets their own isolated storage
const backend = new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity], // [!code highlight]
});
// Per-assistant: all users of the same assistant share storage
const backend = new StoreBackend({
namespace: (rt) => [rt.serverInfo.assistantId], // [!code highlight]
});
// Per-thread: storage scoped to a single conversation
const backend = new StoreBackend({
namespace: (rt) => [rt.executionInfo.threadId], // [!code highlight]
});
您可以组合多个组件来创建更具体的作用域 — 例如, (user_id, thread_id) 用于每个用户每个会话的隔离,或者附加后缀如 "filesystem" 用于在相同作用域使用多个存储命名空间时进行区分。
命名空间组件只能包含字母数字字符、连字符、下划线、点、 @, +、冒号和波浪号。通配符(*, ?)会被拒绝以防止 glob 注入。
,请始终提供命名空间工厂。
ContextHubBackend 页面,如果您不熟悉 agent 代码库和 skill 代码库的话。
将您的 agent 的文件系统存储在 LangSmith Context Hub 代码库中。它可以使用独立的代码库或链接到 skill 代码库的 agent 代码库。 代码库结构: _在 Context Hub 中,_ agent 代码库 AGENTS.md, tools.json保存 agent 的顶级指令和配置(例如, _)。它可以链接到一个或多个_skill 代码库 SKILL.md ,每个代码库都打包为可重用的功能(例如, ContextHubBackend("my-agent"),后端将 agent 仓库挂载到文件系统根目录;链接的技能仓库显示为以下子目录 /skills/.
这意味着您的 agent 上下文有意分散在多个仓库中:每个 agent 一个仓库,每个技能一个独立仓库。这种分离允许技能独立地进行版本控制、共享和跨多个 agent 重用。如果这感觉分散,请参阅 链接的仓库 以了解原理。
使用仓库标识符构造它, owner/name or name format.
工作原理: - 在首次使用时延迟拉取 Hub 仓库树,然后从内存缓存中提供读取服务。 - 将写入和编辑持久化为 Hub 提交,并在成功提交后更新缓存。 - 使用乐观的父提交写入(parent_commit):每次推送都针对最新已知的提交哈希。
行为和限制: - 如果仓库不存在,首次拉取被视为空;首次成功写入可以创建仓库。 - 如果另一个写入者先推进了仓库,您的过时父提交写入可能会失败。发生冲突时重新拉取并重试。 - upload_files() 接受 UTF-8 文本。非 UTF-8 文件按路径被拒绝,并显示 invalid_path.
最适用于: - LangSmith 原生的持久文件系统存储,无需单独连接 LangGraph BaseStore. - 从文件系统变更的 Hub 提交历史中受益的工作流。
CompositeBackend(路由器)
工作原理: - @[CompositeBackend根据路径前缀将文件操作路由到不同的后端。 - 保留列表和搜索结果中的原始路径前缀。
最适用于: - 当你想要为你的代理提供线程作用域和跨线程存储时,可以使用 CompositeBackend 允许你同时提供 StateBackend 和 StoreBackend - 当你有多个想要作为单一文件系统提供给代理的信息源时。 - 例如,你有长期记忆存储在 /memories/ in one Store and you also have a custom backend that has documentation accessible at /docs/.
指定后端
- - 将后端实例传递给
createDeepAgent({ backend: ... })。文件系统中间件将其用于所有工具。 - - 后端必须实现
AnyBackendProtocol(BackendProtocolV1orBackendProtocolV2)——例如,new StateBackend(),new FilesystemBackend({ rootDir: "." }),new StoreBackend(). - - 如果省略,默认值是
new StateBackend().
路由至不同的后端
将命名空间的不同部分路由到不同的后端。常用于持久化 /memories/* 跨线程使用,同时让其他内容保持线程作用域。
const agent = createDeepAgent({
backend: new CompositeBackend(
new StateBackend(),
{
"/memories/": new FilesystemBackend({ rootDir: "/deepagents/myagent", virtualMode: true }),
},
),
});
Behavior: - /workspace/plan.md → StateBackend (线程作用域) - /memories/agent.md → FilesystemBackend 在...下 /deepagents/myagent - ls, glob, grep 聚合结果并显示原始路径前缀。
Notes: - 更长的前缀优先(例如,路由 "/memories/projects/" 可以覆盖 "/memories/"). - 对于 StoreBackend 路由,请确保通过 create_deep_agent(model=..., store=...) 或由平台提供存储。 - Deep Agents 将内部数据(卸载的工具结果、对话历史)写入默认后端。使用 StateBackend 作为默认值,以保持这些产物为临时性的,避免将它们写入磁盘或持久化存储。请参阅 FilesystemBackend 技巧 获取完整示例。
自定义后端
实现自定义后端,将 Deep Agents 连接到数据库、对象存储和远程文件系统等存储系统。请参阅 社区构建的后端 获取示例。
实现后端协议
实现 BackendProtocol (BackendProtocolV2) 并提供以下方法:
| 方法 | 签名 | 功能 |
|---|---|---|
ls | (path: string) => Promise | 列出指定路径下的文件和目录。 |
read | (filePath: string, offset?, limit?) => Promise | 返回文件内容,可选择分页。二进制文件返回 Uint8Array 内容,带有 mimeType. |
readRaw | (filePath: string) => Promise | 返回原始 FileData (框架内部使用)。 |
write | (filePath: string, content: string) => Promise | 创建或覆盖文件。 |
edit | (filePath: string, oldString: string, newString: string, replaceAll?: boolean) => Promise | 在现有文件中进行查找和替换。 |
glob | (pattern: string, path?: string) => Promise | 返回与 glob 模式匹配的路径。 |
grep | (pattern: string, path?, glob?) => Promise | 在文件内容中搜索字面字符串。 |
要同时支持 execute 工具(运行 shell 命令),实现 SandboxBackendProtocol 而不是,它扩展了 BackendProtocolV2 具有 execute method.
所有方法必须返回带有可选 error 字段 — 缺失文件或无效模式时不抛出异常。
Example: S3-style backend skeleton
此骨架将文件系统路径映射到对象键。用存储客户端的列表、读取、搜索、上传和读写操作填充每个方法。
type BackendProtocolV2,
type EditResult,
type GlobResult,
type GrepResult,
type LsResult,
type ReadRawResult,
type ReadResult,
type WriteResult,
} from "deepagents";
class S3Backend implements BackendProtocolV2 {
constructor(private bucket: string, private prefix: string = "") {
this.prefix = prefix.replace(/\/$/, "");
}
private key(path: string): string {
return `${this.prefix}${path}`;
}
async ls(path: string): Promise {
...
}
async read(filePath: string, offset?: number, limit?: number): Promise {
...
}
async readRaw(filePath: string): Promise {
...
}
async grep(pattern: string, path?: string | null, glob?: string | null): Promise {
...
}
async glob(pattern: string, path = "/"): Promise {
...
}
async write(filePath: string, content: string): Promise {
...
}
async edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise {
...
}
}
权限
使用 权限 以声明方式控制代理可以读取或写入的文件和目录。权限适用于内置文件系统工具,并在调用后端之前进行评估。
有关完整的选项集(包括规则排序、子代理权限和复合后端交互),请参阅 权限指南.
添加策略钩子
For custom validation logic beyond path-based allow/deny rules (rate limiting, audit logging, content inspection), enforce enterprise rules by subclassing or wrapping a backend.
Block writes/edits under selected prefixes (subclass):
class GuardedBackend extends FilesystemBackend {
private denyPrefixes: string[];
constructor({ denyPrefixes, ...options }: { denyPrefixes: string[]; rootDir?: string }) {
super(options);
this.denyPrefixes = denyPrefixes.map(p => p.endsWith("/") ? p : p + "/");
}
async write(filePath: string, content: string): Promise {
if (this.denyPrefixes.some(p => filePath.startsWith(p))) {
return { error: `Writes are not allowed under ${filePath}` };
}
return super.write(filePath, content);
}
async edit(filePath: string, oldString: string, newString: string, replaceAll = false): Promise {
if (this.denyPrefixes.some(p => filePath.startsWith(p))) {
return { error: `Edits are not allowed under ${filePath}` };
}
return super.edit(filePath, oldString, newString, replaceAll);
}
}
通用包装器(适用于任何后端):
type BackendProtocolV2,
type LsResult,
type ReadResult,
type ReadRawResult,
type GrepResult,
type GlobResult,
type WriteResult,
type EditResult,
} from "deepagents";
class PolicyWrapper implements BackendProtocolV2 {
private denyPrefixes: string[];
constructor(private inner: BackendProtocolV2, denyPrefixes: string[] = []) {
this.denyPrefixes = denyPrefixes.map(p => p.endsWith("/") ? p : p + "/");
}
private isDenied(path: string): boolean {
return this.denyPrefixes.some(p => path.startsWith(p));
}
ls(path: string): Promise { return this.inner.ls(path); }
read(filePath: string, offset?: number, limit?: number): Promise { return this.inner.read(filePath, offset, limit); }
readRaw(filePath: string): Promise { return this.inner.readRaw(filePath); }
grep(pattern: string, path?: string | null, glob?: string | null): Promise { return this.inner.grep(pattern, path, glob); }
glob(pattern: string, path?: string): Promise { return this.inner.glob(pattern, path); }
async write(filePath: string, content: string): Promise {
if (this.isDenied(filePath)) return { error: `Writes are not allowed under ${filePath}` };
return this.inner.write(filePath, content);
}
async edit(filePath: string, oldString: string, newString: string, replaceAll = false): Promise {
if (this.isDenied(filePath)) return { error: `Edits are not allowed under ${filePath}` };
return this.inner.edit(filePath, oldString, newString, replaceAll);
}
}
多模态和二进制文件
V2 后端原生支持二进制文件。当 read() 遇到二进制文件(根据文件扩展名确定 MIME 类型)时,它返回一个 ReadResult 包含 Uint8Array 内容和相应的 mimeType。文本文件返回 string content.
支持的 MIME 类型
| 类别 | 扩展名 | MIME 类型 |
|---|---|---|
| 图片 | .png, .jpg/.jpeg, .gif, .webp, .svg, .heic, .heif | image/png, image/jpeg, image/gif, image/webp, image/svg+xml, image/heic, image/heif |
| 音频 | .mp3, .wav, .aiff, .aac, .ogg, .flac | audio/mpeg, audio/wav, audio/aiff, audio/aac, audio/ogg, audio/flac |
| 视频 | .mp4, .webm, .mpeg/.mpg, .mov, .avi, .flv, .wmv, .3gpp | video/mp4, video/webm, video/mpeg, video/quicktime, video/x-msvideo, video/x-flv, video/x-ms-wmv, video/3gpp |
| 文档 | .pdf, .ppt, .pptx | application/pdf, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation |
| 文本 | .txt, .html, .json, .js, .ts, .py等。 | text/plain, text/html, application/json等。 |
读取二进制文件
const result = await backend.read("/workspace/screenshot.png");
if (result.error) {
console.error(result.error);
} else if (result.content instanceof Uint8Array) {
// Binary file — content is Uint8Array, mimeType is set
console.log(`Binary file: ${result.mimeType}`); // "image/png"
} else {
// Text file — content is string
console.log(`Text file: ${result.mimeType}`); // "text/plain"
}
FileData 格式
FileData 是在状态和存储后端中存储文件内容所使用的类型。
type FileData =
// Current format (v2)
| {
content: string | Uint8Array; // string for text, Uint8Array for binary
mimeType: string; // e.g. "text/plain", "image/png"
created_at: string; // ISO 8601 timestamp
modified_at: string; // ISO 8601 timestamp
}
// Legacy format (v1)
| {
content: string[]; // array of lines
created_at: string; // ISO 8601 timestamp
modified_at: string; // ISO 8601 timestamp
};
后端在从状态或存储读取时可能会遇到任一格式。框架透明处理两者。新写入默认为 v2 格式。在需要旧格式读取器的滚动部署中,传递 fileFormat: "v1" 给后端构造函数(例如, new StoreBackend({ fileFormat: "v1" })).
从后端工厂迁移
以前,像 StateBackend 和 StoreBackend 这样的后端需要一个接收运行时对象的工厂函数,因为它们需要运行时上下文(状态、存储)才能操作。后端现在通过 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
| 已弃用 | 替代方案 |
|---|---|
BackendFactory 类型 | 直接传递后端实例 |
BackendRuntime 接口 | 后端内部解析上下文 |
StateBackend(runtime, options?) 构造函数重载 | new StateBackend(options?) |
StoreBackend(stateAndStore, options?) 构造函数重载 | new StoreBackend(options?) |
filesUpdate 字段于 WriteResult 和 EditResult | 状态写入现在由后端内部处理 |
迁移示例
// Before (deprecated)
const agent = createDeepAgent({
backend: (config) => new CompositeBackend(
new StateBackend(config),
{ "/memories/": new StoreBackend(config, {
namespace: (rt) => [rt.serverInfo.user.identity],
}) },
),
});
// After
const agent = createDeepAgent({
backend: new CompositeBackend(
new StateBackend(),
{ "/memories/": new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}) },
),
});
从迁移 BackendContext
In 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的方案。命名空间信息应该是只读的,在运行期间保持稳定,而状态是可变的且每步都会变化——从中派生命名空间可能导致数据最终出现在不一致的键下。如果您有需要读取代理状态的使用场景,请 提交问题.
// Before (deprecated, removed in v0.7)
new StoreBackend({
namespace: (ctx) => [ctx.runtime.context.userId], // [!code --]
});
// After
new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity], // [!code ++]
});
协议参考
后端必须实现 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 - 强制 old_string 的唯一性,除非 replace_all=True。如未找到,返回错误。成功时包含 occurrences 。
支持的类型: - LsResult(error, entries) — entries is a list[FileInfo] 成功时, None 失败时。 - ReadResult(error, file_data) — file_data is a FileData 成功时返回字典, None 失败时。 - GrepResult(error, matches) — matches is a list[GrepMatch] 成功时, None 失败时。 - GlobResult(error, matches) — matches is a 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" or "base64"), created_at, modified_at. :::
后端实现 BackendProtocolV2。所有查询方法返回带有结构化结果的 Result 对象,并 { error?: string, ...data }.
必需方法
- - **
ls(path: string) → LsResult** - - 列出指定目录中的文件和目录(非递归)。目录在路径末尾有
/,并且is_dir=true。包含is_dir,size,modified_at(如果有)。 - - **
read(filePath: string, offset?: number, limit?: number) → ReadResult** - - Read file content. For text files, content is paginated by line offset/limit (default offset 0, limit 500). For binary files, the full raw
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 模式匹配的文件作为
FileInfoentries. - - **
write(filePath: string, content: string) → WriteResult** - - 仅创建语义。冲突时,返回
{ error: "..." }。成功时,设置path,对于状态后端设置filesUpdate={...};外部后端应使用filesUpdate=null. - - **
edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean) → EditResult** - - 强制
oldString的唯一性,除非replaceAll=true。如果未找到,返回错误。成功时包含occurrences。
可选方法
- - **
uploadFiles(files: Array<[string, Uint8Array]>) → FileUploadResponse[]** — 上传多个文件(用于沙箱后端)。 - - **
downloadFiles(paths: string[]) → FileDownloadResponse[]** — 下载多个文件(用于沙箱后端)。
结果类型
| 类型 | 成功字段 | 错误字段 |
|---|---|---|
ReadResult | `content?: string \ | Uint8Array, mimeType?: string` |
ReadRawResult | data?: FileData | error |
LsResult | files?: FileInfo[] | error |
GlobResult | files?: FileInfo[] | error |
GrepResult | matches?: GrepMatch[] | error |
WriteResult | path?: string | error |
EditResult | path?: string, occurrences?: number | error |
支持类型
- - **
FileInfo** —path(必填),可选is_dir,size,modified_at. - - **
GrepMatch** —path,line(从 1 开始),text. - - **
FileData** — 带时间戳的文件内容。参见 FileData 格式.
沙箱扩展
SandboxBackendProtocolV2 扩展 BackendProtocolV2 with:
- - **
execute(command: string) → ExecuteResponse** — 在沙箱中运行 shell 命令。 - - **
readonly id: string** — 沙箱实例的唯一标识符。
将现有后端更新到 V2
Migration guide
方法重命名
| V1 方法 | V2 方法 | 返回类型变更 |
|---|---|---|
lsInfo(path) | ls(path) | FileInfo[] → LsResult |
read(filePath, offset, limit) | read(filePath, offset, limit) | string → ReadResult |
readRaw(filePath) | readRaw(filePath) | FileData → ReadRawResult |
grepRaw(pattern, path, glob) | grep(pattern, path, glob) | `GrepMatch[] \ |
globInfo(pattern, path) | glob(pattern, path) | FileInfo[] → GlobResult |
write(...) | write(...) | 未变更(WriteResult) |
edit(...) | edit(...) | 未变更(EditResult) |
类型重命名
| V1 类型 | V2 类型 |
|---|---|
BackendProtocol | BackendProtocolV2 |
SandboxBackendProtocol | SandboxBackendProtocolV2 |
适配工具
如果您有需要与 V2 专用代码一起使用的现有 V1 后端,请使用适配函数:
// Adapt a V1 backend to V2
const v2Backend = adaptBackendProtocol(v1Backend);
// Adapt a V1 sandbox to V2
const v2Sandbox = adaptSandboxProtocol(v1Sandbox);