Приделываем лапки ИИ в 1с

в 17:53, , рубрики: 1c, llm, искусственный интеллект

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

Но непростым пользователям, тем кто может связать две строчки кода, хочется чего-то большего. Было бы неплохо превратить милого, но в общем бесполезного болтуна в эффективного деятеля. И это можно сделать, в том числе в среде 1С, и не очень сильно напрягаясь

Что у нас есть.  Во-первых, модели. Сильно упрощая, чтобы обучить большую языковую модель, нужно, в частности, подготовить много пар: вопрос - правильный ответ. И где это можно было взять? Правильно, у ничего не подозревавшего на тот момент Stack Overflow. Там это все было уже в готовом виде. Большие языковые модели умеют много чего, но лучше всего у них получается в программировании, SQL запросах, JSON.

Во вторых, у нас есть API. Практически все игроки сейчас предоставляют доступ к своим моделям через API. Он, кстати, почти унифицирован. То есть, все сдирают у первопроходца, Open AI. Не всем, правда, удается удержаться, и не внести какие-нибудь изменения от себя.

В принципе, уже этого было бы достаточно. Пишем некоторое количество функций (любых). Получив запрос от пользователя на естественном языке, добавляем к этому запросу сигнатуры наших функций и просим ИИ разобраться: какую функцию и с какими параметрами следует применить. Результат просим представить в JSON. Имея на руках JSON, нам ничего не стоит запустить нужную функцию с нужными параметрами. Это работало, но с некоторыми техническими недоразумениями (время от времени JSON оказывался не совсем тот, который ожидался или вместе с JSON прилетало всякое ненужное бла-бла-бла, от которого нужно было избавляться). Поэтому, с недавних пор у нас есть в-третьих, механизм получения вызовов функций. Он есть у лидеров: Google, OpenAI, Anthropic. Есть у китайцев, которые не отстают от лидеров. К сожалению, нет у Яндекса. Есть у Сбер, но у них модель в принципиально другой весовой категории и недотягивает до Яндекса, не говоря уже о лидерах.

Механизм вызова функций сильно упрощает жизнь разработчикам. Но это не предел! Чтобы улучшить жизнь разработчикам 1С, у нас есть, в-четвертых, Библиотека искусственного интеллекта для 1С (в свободном доступе)

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

/Основная функция. Используется технология GPT для генерации текста
//Результат - текст ответа большой языковой модели (LLM) или массив вызовов функций или неопределено в случае ошибки 
//промт - текст запроса пользователя
//модель - ссылка на элемент справочника БИИ_Модели
//температура - число, уровень "креативности" ответа, 0-минимум креативности
//инструменты - необязательный, массив ссылок на справочник БИИ_Инструменты
Функция Генерация(промт, модель, температура, инструменты=неопределено) экспорт

Доступ к справочнику можно получить из обработки, которая включена в расширение 

Приделываем лапки ИИ в 1с - 1

Для примера создадим описание функции GetGoodsBalance

Приделываем лапки ИИ в 1с - 2

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

Добавим еще одно определение функции.

 

Приделываем лапки ИИ в 1с - 3

 

Теперь напишем сами функции (для типовых УТ/ERP/КА). Функция получения остатка товара будет совсем простой.

Функция GetGoodsBalance(параметры)
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(параметры);	
	данные = ПрочитатьJSON(ЧтениеJSON);
	ЧтениеJSON.Закрыть();
	запрос = новый запрос;
	запрос.Текст =
	"ВЫБРАТЬ
	|	ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток
	|ИЗ
	|	РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура.Наименование ПОДОБНО &Товар) КАК ТоварыНаСкладахОстатки";
	запрос.УстановитьПараметр("Товар","%"+данные.GoodsName+"%");
	выб = запрос.Выполнить().Выбрать();
	если выб.Следующий() тогда
		возврат строка(выб.ВНаличииОстаток);
	иначе
		возврат "Не найден товар: "+данные.GoodsName;
	конецесли;	
КонецФункции

Функция получения баланса взаиморасчетов чуть "покучерявее"
 

Функция GetMutalSettlementsBalance(параметры)
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(параметры);	
	данные = ПрочитатьJSON(ЧтениеJSON);
	ЧтениеJSON.Закрыть();
	баланс = 0;

	запрос = новый запрос;
	запрос.Текст =
	"ВЫБРАТЬ
	|	ЕСТЬNULL(РасчетыСКлиентамиОстатки.СуммаОстаток, 0) КАК СуммаОстаток
	|ИЗ
	|	РегистрНакопления.РасчетыСКлиентами.Остатки(, АналитикаУчетаПоПартнерам.Контрагент.Наименование ПОДОБНО &Контрагент) КАК РасчетыСКлиентамиОстатки";
	запрос.УстановитьПараметр("Контрагент","%"+данные.Partner+"%");
	выб = запрос.Выполнить().Выбрать();
	если выб.Следующий() тогда
		баланс=выб.СуммаОстаток;
	конецесли;	

	запрос = новый запрос;
	запрос.Текст =
	"ВЫБРАТЬ
	|	ЕСТЬNULL(РасчетыСПоставщикамиОстатки.СуммаОстаток, 0) КАК СуммаОстаток
	|ИЗ
	|	РегистрНакопления.РасчетыСПоставщиками.Остатки(, АналитикаУчетаПоПартнерам.Контрагент.Наименование ПОДОБНО &Контрагент) КАК РасчетыСПоставщикамиОстатки";
	запрос.УстановитьПараметр("Контрагент","%"+данные.Partner+"%");
	выб = запрос.Выполнить().Выбрать();
	если выб.Следующий() тогда
		баланс=баланс+выб.СуммаОстаток;
	конецесли;	
    возврат баланс;
КонецФункции

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

Процедура Вызов(имя,параметры)
	если имя="GetGoodsBalance" тогда
		Ответ = Ответ + GetGoodsBalance(параметры)+символы.ПС;
	иначеесли имя="GetMutalSettlementsBalance" тогда
		Ответ = Ответ + GetMutalSettlementsBalance(параметры)+символы.ПС;
	конецесли;	
КонецПроцедуры

 
Проверим работу. Попросим дать остаток товара.

Приделываем лапки ИИ в 1с - 4

 
 

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

Зададим вопрос по взаиморасчетам.

 

Приделываем лапки ИИ в 1с - 5

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

 

Приделываем лапки ИИ в 1с - 6

И теперь в ответ на запрос мы получим...

Приделываем лапки ИИ в 1с - 7

Говорят, что недостатки есть ни что иное, как продолжение достоинств. Так оно и есть! У нас очень хороший работник. Он никогда не разведет лапками и не скажет: "я не могу". Нет у него такой опции. Он будет искать и находить наиболее подходящие варианты для действия. Как мы уже убедились, если ничего не предпринять, это может привести к нежелательным последствиям.

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

 

Функция need_help(параметры)
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(параметры);	
	данные = ПрочитатьJSON(ЧтениеJSON);
	ЧтениеJSON.Закрыть();
	возврат "Не удалось подобрать функцию для вопроса:"+символы.ПС+данные.UserRequest;
КонецФункции

Теперь никакой путаницы

Приделываем лапки ИИ в 1с - 8

 

 

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

Автор: exwill

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js