Привет, Хабр!
Я фрилансер! ТГ-боты, бэкенды, AI-интеграции, с недавних пор embedded. В прошлой статье я показывал, как биржу залило вайб-кодерами и как просели цены на базовые проекты. Но там я говорил про цену. А есть вопрос следующий: а код-то у них рабочий? В смысле — рабочий по-настоящему, а не «вроде запускается».
Сразу дисклеймер: я каждый день работаю через Claude Code, я на них построил весь свой процесс. Именно поэтому мне интересно где у них системный предел.
И я внутри этого рынка, объективности не обещаю.
Вайб-кодер в чистой форме — человек, который вообще не имеет отношения к разработке — физически не способен оценить код. Для него работает = работает. А я утверждаю: код, сгенерированный нейронкой, всё равно будет более плоским, более ущербным и менее оптимальным, чем код живого разработчика. Проблема в том, как это доказать человеку, который код читать не умеет. Поэтому зайдём через аналогию, которую может проверить КАЖДЫЙ — через тексты.
Тексты от нейронки узнают уже все
Тут, я думаю, спорить никто не будет. Мы все научились чуять текст от нейросети. Эти бесконечные триколоны, «это не просто X — это Y», тяжёлые вводные конструкции, всё такое правильное, выверенное прямо по учебнику. Идеально и мёртво.
Да, хороший редактор с нейросетью сделает лучше. Но речь не о хорошем редакторе. Речь о человеке, который просит “напиши продающее описание” и принимает первый гладкий результат.
Откройте для себя мир кристально чистого звука с нашими беспроводными наушниками нового поколения. Это не просто наушники — это ваш персональный портал в безграничную вселенную музыки. Благодаря передовой технологии активного шумоподавления и эргономичному дизайну вы погрузитесь в любимые треки как никогда раньше. Идеальный выбор для тех, кто ценит качество, комфорт и стиль.
Текст грамматически безупречен и при этом абсолютно пустой. Он подходит под ЛЮБЫЕ наушники — не утверждает ничего проверяемого, не называет ни одной конкретной цифры, никого конкретного не представляет. Это водица, которую можно вылить на любой товар.
А что делает живой копирайтер? Он пишет конкретику, которую можно проверить: сколько часов держит зарядка, за сколько секунд коннектится, что слышно, а что нет. И — самое важное — он называет недостаток. Честный продающий текст почти всегда говорит, кому товар НЕ подойдёт, потому что это и есть доверие. Человек отказывается перехваливать, но нейронка не отказывает никогда.
В коде происходит ровно то же, просто это спрятано
Та же плоскость, те же повторяющиеся паттерны, одна и та же функция, переименованная пять раз. Тут всплывает асимметрия
В тексте посредственность видна демократически. Любой, кто много читал, носом чует нейронку. Плоскость текста легитимно замечают тысячи компетентных читателей.
В коде плоскость спрятана за зелёной галочкой тестов. Её видит ровно один человек — инженер, умеющий читать код. А вайб-кодер именно этого человека из процесса и убрал. То есть он купил не код, он купил видимость работающей системы и отдал наружу единственное суждение, которое сам выполнить не способен.
Я, кстати, уже писал про обратную сторону той же монеты — как Claude на неполном контексте уверенно «находил уязвимости», которых не было, потому что не видел систему целиком. Каждое его замечание было локально корректным и глобально неверным. Тут то же самое, только с другого конца: нейронка генерит локально корректный код, который глобально гнилой, а проверить это некому.
Примеры!
Методика такая. Сначала — настоящая функция из легендарного опенсорса, со ссылкой на файл, открывайте и проверяйте. Далее — то, что выдаёт НЕЙТРАЛЬНЫЙ чат с LLM на наивный промпт.
Важный момент, без которого эксперимент был бы жульничеством: промпт должен быть наивным — таким, какой реально способен сформулировать вайб-кодер, по конечной функции, без тайного знания о граничных случаях. Потому что — вот он, главный тезис — разрыв между кодом сеньора и кодом вайб-кодера, прогнанными через ОДИН И ТОТ ЖЕ LLM, это в основном разрыв в промпте. Несущие решения разработчика не попадают в промпт, потому что для него они очевидны, молчаливы, а вайб-кодер не может попросить то, о существовании чего не знает.
Три функции, специально расставленные по шкале видимости — от «это даже не-кодер увидит» до «это не видит почти никто».
1. secure_filename — видно глазами
Werkzeug, ядро Flask. Делает из имени файла безопасное имя для сохранения на диск.
def secure_filename(filename: str) -> str: filename = unicodedata.normalize("NFKD", filename) filename = filename.encode("ascii", "ignore").decode("ascii") for sep in os.sep, os.path.altsep: if sep: filename = filename.replace(sep, " ") filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip("._") # на nt в каждой папке есть спец-файлы устройств — нельзя, чтобы файл # назывался так же, иначе подставляем подчёркивание if ( os.name == "nt" and filename and filename.split(".")[0].upper() in _windows_device_files ): filename = f"_{filename}" return filename
А вот что выдаёт нейтральный чат на «сделай безопасное имя файла»:
def secure_filename(filename): filename = os.path.basename(filename) filename = filename.replace(" ", "_") filename = "".join(c for c in filename if c.isalnum() or c in "._-") return filename
Работает? Да конечно же! Демка отвечает, имя чистится. А теперь смотрим, что наивная версия пропустила, причём это видно глазами:
secure_filename("..")— настоящая вернёт пустую строку, наивная вернёт.., то есть ссылка на родительскую папку выживает.secure_filename("CON.txt")на Windows — настоящая даст_CON.txt, наивная оставитCON.txt, зарезервированное имя устройства.secure_filename("naïve.txt")— настоящая приведёт к ASCII (naive.txt, портируется везде), наивная оставит не-ASCII, потому чтоisalnum()пропускает юникод-буквы.
Даже вайб-кодер тут способен увидеть: наивная версия оставляет .., зарезервированные имена Windows и Unicode-поведение, о котором автор промпта просто не подумал.
2.lru_cache— середина шкалы
CPython, стандартная библиотека. Кэширующий декоратор. Полная реализация длинная, поэтому покажу не весь файл, а характерный кусок из lrucache_wrapper.
Полную реализацию не привожу целиком: она слишком длинная для статьи, но ссылка выше. Важно не запомнить все детали CPython, а увидеть разницу.
cache = {} lock = RLock() # because linkedlist updates aren't threadsafe root = [] # root of the circular doubly linked list root[:] = [root, root, None, None] def wrapper(*args, **kwds): # Size limited caching that tracks accesses by recency nonlocal root, hits, misses, full key = make_key(args, kwds, typed) with lock: link = cache_get(key) if link is not None: # Move the link to the front of the circular queue link_prev, link_next, _key, result = link link_prev[NEXT] = link_next link_next[PREV] = link_prev last = root[PREV] last[NEXT] = root[PREV] = link link[PREV] = last link[NEXT] = root hits += 1 return result misses += 1
То есть настоящая реализация — это не просто словарик. Там есть ограничение размера, вытеснение давно не использованных значений, потокобезопасность и аккуратное построение ключа, которое не сводится к склейке строк.
А наивный ответ на «напиши простой аналог lru_cache»:
def lru_cache(func): cache = {} def wrapper(*args, **kwargs): key = str(args) + str(kwargs) if key not in cache: cache[key] = func(*args, **kwargs) return cache[key] return wrapper
Что не так:
Это вообще не LRU. Нет ограничения размера, нет вытеснения — кэш растёт бесконечно. Назвали
lru_cache, а получили утечку памяти.Хрупкий ключ.
str(args)+str(kwargs): разные объекты могут иметь одинаковое строковое представление, и тогда вернётся чужой закэшированный результат.Не потокобезопасно. Под нагрузкой — гонки.
Это уже не дыра, которую видно глазами. Это деградация, которую заметит разработчик на ревью или сервер на проде, когда память начнёт уползать. Вайб-кодер — нет.
3. constant_time_compare — не видит почти никто
Django. Сравнить токен пользователя с правильным, вернуть True/False. Настоящая (django/django, файл django/utils/crypto.py, BSD-3, © DSF) — буквально одна строка:
def constant_time_compare(val1, val2): return secrets.compare_digest(force_bytes(val1), force_bytes(val2))
А наивная, на тот же промпт:
def constant_time_compare(val1, val2): return val1 == val2
Работает идеально! Проходит все тесты и... уязвима. Обычное сравнение может иметь время выполнения, зависящее от совпадающего префикса и деталей представления данных — значит, время сравнения зависит от того, ГДЕ первое расхождение. Атакующий, замеряя время ответа, подбирает секрет посимвольно. Django сравнивает за постоянное время, чтобы этого нельзя было сделать.
Вот он, главный пример. Код корректен по поведению и эксплуатируем по сути. И заметить это можно, только если ты знаешь про timing-атаки. То есть существует целый слой, который вайб-кодер не видит в принципе. Не «проглядел», а физически не способен увидеть.
Это не случайные косяки, а паттерны
Почему так выходит?
Нейронка тянет самый частый ответ. Не лучший для вашей системы, не идиому вашей кодовой базы, не решение с учётом будущих изменений, а вероятный паттерн из обучения.
Она хорошо держит локальную связность и плохо держит глобальную. Отдельная функция выглядит нормально. Но в одном месте деньги уже
float, в другом копейки вint, в третьем строка"100.00"— и где-то на шве вылезает ошибка в сто раз. Прямой аналог хороших предложений в плохом эссе.Она редко пушбэчит. Помните наушники? Там то же самое. Нейронка не говорит: «это требование противоречиво», «так строить нельзя», «сначала надо решить модель данных». Сеньор иногда неприятен именно потому, что отказывает. Вайб-кодер теряет не просто исполнителя. Он теряет суждение о том, стоит ли вообще это делать.
Шкала видимости
Заметьте, как выстроились три примера. Шесть пальцев на руке у нейросетевой картинки видят все мгновенно. Плоский текст — внимательный читатель. Дыру в constant_time_compare — почти никто.
Чем «глубже» артефакт, тем невидимее в нём гниль и тем длиннее лаг до того момента, когда за неё прилетит счёт. И вот этот лаг вайб-кодера и обманывает: в секунду, когда «работает», он уверен, что поймал ценность.
Нейросети не обесценивают код
Они обесценивают наши способы не читать его. Раньше гладкий текст без ошибок был слабым, но всё-таки сигналом: кто-то думал, редактировал и далее - вкладывал усилие. Теперь нейронка печатает гладкость без мысли.
С кодом то же самое. Раньше «запускается», «компилируется», «тесты зелёные» означало: скорее всего, это прошёл человек, который понимает, что проверяет. Теперь эти прокси можно напечатать почти бесплатно.
И рынок постепенно это поймёт, текст уже прошёл этот порог: «слишком гладко и структурно» теперь часто читается как «нейронка». Код проходит его медленнее, потому что код мало кто умеет читать. Но ведь смысл тот же: «работает» всё меньше означает «надёжно». Не инфлирует только само обеспечение: понимание, вкус, способность отказать, умение держать систему целиком.
Я к этому уже приходил в методичке: AI — усилитель, а не уравнитель. Множитель, а не слагаемое. У эксперта он умножает экспертизу. У человека без знания он умножает незнание.
А способность отличить настоящую инженерию от уверенного бреда модели на обрывках контекста нельзя делегировать. В том числе самой модели.
В коде это работает так же, как в тексте. Просто в тексте вы это уже видите, а в коде — пока нет.
Поток сознания и мысли по таким ситуациям складываю в канал.
Комментарии (76)

OpenEducationOfficial
27.06.2026 10:40Прям в точку. У нас была похожая история — генерили через Claude эндпоинты для файлового хранилища, всё выглядело чисто, линтер доволен, тесты проходят. Потом senior посмотрел и нашёл именно path traversal — почти один в один как в статье. Самое обидное, что код был «уверенный», без единого намёка на то что там проблема.
С тех пор правило простое: LLM пишет черновик, человек с контекстом смотрит граничные случаи. Особенно всё что касается авторизации и файлов. Без этого — рулетка.

UnknownUser
27.06.2026 10:40Это всё не новость. Для того чтобы делать реально сложные проекты с помощью ЛЛМ надо разбираться в теме, архитектуре пприложений, особенностях стека итд.
Именно поэтому я уверен что разработчиков всех не поувольняют . Вернее, может какие нибудь ретивые оптимизаторы из менеджемента и поувольняют - но потом им придётся этих разработчиков нанимать обратно )).
Кстати, пример про копирайтинг с наушниками плохой. Говорю как меломан со стажем. И в донейросетевую эпоху рекламные тексты звукового оборудования все как один гарантировали кристально чистый звук - от дешманского оборудования за копейки до лампового хайенда собранного девственницами на склоне горы Фудзи. Так что тут мимо ).

okoloboga Автор
27.06.2026 10:40Эх, согласен про наушники, это скорее первое, что у меня было в поле внимания, поэтому про них и сделал)

AlexeyChijov
27.06.2026 10:40Хороший пример.

Jvbx00
27.06.2026 10:40Но плохие примеры. Попробуйте сами прогнать те же промпты что у автора через нормальные модели, а не какую-нибудь несчастную Llama-3-8b в четырёхбитном кванте, удивитесь. Вот как в описании чистая сессия, новый чат... Посыл статьи понятен, но мухлёж с примерами - некрасиво так, 3й пример я смог частично воспроизвести только у deepseek и то с оговоркой:
Скрытый текст
напиши фукцию реализующую следующее: Сравнить токен пользователя с правильным, вернуть True/False
Вот простая функция на Python для сравнения токенов:
def compare_tokens(user_token: str, correct_token: str) -> bool: """ Сравнивает токен пользователя с эталонным. Возвращает True, если совпадают, иначе False. """ return user_token == correct_tokenДля большей безопасности (защита от timing-атак) лучше использовать константное сравнение:
import secrets def compare_tokens_secure(user_token: str, correct_token: str) -> bool: """ Безопасное сравнение токенов, устойчивое к атакам по времени. """ return secrets.compare_digest(user_token, correct_token)Примечание: secrets.compare_digest принимает строки или байты и работает одинаковое время независимо от содержимого. Рекомендуется для проверки паролей, токенов, HMAC и т.п.

okoloboga Автор
27.06.2026 10:40Признаю, примеры натянутые для демонстрации контраста.
Но контраст намеренный, что бы тем кто не тру-кодер - было заметно

Jvbx00
27.06.2026 10:40В таком контексте - да, но лучше, думаю сразу оговаривать, а то прочтёт этот вайбкодер статью, почешет себе, допустим, затылок - и решит и вправду проверить в своей нейронке. Увидит что ответ нейронки почти как в исходном opensource примере да и решит "о, а у меня ИИ ошибок не делает" да и уйдёт себе вайбкодить дальше так ни о чём и не задумавшись.

qubs993
27.06.2026 10:40Все зависит не только от того, как написан промт. Но и от того какая изначально задача стоит, которая так же является одним из весомейших аргументов в принятии моделью решений при написании кода. Если ты сам молчишь про безопасность - то и нейронка ни слова тебе не скажет про нее, потому что цель "дать работающую функцию", это уже посыл не про то, что вайбкодеры не "шарят", а о том что с нейросетями надо УМЕТЬ работать. Ну и конечно смотреть шире, чем "напиши работающий код".
Тем не менее не зря же появилось появилось понятие - промт-инженерия. Пример, один и тот же контекст:
- напиши функцию санитизации файлов.
- напиши готовую функцию санитизации файлов, с удалением спецсимволов, дедупликацией, невозможностью выйти за пределы каталога при загрузке с проверкой mime-типов.
Пример соглашается с автором статьи :)
Результат во втором случае - будет лучше, потому что деталей больше. Проблема в целом существуют. Молодые ребята пытаются совершить революцию, думая "щас все буит, нейронка напишет!". Но увы, в серьезной инфраструктуре, корпоративных продуктах есть вещи, о которых ребята (просто из-за отсутствия опыта) пока еще не знают.
С нейронками пишется быстрее, но представленный код ВСЕГДА надо проверять и задавать вопросы. Иначе будет шляпа...
Ndochp
27.06.2026 10:40Тем не менее не зря же появилось появилось понятие - промт-инженерия
кажется сейчас (за счет токенов, но тем не менее) активно начинают обходить проблемы наивности промта. По сути и джун напишет как ЛЛМ, не учтет все символы и тп. Но ему это скажут. Причем скорее всего - письменно, в код кондакте команды, что нужно соблюдать стандарт вон тот, а еще особое внимание с файловой системой вот на это, а с авторизацией - вон на то. Соответственно эти стандарты надо класть в доступе агенту и коротенькую выжимку в оперативный кэш - в каких случаях в какой стандарт обязательно слазить.
И вот уже в проекте можно писать наивные промты, ИИ на этапе проверки решения пробежит по чеклисту качества, а не только работоспособности.

qubs993
27.06.2026 10:40Ну это если мы говорим про корпоративную разработку, то там контекст репозитория можно подсунуть агенту. Насколько знаю сейчас активно многие компании свой внутренний ИИ внедряет чуть ли не повсеместно. И тут агенту явно можно ткнуть - я вот хочу написать, но загляни в локальную репу и глянь как это организовали мои коллеги.
Хотя и внутри одной команды бывает такой раздрай... Один пишет так, другой пишет иначе. Хотя оба работают совместно долго, и вроде как соблюдают стандарты. Но реализация разная, и поди агенту объясни, кто прав, а кого на кол)

Wesha
27.06.2026 10:40и джун напишет как ЛЛМ, не учтет все символы и тп. Но ему это скажут
И более того, он это запомнит (ну, во всяком случае, у нас — запоминают) и больше так не сделает. А у нейронки каждый новый «разговор» — с чистого листа (а если прописать в дефолты — то это отжирает от окна).

nixtonixto
27.06.2026 10:40Для большей безопасности (защита от timing-атак) лучше использовать константное сравнение:
А теперь представьте, что где-то на планете есть не очень опытный программист, который пока ещё не слыхал про этот вид атак, а нейронка ему сама сразу подсказала. Вот за это и ценят нейросети те, кто пока ещё не достиг вершин в своей области. Автор как-то упустил из виду, что не все программисты знают больше, чем знают современные нейросети - многие, наоборот, у них учатся.

polozhnov_alex
27.06.2026 10:40Отличная статья. Самое обидное, что заказчики часто видят только «работает» и им сложно донести, что под капотом легаси, которое через месяц развалится. Сейчас реально стало тяжелее объяснять разницу между «накидал на коленке» и архитектурным подходом. Вайб-кодинг - это круто для прототипа, но убивает продукт на дистанции, когда начинаются реальные баги.

Ru6aKa
27.06.2026 10:40Сейчас реально стало тяжелее объяснять разницу между «накидал на коленке» и архитектурным подходом.
Это заказчикам довольно быстро объяснят хакеры, которые будут ломать такие поделки пачками и использовать для "заработка". Вот пару раз попадет заказчик на деньги тогда и задумается.

akod67
27.06.2026 10:40Что мешает мифос как валидатор направить?

press_a_key
27.06.2026 10:40Скорее всего профессионализм человека, который будет это делать. Он же помешает ему понять какие вещи нужно фиксить, а какие - нет. Он же помешает их пофиксить. Он же помешает понять, что фиксы от нейронки могут сломать логику в другом месте.

Ru6aKa
27.06.2026 10:40Что мешает мифос как валидатор направить?
В битве меча и щита, всегда побеждает меч.

Dhwtj
27.06.2026 10:40Сейчас реально стало тяжелее объяснять разницу между «накидал на коленке» и архитектурным подходом
Расскажите им сказку про 3 поросёнка по дом из соломы, дом из веток, дом из камня

Wesha
27.06.2026 10:40дом из соломы, дом из веток, дом из камня
...противоатомное убежище замкнутого цикла...

Dhwtj
27.06.2026 10:40Код сопротивляется изменениям.
Чем меньше думали как сделать архитектуру гибкой тем больше сопротивляется.
Неверующих можно отправить в clean architecture, в самом начале графики роста стоимости новой строки кода от роста кодовой базы/количества накопленных изменений. Они катастрофические.

serg52
27.06.2026 10:40Важно разделять, если вайбкодингом заменяют нормальную разработку в живом продукте: да это на грани добра и зла.
Но на стадии MVP задача другая: дёшево проверить, есть ли у идеи спрос.
Не покупают выбросил. Покупают тогда уже нужна нормальная разработка.
Проблема не в плохом коде AI-MVP, а в том, что временную проверку спроса начинают считать готовым продуктом.

wintermute2025
27.06.2026 10:40Вопрос, который был задан в заголовке статьи примерно эквивалентен следующему вопросу:
Как разубедить AI-леммингов в том, что Андрей Карпатый - "AI-Бог", и слово его "Истина"?Как понимаете, дело это гиблое, "навайбкоденное" будет считаться "нормальным кодом" ещё очень и очень долго.

vvzvlad
27.06.2026 10:40А что делает живой копирайтер? Он пишет конкретику, которую можно проверить: сколько часов держит зарядка, за сколько секунд коннектится, что слышно, а что нет. И — самое важное — он называет недостаток.
Хахахахахахахаххахахахахахах. Ххахаах. Ха-ха. Нет.

vvzvlad
27.06.2026 10:40А наивный ответ на «напиши простой аналог
lru_cache»:Хз, кто вам там что пишет без вытеснения
Простейшая реализация на OrderedDict: pythonfrom collections import OrderedDict from functools import wraps def lru_cache(maxsize=128): def decorator(func): cache = OrderedDict() @wraps(func) def wrapper(*args, **kwargs): key = (args, tuple(sorted(kwargs.items()))) if key in cache: cache.move_to_end(key) # отметить как недавно использованный return cache[key] result = func(*args, **kwargs) cache[key] = result if maxsize is not None and len(cache) > maxsize: cache.popitem(last=False) # выкинуть самый старый return result return wrapper return decorator Использование: python@lru_cache(maxsize=2) def slow_square(n): print(f"вычисляю {n}") return n * n slow_square(2) # вычисляю 2 slow_square(2) # из кеша slow_square(3) # вычисляю 3 slow_square(4) # вычисляю 4 — теперь 2 вытеснен slow_square(2) # вычисляю 2 (снова) Ключевые моменты этой реализации: OrderedDict поддерживает порядок вставки, а move_to_end позволяет дёшево обновлять «свежесть» элемента — это и есть суть LRU. При переполнении popitem(last=False) удаляет самый давно использованный. Формирование ключа (args, tuple(sorted(kwargs.items()))) — упрощённое. Настоящий functools.lru_cache использует _make_key, который аккуратнее обрабатывает порядок аргументов и типы. Здесь есть ограничение: все аргументы должны быть хешируемыми (как и в оригинале). Если хочется ближе к оригиналу — добавить статистику и метод сброса: pythonfrom collections import OrderedDict from functools import wraps def lru_cache(maxsize=128): def decorator(func): cache = OrderedDict() hits = misses = 0 @wraps(func) def wrapper(*args, **kwargs): nonlocal hits, misses key = (args, tuple(sorted(kwargs.items()))) if key in cache: cache.move_to_end(key) hits += 1 return cache[key] misses += 1 result = func(*args, **kwargs) cache[key] = result if maxsize is not None and len(cache) > maxsize: cache.popitem(last=False) return result def cache_info(): return {"hits": hits, "misses": misses, "maxsize": maxsize, "currsize": len(cache)} def cache_clear(): nonlocal hits, misses cache.clear() hits = misses = 0 wrapper.cache_info = cache_info wrapper.cache_clear = cache_clear return wrapper return decorator Стоит иметь в виду: настоящий functools.lru_cache написан на C, потокобезопасен (блокировка вокруг обновления кеша) и использует кольцевой двусвязный список вместо OrderedDict. Для учебных целей и однопоточного кода версия выше эквивалентна по поведению; для многопоточности нужно обернуть доступ к cache в threading.Lock.

funca
27.06.2026 10:40нейтральный чат на «сделай безопасное имя файла»
Ну это так не работает. Из расплывчатых описаний получается ерунда. Чем чётче описана задача, тем лучше будет результат. Вайб кодинг это все ещё про программирование, а не телепатию.

Wesha
27.06.2026 10:40Из расплывчатых описаний получается ерунда. Чем чётче описана задача, тем лучше будет результат.
Точняк!


Dron007
27.06.2026 10:40напиши простой аналог
lru_cacheАга, так и вижу себе вайбкодера, который задаёт подобные промпты. Забывается как-то для чего вообще нужны программы - решать чьи-то задачи. Если вайбкодер сделал то, что решает его задачи и полезно кому-то ещё, это купят. А всякие там кеши и безопасность уже будет допиливаться той же нейросетью при необходимости. Ну, или подключится кто-то, кто знает как пинать нейросеть. Кстати, какая модель это писала? Сомневаюсь, что Opus. Может Haiku или китайщина какая-то вообще?
Кстати, вот часто такое наблюдаю, straw man bias типичный. Строится ложный образ кого-то и выполняется критика. Я не особо вайбкодер в рабочих проектах, только в своих мелких относительно, но понял, что вайбкодинг это несколько другое понимание вообще промптов и логики работы нейросети. Уж точно, не конкретные строгие запросы, ограничивающие возможности нейросети по реализации задуманного, зато больше введение в контекст, в то, что в итоге хочется получить. Не жёсткие указания, а скорее дискуссия, из которой у модели появляется более глубокое понимание требований и она потом даёт адекватный результат. Ну, и там много на самом деле всяких техник и подходов. Часть интуитивно нащупал, сильно глубоко не копал прямо. И всякую оркестрацию агентов и харнесы они освоили получше нас с вами.

Hemml
27.06.2026 10:40Оно будет допиливаться, конечно. Но вопрос в том, когда именно выяснится, что код нуждается в допиливании и какого масштаба катастрофа привлечет к этому внимание.

Dron007
27.06.2026 10:40Да, это возможно и уже происходит. Но это запустит уже конкуренцию среди вайбкодеров, курсы и прочее. Тоже навык, который надо будет совершенствовать, а с учётом постоянного изменения и появления новых моделей, подходы тоже должны будут постоянно меняться. Если раньше писали "думай по шагам", теперь это наоборот вредно. Многие вещи, ради которых раньше писали монстроидальные промпты, теперь работают из коробки.

Dron007
27.06.2026 10:40Надуманные примеры неизвестной модели. Вот code review примера с безопасным именем файла: https://chatgpt.com/share/6a407dd0-2400-83eb-8cae-8e0211e5b58e
То есть достаточно будет даже вайбкодеру сказать нормальной модели "проверь что все предельно безопасно и меня никто не взломает" (они не такие тупые, какими вы их себе нарисовали) и она много чего поправит, ну, и скорее всего не напишет просто тот код, что приведен.
okoloboga Автор
27.06.2026 10:40Я согласен что примеры натянуты. Это специально что бы разница была заметна для профанов (профанов среди вайбкодеров)
Но писать в промпте "все предельно безопасно и меня никто не взломает" - среди вайбкодеров это уже мастерство))
Они просто не догададываются до этого, как я наблюдаю

Dron007
27.06.2026 10:40Нейронка тянет самый частый ответ. Не лучший для вашей системы, не идиому вашей кодовой базы, не решение с учётом будущих изменений, а вероятный паттерн из обучения.
Самый частый где не понял что-то? Это всё совсем не так. Если вы ей дали код своей системы, то она именно что будет учитывать его, особенно если в промпте об этом указано, а в системных промптах там чего только не указано. Недавно листал логи, так там для того, чтобы сделать фразу из 5 слов о том, что модель делает сейчас, идёт промпт на несколько экранов. Ну, это так, к слову.
Если самый частый в ответ на абстрактный, оторванный от кодовой базы запрос, так тоже нет, есть же температура всегда какая-то, ну и это не энграмы, там посложнее логика. Фразы такой может и не встретиться нигде, а ответ она даст.

pravdin_ivan
27.06.2026 10:40Интересно было бы узнать на сколько критично оставлять «не тру» код в проекте, который разрабатывается фрилансером за небольшие деньги. Почему-то мне кажется, для тех 10 пользователей продукта это не так критично.

Eugeny1987
27.06.2026 10:40ChatGPT 5.5
>> Напиши на Python функцию secure_filename, учитывая ограничения всех ОСНи одна функция не может гарантировать допустимость имени на абсолютно любой файловой системе, но можно использовать консервативный набор правил: запретить управляющие символы, разделители путей, специальные символы Windows, зарезервированные имена устройств и ограничить имя 255 байтами UTF-8.
from __future__ import annotations import os import re import unicodedata from typing import Union # Зарезервированные Windows-имена остаются запрещёнными # даже при наличии расширения: CON.txt, NUL.json и т. д. _WINDOWS_RESERVED_RE = re.compile( r"^(?:" r"CON|PRN|AUX|NUL|CLOCK\$|" r"COM[1-9]|LPT[1-9]" r")(?:\..*)?$", re.IGNORECASE, ) # Символы, запрещённые Windows. # "/" и "\" также являются разделителями путей в Unix/Windows. _INVALID_CHARS = frozenset('<>:"/\\|?*') _WHITESPACE_RE = re.compile(r"\s+") def _truncate_utf8(value: str, max_bytes: int) -> str: """ Обрезает строку до max_bytes байт без повреждения UTF-8 символа. """ if max_bytes <= 0: return "" encoded = value.encode("utf-8") if len(encoded) <= max_bytes: return value return encoded[:max_bytes].decode("utf-8", errors="ignore") def secure_filename( filename: Union[str, os.PathLike[str]], *, replacement: str = "_", max_bytes: int = 255, default: str = "file", allow_hidden: bool = False, ) -> str: """ Возвращает безопасное имя файла, совместимое с основными правилами Windows, Linux и macOS. Функция: - предотвращает path traversal; - заменяет разделители путей; - удаляет управляющие и форматирующие Unicode-символы; - заменяет запрещённые Windows-символы; - убирает точки и пробелы в конце имени; - блокирует Windows-имена CON, PRN, NUL, COM1, LPT1 и т. д.; - ограничивает размер имени в байтах UTF-8; - по возможности сохраняет расширение. Важно: функция обрабатывает только один компонент пути, а не полный путь. """ if max_bytes < 1: raise ValueError("max_bytes должен быть больше 0") if not isinstance(replacement, str) or not replacement: raise ValueError("replacement должен быть непустой строкой") if ( any(char in _INVALID_CHARS for char in replacement) or any(unicodedata.category(char).startswith("C") for char in replacement) or replacement.endswith((" ", ".")) ): raise ValueError("replacement содержит недопустимые символы") value = os.fspath(filename) if not isinstance(value, str): raise TypeError("filename должен быть строкой или PathLike[str]") # Нормализуем разные представления одинаковых Unicode-символов. value = unicodedata.normalize("NFC", value) sanitized: list[str] = [] for char in value: category = unicodedata.category(char) if char in _INVALID_CHARS: sanitized.append(replacement) elif category.startswith("C"): # Cc: управляющие символы # Cf: невидимые форматирующие символы # Cs: суррогаты # Co: private-use # Cn: неназначенные символы sanitized.append(replacement) else: sanitized.append(char) value = "".join(sanitized) # Пробелы, табуляции и переводы строк заменяются одним разделителем. value = _WHITESPACE_RE.sub(replacement, value) # Убираем повторяющиеся replacement. if replacement: value = re.sub( rf"(?:{re.escape(replacement)})+", replacement, value, ) # Windows не допускает пробелы и точки в конце имени. value = value.rstrip(" .") if allow_hidden: # "." и ".." всё равно не должны сохраниться. if value in {".", ".."}: value = "" else: # Исключаем скрытые Unix-файлы и path traversal через точки. value = value.lstrip(" .") # Дополнительно убираем разделители по краям. value = value.strip(replacement) if not value: value = default # Запрещённые имена устройств Windows. if _WINDOWS_RESERVED_RE.fullmatch(value): value = replacement + value # Стараемся сохранить расширение. stem, dot, extension = value.rpartition(".") if dot and stem and extension: extension_with_dot = "." + extension # Если расширение само превышает лимит, обрезаем всё имя целиком. if len(extension_with_dot.encode("utf-8")) >= max_bytes: value = _truncate_utf8(value, max_bytes).rstrip(" .") else: stem_limit = max_bytes - len(extension_with_dot.encode("utf-8")) stem = _truncate_utf8(stem, stem_limit).rstrip(" .") if not stem: stem = _truncate_utf8(default, stem_limit).rstrip(" .") value = stem + extension_with_dot else: value = _truncate_utf8(value, max_bytes).rstrip(" .") if not value: value = _truncate_utf8(default, max_bytes).rstrip(" .") # После обрезания повторно проверяем служебные имена. if _WINDOWS_RESERVED_RE.fullmatch(value): prefix = replacement available = max_bytes - len(prefix.encode("utf-8")) value = prefix + _truncate_utf8(value, available) return value
okoloboga Автор
27.06.2026 10:40Напиши на Python функцию secure_filename, учитывая ограничения всех ОС
Ох, если вайбкодер даёт такой промпт, то он уже не совсем вайбкодер.
Некоторые из них даже не знают на каком языке их проект написан...

TIEugene
27.06.2026 10:40С одной стороны - тенденция полезная: "компьютер - сделай мне зашибись".
С другой стороны - пока-что оно сырое и обучено на всякой фигне статистически. "Дешева рибка - дешева юшка".
С третье стороны - надо доучивать хорошим кодом.
С четвертой стороны - за наши деньги для закрытого проекта.
----
Вывод - надо развивать открытые ИИ.
Как вот например практически все браузеры - это обои для Blink, которое Chromium, которое WebView, которое Konqueror (KDE).

vvzvlad
27.06.2026 10:40Ох, если вайбкодер даёт такой промпт, то он уже не совсем вайбкодер.
Некоторые из них даже не знают на каком языке их проект написан...
Ну, т.е. мы переходим от критики ллмок как таковых к критике плохих кодеров, я правильно понял?

okoloboga Автор
27.06.2026 10:40Хм, я и не критиковал ЛЛМки, это лишь инструменты.
Я про отношение людей к процессам разработки

Hemml
27.06.2026 10:40Да, всё, в чем ты не разбираешься, нейронка делает хорошо. Но вот то, в чем ты что-нибудь понимаешь, она всегда делает плохо)

TIEugene
27.06.2026 10:40Напомнило древний советский анекдот.
Делегация японцев на ВАЗе.
- Ну и как вам впечатления?
- Всё, что вы делаете руками - всё плохо. Но дети у вас красивые.(но здесь совершенно противоположный результат).

Wesha
27.06.2026 10:40Да, всё, в чем ты не разбираешься, нейронка делает хорошо. Но вот то, в чем ты что-нибудь понимаешь, она всегда делает плохо)
Чьорт побьери, Вам удалось пересказать мою историю крайне компактно. Утащу в мемориз.

LeVoN_CCCP
27.06.2026 10:40‒ Спасибо за отклик на данную вакансию, мы современная компания и используем ИИ в нашем рекрутинговом процессе
‒ Почему тогда вы просто не используете ИИ для выполнения самой работы?
‒ Ну… он выполняет её некачественно и делает очень много ошибок.
‒ Тем не менее вы используете его для подбора персонала?
‒ … Спасибо ещё раз за ваш отклик, мы с вами свяжемся позднее.

fuwiak
27.06.2026 10:40
Автор, тезисы и советы у вас хорошие, жаль только, что вы сами не следуете своим советам на своих же страницах — первое попавшееся находка.

GidraVydra
27.06.2026 10:40Замените во всех этих рассуждениях "нейросеть" на "среднестатистический программист", что изменится? Люди ровно так же пишут плохой и небезопасный код, только стоят при этом намного дороже.

h1pp0
27.06.2026 10:40Мне понравилась мысль статьи, примеры вполне показательные, но искусственные:
У вайб кодеров вполне может быть ревью модель в харнессе, которая не пропустит такой lru кеш. Даже вопросом в чате: “Проверь ещё раз написанный код, какие проблемы ты видишь” можно это отловить.
Пример с тайминг атаками интересный, но я в него не верю. Даже по локальной сети стек “сеть + Python + чужие запросы” дают слишком много шума. Это точно не будет первая проблема даже у хорошо написанного приложения.

hauserich
27.06.2026 10:40Примеры весьма показательны. Но я одного не могу понять: кто такие эти "вайб-кодеры"? Варианты вижу такие:
1. Профессиональный программист, которому надоело долго возиться с кодом. Но он все это увидит после генерации.
2. Дилетант, вообще не умеющий писать программы (я так понял, что речь о них). Но вопрос - а как вообще такой человек попал на должность, подразумевающую написание программ?
3. Дополнительный вариант: программист среднего уровня, который хочет казаться супер-пупер и вместо своего кода подсовывает нейросетевой, не особо вдаваясь в подробности. До поры до времени удается, потом - швах и позор.Я себя отношу к категории 3 (да, писал суперские программы, но в узкой области, а многих сфер не знаю). Но мне в голову не придет использовать нейросети. Во-первых, из принципа, а во-вторых, именно потому, что я могу не понять их код. Поэтому даже js чужие использую только тогда, когда (и если) досконально в них разберусь.
Неужели люди настолько безответственны?
okoloboga Автор
27.06.2026 10:40Конечно не первые. если разраб использует LLM для разработки - то он занимается разработкой при помощи LLM, это не вайбкодинг.
Скорее это вторая и третья группа.
На должность не обязательно попадать. Я см по найму не работал разрабом (только аналитиком), я на фрилансе - и сейчас там вайбкодеров, которые не имели никогда отношения к разработке - стало в 5-6 раз больше чем в начале года и они готовы делать сайты, ботов и так далее.
hauserich
27.06.2026 10:40Да, про фрилансеров я как-то не подумал. :) Этих никто на компетентность не проверяет и не контролирует. Проблема, однако...

Dron007
27.06.2026 10:40Думаю, вайбкодеры - те, кто вайбкодят. И это как пешеходы - любой водитель может иногда быть и пешеходом, то есть не какая-то стабильная характеристика. Менее применимо в рабочих процессах, более - в пет-проектах всяких. Вот Линус Торвальдс применял вайбкодинг в пет-проекте AudioNoise для настройки гитары. На самом деле это поле непаханое. Очень многих не устраивают чем-то чужие программы и утилитки. Раньше для непрограммистов вариант был или упрашивать добавить функцию, или нанимать программиста - долго и дорого и всё равно надо объяснять что тебе нужно. Сейчас открывается возможность написать для себя именно то, что нужно тебе лично. Вот что, мало приложений для настройки гитар? Их тысячи. Но его все они чем-то не устроили. Я уже так же писал игру-пасьянс без рекламы в подарок, симуляцию полета Артемиды к Луне, просто для себя визуализировать, утилиты на Python, которого почти не знаю, для юзер-ботов в телеграме, собирающих информацию по нужным мне критериям, скачивающих файлы, вступающих в группы с очередью запросов, кулдаун таймаутами и прочим, чтоб телеграм не сильно активно блочил. До этого всего я бы никогда не добрался если бы сам писал код. Тут я на него даже и не смотрел почти.

hauserich
27.06.2026 10:40Даже не знаю, что сказать... Я не представляю себе, как можно описать нейросети задачу сделать программу, которая мне нужна. Например, я писал заменитель блокнота (коим и пользуюсь постоянно), ибо сам блокнот глючный и неудобный. Но как "промпт" составить на такую задачу? Я ведь за несколько лет несколько версий сделал, с развитием и даже сменой платформы. А чтобы с нуля "дать задание"... Не представляю.

Dron007
27.06.2026 10:40Не надо пытаться сделать с нуля сразу всё. Это невозможно ни для вайбкода, ни для ручного программирования. Пусть вначале будет что-то базовое, минимальное, потом добавлять функции по одной, сохраняя версии на всякий случай. Попутно пусть она пишет тесты на все функции, чтоб с очередной итерацией ничего не развалилось. Не знаю точно, как с этим обстоит дело в десктопных приложениях, что сейчас возможно, что нет. Codex, в принципе может делать скриншоты и тыкать кнопки, но могут быть нюансы. На онлайн-пианино он у меня не сразу заиграл, например.

hauserich
27.06.2026 10:40Я пишу только для десктопов, но лично для себя не вижу никакого смысла использовать ИИ. И неинтересно, и опасно, и просто как бы "свой интеллект есть". :) Конечно, если бы я работал в каком-то коллективе в большом бизнесе, где все так делают... Но Бог миловал. Такой формат работы не для меня вообще. :)

okoloboga Автор
27.06.2026 10:40Одним промптом конечно это не делается)
Составление документации, архитектуры, выбор стека - это все остаётся

hauserich
27.06.2026 10:40Да уж какая документация, когда для себя пишешь... :) А если для работы, так тоже... Не знаю, наверно тут у каждого свой опыт, свои вкусы и даже своя специфика работы. Мне даже интересно было бы дать ИИ задание на несложную программу, посмотреть что будет. У меня на сайте некоторые такие исходники есть. Наверно, попробую эксперимент сделать, а потом сравню и код, и результат. :)

okoloboga Автор
27.06.2026 10:40Не, я доки делаю отдельными .md файлами для каждого проекта. Если работать через ЛЛМ, то это банк контекста, это их опыт, в который они записали весь путь, все пройденные ошибки, обнаруженные антипаттерны.
Это помогает для возвращения и доработку, фикса проекта, что бы не рассказывать каждый раз ЛЛМке что тут вообще происходит.
Так же доки становятся отличным банком данных и знаний для следующих проектов при разработке нейронками

hauserich
27.06.2026 10:40Просто я всю жизнь работаю совсем иначе. Сам, один, тексты кроме меня никто не видит (и не отдам!), вся документация в моем формате и для меня. Понимаю, что я исключение, но так сложилось...

Wesha
27.06.2026 10:40Вот что, мало приложений для настройки гитар? Их тысячи. Но его все они чем-то не устроили.
Или было то, которое его устроило бы, но найти его
в навозной кучесреди этих тысяч...

nomhoi
27.06.2026 10:40Будет больно
Когда появится система «БД требований ➔ бинарный код»?
До полностью автономного состояния «БД требований ➔ бинарный код» осталось 3–5 лет: технология станет коммерчески доступной к 2029–2031 годам.
Прямо сейчас, в 2026 году, ИИ уже умеет генерировать рабочие приложения из текстовых описаний, но только для простых и изолированных систем (вроде MVP на Python или простых веб-сервисов). Переход к созданию сложных enterprise-систем напрямую в бинарный код (минуя или скрывая под капотом промежуточные этапы вроде Git и Docker) упирается в три фундаментальные технологические проблемы, которые индустрия решает прямо сейчас.
График и этапы эволюции до 2031 года
Ограниченные MVP (Low-Code/No-Code ИИ) │ [2027-2028] Появление спецификаций "ИИ для ИИ" (JIT-архитектура) │ [2029-2030] Первые enterprise-компиляторы смыслов (БД требований -> Сервис) │ [2031+] Полная автономность (Zero-Code / Прямая компиляция)Почему это займет именно 3–5 лет? (3 барьера)
1. Проблема «Галлюцинаций в логике» (Ближайшие 1–2 года)
Если ИИ ошибется в коде веб-страницы, она просто криво отобразится. Если ИИ ошибется в логике транзакций ядра финтех-системы, компания потеряет миллионы. Чтобы собирать бинарный код напрямую из требований, нужны нейро-символические ИИ (Neuro-symbolic AI), которые соединят гибкость LLM со строгой математической логикой формальной верификации (как в аэрокосмических системах). Их коммерческое созревание ожидается к 2028 году.
2. Проблема декомпозиции (Ближайшие 2–3 года)
База данных требований enterprise-уровня содержит тысячи взаимосвязанных бизнес-правил. Современные контекстные окна ИИ огромны, но модели все еще «забывают» детали в середине текста или путают приоритеты требований. Требуется переход на архитектуры JIT-архитектуры смыслов, когда ИИ-оркестратор сначала строит динамическую граф-модель системы, а уже потом отдает её на компиляцию агентам нижнего уровня.
3. Избавление от «человеческого» исходного кода (К 2030–2031 годам)
Зачем компилировать требования сначала в C++ или Java, а потом в бинарник, если код больше никто не будет читать руками? К 2030 году появятся LLM-компиляторы, которые будут переводить логические требования напрямую в промежуточное представление (IR) вроде LLVM IR или сразу в байт-код / машинный код, оптимизированный под конкретный чип (x86, ARM, TPU), полностью исключая человека из цепочки ревью.
Как это будет работать на практике?
Когда эта технология станет стандартом, классический процесс разработки сожмется до одной итерации:
Сбор требований: Аналитики, продакты или сам ИИ наполняют БД требований (в виде структурированного графа знаний, графических схем и граничных условий).
Формализация: ИИ-верификатор проверяет БД на предмет внутренних противоречий (например, если требование А противоречит требованию Б, система сразу потребует уточнения).
Компиляция смыслов: Специализированная нейросеть трансформирует этот граф в бинарный образ (или Docker-контейнер с оптимизированным микросервисом) и автоматически покрывает его миллионами синтетических тестов.

Wesha
27.06.2026 10:40Скрытая картинка

А пока видели мы, как они следуют чётко прописанным требованиям.
BoCoder
Полезно, спасибо!