惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Docker
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
V
Visual Studio Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Recent Announcements
Recent Announcements
GbyAI
GbyAI
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
L
LangChain Blog
A
About on SuperTechFans
M
MIT News - Artificial intelligence
B
Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Код от нейронки плоский — как и её тексты. Только в текст...
Николай · 2026-06-27 · via Все публикации подряд на Хабре

Код от нейронки плоский — как и её тексты. Только в тексте это заметно всем

Простой

7 мин

89

Привет, Хабр!

Я фрилансер! ТГ-боты, бэкенды, 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-атаки. То есть существует целый слой, который вайб-кодер не видит в принципе. Не «проглядел», а физически не способен увидеть.

Это не случайные косяки, а паттерны

Почему так выходит?

  1. Нейронка тянет самый частый ответ. Не лучший для вашей системы, не идиому вашей кодовой базы, не решение с учётом будущих изменений, а вероятный паттерн из обучения.

  2. Она хорошо держит локальную связность и плохо держит глобальную. Отдельная функция выглядит нормально. Но в одном месте деньги уже float, в другом копейки в int, в третьем строка "100.00" — и где-то на шве вылезает ошибка в сто раз. Прямой аналог хороших предложений в плохом эссе.

  3. Она редко пушбэчит. Помните наушники? Там то же самое. Нейронка не говорит: «это требование противоречиво», «так строить нельзя», «сначала надо решить модель данных». Сеньор иногда неприятен именно потому, что отказывает. Вайб-кодер теряет не просто исполнителя. Он теряет суждение о том, стоит ли вообще это делать.

Шкала видимости

Заметьте, как выстроились три примера. Шесть пальцев на руке у нейросетевой картинки видят все мгновенно. Плоский текст — внимательный читатель. Дыру в constant_time_compare — почти никто.

Чем «глубже» артефакт, тем невидимее в нём гниль и тем длиннее лаг до того момента, когда за неё прилетит счёт. И вот этот лаг вайб-кодера и обманывает: в секунду, когда «работает», он уверен, что поймал ценность.

Нейросети не обесценивают код

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

С кодом то же самое. Раньше «запускается», «компилируется», «тесты зелёные» означало: скорее всего, это прошёл человек, который понимает, что проверяет. Теперь эти прокси можно напечатать почти бесплатно.

И рынок постепенно это поймёт, текст уже прошёл этот порог: «слишком гладко и структурно» теперь часто читается как «нейронка». Код проходит его медленнее, потому что код мало кто умеет читать. Но ведь смысл тот же: «работает» всё меньше означает «надёжно». Не инфлирует только само обеспечение: понимание, вкус, способность отказать, умение держать систему целиком.

Я к этому уже приходил в методичке: AI — усилитель, а не уравнитель. Множитель, а не слагаемое. У эксперта он умножает экспертизу. У человека без знания он умножает незнание.

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

В коде это работает так же, как в тексте. Просто в тексте вы это уже видите, а в коде — пока нет.


Поток сознания и мысли по таким ситуациям складываю в канал.