eve — фреймворк от Vercel для агентов, которые живут в файлах

· 4 мин чтения
ai-agents framework typescript vercel tools
📂 Исходный код на GitHub

Фреймворк от Vercel для ИИ-агентов. Возможности агента описаны файлами в проекте: инструкции, инструменты, навыки, каналы и расписания. Сессии переживают перезапуски, есть изолированная песочница и встроенные проверки поведения.

eve — фреймворк от Vercel для агентов, которые живут в файлах

eve — фреймворк от Vercel для ИИ-агентов, у которых все возможности описаны обычными файлами проекта. Системный промпт — это markdown-файл, инструменты — это функции на TypeScript, расписание — это файл с cron-выражением. Никакого отдельного языка описания и никакой визуальной студии: обычный репозиторий, который можно читать, ревьюить и править руками.

Фреймворк написан на TypeScript, распространяется как npm-пакет eve и сейчас находится в статусе beta. Лицензия — Apache 2.0. Требуется Node.js 24 или новее.

Стоит сразу развести две вещи. eve — это не готовый агент, которого вы запускаете и общаетесь с ним. Это набор кирпичиков, из которых вы собираете своего агента. Агент, которого вы сделаете, будет отдельной программой в вашем проекте. Поэтому eve относится к фреймворкам для сборки агентов, а не к самим агентам.

Файловая структура вместо конфига

Типичный проект с агентом выглядит так:

my-agent/
└── agent/
    ├── agent.ts            # Optional: model and runtime config
    ├── instructions.md     # Required: the always-on system prompt
    ├── tools/              # Optional: typed functions the model can call
    │   └── get_weather.ts
    ├── skills/             # Optional: procedures loaded on demand
    │   └── plan_a_trip.md
    ├── channels/           # Optional: message channels (HTTP, Slack, Discord)
    │   └── slack.ts
    └── schedules/          # Optional: recurring cron jobs
        └── weekly_recap.ts

Разберём каталоги по очереди.

agent/instructions.md — единственный обязательный файл. Это системный промпт агента, который подмешивается в каждый вызов модели. Писать его нужно коротко: всё, что сюда попало, оплачивается на каждом запросе к модели.

agent/tools/ — функции, которые модель может вызвать. Имя файла становится именем инструмента, которое видит модель: agent/tools/get_weather.ts доступен как get_weather.

agent/skills/ — процедуры, которые модель подгружает сама, когда они понадобятся. О них подробно ниже.

agent/channels/ — каналы связи: HTTP, Slack, Discord, другие мессенджеры. Через них пользователь попадает к агенту.

agent/schedules/ — задачи по расписанию в формате cron.

Полная документация лежит на eve.dev/docs, а в репозитории есть карта документации, с которой удобно начать.

Быстрый старт

Создать новый проект с агентом:

npx eve@latest init my-agent

Команда создаёт каталог, ставит зависимости, инициализирует Git и открывает терминальный интерфейс.

Если нужна другая модель, передайте её идентификатор:

npx eve@latest init my-agent --model openai/gpt-5.6-terra

Если у вас уже есть проект, добавьте в него eve из корня:

cd myapp
npx eve@latest init .

Требуется Node.js 24 или новее. В терминале подключаете подписку ChatGPT, аккаунт Vercel или ключ API — Vercel AI Gateway, OpenAI или Anthropic. Проект Vercel для первого разговора не нужен. Подробности есть в Getting Started.

Минимальный агент

Замените agent/instructions.md на одну строку:

You are a concise weather demo assistant. Tell users that the weather data is mocked.

Добавьте инструмент погоды в agent/tools/get_weather.ts:

import { defineTool } from "eve/tools";
import { z } from "zod";

export default defineTool({
  description: "Return mock weather data for a city.",
  inputSchema: z.object({ city: z.string().min(1) }),
  async execute({ city }) {
    return { city, condition: "Sunny", temperatureF: 72 };
  },
});

Модель задаётся в agent/agent.ts:

import { defineAgent } from "eve";

export default defineAgent({
  model: "spacexai/grok-4.7",
});

Дальше запускаете npm run dev — и агент работает. Разбор устройства инструментов есть в документации по tools.

Сессии, которые переживают перезапуск

Главное отличие eve от многих других фреймворков — сессия здесь долговечная. Она может идти несколько дней и переживать перезапуск процесса и повторный деплой, причём вам не нужно ничего делать.

Работа раскладывается на три уровня:

Уровень Что это
Сессия весь разговор или задача, долговечная, живёт днями и недели
Ход одно сообщение пользователя и вся порождённая им работа
Шаг контрольная точка внутри хода, по умолчанию один вызов модели и следующие за ним вызовы инструментов

Каждая сессия выполняется как один долговечный процесс, построенный на открытом Workflow SDK. Если вы деплоите на Vercel, это Vercel Workflow. Локально и при самостоятельном хостинге используется локальный режим SDK: состояние процесса лежит на диске в .eve/.workflow-data. Подробное описание модели исполнения — в Execution Model and Durability.

Есть нюанс, о котором стоит знать заранее. Живая работа не переносится между деплоями. Если в момент нового релиза у сессии крутится ход, ждёт ответа человека или висит в очереди, она остаётся на прежнем деплое. Переехать может только «уснувшая» сессия, у которой вся работа завершена. Это осознанное ограничение: так состояние не теряется посреди процесса.

Навыки, которые модель подгружает сама

Навык — это процедура в формате SKILL.md. Отличие от инструкций в том, что модель не носит её в контексте постоянно. Фреймворк показывает модели только описание навыка, а полный текст подгружается, когда модель сама решает, что он нужен. В eve это называется load_skill.

Самый простой навык — плоский markdown-файл:

Use the weather tool before answering forecast or temperature questions.

Если нужны дополнительные файлы рядом, навык делают каталогом: SKILL.md плюс соседние references/, assets/, scripts/. У такого SKILL.md обязательно должно быть поле description во вводном блоке:

---
description: Research unfamiliar topics before answering with confidence.
---

When the task is novel or ambiguous, gather evidence first, then answer with the
key facts and the remaining uncertainty.

Описание здесь — не ярлык, а подсказка для маршрутизации. Его пишут как задачу, которая должна вызвать срабатывание: «используй, когда пользователю нужен релизный чек-лист». Формат совпадает со стандартом Agent Skills, так что навык, написанный под этот стандарт, переносится сюда как есть.

Когда markdown не хватает, навык пишут на TypeScript через defineSkill — так можно задать типизированные значения, сгенерировать содержимое и положить соседние файлы. Фреймворк сам соберёт из этого SKILL.md. Полное описание — в Skills.

Инструменты и согласование с человеком

Инструмент — это типизированное действие, которое агент может вызвать: сходить в API, выполнить запрос, записать файл. Схема входных данных проверяется до запуска кода, причём понимаются и Zod, и Standard Schema, и обычная JSON Schema.

Отдельная механика — согласование с человеком. Инструмент можно пометить политикой, и тогда он либо выполняется сразу, либо ставит запуск на паузу и ждёт решения живого человека. Помощники из eve/tools/approval дают четыре варианта: auto(), always(), once(), never().

import { defineTool } from "eve/tools";
import { auto } from "eve/tools/approval";
import { z } from "zod";

export default defineTool({
  description: "Refund a charge.",
  inputSchema: z.object({ tenantId: z.string(), chargeId: z.string(), amount: z.number() }),
  approval: auto(),
  async execute(input) {
    return refund(input);
  },
});

Одобрение закрывает ход, и сессия засыпает в состоянии session.waiting. Вопрос агента пользователю оставляет ход открытым. В обоих случаях ожидание долговечное: хоть секунды, хоть дни, а получив ответ, сессия продолжает с того же места. Подробности — в Human-in-the-Loop.

Подключение к внешним сервисам

Соединения (connections) нужны, когда возможности агента публикует чужой сервис, который вы не писали. Это может быть MCP-сервер — Linear, GitHub, склад — или любой HTTP API с описанием OpenAPI. Фреймворк сам находит удалённые инструменты, показывает их модели и берёт на себя авторизацию.

Модель никогда не видит адрес сервера и его учётные данные. Она находит инструменты через встроенный поиск connection_search и вызывает их по полному имени вида <соединение>__<инструмент>, например linear__list_issues. Токен подставляется в каждый исходящий запрос, кэшируется на шаг и не попадает в долговечное состояние. Детали — в Connections.

Каналы: как пользователь попадает к агенту

Канал — это прослойка между платформой и агентом. Она делает три вещи: превращает вход платформы в сообщение пользователя, хранит адрес, по которому переписка в этой платформе связана с текущей сессией, и решает, как и куда уйдёт ответ.

Дальше начинается самое приятное. После нормализации сообщения работает один и тот же агент независимо от того, откуда пришло сообщение. Инструментам и инструкциям не нужно знать про каналы.

Отдельно стоит политика обработки сообщений. По умолчанию действует turnPolicy: "steer": новое сообщение пользователя может перебить ещё не выданный ответ и продолжить тот же ход с поправкой. Уже выполненные инструменты при этом сохраняют результаты. Если каждый ход должен завершаться до начала следующего, поставьте turnPolicy: "queue". Подробнее — в Channels.

Под-агенты

Под-агент — это отдельный запуск, который берёт на себя независимую часть работы. Есть три способа.

Встроенный инструмент agent запускает копию корневого агента. Копия использует те же инструкции, соединения, авторизацию и песочницу, у неё свежая история диалога и чистое состояние, но нет доступа к самому инструменту agent. Это защита от бесконечного ветвления.

Объявленный локальный под-агент — это специалист со своим каталогом, своими инструкциями и своими инструментами. Он не наследует возможности родителя.

Удалённый агент — это отдельно развёрнутый экземпляр eve, в который можно делегировать работу между деплоями.

Любой вызов под-агента выполняется как задача: вызов сразу возвращает её идентификатор, ребёнок работает в фоне, а его финальный ответ приходит как результат задачи. Ход родителя при этом не заканчивается. Всё это описано в Subagents.

Расписания

Расписание запускает агента по своему времени, а не ждёт входящего сообщения. Это удобно для ежедневных дайджестов, синхронизации данных, уборки и проверок по таймеру.

У каждого расписания есть cron-выражение и ровно одно из двух: markdown с готовым промптом или run с функцией-обработчиком.

import { defineSchedule } from "eve/schedules";

export default defineSchedule({
  cron: "*/5 * * * *",
  markdown: "Pull open Linear issues and POST a summary to the metrics endpoint.",
});

Cron — стандартная строка из пяти полей с точностью до минуты. На Vercel каждое расписание становится Cron Job, и время считается в UTC. Режим eve dev расписания по cron не запускает. Подробнее — в Schedules.

Память между сессиями

eve разделяет две вещи, которые часто путают. defineState — это именованная ячейка долговечной памяти внутри сессии. Значения переживают границы шагов, падения и повторные деплои.

import { defineState } from "eve/context";

export const budget = defineState("my-agent.budget", () => ({ count: 0, cap: 25 }));

Дальше get() читает значение, а update() заменяет его. Объявлять ячейку нужно один раз на уровне модуля, а использовать можно из любого инструмента или обработчика.

Память между сессиями — отдельный механизм, memory. Вы объявляете слот файлом, выбираете, кому он принадлежит, и указываете провайдера, который занимается хранением и поиском. Перед каждым ходом eve просит провайдера вспомнить подходящий контекст, после хода — сохранить, что произошло. Провайдеров несколько: встроенный файловый, Supermemory, Upstash AgentKit и свои реализации. Подробности — в разделе Memory и в State.

Безопасность: два контура

Агент работает в двух средах, и между ними проходит граница доверия.

Среда приложения Песочница
Переменные окружения и секреты Есть Нет
Ваш код на Node.js Есть Нет
Сеть Без ограничений По политике
Файловая система Своя у приложения Изолированный /workspace

Среда приложения — доверенная сторона. Там живут ваши инструменты, вызовы модели, соединения, состояние и долговечное исполнение, доступны process.env и полный Node.js. На Vercel это Vercel Function.

Песочница — изолированная сторона. Модель выполняет там команды и читает файлы через встроенные инструменты bash, read_file и write_file. У неё своя файловая система /workspace, но нет ни переменных окружения, ни секретов, ни обратного пути в среду приложения. На Vercel это микро-ВМ Vercel Sandbox с изоляцией на уровне железа.

Пример из документации: вызов инструмента charge_card выполняется в среде приложения, читает process.env.STRIPE_KEY, ходит в Stripe и возвращает { ok: true }. Модель видит только { ok: true }. Ключ никогда не покидает доверенную сторону.

Есть и приём посложнее — передача учётных данных. Он даёт модели доступ с авторизацией прямо из песочницы. Например, git clone приватного репозитория работает, даже если для этой задачи у вас нет ни инструмента, ни соединения. Заголовки авторизации подставляет сетевой фильтр песочницы, поэтому секрет остаётся в среде приложения. Подробнее — в Security Model.

Обратите внимание на предупреждение из документации. Пока вы не настроите свои ограничения, агенты eve работают с вольно настроенными параметрами: инструменты могут выполняться без согласования с человеком, а сеть песочницы не обязана быть закрыта. Полагаться только на поведение модели нельзя.

Проверка поведения

eve поддерживает свои проверки, которые прогоняют агента по реальным сессиям и сравнивают результат с ожиданием. Файлы лежат в каталоге evals/ с расширением .eval.ts, путь к файлу и есть идентификатор проверки.

import { defineEval } from "eve/evals";
import { includes } from "eve/evals/expect";

export default defineEval({
  description: "Basic message and tool-usage coverage for the weather agent.",
  async test(t) {
    const turn = await t.send("What is the weather in Brooklyn?");
    t.succeeded();
    t.calledTool("get_weather");
    t.check(turn.message, includes("Sunny"));
  },
});

Тест поднимает настоящий сервер агента, общается с ним по тому же протоколу HTTP, который используют пользователи, и проверяет ответ. Это полезно: правка промпта или инструмента не проходит незамеченной. Подробности — в Evals.

Несколько агентов в одном проекте

Один агент — это каталог agent/ рядом с кодом приложения. Если агентов нужно несколько и к ним обращаются по отдельности, они складываются в рабочее пространство:

project/
├── package.json
├── agents/
│   ├── support/
│   │   ├── agent/
│   │   └── evals/
│   └── research/
│       ├── agent/
│       └── evals/
└── apps/
    └── web/

Создать такое рабочее пространство и запустить нужного агента:

npx eve@latest init operations --agents support,research
cd operations
npx eve dev --agent support

У участников такого рабочего пространства нет собственных package.json — если он есть, каталог выпадает из обнаружения. Зато у них общие зависимости, скрипты и деплой. Если агентам нужны независимые версии и отдельные циклы релизов, выносите их в отдельные пакеты. Схема описана в Project Structure.

Для кого это подходит

eve стоит посмотреть, если вы пишете агента, который живёт не один запрос, а сутками. Регулярные отчёты, поддержка в Slack, агент, который разбирает входящие и сам ставит задачи, — всё это как раз про долговечные сессии, контрольные точки и расписания.

Понятно и ограничение. Проект в статусе beta: и фреймворк, и API, и документация, и поведение могут измениться до выхода в стабильную версию. Это указано и в README, и в документации.

Что ещё стоит знать. Пакет eve включает свою документацию, поэтому агент может читать её локально из node_modules/eve/docs. В репозитории есть дополнительные расширения: @eve/code для работы с кодом, @eve/computer-use для управления рабочим столом в песочнице, @eve/catalog как единый источник описаний интеграций, адаптер ACP и расширения для самомодификации.

Участие в проекте открытое: инструкции по локальному запуску лежат в CONTRIBUTING.md, вопросы и обсуждения — в GitHub Discussions, правила поведения — в CODE_OF_CONDUCT.md. По вопросам безопасности действует отдельный порядок, описанный в SECURITY.md. Лицензия — Apache 2.0.

Источник: https://github.com/vercel/eve