vercel/eve · Stars=1802 · 新项目

eve: 文件系统优先
的持久化 AI Agent 框架

eve 把 AI Agent 的核心能力(指令、工具、技能、连接、子 Agent、定时任务)全部表达为磁盘上的常规文件,让项目目录本身成为可编辑、可版本控制、可审计的 Authoring Interface。

⭐ 1802 TypeScript monorepo (pnpm workspaces) MIT Beta

# 架构总览

eve 是一个编译型框架:Authoring Layer(磁盘上的 agent/ 目录)→ Compiler(发现+验证+归一化)→ CompiledArtifact(version=29 的 CompiledAgentManifest)→ Runtime(Bootstrap + Harness 两阶段)。

┌─────────────────────────────────────────────────────────────────────────┐
│                     Authoring Layer (磁盘文件)                          │
│                                                                         │
│  my-agent/                                                               │
│  └── agent/                                                              │
│      ├── agent.ts       ← 模型配置(provider/routing/model)            │
│      ├── instructions.md← 系统提示(always-on)                          │
│      ├── tools/         ← TypeScript 工具定义(defineTool)              │
│      ├── skills/        ← Markdown 技能文件(按需加载)                  │
│      ├── channels/      ← HTTP/Slack/Discord 通道定义                   │
│      ├── schedules/     ← Cron 定时任务                                  │
│      ├── connections/   ← MCP/OpenAPI 连接配置                           │
│      └── subagents/     ← 子 Agent 目录                                 │
└─────────────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼ compileAgent()
┌─────────────────────────────────────────────────────────────────────────┐
│  Compiler (#compiler/*)                                                 │
│                                                                         │
│  discoverAgent()  →  ResolveDiscoveryProject → writeCompilerArtifacts()│
│  ├── discover-agent.ts    遍历 agent/ 目录,读取所有模块                 │
│  ├── normalize-*.ts       归一化:instructions / tools / skills /        │
│  │                         channels / connections / subagents / hooks    │
│  ├── compile-from-memory.ts 内存编译(dev server 路径)                  │
│  ├── compile-agent.ts     顶层 compileAgent() 入口                        │
│  └── manifest.ts          Zod 验证 + v29 CompiledAgentManifest schema    │
└─────────────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼ 写盘:.eve/artifacts/manifest.json
┌─────────────────────────────────────────────────────────────────────────┐
│  CompiledArtifact (version=29)                                          │
│                                                                         │
│  {                                                                        │
│    version: 29,                                                          │
│    kind: "eve-agent-compiled-manifest",                                  │
│    nodes: { __root__: { instructions, tools, channels, connections, ...} }│
│    edges: [ {parentNodeId, childNodeId} ],                               │
│    model: { id, routing: { kind:"gateway"|"external", ... } },          │
│    tools: [ { name, description, inputSchema, sourceRef } ],             │
│    channels, skills, schedules, sandbox, compaction, build               │
│  }                                                                        │
└─────────────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼ loadCompiledManifest()
┌─────────────────────────────────────────────────────────────────────────┐
│  Runtime (#runtime/*)                                                    │
│                                                                         │
│  ┌─ Bootstrap Runtime ──────────────────────────────────────────────┐    │
│  │ BOOTSTRAP_RUNTIME_MODEL_ID="eve-bootstrap-model"                  │    │
│  │ 仅用于冷启动阶段,真正模型由 resolveRuntimeModelReference() 决定    │    │
│  └──────────────────────────────────────────────────────────────────┘    │
│  ┌─ Authored Runtime ───────────────────────────────────────────────┐    │
│  │ resolve-model.ts → resolveRuntimeModelReference()                 │    │
│  │   1. resolveBootstrapRuntimeModel()  → bootstrap 模型             │    │
│  │   2. resolveMockAuthoredRuntimeModel() → 测试 mock                 │    │
│  │   3. loadSourceBackedRuntimeModelReference() → 源码模块中的模型    │    │
│  │   4. return reference.id (字符串,框架外部解析)                     │    │
│  └──────────────────────────────────────────────────────────────────┘    │
│                                                                         │
│  runtime/agent/      bootstrap.ts, resolve-model.ts, bootstrap-model.ts │
│  runtime/tools/      工具执行(动态工具 resolve-dynamic-tool.ts)         │
│  runtime/skills/     技能加载(按事件名称动态加载)                       │
│  runtime/channels/   HTTP/WebSocket/Slack/Discord 通道                  │
│  runtime/connections MCP / OpenAPI 连接                                 │
│  runtime/sandbox/    沙箱后端(local / vercel / local-just-bash)        │
│  runtime/schedules/  Cron 调度器                                        │
│  runtime/subagents/  子 Agent 生命周期管理                              │
│  runtime/workspace/  工作区资源(agent/sandbox/workspace/)             │
│  runtime/hooks/      钩子事件处理器                                     │
└─────────────────────────────────────────────────────────────────────────┘

核心设计原则

① 文件系统即创作界面:所有能力都是文件,无需特殊 SDK 或 DSL。

② 编译时验证:发现-诊断-归一化链路在启动前捕获所有错误。

③ Manifest 驱动:version=29 的 CompiledAgentManifest 是框架与运行时的唯一契约。

④ 多后端沙箱:local / vercel / local-just-bash 三种运行时后端。

与其他框架的差异

对比 OpenClaw:OpenClaw 以消息通道为核心,eve 以文件系统布局为核心。

对比 Kimi Code:Kimi Code 侧重多 Agent 编排;eve 侧重 Agent 项目的可维护性。

对比 OpenHands:OpenHands 以动作为核心;eve 以声明式配置为核心。


# 编译管道:compileAgent()

compile-agent.ts 是编译管道的顶层入口,串联了发现(discover)、验证(diagnostics)和归一化(normalize)三大阶段。

// packages/eve/src/compiler/compile-agent.ts
export async function compileAgent(input: CompileAgentInput = {}): Promise<CompileAgentResult> {
  // 1. 创建磁盘(或内存)项目源
  const source = input.source ?? createDiskProjectSource();

  // 2. 解析项目根目录,找到 agent/ 入口
  const project = await resolveDiscoveryProject(input.startPath, { source });

  // 3. 执行发现:遍历所有文件,归一化,收集诊断
  const discoveryResult = await discoverAgent({ ...project, source });

  // 4. 写编译产物(manifest.json + metadata)
  const writtenArtifacts = await writeCompilerArtifacts({
    appRoot:       project.appRoot,
    diagnostics:   discoveryResult.diagnostics,
    manifest:      discoveryResult.manifest,
  });

  // 5. 若发现错误,抛出 CompileAgentError(带完整诊断报告)
  if (hasDiscoverErrors(discoveryResult.diagnostics)) {
    throw new CompileAgentError(result);
  }

  return result;
}

dev server 使用 compile-from-memory.ts(内存编译),跳过磁盘写操作;生产构建使用完整 compileAgent() 写盘。

发现阶段(discover-*)

discover-agent.ts 递归遍历 agent/ 目录,识别 instructions.md、agent.ts、tools/、skills/、channels/、schedules/、connections/、subagents/ 等约定目录,按类型调用对应的 normalize 函数归一化为中间 Manifest 结构。

诊断系统

DiscoverDiagnostic 有三种 severity:error(阻止编译)、warning(警告但放行)、info(提示)。所有错误汇总在 .eve/artifacts/diagnostics.json 中,开发者可逐条修复后再编译。


# CompiledAgentManifest v29

manifest.ts 定义了完整的 Zod schema。v29 是当前版本,每次 schema 变更都会升级版本号,运行时会验证版本兼容性。

// manifest.ts — 核心类型(简化)

// 稳定 manifest 标记
export const COMPILED_AGENT_MANIFEST_KIND = "eve-agent-compiled-manifest";
export const COMPILED_AGENT_MANIFEST_VERSION = 29;

// 根节点 ID(__root__ 指向主 agent)
export const ROOT_COMPILED_AGENT_NODE_ID = "__root__";

// Model routing — 编译时决定,运行时无需再解析
type ModelRouting = { kind: "gateway", target: string, byok?: string }
                       | { kind: "external", provider: string };

// CompiledAgentManifest = 根节点 + 子节点图 + 边
// nodes["__root__"] 是主 agent,nodes["subagent-id"] 是子 agent
// edges 描述父子关系,用于拓扑排序和递归执行
type CompiledAgentManifest = {
  kind:    "eve-agent-compiled-manifest",
  version: 29,
  nodes: Record<string, CompiledAgentNodeManifest>,
  edges:  ReadonlyArray<{ parentNodeId: string; childNodeId: string }>,
  tools:   CompiledToolDefinition[],        // defineTool 归一化结果
  skills:  CompiledSkillDefinition[],        // Markdown / module / skill-package
  channels:CompiledChannelEntry[],           // HTTP/WebSocket/Slack/Discord
  schedules:CompiledScheduleDefinition[],     // Cron 任务
  connections: CompiledConnectionDefinition[],// MCP / OpenAPI
  sandbox: CompiledSandboxDefinition,
  build:   { externalDependencies?: string[] },
  compaction?: { model?: CompiledRuntimeModelReference; thresholdPercent?: number },
};
字段来源说明
versionmanifest.ts 常量当前=29,每次 schema 变更升级
kindmanifest.ts 常量用于运行时 schema 验证
nodesnormalize-subagent.ts主 agent + 所有子 agent 的归一化定义
edgesnormalize-subagent.ts父子关系边列表(拓扑排序用)
toolsnormalize-tool.tsdefineTool() 导出 + Zod inputSchema 验证
modelnormalize-agent-config.ts编译时解析 provider/routing 策略
channelsnormalize-channel.ts支持 GET/POST/PUT/PATCH/DELETE/WEBSOCKET
connectionsnormalize-connection.tsprotocol: "mcp" | "openapi",含 Vercel Connect 集成

# 运行时:Bootstrap + Authored

eve 的运行时分为 Bootstrap Runtime(仅用于冷启动)和 Authored Runtime(加载真实模型)。模型解析策略在 resolve-runtime-model-reference 中。

// packages/eve/src/runtime/agent/resolve-model.ts
export async function resolveRuntimeModelReference(
  reference: RuntimeModelReference,
  input: { compiledArtifactsSource?: RuntimeCompiledArtifactsSource }
): Promise<LanguageModel | string> {

  // 策略 1: Bootstrap 模型(框架自带的最小引导模型)
  const bootstrapModel = resolveBootstrapRuntimeModel(reference);
  if (bootstrapModel !== null) return bootstrapModel;

  // 策略 2: Mock 模型(测试/开发路径)
  const mockModel = resolveMockAuthoredRuntimeModel(reference);
  if (mockModel !== null) return mockModel;

  // 策略 3: 源码模块中的模型定义
  if (isSourceBackedRuntimeModelReference(reference)) {
    return await loadSourceBackedRuntimeModelReference(reference, input);
  }

  // 策略 4: 直接返回模型 ID(由框架外部的 AI SDK 解析)
  return reference.id;
}

两阶段引导

bootstrap.ts 定义了 BOOTSTRAP_RUNTIME_MODEL_ID = "eve-bootstrap-model",这是一个框架内置的最小引导模型,用于在开发者未配置真实模型时的初始化阶段。

真正的模型由 agent.ts 中的 defineAgent({ model: "anthropic/claude-sonnet-4.6" }) 指定,resolve-runtime-model-reference 在运行时解析该字符串为对应的 LanguageModel 实例。

Compaction(压缩)机制

CompiledAgentManifest 支持可选的 compaction 字段:配置一个独立的压缩模型和阈值百分比。当对话上下文超过阈值时,使用 compactionModel 对历史对话进行摘要压缩,释放上下文窗口。


# 文件系统即创作界面

eve 的核心理念:开发者通过目录结构声明 Agent 能力,而不是通过代码 API。

my-agent/
└── agent/
    ├── agent.ts           // defineAgent({ model, description, compaction, build })
    ├── instructions.md    // always-on 系统提示(Markdown)
    ├── tools/             // defineTool() TypeScript 模块
    │   └── get_weather.ts
    ├── skills/            // Markdown 技能文件,按事件名加载
    │   └── plan_a_trip.md
    ├── channels/          // HTTP / Slack / Discord 适配器
    │   └── slack.ts
    ├── schedules/         // Cron 定时任务
    │   └── weekly_recap.ts
    ├── connections/        // MCP / OpenAPI 连接(含 Vercel Connect 集成)
    │   └── linear.ts
    ├── subagents/          // 子 Agent 子目录(递归结构)
    │   └── planner/
    │       ├── agent.ts
    │       └── instructions.md
    └── sandbox/           // 沙箱配置 + workspace/ 初始文件
        └── workspace/

工具定义(normalize-tool.ts)

每个 agent/tools/*.ts 文件使用 defineTool() 导出工具。defineTool 接受 Zod inputSchema,编译器验证 execute 函数的参数与 schema 一致。

技能加载(normalize-skill.ts)

Markdown 技能文件(agent/skills/*.md)支持动态加载。运行时按事件名称(如 onToolCall、onTurnEnd)匹配并加载对应技能,技能内容作为 prompt 片段注入。

子 Agent(normalize-subagent.ts)

子 Agent 递归定义在 agent/subagents/*/ 下,每个子目录包含自己的 agent.ts + instructions.md + tools/。编译时生成 nodes 和 edges,运行时通过子 Agent 生命周期管理。


# 多后端沙箱

eve 的 sandbox/ 子系统抽象了三类执行后端。

后端backendName说明
local"local"本地进程隔离,通过 agent/sandbox/workspace/ 初始化工作目录
vercel"vercel"Vercel 平台沙箱,冷启动优化,serverless 函数模型
local-just-bash"local-just-bash"最小化后端,仅 bash 脚本执行,不启动完整 Node 运行时

Workspace 初始化

agent/sandbox/workspace/ 目录内容被序列化为 CompiledSandboxWorkspace(记录 rootEntries 和 sourcePath),在沙箱冷启动时挂载为工作目录,实现可重现的初始状态。


# 技术亮点

eve 区别于其他 Agent 框架的核心创新点。

① 版本化 Manifest 契约

version=29 的 CompiledAgentManifest 是框架与运行时的唯一契约。每次 schema 变更升级版本,运行时严格验证,开发者可见所有破坏性变更。

② 编译时全量诊断

发现-验证-归一化链路在 compileAgent() 中同步完成,所有错误和警告写入 diagnostics.json,开发者无需运行时调试就能修复配置问题。

③ 动态工具 & 技能

工具和技能支持动态解析:CompiledDynamicToolDefinition 和 CompiledDynamicSkillDefinition 携带事件名称数组(eventNames),运行时按事件触发懒加载。

④ Vercel Connect 集成

connections 支持 vercelConnect.connector 字段(OAuth UID 或 service-connector key),打通 Vercel Connect 平台的托管认证流。

⑤ 严格类型工具 Schema

每个 defineTool() 绑定 Zod inputSchema,编译器验证 execute 函数签名与 schema 一致,运行时类型安全。

⑥ 多后端统一抽象

SandboxDefiniton 的 backendName 在编译时捕获,运行时不分支——build 管道根据后端选择打包策略(是否包含 just-bash 引擎包)。