Задача: посадить на сайт консультанта, который продаёт, пока я сплю
У меня есть контентный портал с обзорами финансовых продуктов — статьи, сравнения, разборы условий. Трафик на такие страницы идёт из поиска с конкретным вопросом в голове: чем один продукт отличается от другого, какие условия, что выгоднее в моей ситуации. Часть этих вопросов повторяется из статьи в статью, и обычная страница отвечает на них плохо — либо ответ зарыт в середине текста, либо его вообще нет, потому что автор не предугадал именно эту формулировку вопроса.
Идея была не «добавить чат ради модного виджета», а поставить на сайт маркетинговый инструмент: AI-консультанта, который отвечает на частые вопросы по теме сайта здесь и сейчас, а не отправляет читателя листать статью до конца, и мягко подводит к целевому действию — переходу по партнёрскому офферу. По сути это ещё один канал воронки, работающий 24 часа в сутки без выходных.
Как устроена архитектура: без своего сервера
Соблазн в такой задаче — сразу думать в терминах «нужен бэкенд, база данных, сервер, который это всё крутит». Я решил не открывать этот путь вообще. Вся система — это две части:
- Фронт — лёгкий чат-виджет на сайте: поле ввода, история сообщений, ничего лишнего. Он не хранит никакой логики, кроме отправки вопроса пользователя на бэкенд и отображения ответа.
- Бэкенд — один Cloudflare Worker. Это serverless-функция: она не работает постоянно, а просыпается на каждый запрос, обрабатывает его и засыпает обратно. Никакого VPS, который нужно администрировать, обновлять и оплачивать за простой — платишь фактически за вызовы, а не за аренду железа.
Логика Worker-а простая до банальности, если разложить по шагам:
- Приём вопроса. Виджет отправляет в Worker текст вопроса пользователя обычным HTTP-запросом.
- Подмешивание контекста. Worker добавляет к вопросу системный промпт — в нём база знаний о продукте, тон общения и инструкция вести разговор к целевому действию, если это уместно.
- Проксирование к LLM. Собранный запрос уходит к языковой модели. Worker здесь — прослойка, а не источник интеллекта: весь «ум» ассистента находится в модели и в промпте, который в неё передаётся.
- Возврат ответа. Ответ модели идёт обратно в виджет и показывается пользователю как реплика чата.
Ни одного шага, где нужна своя база данных, свой сервер приложений или очередь задач. Вся сложность, которая обычно съедает недели на «поднять инфраструктуру», отсутствует по конструкции.
Ключевое решение: ключ живёт только на сервере
Здесь есть развилка, на которой спотыкаются почти все, кто впервые делает что-то подобное вайбкодингом. Есть два способа обратиться к LLM из чата на сайте: либо фронтенд сам напрямую стучится к API модели, либо между фронтом и моделью стоит прослойка.
Первый способ проще написать за пять минут — но он ломается на первом же принципе безопасности. Чтобы фронтенд мог вызвать API языковой модели, ему нужен API-ключ. А любой код, который выполняется в браузере, полностью виден пользователю: открыл вкладку «Инструменты разработчика», нашёл ключ в коде или в сетевом запросе — и вот уже чужой ключ работает на кого-то другого, счёт за использование модели приходит мне, а не автору кражи.
API-ключ LLM не должен попадать в браузер ни при каких обстоятельствах — ни в коде виджета, ни в переменной окружения, которая собирается во фронтенд-бандл. Единственное безопасное место для ключа — сервер, к которому у пользователя нет доступа на чтение. Cloudflare Worker для этого подходит идеально: ключ хранится в его серверных переменных окружения (secrets), Worker выполняется на стороне Cloudflare, а не в браузере посетителя, и единственное, что видит фронтенд — это уже готовый текстовый ответ. Это не деталь реализации, а условие, без которого проект вообще нельзя выпускать в прод.
Разница на уровне архитектуры выглядит так: фронт знает адрес Worker-а и ничего больше. Worker знает ключ, знает базу знаний и знает, как обратиться к модели. Пользователь физически не может добраться до секрета, потому что секрет никогда не покидает серверную среду.
Обновление знаний: без миграций и без БД
Второй практический вопрос — как ассистент «узнаёт» новое. У сайта с обзорами финансовых продуктов условия периодически меняются: тарифы, лимиты, акции. Обычный инстинкт — завести базу данных, админку для редактирования записей, API для чтения из этой базы во время ответа. Это рабочий путь, но избыточный для задачи такого размера.
Вместо этого база знаний — это просто текст внутри системного промпта, который Worker подмешивает к каждому запросу. Обновить знания ассистента значит:
- Открыть код Worker-а, найти системный промпт.
- Поправить или дополнить текст — добавить новый факт, убрать устаревшее условие, уточнить формулировку.
- Передеплоить Worker одной командой.
Всё. Не нужна отдельная база данных, не нужна миграция схемы, не нужен цикл «правка в админке → инвалидация кэша → проверка, что фронт подтянул новые данные». Правка текста и передеплой — это буквально пара минут, и всё это происходит на стороне сервера, ни разу не касаясь фронтенда и ни разу не выставляя ничего лишнего в браузер.
Скорость сборки: от идеи до прода за вечер
Вся система — фронтенд-виджет, Worker, системный промпт с базой знаний, логика проксирования к модели — собрана вайбкодингом за один вечер. Не потому что задача тривиальная сама по себе, а потому что архитектура выбрана правильно с самого начала: минимум движущихся частей, никакой инфраструктуры, которую нужно поднимать и поддерживать отдельно.
Каждая лишняя часть системы — это не только время на разработку, но и точка, которая может сломаться, устареть или создать дыру в безопасности. Чат-виджет плюс один Worker с ключом внутри — это ровно тот минимум, который нужен, чтобы задача была решена и при этом не оставляла после себя ничего, что придётся администрировать.
Результат и что переносится на другие проекты
Результат — консультант, который стоит на сайте постоянно, отвечает на частые вопросы посетителей по теме портала и там, где это уместно, ведёт разговор к переходу по партнёрскому офферу. Он не заменяет статьи, а работает как ещё один вход в воронку для тех, кто пришёл с конкретным вопросом и не хочет искать ответ по всему тексту.
Что из этого переносится на любой другой контентный проект:
- AI-чат на сайте не требует своего сервера — serverless-функция вроде Cloudflare Worker закрывает всю бэкенд-логику: приём запроса, подмешивание контекста, обращение к модели, возврат ответа.
- API-ключ модели живёт только на сервере и никогда не передаётся во фронтенд — это не опция, а обязательное условие безопасности для любого проекта, где чат обращается к платному API.
- База знаний ассистента может быть просто текстом в промпте, а не отдельной базой данных — для задачи «ответить на частые вопросы по продукту» это быстрее в разработке и проще в поддержке.
- При такой архитектуре весь проект — от идеи до рабочего прода — реально закрыть за один вечер вайбкодинга, без найма разработчика под бэкенд.
Если планируете похожий чат-консультант на своём сайте — начните с того же вопроса, с которого начал я: где будет жить API-ключ. Ответ «только на сервере, никогда в браузере» определяет всю остальную архитектуру и экономит недели работы над тем, чего вообще не должно было быть в проекте.