Перейти к содержимому

Как я не выучил программирование, поймал шифровальщика и собрал Ai-платформу

Как я не выучил программирование, поймал шифровальщика и собрал AI-платформу

Я несколько раз пытался научиться программировать. В подростковом возрасте, позже - уже осознанно, с разными языками и курсами. Однажды даже добрался до Solidity. Но устойчивого результата не было: синтаксис быстро забывался, учебные упражнения казались оторванными от жизни, а перспектива несколько месяцев учиться ради гипотетического полезного приложения демотивировала.

При этом технические системы мне всегда были интересны. Я мог понять, как связаны сервисы, почему один интерфейс удобнее другого и где возникает проблема в пользовательском сценарии. Но перенести идею в рабочий код самостоятельно не получалось.

Перелом произошёл, когда я решил сделать PWA для личного учёта расходов, доходов, заправок и обслуживания автомобиля. Вместо курса по JavaScript я открыл нейросеть и описал словами, что должно происходить. Результат оказался неидеальным, но приложение заработало. Позже Gemini примерно за минуту собрала для меня простую HTML-игру. Тогда я впервые понял: начинать разработку можно не с синтаксиса, а с задачи, логики и интерфейса.

Разумеется, это не означает, что знания больше не нужны. Архитектура, безопасность, базы данных, тестирование и обслуживание никуда не исчезли. Просто изучать их я начал не последовательно по учебнику, а в тот момент, когда конкретная проблема возникала в собственном проекте.

Почему no-code тоже оказался программированием

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

В какой-то момент стало очевидно, что no-code не отменяет программирование. Он лишь меняет форму: вместо строк кода появляются блоки, параметры и стрелки между ними.

Тогда возникла идея убрать и этот уровень сложности. Пользователь должен описывать задачу обычным языком, а система - сама определять:

- какие инструменты потребуются;
- какие данные нужно уточнить;
- когда запускать процесс;
- куда отправлять результат;
- какие действия выполнять автоматически.

В середине июня появился первый коммит Agent Platform. Изначально это был небольшой эксперимент на локальном компьютере, но вскоре проекту стало тесно. Я перенёс его на первый VPS, полагая, что самая трудная часть уже позади.

Через несколько минут база данных на сервере исчезла.

Первый VPS и шифровальщик

Это оказался шифровальщик. К счастью, пользователей ещё не было, а данные были тестовыми, поэтому реальных потерь удалось избежать. Но урок оказался важнее самих файлов.

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

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

Что получилось собрать

К середине июля система уже включала несколько основных режимов работы.

1. Сообщение - ответ

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

2. Сообщение - сценарий

Здесь запрос превращается в автоматизацию. Пользователь может написать: "Каждый понедельник собирай новости по теме и отправляй краткое резюме в Telegram".

Система должна разобрать намерение, определить расписание, выбрать источники, сформировать последовательность действий, запросить недостающие параметры и сохранить готовый сценарий.

3. Триггер - результат

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

Главная сложность здесь заключается не в генерации текста, а в надёжном исполнении: нужно учитывать ошибки сервисов, повторные запуски, задержки, ограничения API и ситуации, когда часть шагов завершилась успешно, а часть - нет.

Как фраза превращается в автоматизацию

Чтобы естественный язык стал рабочим сценарием, система проходит несколько этапов:

1. выделяет намерение пользователя;
2. определяет необходимые действия;
3. проверяет, хватает ли входных данных;
4. предлагает или выбирает инструменты;
5. формирует структуру сценария;
6. просит подтверждение для потенциально опасных действий;
7. сохраняет автоматизацию;
8. запускает её вручную или по триггеру.

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

Память - не архив всей переписки

Сначала кажется логичным сохранять всю историю сообщений. На практике это быстро становится дорогим, медленным и неудобным решением. Большой контекст перегружает модель, а старые детали начинают мешать актуальной задаче.

Поэтому память лучше разделять на уровни:

- краткосрочный контекст текущего диалога;
- устойчивые пользовательские настройки;
- сведения о проектах и сценариях;
- результаты прошлых действий;
- технические журналы и ошибки.

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

PostgreSQL против Redis

Redis удобен для быстрых временных данных, блокировок, очередей и кэша. Но делать его единственным хранилищем состояния рискованно. Для пользователей, сценариев, истории запусков и настроек лучше использовать PostgreSQL.

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

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

Инструменты и изолированный sandbox

Агенту недостаточно уметь генерировать текст. Ему нужны инструменты: запросы к API, работа с файлами, обработка данных, уведомления и выполнение ограниченного кода.

Однако запускать сгенерированный код напрямую на основном сервере опасно. Для таких операций требуется изолированный sandbox с ограничениями по:

- доступу к файловой системе;
- сетевым соединениям;
- времени исполнения;
- потреблению памяти и CPU;
- доступным библиотекам;
- правам пользователя.

Даже безопасный на вид скрипт может удалить файлы, отправить данные наружу или создать бесконечный процесс. Изоляция должна быть предусмотрена архитектурой, а не добавлена после первой аварии.

Безопасность персональных данных

AI-платформа может работать с перепиской, документами, контактами и финансовой информацией. Поэтому нельзя бездумно передавать модели весь контекст.

Практичный подход - минимизация данных. Модели передаётся только то, что необходимо для конкретной операции. Секреты следует хранить отдельно, не вставлять в промпты и не записывать в обычные логи.

Также важно разделять права пользователя и права агента. Наличие токена не должно автоматически означать доступ ко всем данным аккаунта. Каждое действие должно проходить через проверку разрешений.

Бэкап, который не проверяли, не является бэкапом

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

Надёжная схема предполагает:

- регулярное автоматическое копирование;
- хранение копий отдельно от VPS;
- шифрование;
- ограничение доступа;
- контроль успешности создания;
- периодическое тестовое восстановление.

Последний пункт особенно важен. Только восстановление показывает, действительно ли резервная копия пригодна для работы.

Как проверять код, написанный нейросетью

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

- анализ зависимостей;
- проверку обработки ошибок;
- тестирование граничных случаев;
- поиск утечек секретов;
- проверку прав доступа;
- нагрузочные испытания;
- просмотр логики повторного запуска.

Полезно просить модель не только написать решение, но и объяснить риски, перечислить допущения и подготовить тесты. Однако финальная проверка всё равно остаётся за разработчиком или техническим специалистом.

Что означает "система держит 1500 запросов"

Такая формулировка сама по себе почти ничего не говорит. Нужно уточнить, о каких запросах идёт речь: коротких HTTP-вызовах, обращениях к модели, фоновых задачах или полных пользовательских сценариях.

Также важны:

- среднее и пиковое время ответа;
- доля ошибок;
- лимиты внешних API;
- размер входного контекста;
- объём памяти;
- количество одновременных пользователей;
- стоимость обработки.

Без этих параметров цифра производительности превращается в рекламное утверждение.

ИИ ошибался - и часто

Модель могла неправильно понять задачу, выбрать не тот инструмент, потерять часть контекста или сгенерировать код с незаметной логической ошибкой. Особенно опасны уверенные ответы, которые выглядят правдоподобно.

Поэтому в платформе нужны наблюдаемость и контроль:

- журнал решений агента;
- история вызовов инструментов;
- понятные сообщения об ошибках;
- повторные попытки с ограничением;
- ручная остановка сценария;
- уведомления о подозрительном поведении;
- возможность отката изменений.

Пользователь должен видеть не только итог, но и понимать, что именно сделала система.

Три сценария для первого запуска

Чтобы не пытаться автоматизировать всё сразу, разумно начать с простых и полезных процессов:

1. Ежедневная сводка задач и напоминаний.
2. Сбор информации из нескольких источников с кратким резюме.
3. Обработка входящих сообщений с классификацией и уведомлением.

Такие сценарии позволяют проверить диалоговый интерфейс, память, расписание, интеграции и обработку ошибок без чрезмерного риска.

Что я понял в итоге

Я так и не стал классическим программистом в привычном смысле. Но научился формулировать задачи, проектировать системы, проверять решения и понимать, где нейросети можно доверять, а где необходим ручной контроль.

Главный результат - не сам интерфейс и не набор агентов. Важнее переход от идеи "модель напишет приложение" к более честной формуле: модель помогает собрать продукт, но архитектура, безопасность, данные и ответственность остаются на человеке.

AI действительно снижает порог входа в разработку. Однако он не отменяет инженерное мышление. Чем больше автономности получает система, тем важнее контроль, изоляция, резервное копирование и ясное понимание того, что происходит за каждым простым сообщением пользователя.

Прокрутить вверх