调研起点:vercel/eve · Cloudflare Think 官方文档
AI 参与说明(Agent:Codex):本文由 Codex 根据 Eve 已核验的固定提交源码、Cloudflare 官方文档与 Context7 检索资料辅助调研、撰写和校验,整理日期为 2026-10-08。Eve 对照基线为
0.73.0;Cloudflare 的 Think 仍处于 experimental,PiHarness 处于 beta,Sandboxes 按当前 1.0 文档讨论。运行记录:模型gpt-6.1-sol,reasoning effortultra,执行入口 Codex Desktop,提供方openai,运行记录中的 CLI 版本0.162.0-alpha.2(不代表桌面 App 版本)。
部署边界补充(2026-10-08,Agent:Codex):补充直接运行 Eve 与选择 Cloudflare 原生框架的区别,核对官方 Node self-hosting、Containers 持久化条件与社区 Cloudflare World 的版本。未执行 Eve 的 Cloudflare 部署。本次运行记录:模型
gpt-6.1-sol,reasoning effortultra,执行入口 Codex Desktop,提供方openai,运行记录中的 CLI 版本0.162.0-alpha.2(不代表桌面 App 版本)。
Cloudflare 有对标 Eve 的方案,最直接的是 Agents SDK 上的 Think。 普通工具型聊天可以从 Think 开始;需要持久业务步骤时接 Workflows,需要运行 Linux 程序时接 Sandboxes 的 Containers。并非每个 Agent 都需要把这些产品全部装上。
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| Agent harness | 智能体运行框架 | 管理模型、工具循环、会话与恢复的框架层 |
| Think | Think 框架 | Agents SDK 上层的聊天与工具执行框架 |
| Durable Object | 持久对象 | 一个可按名称定位、拥有持久存储的有状态运行实例 |
| Session | 会话 | 保存对话历史、上下文与分支的单元 |
| Fiber | 持久任务单元 | 保存任务元数据和恢复快照,由恢复处理逻辑继续执行 |
| Workflow | 持久工作流 | 把业务过程分成可保存结果、重试或等待事件的步骤 |
| Sandbox | 沙箱 | 执行不可信代码的隔离环境,能力取决于所选后端 |
| Workspace | 工作区 | Agent 操作的文件状态;不能据此推断存在 Linux 进程环境 |
最接近 Eve 的是 Think
Think provides an opinionated agent harness on top of the Agents SDK. AIChatAgent 主要负责聊天协议、消息持久化与流式传输;Think 进一步提供完整 Agent loop,开发者通过 getModel()、getSystemPrompt()、getTools() 和 configureSession() 配置行为。Think 与 AIChatAgent
这里已经有框架层的对应。区别在于编写接口:Eve 用 agent/instructions.md、tools/、skills/、channels/ 等目录约定发现能力;Think 主要通过 TypeScript class 的方法与配置组织能力。Think 支持 Agent Skills 和 Workspace 文件操作,但这不等于采用 Eve 的整套项目目录、编译与评估约定。Think configuration Eve Agent Files
| Eve 的能力 | Cloudflare 对应 | 使用边界 |
|---|---|---|
| 模型与工具循环 | Think + AI SDK;也可自定义 AIChatAgent | Think 接管默认循环;自定义模型流水线可选择 AIChatAgent |
| Session、历史与上下文 | Think Session + Durable Object SQLite | 可保存树状消息、context blocks、摘要和全文检索 |
| Durable Session 执行 | Think durable recovery;复杂业务接 Workflows | Think 的会话不会天然变成一个 Cloudflare Workflow |
| 文件与命令工具 | Think Workspace;Linux 执行接 Containers | 默认 bash 是 just-bash,不能运行任意 Linux 二进制 |
| Channels 与主动任务 | Think Channels / Messengers / Scheduled tasks | 浏览器 WebSocket、Chat SDK adapter 与渠道策略可以组合 |
| Subagents 与 Skills | sub-agent RPC、Agents as tools、Agent Skills | 子 Agent 能力和运行边界仍需由应用声明 |
| 模型网关 | AI Gateway;推理可选 Workers AI 或外部 provider | 网关管理模型请求,不负责 Session 或业务步骤恢复 |
Session 与 turn API 见 Think overview,渠道见 Channels,工具和 Skills 的组合见 Tools。Agents 可以调用外部模型,采用 Cloudflare 运行栈并不要求把所有模型换成 Workers AI。Using AI Models AI Gateway
渠道能力还应按具体 transport 验证:当前 voice / custom 的 out-of-band delivery 尚未接通,deliverNotice() 会抛错。Channels delivery Scheduled tasks 是 at-least-once,确定动作应以 occurrence key 去重;不能把定时调度当成副作用只执行一次的保证。Scheduled tasks
持久状态、聊天恢复与业务步骤分别解决什么
Eve 的一个 Session 对应一个 Workflow SDK durable workflow,模型和工具工作在 Step 边界推进。Cloudflare 的原生组织方式是先给 Agent 一个 Durable Object,在 SQLite 保存状态,再按任务性质选择恢复机制。Eve 的具体执行模型可参见项目研究。
flowchart TD
A["Web / Messenger / Scheduled task"] --> B["Think · Agents SDK"]
B --> C["Durable Object SQLite\nSession / Workspace / Submissions"]
B --> D["Model provider\nWorkers AI 或外部模型"]
B --> E["Tools / Skills / Subagents"]
E -. "持久业务步骤" .-> F["Cloudflare Workflows"]
E -. "Linux 程序" .-> G["Sandboxes · Containers"]
E -. "受控动态代码" .-> H["Dynamic Workers / Code Mode"]
图中的三个执行分支均按需要接入;AI Gateway 可位于模型请求路径上。
Persistent state does not automatically resume arbitrary JavaScript execution. 基础 Agents 的 runFiber() 保存任务记录,stash() 保存恢复快照;进程被驱逐后,原来的 closure 不会自动重放,应用要在 onFiberRecovered() 中明确如何从快照继续。业务异常也不会因为放入 fiber 就自动重试。Durable execution with fibers
Think 已为聊天轮次写好这层恢复逻辑。它默认把 WebSocket、sub-agent RPC、durable submission 等推理路径放入可恢复 fibers,保存 partial output,并在中断后 continuation 或 retry。恢复受尝试次数、无进展时限和工作量预算约束;未完成的工具调用默认修为错误结果,再继续会话,不保证原工具执行续跑。它恢复的是会话工作,不是把已断开的供应商网络连接原封不动接回去。Durable recovery
若任务是“抓取资料 → 分析 → 等待批准 → 发布报告”,每一步有独立结果、重试策略或外部事件,使用 Cloudflare Workflows 更合适。step.do() 保存步骤结果并支持重试;Agent 可以作为实时交互入口,Workflow 负责业务过程。Using Agents with Workflows
Think 还提供 @cloudflare/think/workflows 的 ThinkWorkflow:step.prompt() 在业务步骤中获得带 schema 的模型输出,step.do() 执行确定动作,Agent 通过 runWorkflow() 启动流程并注入身份。它把模型推理接到 Workflow 上,无须重新手写整套桥接逻辑。Think Workflows
step.prompt() 运行可调用工具的完整 agentic turn,再通过内部 final-answer 工具形成结构化结果。模型必须可靠支持 streaming forced tool calls,否则该步骤可能进入终态错误;不能把 schema 配置等同于任意模型都能返回有效结果。ThinkWorkflow behavior notes
需要 webhook 或 RPC 快速确认时,Think 的 runTurn({ mode: "submit", ... }) / submitMessages() 先持久接收,再异步执行,并可用 idempotencyKey 避免重复接收同一个 submission。Programmatic submissions
Submission 去重不等于外部写入只执行一次:支付、发信、创建 PR 等工具仍应使用业务幂等键。Rules of Workflows 关页后的 durable ACK 与恢复细节见聊天持久性专题。
Sandbox:默认 bash 与 Linux 执行不是同一层
Think 默认拥有 SQLite-backed Workspace,内置 read、write、edit、list 等文件工具。默认 bash 将 Workspace 挂到 just-bash 虚拟文件系统执行,禁用网络,再把文件修改写回 Workspace。它适合组合文件操作,不能据此认为 npm install、原生编译器或任意后台进程都可运行。Think built-in workspace tools
当前 Sandboxes 1.0 文档区分两个后端:
| 后端 | 适合的任务 | 与状态保存的关系 |
|---|---|---|
| Containers | 完整 Linux 环境、安装依赖、运行 CLI、Python 程序或长进程 | microVM 隔离;文件要按需求保存或备份 |
| Dynamic Workers | 动态执行 JS、Python、Wasm,并只暴露所需 API | Workers runtime 隔离,适合受控代码执行;不是完整 Linux 系统 |
Sandboxes 需要 Workers Paid plan;Containers 当前使用的 Durable Object scheduling policy 标记为 public beta。Sandboxes overview
Container snapshot 保存的是 writable root filesystem,不包含内存、正在运行的进程或 mounts。所以恢复文件后仍要重新启动程序;Workflow 或 Agent 的持久状态也不会自动保存容器进程。Snapshots 当前也处于 public beta。Save and restore a workspace
Code Mode 可让模型生成代码来组合工具,适合执行受控动态逻辑。它与 Linux Container 是不同的选项,不能因为名称里都有 code execution 就互相替代。Code Mode
可以直接把 Eve 部署到 Cloudflare 吗
Eve supports Node self-hosting; native Workers deployment needs separate integration work. Eve 的 Vercel 集成较完整,但 AI SDK / Workflow SDK 这类开源依赖不等于必须使用 Vercel 托管服务。模型可以直接调用 provider,认证可选择 JWT / generic OIDC 等方式,Sandbox 也提供 custom provider 接口。Eve self-hosting
| 部署范围 | 当前判断 | 主要条件 |
|---|---|---|
| Cloudflare 入口,外部 Node host 运行 Eve | 符合官方 self-hosting 路径 | 同时转发 /eve/ 和 /.well-known/workflow/,保留认证、streams 与持久状态 |
| Cloudflare Containers 运行 Eve Node server | 可按 self-hosting 评估;本文未部署验证 | Container 默认磁盘休眠后重置,须解决 Workflow 数据持久化,并选择或适配 Sandbox |
| Workers / Durable Objects 直接运行 Eve | 本次未找到 Eve 官方完整部署流程 | 适配 runtime、Workflow World、Bindings、调度及 Sandbox;不能只改 Nitro preset |
Nitro 已支持 Cloudflare presets,Workers 也有许多 Node.js APIs,但这两点不能证明整个 Eve runtime 已兼容。node:child_process 仍是 non-functional stub,Workers 的临时文件区也不能直接承担 Eve local World 的持久目录。Nitro Cloudflare Workers Node.js compatibility Workers filesystem Containers 则保留完整 Node 服务环境,但 filesystem snapshot 只是点时状态,不能自动保证每次 Workflow 写入均已持久保存。Containers persistence
Workflow SDK 的 Worlds 目录已有社区 @fantasticfour/world-cloudflare;截至 2026-10-08,它的 2.4.3 发布包依赖 @workflow/world 4.5.0,与 Eve 0.73.0 的 @workflow/world 5.0.2 存在主版本差异,目录还注明没有 E2E test data。它是值得评估的适配实现,不能据此把当前 Eve 标为已支持 Workers。Community Cloudflare World Published metadata Eve dependencies
需要保留 Eve 时,先验证 Node self-hosting、状态恢复和 Sandbox;需要直接使用 Workers / Durable Objects 的平台机制时,再选择 Think。完整依赖拆分、Docker-in-Docker 与 Self-Modification 边界,以及自托管验收步骤,见 Eve 项目研究的部署章节。Cloudflare Workflows 与 Workflow SDK 的执行 API 不同,二者也不能只通过替换 package 名称互换。
按任务选择最小组合
下面是本文基于已核验能力给出的工程建议。
| 目标 | 建议起点 | 验收依据 |
|---|---|---|
| 有工具和长期记忆的聊天助手 | Think + Durable Objects + 模型 provider | 同一 instance 重连后历史保留;工具结果正确;中断有终态 |
| 多渠道、定时主动工作的 Agent | 上述组合 + Channels / Messengers / Scheduled tasks | 相同身份与会话映射正确;重复 webhook 不重复接收 |
| 等人工输入的多步骤任务 | Think + Workflows | 已完成步骤不重复计算;等待后继续;外部写入幂等 |
| Coding Agent、安装依赖、执行 Linux 程序 | Think + Containers;文件按需持久化 | 冷启动后文件可恢复,程序重新启动,任务状态正确 |
| 已有 Pi 应用,希望接入 Durable Objects | 评估 PiHarness | 验证现有事件协议、工具权限与恢复行为的适配 |
PiHarness 是另一个当前官方支持的 harness,负责把 Pi Durable 接到 Durable Object SQLite 与唤醒机制。它处于 beta,Pi Durable 仍是 experimental;当前 Known limitations 包括工具调用尚无 approval / permission step,事件流也没有 resume cursor。单个模型请求超过 15 分钟可能中断,忽略 abort signal 的工具也会让 abort() 等待其返回。需要这些行为时,应先按实际契约选型。PiHarness
Eve 的 remote Self-Modification 包含修改源码并创建 Draft PR 的专门流程。在本次核验的 Think 文档中,没有找到与该流程完全相同的默认能力。Cloudflare 上可以组合 Workspace、执行后端、GitHub API 和发布流水线实现,但这部分仍是需要设计和验收的应用功能;具备文件写入工具不等于已经完成源码审查和部署闭环。
Eve 的文件约定、可自托管运行时和统一开发入口有独立价值;Cloudflare 原生方案则直接围绕 Workers、Durable Objects 和平台 Bindings 构建。如果部署目标已经确定为 Cloudflare,本文建议先验证 Think,而不是先把 Eve 的运行时整体移植过去。双方仍有实验性能力,最终选择应依据实际任务的恢复、工具执行和迁移测试。
最小 Think 服务端示例
下面给出 TypeScript Worker 核心,用一个确定性工具展示 Think 的配置方式。它是服务端示例,网页聊天界面可按官方 Getting started 接入;它不启动 Container,也不使用 Workflows。
本次验证环境为 Node.js 26.0.0、npm 11.12.1;安装基线为 Think 0.20.1、agents 0.27.0、AI SDK 7.0.133、workers-ai-provider 4.0.0 和 Zod 4.6.5。虽然官方概览同时介绍 AI SDK v6 / v7,当前这组 Think 与 provider 的 npm peer dependencies 要求 v7,应按锁定版本配套安装。Think package
npm install --save-exact @cloudflare/think@0.20.1 agents@0.27.0 \
@cloudflare/ai-chat@0.12.1 @cloudflare/shell@0.4.3 \
ai@7.0.133 workers-ai-provider@4.0.0 zod@4.6.5
npm install --save-dev --save-exact typescript@7.0.2 \
@cloudflare/workers-types@5.20261008.1 wrangler@4.148.0
sum_numbers.ts:
import { tool } from "ai";
import { z } from "zod";
export const sumNumbersInput = z.object({ a: z.number(), b: z.number() });
export const sumNumbersTool = tool({
description: "Add two numbers and return their sum.",
inputSchema: sumNumbersInput,
execute: async ({ a, b }) => ({ sum: a + b }),
});
worker.ts:
import { Think } from "@cloudflare/think";
import { routeAgentRequest } from "agents";
import type { ToolSet } from "ai";
import { createWorkersAI } from "workers-ai-provider";
import { sumNumbersTool } from "./sum_numbers";
interface Env {
AI: Ai;
Assistant: DurableObjectNamespace;
}
export class Assistant extends Think<Env> {
override workspaceBash = false;
override getModel() {
return createWorkersAI({ binding: this.env.AI })(
"@cf/moonshotai/kimi-k2.6",
);
}
override getTools(): ToolSet {
return { sum_numbers: sumNumbersTool };
}
}
export default {
async fetch(request: Request, env: Env) {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;
getTools() 的返回值与内置工具合并;workspaceBash = false 只关闭 Bash,其他 Workspace 工具仍然存在。因此这个示例不能被当成仅开放加法的工具权限清单。Tool merge order
wrangler.jsonc 注册模型 binding 与 SQLite-backed Durable Object:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "think-sum-example",
"main": "worker.ts",
"compatibility_date": "2026-10-08",
"compatibility_flags": ["nodejs_compat"],
"ai": { "binding": "AI" },
"durable_objects": {
"bindings": [{ "name": "Assistant", "class_name": "Assistant" }]
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["Assistant"] }]
}
tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["ES2022"],
"types": ["@cloudflare/workers-types"],
"strict": true,
"noEmit": true,
"skipLibCheck": true
},
"include": ["worker.ts", "sum_numbers.ts"]
}
使用 npx tsc 检查类型,使用 npx wrangler dev 启动开发入口。模型调用需要实际 Cloudflare 账户和 Workers AI 访问;网页端用 useAgent 定位稳定的 instance name,再用 useAgentChat 对话。Think Getting started
示例的路由适用于公开测试。涉及私有会话时,应在路由前校验身份和目标 instance 的访问权,不能把知道 instance name 当成授权。Agents routing authentication
本次严格 noEmit 类型检查通过;工具的 17 + 25 = 42、负数、零、小数计算及 string / NaN 输入拒绝均通过。没有执行真实模型、WebSocket、部署或 Durable Object 崩溃恢复,相关保证来自前文引用的官方契约。接入模型后还应确认实际轨迹出现 sum_numbers 调用和 { "sum": 42 },而不是只检查最终文字包含 42。
关联阅读
- Eve:文件约定、Durable Agent 与部署边界。
- Cloudflare Workflows:步骤、事件与恢复 API。
- Dynamic Workers、Containers 与 Sandbox 的关系:原有示例需结合其资料日期阅读,本文后端分类按当前 Sandboxes 1.0 文档。