eve — фреймворк от Vercel для агентов, которые живут в файлах
📂 Исходный код на GitHubФреймворк от 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