Cloudflare发布Project Think,打造持久运行的AI代理
Cloudflare AI··作者 Kate Reznykova
关键信息
该SDK利用Cloudflare的Durable Objects实现状态持久化,通过Dynamic Workers支持动态代码在隔离环境中执行,并引入从工作区到浏览器沙箱的执行层级,确保任务安全模块化。
资讯摘要
Cloudflare的Project Think推出了一套强大的新框架,用于构建可长期运行的AI代理,能处理复杂的多步骤工作流。它解决了当前AI代理的关键局限:如绑定单一设备、空闲时成本高、需手动配置等,提供带崩溃恢复的持久执行、用于任务分解的子代理以及用于安全性的沙盒代码执行。系统基于Cloudflare全球边缘网络和Durable Objects构建,使代理能在会话间持久存在并按需唤醒。
这将代理从临时工具转变为类似基础设施的存在,实现低成本的企业级部署。开发者可直接使用预建原语或快速上手的Think基础类。

资讯正文
今天,我们推出了 Project Think:下一代 Agents SDK。
Project Think 是一套用于构建长期运行代理(持久执行、子代理、沙箱代码执行、持久会话)的新原语,以及一个经过明确设计的基类,将所有这些功能整合在一起。你可以使用这些原语构建完全符合需求的功能,也可以直接使用基类快速上手。
今年早些时候发生了一件事,改变了我们对人工智能的看法。像 Pi、OpenClaw、Claude Code 和 Codex 这样的工具证明了一个简单但强大的理念:如果让大型语言模型具备读取文件、编写代码、执行代码并记住所学内容的能力,你得到的就不只是一个开发者工具,而更像是一个通用助手。
这些编码代理不再只是写代码了。人们正在用它们管理日历、分析数据集、协商采购、报税,甚至自动化整个业务流程。其模式始终如一:代理读取上下文,进行推理,编写代码来采取行动,观察结果,并迭代改进。代码是行动的通用媒介。
我们的团队每天都在使用这些编码代理。但我们不断遇到同样的障碍:
它们只能在你的笔记本电脑或昂贵的虚拟私有服务器(VPS)上运行:无法共享,无法协作,也无法在设备之间交接任务。
闲置时成本高昂:无论代理是否工作,都要支付固定的月费。扩展到团队或公司规模时,费用迅速累积。
需要人工管理和手动配置:安装依赖项、管理更新、配置身份和密钥。
还有一个更深层次的结构性问题。传统应用程序从单个实例服务多个用户。正如我们在《欢迎来到代理周》中提到的那样,代理是一对一的。每个代理都是一个独立实例,服务于一位用户,执行一项任务。餐厅有一份菜单和一个优化为批量制作菜肴的厨房;而代理更像是私人厨师:每次使用的食材、技巧和工具都不同。
这从根本上改变了扩展逻辑。如果一亿名知识工作者每人仅以适度并发使用一个代理助手,你就需要支持数千万个同时会话的容量。按当前每个容器的成本计算,这是不可持续的。我们需要一个全新的基础架构。
这正是我们一直在构建的内容。
推出 Project Think
Project Think 为 Agents SDK 提供了一套新的原语:
持久执行:通过纤程实现崩溃恢复、检查点和自动保持连接
子代理:具有独立 SQLite 数据库和类型化 RPC 的隔离子代理
持久会话:树状结构消息、分叉、压缩和全文搜索
沙箱代码执行:动态 Worker、代码模式、运行时 npm 解析
执行层级:工作区、隔离环境、npm、浏览器、沙箱
自动生成扩展:代理可在运行时自行编写工具
以上每项功能都可以直接与 Agent 基类一起使用。你可以用原语构建所需的一切,也可以使用 Think 基类快速起步。让我们逐一看看每个功能的作用。
当前的智能体(Agents)本质上是短暂存在的。它们仅在一次会话中运行,与单一进程或设备绑定,随后便消失。一个在笔记本电脑休眠时就终止的编码智能体,只是一个工具;而一个能够持久存在——可按需唤醒、在中断后继续工作,并且不依赖本地运行环境来保持状态的智能体——开始呈现出基础设施的特征。这彻底改变了智能体的扩展模型。
Agents SDK 基于 Durable Objects 构建,为每个智能体赋予唯一身份、持久化状态,并支持消息触发唤醒功能。这就是所谓的“Actor 模型”:每个智能体都是一个可寻址实体,拥有自己的 SQLite 数据库。当处于休眠状态时,它消耗零计算资源。当某个事件发生(如 HTTP 请求、WebSocket 消息、定时警报或传入邮件)时,平台会唤醒该智能体,加载其状态,并将事件传递给它。智能体完成任务后,再次进入睡眠状态。
| 虚拟机 / 容器 | Durable Objects |
| 空闲成本 | 始终占用完整计算资源 | 零(休眠状态) |
| 扩展方式 | 手动配置和管理容量 | 按每个智能体自动扩展 |
| 状态存储 | 需要外部数据库 | 内置 SQLite |
| 故障恢复 | 自行构建(如进程管理器、健康检查) | 平台重启后自动恢复,状态保留 |
| 身份/路由 | 自行构建(如负载均衡器、粘性会话) | 内置(名称 → 智能体) |
假设我们有 10,000 个智能体,每个智能体活跃时间仅占 1%,那么:
- 使用虚拟机/容器方案需要维持 10,000 个始终在线实例;
- 使用 Durable Objects 方案则最多只有约 100 个智能体同时活跃。
这种变化显著降低了大规模运行智能体的成本。不再需要“每位高级用户配备一个昂贵的智能体”,而是可以实现“每位客户一个智能体”、“每项任务一个智能体”或“每封邮件线程一个智能体”。新增一个智能体的边际成本几乎为零。
应对崩溃:通过纤程(fibers)实现持久执行
调用大语言模型(LLM)可能耗时 30 秒,一个多轮交互的智能体循环甚至可能持续更长时间。在此期间的任意时刻,执行环境都可能突然消失:部署更新、平台重启、达到资源上限等。此时上游模型提供商的连接会被永久切断,内存中的状态丢失,客户端看到的数据流戛然而止,毫无解释。
runFiber() 解决了这个问题。纤程是一种持久化的函数调用:在执行前注册到 SQLite 中,可以通过 stash() 在任意节点进行快照保存,也可通过 onFiberRecovered 回调在重启后恢复执行。
import { Agent } from "agents";
export class ResearchAgent extends Agent {
async startResearch(topic: string) {
void this.runFiber("research", async (ctx) => {
const findings = [];
for (let i = 0; i < 10; i++) {
const result = await this.callLLM(`Research step ${i}: ${topic}`);
findings.push(result);
// 快照点:如果被驱逐,我们将从这里恢复
ctx.stash({ findings, step: i, topic });
this.broadcast({ type: "progress", step: i });
}
return { findings };
});
}
async onFiberRecovered(ctx) {
if (ctx.name === "research" && ctx.snapshot) {
const { topic } = ctx.snapshot;
await this.startResearch(topic);
}
}
}
SDK 会在纤维执行期间自动保持代理活跃,无需特殊配置。对于以分钟为单位的任务,使用 keepAlive() 或 keepAliveWhile() 可防止在工作过程中被驱逐;对于更长时间的操作(如 CI 管道、设计评审或视频生成),代理会启动任务、保存作业 ID、进入休眠状态,并在回调时唤醒。
委托任务:通过 Facets 使用子代理
单一代理不应承担所有工作。
子代理是与父代理共置的 Durable Object,它们通过 Facets 实现,每个子代理都有独立的 SQLite 数据库和执行环境:
import { Agent } from "agents";
export class ResearchAgent extends Agent {
async search(query: string) { /* ... */ }
}
export class ReviewAgent extends Agent {
async analyze(query: string) { /* ... */ }
}
export class Orchestrator extends Agent {
async handleTask(task: string) {
const researcher = await this.subAgent(ResearchAgent, "research");
const reviewer = await this.subAgent(ReviewAgent, "review");
const [research, review] = await Promise.all([
researcher.search(task),
reviewer.analyze(task)
]);
return this.synthesize(research, review);
}
}
子代理在存储层面彼此隔离。每个子代理拥有自己的 SQLite 数据库,且它们之间不会隐式共享数据。这种隔离由运行时强制执行,因为子代理之间的 RPC 调用本质上就是函数调用。TypeScript 会在编译时捕获误用情况。
持久化对话:Session API
运行数天甚至数周的代理需要的不只是普通的消息列表。实验性的 Session API 明确建模了这一点。该 API 可直接在 Agent 基类中使用,对话以树形结构存储,每条消息都有一个 parent_id。这支持分叉(探索替代路径而不丢失原始路径)、非破坏性压缩(对旧消息进行摘要而非删除),以及通过 FTS5 在整个对话历史中实现全文搜索。
import { Agent } from "agents";
import { Session, SessionManager } from "agents/experimental/memory/session";
export class MyAgent extends Agent {
sessions = SessionManager.create(this);
async onStart() {
const session = this.sessions.create("main");
const history = session.getHistory();
const forked = this.sessions.fork(session.id, messageId, "alternative-approach");
}
}
Session 可直接与 Agent 配合使用,它是 Think 基类所构建的存储层。
从工具调用到代码执行
传统的工具调用方式存在明显缺陷。模型调用一个工具,将结果拉回上下文窗口,再调用另一个工具,如此反复。随着工具数量增加,这种方式变得既昂贵又笨拙。一百个文件意味着要经过一百次往返模型处理。
但模型写代码来操作系统的效率,远高于玩工具调用的游戏。
这就是 @cloudflare/codemode 的核心洞察:不是顺序调用多个工具,而是让大语言模型编写一个完整的程序来完成整个任务。
// LLM 编写的代码,它将在沙箱化的动态 Worker 中运行。
const files = await tools.find({ pattern: "**/*.ts" });
const results = [];
for (const file of files) {
const content = await tools.read({ path: file });
if (content.includes("TODO")) {
results.push({ file, todos: content.match(/\/\/ TODO:.*/g) });
}
return results;
与其进行100次模型调用,你只需运行一个程序。这减少了使用的token数量,执行速度更快,结果也更好。
Cloudflare API MCP服务器展示了这种模式的规模化应用。我们只暴露两个工具:search()和execute(),它们总共消耗约1000个token,而如果采用每个端点对应一个工具的朴素方式,则需要约117万个token。这是99.9%的减少。
缺失的原语:安全沙箱
一旦你接受模型应该为用户编写代码,问题就变成了:这些代码在哪里运行?不是将来,也不是等产品团队把它变成路线图上的一个项目。而是现在,对这个用户,针对这个系统,在权限严格定义的情况下。
动态Workers(Dynamic Workers)就是这样的沙箱。它在运行时毫秒级地创建一个新的V8隔离环境,仅占用几MB内存。这比容器快大约100倍,内存效率最高可达100倍。你可以为每个请求都启动一个新的沙箱,运行一段代码,然后立即丢弃。
关键的设计选择是能力模型(capability model)。不是从一个通用机器开始再试图限制它的行为,而是Dynamic Workers从几乎没有任何默认权限(globalOutbound: null,无网络访问)出发,开发者通过绑定逐资源明确授予能力。我们从“如何阻止这个东西做太多事?”转变为“我们究竟希望它能做什么?”
这才是代理基础设施应有的正确问题。
执行层级
这种能力模型自然引出了一个计算环境的谱系,即所谓的执行层级(execution ladder),代理会根据需要逐步提升层级:
第0层是Workspace,这是一个由SQLite和R2支持的持久化虚拟文件系统。可以读取、写入、编辑、搜索、grep、diff。由@cloudflare/shell驱动。
第1层是动态Worker:LLM生成的JavaScript代码在一个无网络访问的沙箱隔离环境中运行。由@cloudflare/codemode驱动。
第2层增加了npm支持。@cloudflare/worker-bundler从注册表获取包,使用esbuild打包,并将结果加载到动态Worker中。代理可以写import { z } from "zod",它就能直接工作。
第3层是通过Cloudflare Browser Run提供的无头浏览器:导航、点击、提取内容、截图。当服务尚未通过MCP或API支持代理时特别有用。
第4层是一个配置好的Cloudflare Sandbox,里面包含了你的工具链、仓库和依赖项:git clone、npm test、cargo build,与Workspace双向同步。
核心设计原则是:代理在第0层单独就能发挥作用,每一层都是叠加式的。
用户可以在过程中逐步添加能力。
构建模块,而非框架
所有这些原语都可以作为独立包使用:
动态Workers
@cloudflare/codemode
@cloudflare/worker-bundler
以及@cloudflare/shell
(一个持久的文件系统和工具)都可以直接与Agent基类一起使用。你可以将它们组合起来,为任何代理提供工作区、代码执行和运行时包解析功能,而无需采用一种特定的框架。
平台
以下是Cloudflare上构建代理的完整技术栈:
能力
作用
由……驱动
每个代理的隔离性
每个代理都是独立的世界
Durable Objects(DO)
空闲时零成本
$0,直到代理被唤醒
DO休眠
持久状态
可查询、事务性的存储
DO SQLite
持久文件系统
即使重启也能保存的文件
工作区(SQLite + R2)
沙盒化代码执行
安全地运行LLM生成的代码
Dynamic Workers + @cloudflare/codemode
运行时依赖
import * from react 直接可用
@cloudflare/worker-bundler
网络自动化
浏览、导航、填写表单
Browser Run
完整的操作系统访问权限
git、编译器、测试运行器
沙盒环境
定时执行
主动式,不只是被动响应
DO Alarms + Fibers
实时流式传输
逐个令牌发送到任意客户端
WebSockets
外部工具
连接到任意工具服务器
MCP
代理协调
代理之间的类型化RPC
子代理(Facets)
模型访问
连接到LLM以驱动代理
AI Gateway + Workers AI(或自带模型)
这些组件都是基础模块。它们共同构成了一个全新的平台:任何人都可以在这里构建、部署并运行AI代理,其能力堪比你今天在本地机器上运行的那些代理,但具有无服务器、持久性和内置安全性。
Think基类
现在你已经了解了这些基本构件,让我们看看把它们全部连接在一起会发生什么。
Think是一个带有明确设计倾向的框架,它处理完整的聊天生命周期:代理循环、消息持久化、流式传输、工具执行、流恢复以及扩展功能。你只需专注于让你的代理与众不同的部分。
最简化的子类看起来像这样:
import { Think } from "@cloudflare/think";
import { createWorkersAI } from "workers-ai-provider";
export class MyAgent extends Think<Env> {
getModel() {
return createWorkersAI({ binding: this.env.AI })(
"@cf/moonshotai/kimi-k2.5"
);
}
}
这实际上就是你需要的一切,即可拥有一个具备流式传输、持久化、中断/取消、错误处理、可恢复流和内置工作区文件系统的聊天代理。通过 npx wrangler deploy 部署即可。
Think会为你做决策。当你需要更多控制权时,可以覆盖你关心的部分:
覆盖方法
用途
getModel()
返回要使用的 LanguageModel
getSystemPrompt()
系统提示词
getTools()
用于代理循环的兼容AI SDK的 ToolSet
maxSteps
每轮最多工具调用次数
configureSession()
上下文块、压缩、搜索、技能配置
Think内部会在每轮中运行完整的代理循环:它组装上下文(基础指令 + 工具描述 + 技能 + 记忆 + 对话历史),调用 streamText,执行工具调用(输出截断以防止上下文膨胀),追加结果,直到模型完成或达到步骤限制为止。每次轮次后所有消息都会被持久化。
生命周期钩子
Think 在每个对话回合的各个阶段都提供了钩子,而无需你掌控整个处理流程:
beforeTurn()
→ streamText()
→ beforeToolCall()
→ afterToolCall()
→ onStepFinish()
→ onChatResponse()
你可以切换到成本更低的模型进行后续对话,限制其可用工具,并在每轮对话中传入客户端上下文。同时,还可以记录每次工具调用到分析系统中,并在模型完成时自动触发一轮额外的后续对话,而无需替换 onChatMessage。
持久记忆与长对话
Think 基于 Session API 作为存储层,为你提供带有分支结构的消息树。
在此基础上,它通过 context blocks 添加了持久记忆功能。这些是模型可以读取和更新的系统提示结构化部分,并且即使在休眠状态下也能持续存在。
模型会看到“MEMORY(重要事实,请使用 set_context 更新)[42%,462/1100 tokens]”,并能主动记住信息。
configureSession(session: Session) {
return session
.withContext("soul", {
provider: { get: async () => "You are a helpful coding assistant." }
})
.withContext("memory", {
description: "Conversationally learned important facts.",
maxTokens: 2000
})
.withCachedPrompt();
}
会话非常灵活。你可以让一个代理运行多个对话,并对其进行分叉以尝试不同方向,而不会丢失原始内容。
随着上下文增长,Think 使用非破坏性压缩来处理限制:较旧的消息会被摘要而非删除,完整的历史记录仍保存在 SQLite 中。
内置搜索功能也已集成。利用 FTS5,你可以在单个会话内或跨所有会话查询对话历史。代理还能使用 search_context 工具搜索自己的过往记录。
完整的执行链条
Think 将整个执行链条整合为单一的 getTools() 方法:
import { Think } from "@cloudflare/think";
import { createWorkspaceTools } from "@cloudflare/think/tools/workspace";
import { createExecuteTool } from "@cloudflare/think/tools/execute";
import { createBrowserTools } from "@cloudflare/think/tools/browser";
import { createSandboxTools } from "@cloudflare/think/tools/sandbox";
import { createExtensionTools } from "@cloudflare/think/tools/extensions";
export class MyAgent extends Think<Env> {
extensionLoader = this.env.LOADER;
getModel() {
/* ... */
}
getTools() {
return {
execute: createExecuteTool({
tools: createWorkspaceTools(this.workspace),
loader: this.env.LOADER
}),
...createBrowserTools(this.env.BROWSER),
...createSandboxTools(this.env.SANDBOX), // per-agent 配置:工具链、仓库、快照
...createExtensionTools({ manager: this.extensionManager! }),
...this.extensionManager!.getTools()
};
}
}
自定义扩展
Think 进一步推进代码执行能力。代理可以编写自己的扩展:运行在 Dynamic Workers 中的 TypeScript 程序,声明网络访问和工作区操作权限。
{
"name": "github",
"description": "GitHub 集成:PR、问题、仓库",
"tools": ["create_pr", "list_issues", "review_pr"],
"permissions": {
"network": ["api.github.com"]
}
}
workspace: "read-write"
}
}
Think 的 ExtensionManager 将扩展(可选地通过 @cloudflare/worker-bundler 包含 npm 依赖项)打包,加载到动态 Worker 中,并注册新的工具。该扩展会持久保存在 DO 存储中,即使在休眠状态下也能保留。当用户下次询问关于拉取请求的问题时,代理已经拥有了一个 30 秒前还不存在的 github_create_pr 工具。
这种自我改进循环才是让代理随着时间推移真正变得更实用的关键——不是通过微调或基于人类反馈的强化学习(RLHF),而是通过代码实现。代理能够在沙箱环境中编写自己的新功能,这些功能都是可审计且可撤销的 TypeScript 代码。
子代理 RPC
Think 还可以作为子代理运行,通过父代理调用 chat() 方法并通过回调函数流式传输事件:
const researcher = await this.subAgent(ResearchSession, "research");
const result = await researcher.chat(`Research this: ${task}`, streamRelay);
每个子代理都有独立的对话树、记忆、工具和模型。父代理无需了解细节。
开始使用
Project Think 目前仍处于实验阶段。API 表面稳定,但未来几天和几周内将持续演进。我们已经在内部使用它构建自己的后台代理基础设施,并提前分享出来,以便你能够与我们一起开发。
npm install @cloudflare/think agents ai @cloudflare/shell zod workers-ai-provider
// src/server.ts
import { Think } from "@cloudflare/think";
import { createWorkersAI } from "workers-ai-provider";
import { routeAgentRequest } from "agents";
export class MyAgent extends Think<Env> {
getModel() {
return createWorkersAI({ binding: this.env.AI })(
"@cf/moonshotai/kimi-k2.5"
);
}
}
export default {
async fetch(request: Request, env: Env) {
return (
(await routeAgentRequest(request, env)) ||
new Response("Not found", { status: 404 })
);
}
} satisfies ExportedHandler<Env>;
// src/client.tsx
import { useAgent } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";
function Chat() {
const agent = useAgent({ agent: "MyAgent" });
const { messages, sendMessage, status } = useAgentChat({ agent });
// 渲染你的聊天界面
}
Think 使用与 @cloudflare/ai-chat 相同的 WebSocket 协议,因此现有的 UI 组件可以直接工作。如果你之前基于 AIChatAgent 开发过,客户端代码无需更改。
第三波浪潮
我们认为人工智能代理的发展经历了三个阶段:
第一波是聊天机器人。
它们无状态、被动响应且脆弱。每次对话都从头开始,没有记忆、没有工具,也无法采取行动。这使得它们适合回答问题,但也仅限于回答问题。
第二波是编程代理。
这些代理是有状态的、能使用工具的,例如 Pi、Claude Code、OpenClaw 和 Codex 等工具。这些代理可以读取代码库、编写代码、执行代码并迭代优化。它们证明了只要搭配合适的工具,大型语言模型就是通用机器,但它们运行在你的笔记本电脑上,仅供单个用户使用,且无法保证持久性。
现在我们正进入第三波:代理即基础设施。
持久、分布式的、结构安全的且无服务器的。这些智能体运行在互联网上,能够抵御故障,空闲时无需付费,并通过架构而非行为来强制执行安全措施。任何开发者都可以为任意数量的用户构建和部署这些智能体。
这就是我们正在押注的方向。
Agent SDK 已经为数千个生产环境中的智能体提供支持。借助 Project Think 及其引入的基础功能,我们正在补充缺失的关键组件,使这些智能体的能力得到显著提升:持久的工作空间、沙箱环境中的代码执行、持久的长时间任务、结构化安全机制、子智能体之间的协调能力,以及由智能体自主编写的扩展模块。
目前该功能已进入预览阶段。我们正与您一同开发,非常期待看到您(以及您的编程智能体)用它创造出什么成果。
Think 是 Cloudflare Agent SDK 的一部分,可通过 @cloudflare/think 获取。本文描述的功能仍处于预览阶段,API 可能会根据反馈进行调整。请查阅文档和示例以开始使用。
来源与参考
收录于 2026-04-16