Image

Подножка для AI в виде UTF-8

Output
Output

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

Опыты с генерацией кода

Я немного экспериментировал с генерацией кода с помощью GigaChat и DeepSeek. Это не рабочие задачи и не полноценное исследование. Мне просто было интересно найти примеры пересечения некой грани сложности при решении задачи, после которой начинаются проблемы с генерацией C++ кода.

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

Кстати, здесь вырисовывается потенциальная проблема при обучении программированию: слишком велик соблазн сразу получить ответ, так и не разобравшись, как всё работает. Видимо, придётся обратно возвращаться к написанию кода на бумаге 🙂 Но сейчас не будем углубляться в эту тему.

Для одного из экспериментов я выбрал создание программы, которая будет читать файлы с исходным кодом и выполнять ряд операций над названиями переменных или их составными частями. Одна из задач — это получить из имени переменной «RedColor» три токена: «RedColor», «Red» и «Color».

Думаю, задача разбития на токены часто встречается в программировании, и существует много открытого кода на эту тему. Поэтому в такой постановке GigaChat и DeepSeek с этой задачей справляются хорошо.

Однако мир сложнее, и нужно работать не просто со стандартной ANSI кодировкой, но и, например, с UTF-8. Поэтому я начал просить писать код, обрабатывающий файлы в том числе в формате UTF-8. И в этот момент генераторы кода поплыли.

Полагаю, количество открытого кода, учитывающего кодировки, в том числе и UTF-8, в несколько раз меньше. Дополнительно мои формулировки задания стали сложнее и от этого расплывчатее. Кстати, за пару подходов у меня не получилось добиться работающего кода. Думаю, это можно сделать, проведя ещё несколько генераций с уточнениями задания. Но у меня нет цели написать конечную программу и мне интересно экспериментировать именно со сбоями 🙂

Баги

Итак, приведённый ниже код сделал для меня GigaChat. Интересно, кстати, что пока он схалтурил: решил не делать настоящую конвертацию кода. Но при этом сам момент, что надо обрабатывать UTF-8, уже приводит к возникновению некорректного C++ кода.

…. // Вспомогательная функция для преобразования // char-вектора в utf-8 строку std::string to_utf8(const std::vector<char>& data) { // Для простоты считаем, что вектор представлен в UTF-8 изначально return { data.begin(), data.end() }; } …. // Главная функция для разделения строки на токены std::vector<std::string_view> tokenize_string_giga(const std::vector<char>& input_data) { std::string text = to_utf8(input_data); std::vector<std::string_view> result; size_t pos = 0; while (pos < text.size()) { if (is_letter(text[pos]) || is_digit(text[pos])) { size_t begin_pos = pos++; // ищем конец текущего набора алфавитно-цифровых символов while (pos < text.size() && (is_letter(text[pos]) || is_digit(text[pos]))) ++pos; // Извлекаем полное слово std::string_view current_word = text.substr(begin_pos, pos — begin_pos); // Дробим слово на отдельные токены split_word_into_tokens(current_word, result); } else { ++pos; // пропускаем неалфавитно-цифровые символы } } return result; }

Ошибка связана со временем жизни объекта. Обратите внимание на фрагмент, где извлекаются слова:

std::string_view current_word = text.substr(begin_pos, pos — begin_pos);

Функция substr создаёт временный объект типа std::string, который затем разрушается. В результате в current_word сохраняются указатели на уже разрушенный объект.

Естественно, я попробовал запустить PVS-Studio. Он выявляет эту ошибку следующим предупреждением: V1017 [CWE-416] Variable of the ‘string_view’ type references a temporary object which will be removed after evaluation of an expression. Tokenizer_giga.cpp 79

Что интересно, приблизительно на том же споткнулся и DeepSeek. Он сгенерировал больше кода, так как не поленился повозиться с UTF-8, поэтому приведу здесь сразу выжимку:

std::vector<std::string_view> tokenize_string(const std::vector<char>& buffer) { std::vector<std::string_view> tokens; …. std::string utf8_text = detect_and_convert_to_utf8(buffer); …. std::string_view token(utf8_text.data() + token_start, pos — token_start); …. tokens.push_back(token); …. return tokens; }

В функции создаётся локальная переменная utf8_text типа std::string. Её разбивают на токены и записывают указатели на них в выходной массив tokens. Естественно, после выхода из функции переменная utf8_text уничтожается и ссылки становятся невалидными. К сожалению, здесь PVS-Studio пока помочь не смог: у него не получилось сопоставить время жизни utf8_text и tokens.

Осмысление

Было интересно наблюдать, как повышение сложности задачи привело к сбою в сгенерированном коде.

Наверное, нет одной причины, почему так получается, и влияние следующих моментов суммируется:

  1. Более обобщённая и, следовательно, менее чёткая постановка задачи.

  2. В мире меньше кода, который «умеет в UTF-8». Соответственно, система хуже обучена. Из этого следует, что чем более нетиповая задача решается, тем хуже будет результат.

  3. Класс std::string_view относительно молодой (C++17), и ещё создан не такой огромный объём кода с его участием, как, например, с std::string.

  4. Возможно, концепция времени жизни объектов сложна для обучения.

Пара слов про статический анализ. Наверное, может поменяться стиль использования инструментов для проверки кода. Здесь нет смысла править руками ошибку — проще заново сгенерировать весь код функции, уточнив задание. Анализатор поможет человеку быстрее понять, почему код не работает как ожидалось. И уже на основании этих знаний человек может указать генератору, что он сделал не так. В общем, поможет уточнить или переформулировать задачу. Или разбить её на несколько подзадач.

В противном случае остаётся или генерировать код, меняя формулировки, пока он не заработает, или самому делать обзор кода. Оба сценария так себе. Конечно, статический анализ не панацея, но если он поможет быстрее исправить ошибку, то замечательно. Собственно, так всегда и было 🙂 В этом его суть.

P.S. Как и ранее, приглашаю в комментариях поделится подобными случаями.

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. Stumbling block for AI: UTF-8.

Источник: habr.com

✅ Найденные теги: новости, Подножка

ОСТАВЬТЕ СВОЙ КОММЕНТАРИЙ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Фото сгенерированных лиц: исследование показывает, что люди не могут отличить настоящие лица от сгенерированных
Нейросети построили капитализм за трое суток: 100 агентов Claude заперли…
Скетч: цифровой осьминог и виртуальный мир внутри компьютера с человечком.
Сцена с жестами пальцами, где один жест символизирует "VPN", а другой "KHP".
‼️Paramount купила Warner Bros. Discovery — сумма сделки составила безумные…
Скриншот репозитория GitHub "Claude Scientific Skills" AI для научных исследований.
Структура эффективного запроса Claude с элементами задачи, контекста и референса.
Эскиз и готовая веб-страница платформы для AI-дизайна в современном темном режиме.
ideipro logotyp
Image Not Found
Звёздное небо с галактиками и туманностями, космос, Вселенная, астрофотография.

Система оповещения обсерватории Рубина отправила 800 000 сигналов в первую ночь наблюдений.

Астрономы будут получать оповещения о небесных явлениях в течение нескольких минут после их обнаружения. Теренс О'Брайен, редактор раздела «Выходные». Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной…

Мар 2, 2026
Женщина с длинными тёмными волосами в синем свете, нейтральный фон.

Расследование в отношении 61-фунтовой машины, которая «пожирает» пластик и выплевывает кирпичи.

Обзор компактного пресса для мягкого пластика Clear Drop — и что будет дальше. Шон Холлистер, старший редактор Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной странице вашего…

Мар 2, 2026
Черный углеродное волокно с текстурой плетения, отражающий свет.

Материал будущего: как работает «бессмертный» композит

Учёные из Университета штата Северная Каролина представили композит нового поколения, способный самостоятельно восстанавливаться после серьёзных повреждений.  Речь идёт о модифицированном армированном волокном полимере (FRP), который не просто сохраняет прочность при малом весе, но и способен «залечивать» внутренние…

Мар 2, 2026
Круглый экран с изображением замка и горы, рядом электронная плата.

Круглый дисплей Waveshare для креативных проектов

Круглый 7-дюймовый сенсорный дисплей от Waveshare создан для разработчиков и дизайнеров, которым нужен нестандартный экран.  Это IPS-панель с разрешением 1 080×1 080 пикселей, поддержкой 10-точечного ёмкостного сенсора, оптической склейкой и защитным закалённым стеклом, выполненная в круглом форм-факторе.…

Мар 2, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых