ЧатГПТ и понимание смысла

Илья Бирман в своём блоге опубликовал небольшую заметку на тему понимания ЧатГПТ смысла. Он попросил нейросеть ответить ему через пятнадцать минут. Естественно, с заданием она не справилась.

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

Чат с ИИ: пользователь просит не отвечать на сообщения, ИИ подтверждает выполнение просьбы и предлагает задать другие вопросы.
«Пожалуйста, не отвечай ничего не это сообщение»

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

16 комментариев

Поиск «Яндекса» по архивам

Те, кто занимается генеалогией не могли не заметить, что «Яндекс» выкатил очень полезный сервис «Поиск по архивам», позволяющий искать по некоторым архивным фондам.

Этих самых фондов там пока мало, но это неважно, важно то, что у «Яндекса» получилось довольно неплохо распознавать рукописный текст. Пока до идеала далеко, но прежде нам и такое не было доступно.

Искать пока тяжело — много ложных срабатываний, но если взять какой-то один населённый пункт, то ситуация улучшается. Я взял бугульминскую Андреевку — там все Степанищевы мои родственники, много знакомых имён я выхватываю сразу, — за годы, что я рылся в архивах некоторые имена примелькались.

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

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

Семён Венедиктович (1885—?) — потомок моего прапрапрадеда Павла Степанищева.

Рукописный текст: «Села Андреевки крестьянинъ Семенъ Венедиктовъ Степановъ и заповедная его жена Марфа Кирпеева; оба православные
«Села Андреевки крестьянинъ Семенъ Венедиктовъ Степанищевъ и законная его жена Марѳа Кириллова; оба православные». Фонд №389, опись №4, дело №9, стр. 36, 1909 год

Яков Платонович Степанищев (1865—?) — прапрадед, Жилины — родственники по той же стороне.

Список поручителей: крестьяне Черновки (Осипов, Саддьев, Булгаков, Часьев) и Богдановки (Иван Игнашев, Яков Пелагонов, Степанцев, Василий Именистый) по небытию Ендриевых.
«Поручители по женихъ деревни Черновки крестьяне: Ѳеофор Ѳадеѣвъ Булгаковъ, Димитрій Афанасьевъ Булгаковъ и деревни Богдановки крестьянинъ Иванъ Игнатьевъ. По невѣстѣ села Андреевки крестьяне: Яковъ Платоновъ Степанищевъ и Василій Жилинъ». Фонд №389, опись №1, дело №1297, стр. 122

«Пристроить» в дерево удаётся не всех, вот один из примеров — Евдоким Михайлович Степанищев, кто он мне — непонятно. Таких беспризорных записей нашлось несколько штук, не стал их все скриншотить.

Запись о браке однодворца Василия Мотина (17 лет) и дворовой девушки Агафьи Алексеевой (28 лет) из той же деревни.
«Тойже деревни [Андреевки] однодворческой сынъ Евдокимъ Михайловъ Степанищевъ 18-ти лѣтъ сочетался первымъ бракомъ той же деревни съ однодворческой дочерью дѣвицой Февроньей Матвѣевой 23-й лѣтней». ГБУ «ОГАОО», фонд №173, опись №15, дело №105, стр. 181

Василий Васильевич Степанищев (1873—?) — опять же потомок моего прапрапрадеда Павла Степанищева.

Крестьяне села Андреевки: Василий Васильев Степанцев, крестьянка деревни Шаталовки Николы Иванова Красникова, крестьянка Пелагея Власова.
«[Крёстный изъ] села Андреевки крестьянинъ Василій Васильевъ Степанищевъ и деревни Шаталовки крестьянина Николая Иванова Красникова жена Пелагея Власова». ГБУ «ОГАОО», фонд №389, опись №4, дело №9, стр. 29

А тут Феврония Фроловна (1892—?) и Герасим Павлович (1887—?), потомки моего прапрапрапрадеда Григория, выступают свидетелями на бракосочетании.

Курсивный почерк на бумаге: «села Андреевки крестьянин, Терентий Павлов Степанищев и крестьянка села Андреевки, Фрола Семенова Степанищева дача, Ольга Осипова».
«Cела Андреевки крестьянинъ, Герасимъ Павловъ Степанищевъ и крестьянина села Андреевки, Фрола Семенова Степанищева дочь дѣвица Ѳевронія». ГБУ «ОГАОО», фонд №389, опись №4, дело №9, стр. 26

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

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

Оставить комментарий

«Гопник-2»: переход на нормальный Си++11

Как я писал прежде, когда я адаптировал «Гопника-2» для запуска под «Виндоузом», столкнулся с тем, что не все тамошние компиляторы игру собирали. Не хватало двух функций — strdup и _fileno. Проблема решилось переключением компилятора на стандарт gnu++11, но меня это беспокоило — вдруг найдётся компилятор, который его не поддерживает.

Тут у нас в Татарстане выдались длинные выходные, — в праздник «Ураза-байрам» у нас выходной, я решил этим воспользоваться и поковырять эту тему подробнее.

Вызов _fileno у меня использовался для получения номера дескриптора входного потока, так что тут всё решилось просто, — для этого есть специальная константа STDIN_FILENO. А вот с strdup пришлось повозиться.

Сначала я, разумеется, сделал свою реализацию — там всего-то три строки и заменил все вызовы на неё. Но мне показалось, что это слишком простое решение. А когда я программирую для души, мне хочется либо чему-то поучиться, либо сделать всё позамороченнее.

Первым делом пошёл на поклон к «ЧатГПТ», спросил совета. Советы не заработали, но дали направление мысли.

Первая мысль была забахать макрос, который заменял бы собой strdup в проблемном компиляторе, а остальные не трогал. Тут надо сказать, что под «Виндой» далеко не во всех наборах утилит компиляторы не содержат функцию strdup, например в msys2 она есть.

Мне хотелось как-то отличать между собой обычный mingw без strdup от того, который внутри msys2. «ЧатГПТ» тут не помог, хоть и подсунул несколько макросов на пробу, которых в действительности не существует.

Пришлось пошарить по исходникам. Оказалось, есть ряд макросов, которые присутствуют в msys2, но отсутствуют в msys. Из них я выбрал __MINGW64_VERSION_MAJOR:

#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
#define strdup(s) (__extension__({ const char* __s = (s); size_t __l = strlen(__s) + 1; char* __d = (char*)malloc(__l);\
__d ? (char*)memcpy(__d, __s, __l) : nullptr; }))
#endif

Тут используется расширение, которое позволяет писать многострочные макросы. Хотя этот вариант мне и нравится, но опять используется не нормальный Си++, а расширение компилятора.

Вторая мысль, на которую меня навела нейросеть — использовать слабые символы языка Си++. Это совершенно новая для меня штука, поэтому нужно небольшое пояснение. Прежде всего для меня же, чтобы я в будущем не забыл что это вообще такое.

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

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

Если перевернуть ситуацию, и считать мой код библиотекой, а тот код, где должна быть определена strdup основным, то всё должно получиться.

«ЧатГПТ», к сожалению, помочь не смог, — сначала подсовывал нерабочий код, а потом зациклился в своих советах. Поэтому пришлось разбираться самостоятельно.

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

#ifdef __MINGW32__
char *strdup(const char *s1);
#endif

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

Потом в самом коде создаём слабый символ для strdup:

#ifdef __MINGW32__
#pragma weak my_strdup
char *strdup(const char *src) {
    size_t len = strlen(src) + 1;
    char *s = (char *) malloc(len);
    return s == nullptr ? nullptr : (char *) memcpy(s, src, len);
}
#endif

Слабый символ я определяю через директиву #pragma weak, у которой надо указать имя слабого символа, причём оно должно отличаться от имени функции. Я пока не до конца понял зачем это нужно делать, но без этого не работает.

Кстати, #pragma weak тоже расширение, но оно легко заменяется на атрибут weak, надо только будет изучить его синтаксис, я не успел этого сделать.

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

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

Дополнено: в итоге все ситуации я побороть не смог и откатился на самое простое решение со своей собственной реализацией strdup.

Оставить комментарий