Искусственный интеллект

]Искусственный интеллект: очередная «Next Big Thing» или рабочий инструмент?

Искусственный интеллект переживает взрывной интерес. Ее называют Next Big Thing и пророчат, что она изменит мир. Но так ли это? На моей памяти было множество NBT, и каждой пророчили нечто подобное. Из последних — блокчейн. До этого — NoSQL, low-code системы… Если покопаться в памяти и архивах, найдется куда больше. Но все они прошли этап взрывного интереса, спада и наконец заняли свою нишу.

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

Обсуждение плюсов и минусов ИИ, а также возможного применения ИИ в жизни заняло бы не один том. Этот же текст не претендует на исчерпывающий анализ ИИ и его места в жизни. Это то, на что, на мой взгляд, обращают мало внимания, обсуждая ИИ.

Ограничения, с которыми нужно жить

Есть большой пласт проблем, о которых я не буду подробно говорить. Не потому, что это не важно, а потому, что это ограничения технологии — о них просто нужно знать и уметь с ними жить. Это и «галлюцинации», и ограничение контекста, и искажение входных данных, и их неправильная интерпретация. Мы же не виним автомобиль в том, что у него тормозной путь длиннее, чем у бегуна? Мы просто знаем это и держим дистанцию. Вот и с ИИ так: хочешь пользоваться — изучи его слепые зоны и научись жить с этим.

Зависимость от человека

Начну с общего: ИИ ценен до тех пор, пока учится на результатах работы человека. Чем меньше будет в интернете написано (нарисовано, снято, сыграно, запрограммировано) человеком, тем глупее и однообразнее будут ответы ИИ. Какое-то время это будет незаметно просто потому, что уже накоплена большая база данных, созданных людьми, потому что алгоритмы, поддерживающие ИИ, будут совершенствоваться, потому что мощности будут увеличиваться… Но у этого есть предел. Без притока свежих идей, ошибок и озарений, свойственных только человеку, ИИ начнет «захлебываться» собственным однообразием.

Почему программисты останутся

Фразы о том, что программисты станут не нужны и каждый пользователь сможет сам создавать программы, не изучая языков программирования, я уже слышал раньше — в отношении low-code систем. Они появились довольно давно, но так и не смогли заменить программистов.

Причина тут довольно тривиальна: программист — это не просто человек, который пишет код. Значимая часть его работы — понять задачу, сформулировать пути решения и продумать архитектуру приложения. Тот, кто хоть раз составлял техническое задание со слов пользователей (и тем более согласовывал его), знает, насколько это непростая задача. А когда задача затрагивает нескольких пользователей с противоречащими интересами… сложность возрастает в геометрической прогрессии. Мало кто из непрограммистов способен на это. А грамотно составленное техническое задание — это больше половины успеха.

Умение понять противоречивую задачу, разложить ее по полочкам и придумать стройную архитектуру — это не про знание синтаксиса. Это про образ мышления. И пока пользователи не умеют мыслить системно (а они в своей массе не умеют), ни low-code, ни нейросети не отменят программиста как профессию.

Язык программирования как страховка от хаоса

Еще один примечательный нюанс. Сейчас ИИ служит переводчиком с обычного языка на язык программирования. Но зачем? Почему не сразу в машинный код? Зачем нужна лишняя прослойка?

Все потому, что язык программирования — это язык для строгого формализованного описания алгоритма. То, что написано в коде, при компиляции или интерпретации будет давать один и тот же результат из раза в раз.

ИИ же по своей природе — генератор вариативности. Один и тот же запрос, отправленный несколько раз, будет каждый раз давать другой результат. Они могут быть похожи, могут даже делать одно и то же. Но они будут разными. А это значит — разные ошибки, разные проблемы, разное взаимодействие с другим кодом.

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

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

Музыкальный пример

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

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

Художники против ИИ

Для меня возможность «рисовать» с помощью ИИ сулила множество интересных перспектив. Рисовать я не умею, но воображением не обделен и всегда страдал от невозможности перенести картинку из головы на экран или бумагу.

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

С другой стороны, ниша таких «стандартных» картинок весьма востребована. Открытки на праздник, иллюстрации к статье, заставки для видеоролика, иконки для приложения — здесь ИИ незаменим. Или, когда нужно сделать несколько вариантов одной картинки, раскадровку для фильма или игры — словом, сделать что угодно быстро и без изысков. Черновик. А для черновика идеальный инструмент — тот, который работает быстро и не требует много навыков.

Где ИИ действительно хорош

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

Полученный код, правда, лучше проверять. И для этого прекрасно подходит Test Driven Development (еще одна недавняя Next Big Thing). В связке с ИИ эта технология дает прекрасную синергию.

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

Факты, конечно, стоит перепроверять, но общий тон текста мне более чем нравится. Да, я мог бы потом сесть и переписать текст самостоятельно, в более спокойных выражениях (и раньше я так и делал), но зачем, если можно призвать на помощь ИИ?

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

Ещё одно прекрасное применение искусственного интеллекта — анализ данных. Кода, текста, изображения — да чего угодно, что можно оцифровать. Нужно разобраться в том, что написано в чужом запутанном коде? ИИ поможет. Надо проверить на орфографические и синтаксические ошибки? ИИ поможет. Надо перевести на другой язык? ИИ поможет. И часто более адекватно чем старые переводчики вроде Google/Yandex translate. Надо проверить фактологическую часть? ИИ поможет (хотя тут с оговорками).

Это далеко не все, что ИИ может. Но это то, чем я активно пользуюсь и вижу от этого пользу.

ИИ против всех

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

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

Как сканеры с распознаванием текста заменили машинисток, так и ИИ заменит ремесленников от компьютера. Не скажу, что это плохо. Халтура человека мало чем отличается от халтуры ИИ.

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

Для апологетов и ненавистников ИИ могу сказать одно: ИИ не заменит человека. Но от ИИ мы уже никуда не денемся. Это слишком удобный инструмент.

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

О современных языковых моделях

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

А все спекуляции про то, что ИИ стал разумным и может захватить мир, — лишь спекуляции.

Да, евангелисты от ИИ будут убеждать в обратном. Они продают вам эту технологию, и им надо показать, что она может всё.

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

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

То, что сейчас представляют как революционный прорыв, — это на самом деле эволюционное развитие. Революцией это стало только в статьях маркетологов.

Rust…

Прочитал новость про то, что какой-то инженер из майкрософт обещает к 2030 году избавиться от всего кода на C/C++ и перейти на Rust. Решил освежить память, посмотреть и вспомнить, что это за язык. Тем более, к C/C++ у меня накопилось достаточно претензий, что бы захотеть найти им замену.

Посмотрел.

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

fn вместо привычного func или function режет глаз. Vec вместо Vector… i32 вместо int или Int. Зачем? Что за мания сокращать до нечитаемых аббревиатур? Странно, что return оставили, а не сократили до ret.

Визуально становиться очень трудно отделить названия переменных от ключевых слов языка. i это тип или переменная? А i2, i256? Ну очень плохое решение.

Дальше больше, let для объявления константы — хорошо. Но let mut для объявления переменной??? Чем var не угодил? Куда делась страсть все сокращать?!

А зачем ввели :: для обращения к методу класса? Это уже в C++ смотрелось кошмарно. Обращения вида Configuration::TypeOfVal::SomeCoolVal — выглядят очень неопрятно. Зачем?

И таких мелочей — очень много.

Про сам язык я не могу сказать ничего. Ни плохого, ни хорошего. Мне просто не хочется продираться сквозь этот корявый синтаксис. Да я знаю что в нем есть интересные и спорные решения по работе с памятью, я знаю что он достаточно близок к C в части системного программирования. Но… Нет. На что уж я интересуюсь новыми языками и люблю в них разбираться, но Rust… Не могу и не хочу.

Единственный язык который вызывает у меня большее отторжение, это Go.

auto и const

Еще неочевидная проблема. Реализована два метода получения объекта по индексу — At. Оба возвращают ссылку. Один константный возвращает константную ссылку, потому, что есть константные методы, из которых нельзя вызывать не константные методы. Второй — для редактирования. Возвращает ссылку которую можно редактировать.

Есть код:

auto object = At(x, y);

object.field = <какое-то значение>;

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

Почему не предупредить, что объект константный и нельзя менять значение его полей? Почему не выдать ошибку? Исключение? Хоть что-то?!

Да, проблема решается просто:

Object& object = At(x, y);

Но надо же еще найти, что проблема в этом!

Вывод один: auto — Зло. Ну или не зло, но за ним надо смотреть в оба глаза.

Контейнеры и ссылки

Начал переписывать свой проект со swift на C++ и посыпались проблемы, от которых я уже отвык. Начнем по порядку.

В С++ невозможно сделать массив ссылок. Ни массив, ни контейнер из STL ссылки не поддерживают.

Объекты достаточно большие, копировать их не хочется. В классы передаются ссылками. Морочится с указателями, new и delete не вдохновляет. Что делать?

Берем smart_ptr. Начинаются проблемы. В smart_ptr нельзя обернуть this. Точнее можно, при условии если унаследовать специальный класс, если гарантировать, что объект создан через smart_ptr.

То есть, использовать smart_ptr везде нельзя. Остается зоопарк из ссылок и smart_prt.

Делаем контейнер из smart_ptr и узнаем, что он не понимает иерархию классов. Надо вручную приводить добавляемый в контейнер объект к родительскому классу.

Получается вот такая сложная конструкция:

std::vector<std::shared_ptr<Object>> Objects;
someObject= std::make_shared<SomeObject>();
Objects.push_back(std::static_pointer_cast<Object>(someObject));

То же самое на Swift:

var objects = [Objects]()
let somObject = SomeObject()
objecs.append(someObject)

И никаких «;» «<>». При том, что мы сразу получаем массив ссылок. Объекты не копируются и не надо городить над ними ничего лишнего.

Исправить нумерацию объектов

ОбновитьНумерациюОбъектов();

Код 1C v 8.х
 ОбновитьНумерациюОбъектов(<Метаданные>)    


Параметры:
<Метаданные> (необязательный, НО Если значение параметра не указано, то обновление будет выполнено для всех типов объектов)

Тип:
Массив; Объекты метаданных. Объект метаданного или массив объектов метаданных, для объектов которого будет выполнено обновление. Если значение параметра не указано, то обновление будет выполнено для всех типов объектов.

Описание:
Выполняет обновление номеров в соответствии с номерами, записанными в базе данных. После вызова данного метода все выданные, но не записанные номера, становятся невалидными, т.к. не гарантируется их уникальность. Данный метод разрешено вызывать только администратору системы.

Доступность:
Сервер, толстый клиент, внешнее соединение

Построитель отчета, агрегатная функция МАССИВ

Век живи — век учись. Для меня стало неожиданным и приятным сюрпризом, что в построителе отчетов 1С, на закладке Ресурсы, помимо стандартных агрегатных функций вроде КОЛИЧЕСТВО, МАКСИМУМ и МИНИМУМ есть функция МАССИВ, которая собирает значения вместе.

При чем, в самом построителе отчета эта функция не отображается. Надо вводить вручную.

Прекрасная функция, экономит массу усилий и времени.

Получить курс валюты на дату документа в запросе 1С

ВЫБРАТЬ
	ВложенныйЗапрос.Ссылка КАК Ссылка,
	ВложенныйЗапрос.Валюта КАК Валюта,
	ВложенныйЗапрос.ДатаКурса КАК ДатаКурса,
	КурсыВалют.Курс КАК Курс,
	КурсыВалют.Кратность КАК Кратность
ИЗ
	(ВЫБРАТЬ
		ПриобретениеТоваровУслуг.Ссылка КАК Ссылка,
		ПриобретениеТоваровУслуг.Валюта КАК Валюта,
		МАКСИМУМ(КурсыВалют.Период) КАК ДатаКурса
	ИЗ
		Документ.ПриобретениеТоваровУслуг КАК ПриобретениеТоваровУслуг
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
			ПО ПриобретениеТоваровУслуг.Валюта = КурсыВалют.Валюта
				И ПриобретениеТоваровУслуг.Дата >= КурсыВалют.Период
	
	СГРУППИРОВАТЬ ПО
		ПриобретениеТоваровУслуг.Ссылка,
		ПриобретениеТоваровУслуг.Валюта) КАК ВложенныйЗапрос
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
		ПО ВложенныйЗапрос.Валюта = КурсыВалют.Валюта
			И ВложенныйЗапрос.ДатаКурса = КурсыВалют.Период

Результат работы СКД в запросе

В модуле объекта «Отчет» добавить:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	
	КомпоновщикМакета 		= Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновкиДанных 	= КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
	
	Если МакетКомпоновкиДанных.НаборыДанных.Количество() &gt; 0 Тогда
		Сообщить(МакетКомпоновкиДанных.НаборыДанных&#91;0].Запрос);      // Итоговый текст запроса
	КонецЕсли;
	
КонецПроцедуры // ПриКомпоновкеРезультата()

Exception Details: System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (:)

Ошибка:
«Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (:).

Решение:

1. Добавить параметр в раздел system.webServer:

<security>
    <requestFiltering allowDoubleEscaping="true" />
</security>

2. Добавить параметр в раздел configuration

<system.web>
    <pages validateRequest="false" />
    <httpRuntime requestPathInvalidCharacters="" />
</system.web>


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

Источник: http://www.koderline.ru/expert/programming/article-problemy-bezopasnosti-pri-rabote-s-1s-cherez-iis/