Подготовьте серверный TypeScript-проект
Проект простой, но пара решений в нём принципиальна. Примеры используют ESM, TypeScript и официальные SDK всех трёх провайдеров. Версии в книге не закреплены намеренно: перед установкой проверяйте release notes и держите реально проверенную сборку в lockfile - API-линейки меняются быстрее, чем продуктовая логика.
Ставится всё несколькими командами.
npm init -y
npm pkg set type=module
npm install openai @anthropic-ai/sdk @google/genai zod
npm install -D typescript tsx @types/nodeКлючи и модель живут в окружении, а не в коде. И модель - это конфигурация деплоя, а не константа домена: сегодня gpt-5.6, завтра другая, и менять её надо переменной, а не правкой исходников.
# .env.local, никогда не коммитьте этот файл
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...
GEMINI_API_KEY=...
# Модель является конфигурацией deploy, а не константой домена
OPENAI_MODEL=gpt-5.6
ANTHROPIC_MODEL=claude-sonnet-5
GOOGLE_MODEL=gemini-3.6-flashФайлы разложены так, чтобы пережить смену провайдера: контракт и runtime отдельно, провайдерские адаптеры отдельно, tools отдельно, endpoints и evals рядом.
src/
agent/
contracts.ts
prompt.ts
runner.ts
tool-registry.ts
providers/
openai.ts
anthropic.ts
google.ts
tools/
policy-search.ts
order-read.ts
refund-preview.ts
handoff-prepare.ts
api/
turn.ts
approve.ts
evals/
cases.ts
run.tsИ одно правило, нарушение которого стоит дороже всего.
Ключи только на сервере. Ни переменная с префиксом NEXT_PUBLIC_, ни клиентский fetch к provider API не подходят. Браузер обращается к вашему endpoint, где действуют session, limits и audit. Ключ, попавший в бандл, - это ключ, попавший всем.Проект готов - собираем его сердцевину. Начнём с контракта, который делает агента переносимым между тремя API.