[Java, Scala, API, Apache, Natural Language Processing] Язык определения интентов NlpCraft IDL
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Данная статья является продолжением заметки “Проектируем интенты с Apache NlpCraft” и содержит детальное описание возможностей языка определения интентов NlpCraft IDL, созданного для использования в NLP проектах основанных на системе Apache NlpCraft. Поддержка NlpCraft IDL добавлена в систему начиная с версии 0.7.5. Новая версия декларативного языка определения интентов, получившая название NlpCraft IDL (NlpCraft Intents Definition Language), значительно упростила процесс работы с интентами в диалоговых и поисковых системах, построенных на базе проекта Apache NlpCraft и вместе с тем расширила возможности системы.
NlpCraft IDL - это декларативный язык, позволяющий создавать определения интентов для их последующего использования в моделях Apache NlpCraft.Начнем с примеров, демонстрирующих общие возможности языка, приведем необходимые пояснения, а далее опишем конструкции языка чуть более формально. Напомню, что в точке выбора интента, NLP системы как правило уже имеют на входе обработанный пользовательский запрос, включающий в себя все полученные при разборе запроса комбинации токенов и прочую сопутствующую информацию.Примеры интентов, определенных с помощью NlpCraft IDL
intent=xa
flow="^(?:login)(^:logout)*$"
meta={'enabled': true}
term(a)={!(tok_id()) != "z"}[1,3]
term(b)={
meta_intent('enabled') == true &&
month() == 1
}
term(c)~{
@tokId = tok_id()
@usrTypes = meta_model('user_types')
(tokId == 'order' || tokId == 'order_cancel') &&
has_all(@usrTypes, list(1, 2, 3) &&
abs(meta_tok('order:size')) > 10
)
}
Пояснение:
- Имя интента - “xa”.
- Интент содержит три terms. Term - это элемент, определяющий правило, каждое из которых должно быть выполнено для срабатывания интента.
- Правило первое (a) - разобранный запрос должен содержать от одного до трех токенов с идентификаторами отличными от “z”, без учетах данных из истории диалога (тип term =) .
- Правило второе (b) - интент должен быть активен в момент срабатывания - флаг ”enabled” метаданных модели. Кроме того, такой интент может сработать лишь в январе - функция month().
- Правило третье(c) - в запросе или в истории диалога (тип term ~) должен быть найден токен с идентификатором “order” или “order_cancel”. Также должны быть учтены ограничения, наложенные на значения метаданных модели и абсолютное значение размера ордера. В определении третьего правила используются переменные, о них мы поговорим чуть позже.
- Flow. В данном разделе определено дополнительное правило, согласно которому для срабатывания интента необходимо, чтобы в рамках текущей сессии уже хотя бы один раз сработал интент с идентификатором “login”, и ни разу не срабатывал интент с идентификатором “logout”. Правило определено в виде регулярного выражения, основанного на идентификаторах предыдущих интентов пользовательской сессии. Ниже также будут рассмотрены другие способы создания подобных правил.
- Meta. Для описываемого интента определен некий набор данных, в данном случае конфигурация, с помощью которой можно включить или выключить интент.
intent=xb
flow=/#flowModelMethod/
ordered=true
term(a)=/org.mypackage.MyClass#termMethod/?
fragment(frag)
Пояснение к следующему примеру:
- Имя интента - “xb”.
- Интент может содержать один term (”a”, опционально, согласно квантификатору “?“, детальные пояснения будут приведены ниже), определенный в коде - org.mypackage.MyClass#termMethod.
- Fragment с идентификатором “frag” расширяет список terms интента, дополнительными, ранее определенными terms. Элемент “frag” должен быть определен выше в коде или доступен с помощью import.
- Flow содержит условие, заданное в коде модели в методе flowModelMethod.
Больше примеров - здесь. Разберем элементы языка более детально. Хочу обратить ваше внимание на то, что данная статья является лишь кратким обзором возможностей NlpCraft IDL и не пытается быть исчерпывающим мануалом. Перед началом полноценной работы с системой рекомендуется изучить детальное описание синтаксиса и всех возможностей языка в соответствующих разделах документации.Место определения интентов
- Интенты, определяемые с помощью NlpCraft IDL могут быть объявлены непосредственно в файлах статического определения модели. Данный подход очень удобен для простых случаев. Пример доступен по ссылке.
- Также интенты могут быть определены непосредственно в коде модели с помощью аннотаций. Пример по ссылке.
- Кроме того, интенты могут быть определены в отдельных файлах. Модели при этом будет ссылаться на определение интентов согласно указанному пути к этим файлам или URL ресурсам с помощью элемента import. Данный подход удобен при работе с большими моделями, при редактировании определений которых может оказаться полезной подсветка синтаксиса и прочие возможности предоставляемые IDE (так, например, Intellij Idea обеспечивает подсветку ключевых слов, подсказки и проверку синтаксиса файлов произвольных типов согласно заданной конфигурации). Кроме того данный подход может быть полезен при работе специалистов, не имеющих возможности или желания редактировать код напрямую. Пример доступен по ссылкам: 1, 2.
Ключевые слова NlpCraft IDLflow, fragment, import, intent, meta, ordered, term, true, false, null.
- intent, flow, fragment, meta, ordered, term - составные части определения интента.
- Ключевое слово fragment также используется для создания именованных списков terms, включаемых в определения интентов.
- import - необходим при подключении внешних файлов для возможности использования определенных в них элементов fragment, intent или других import.
- true, false, null - используются при работе со встроенными функциями, о которых мы поговорим чуть ниже.
Структура программы NlpCraft IDLПрограмма содержит набор следующих необязательных элементов, расположенных в произвольном порядке:
- import
- fragment
- intent
Отладка и запускИнтент компилируется при запуске модели и может быть отлажен лишь в процессе отладки модели. Для задания сложных интентов рекомендуется создавать их в отдельных файлах и использовать возможности редактирования, предоставляемые IDE для обеспечения начальной валидации сложных конструкций. Элементы раздела import и fragment могут быть задействованы и проверены только совместно с использующим эти элементы интентом. Структура определения импортаСодержит ключевое слово “import” и имя файла или URL ресурса в круглых скобках.Пример: import('http://mysite.com/nlp/idls/external.idl)Структура определения фрагментаСодержит ключевое слово “fragment” с именем и список terms. Terms в данном случае могут быть параметризованными. Пример простого fragment:fragment=buzz term~{tok_id() == 'x:alarm'}Пример параметризованного fragment c аргументами ‘a’ и ‘b’:
fragment=p1
term={
meta_frag('a') &&
has_any(get(meta_frag('b'), 'Москва'), list(1, 2))
}
Ниже приведен пример использования данного fragment в интенте. Аргументам ‘a’ и ‘b’ ставятся в соответствие значения параметров.
intent=i1
fragment(p1, {'a': true, 'b': {'Москва': [1, 2, 3]}})
Структура определения интентаИмя интентаОбязательный элемент. Имя - это уникальный в рамках модели идентификатор, необходимый для создания в колбеках ссылок на интент. Ниже приведен пример использования ссылки на интент "timeIntent".
@NCIntentRef("timeIntent")
fun onTimeMatch(
ctx: NCIntentMatch,
@NCIntentTerm("t1") tok: NCToken
): NCResult { ... }
Набор termsОбязательный элемент. Term - это основной элемент определения интента. В каждом term задается правило срабатывания интента на основе сконфигурированного условия, тела term. Составные части правил могут относиться к токену или опираться на какие-то иные факторы. Как определятеся term:
- Ключевое слово term. Обязательный элемент.
- Имя в круглых скобках. Опционально. Служит для создания ссылок на найденный токен в аргументах колбека, смотри пример выше, токен “t1”.
- Тип term. Обязательный элемент. Поддерживается два типа term:
- “~“ - токен может быть получен из истории диалога или из текущего запроса.
- “=“ - токен должен быть получен только из текущего запроса.
Пример: term(nums)~{tok_id() == 'nlpcraft:num'}Выбор типа term имеет смысл только для terms относящихся к токенам, в противном случае значение выставленного типа игнорируется.
- Тело term. Обязательный элемент. Существуют два способа задания тела term: с помощью встроенных функций или с помощью программного кода. Примеры:
- term(nums)={tok_id() == 'nlpcraft:num'}
- term(nums)~{true}
- term~/org.mypackage.MyClass#termMethod/?
Обратите внимание на специальный синтаксис последнего term.
- Квантификатор. Опционально. Поддерживаются следующие типы квантификаторов:
- [M, N] - условие должно сработать от N до M раз.
- * - условие должно сработать хотя бы один раз, эквивалентно [0, ∞]
- + - условие должно сработать более одного раза, эквивалентно [1, ∞]
- ? - условие должно сработать 0 или 1 раз, эквивалентно [0, 1]
Примеры:
- term(nums)={tok_id() == 'nlpcraft:num'}[1,2] - запрос должен содержать один или два токена с идентификатором “nlpcraft:num”.
- term(nums)={tok_id() == 'nlpcraft:num'}* - запрос должен содержать один или более токенов с идентификатором “nlpcraft:num”.
Подробнее о встроенных функциях NlpCraft IDL. Поддерживаемые в языке функции условно подразделяются на следующие типы:
- Основанные на базовых свойствахтокенов - идентификаторах, группах. Примеры: tok_id(), tok_groups(), tok_parent().
- Основанные на NLP свойствахтокенов - стеммах, леммах, частях речи, признаках стоп-слов. Примеры: tok_lemma(), tok_is_wordnet(), tok_swear().
- Основанные на информации о том, как токен был обнаружен в пользовательском запросе - значениях синонимов и т.д. Примеры: tok_value(), tok_is_permutated(), tok_is_direct().
- Основанные на данных о пользовательском запросе - времени запроса, типе user agent. Примеры: req_tstamp(), req_addr(), req_agent().
- Основанные на различных метаданных - токенов, модели, запроса и т.д. Примеры: meta_model('my:prop'), meta_tok('nlpcraft:num:unit'), meta_user('my:prop').
- Основанные на данных, предоставляемых NER провайдерами токенов. Пример, для “geo:city“ это может быть количество жителей или координаты, полученные из метаданных.
- Основанные на данных пользователя системы и его компании - статусы, время регистрации. Примеры: user_admin(), comp_name(), user_signup_tstamp().
- Основанные на системных данных - значениях переменных окружения, системном времени и т.д. Примеры: meta_sys('java.home'), now(), day_of_week().
- Математические, текстовые функции, функции работы с коллекциями и т.д. Примеры: lowercase("TeXt"), abs(-1.5), distinct(list(1, 2, 2, 3, 1)).
Более детальная информация и описание каждой функции - по ссылке. Тело term - это предикат, построенный на основе комбинации этих функций. Для предотвращения необходимости повторных вычислений при работе с функциями, могут быть использованы локальные переменные, пример ниже:
term(t2)={
@a = meta_model('a')
@list = list(1, 2, 3, 4)
(@a == 42 || @a == 44) && has_all(@list, list(3, 2))
}
Локальные переменные определяются с помощью специального префикса @. Их использование помогает избежать повторных вычислений и сокращает запись. Подразумевается, что существующего набора встроенных функций и средств NlpCraft IDL достаточно для определения большинства возможных term любого интента. Но при необходимости пользователь может создать свои собственные предикаты на java, scala, kotlin, groovy или другом java based языке и прописать их в теле term. То есть NlpCraft IDL может содержать ссылки на фрагменты кода, полностью написанного на других языках. Пример: term(a)=/MyClass#myMethod/На входе пользовательская функция получает аргумент, содержащий все имеющиеся данные о пользовательском запросе, а на выходе должна вернуть значение определенного типа.FragmentFragment это поименованный набор terms, создаваемый для возможности повторного использования в разных интентах. Пример по ссылке. FlowЗдесь мы определяем дополнительное правило срабатывания интента, опирающееся на данные по предыдущим срабатываниям в рамках сессии. Данное правило может быть определено на основе regex, составленного на основе идентификаторов предыдущих сработавших интентов. Пример такого определения: flow="^(?:login)(^:logout)*$" Данное правило означает, что для срабатывания интента необходимо, чтобы в рамках текущей сессии уже было срабатывание интента с идентификатором “login”, и не было с идентификатором “logout”. В случае необходимости задания более сложной логики, она также может быть вынесена в пользовательский код, написанный на Java-based языке, как и тело term. Пример определения в интенте:
@NCIntent("intent=x
flow=/com.company.dialog.Flow#customFlow/
term~{tok_id() == 'some_id'}"
)
def onX(): NCResult = { .. }
Предикат, определенный в методе customFlow(), получает на входе список с информацией по всем интентам, ранее вызванным в рамках текущей сессии, и возвращает значение типа boolean. MetaОпциональный элемент. Набор данных для задания дополнительных условий срабатывания интента представленный в формате JSON.Ordered flagОпциональный элемент. По умолчанию false. Определяет правило - должны ли токены сработавших terms быть упорядочены в запросе. Зачем вообще нужен отдельный языкЕще раз обратите внимание на то, что вся логика создания интентов, определенная с помощью NlpCraft IDL, может быть написана на любом java based языке. Зачем тогда вообще нужен этот новый язык? Даже если его синтаксис краток, прост и понятен, все равно придется потратить какое-то время на его изучение. Ниже приведем ряд аргументов в пользу использования NlpCraft IDL.
- Краткость записи. Запись на специализированном DSL всегда короче записи той же логики на базовом языке. Для интентов с небанальными правилами это может быть важно.
- В случае если NlpCraft IDL код был вынесен в отдельный файл, то редактирование IDL программы, например для изменения логики срабатывания интента, не влечет за собой необходимости пересобирать код модели и ее колбеков.
- Разнесение логики написания колбеков и логики срабатывания интентов. Данными вопросами могут заниматься разные специалисты. В силу осознанной ограниченности языковых средств, DSL проще для изучения.
- В настоящее время модели могут быть созданы на любом java based языке. В ближайших планах Apache NlpCraft расширение списка поддерживаемых языков. Использование NlpCraft IDL позволит сохранить один общий язык определения интентов для разных типов моделей в рамках одного проекта.
ЗаключениеНадеюсь вы смогли получить первое представление о возможностях языка определения интентов NlpCraft IDL и типах задач, которые можно решить с его помощью. Здесь вы найдете детальное описание языка и его возможностей. Дополнительные примеры моделей созданных на java, kotlin, groovy и scala, использующих для определения интентов NlpCraft IDL, доступны в гитхабе проекта.
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, Разработка под Linux, Законодательство в IT] Пользователь получил предупреждение от провайдера за скачивание Ubuntu
- [CMS, Java] MastermindCMS – что это такое? Система управления контентом? Фреймворк?
- [Python, MongoDB, API, Apache] Продолжаем знакомство с APIM Gravitee
- [Информационная безопасность, Разработка мобильных приложений, Разработка под Android, Google API] Обновляемся на новую версию API Android по наставлению Google
- [Венчурные инвестиции, Развитие стартапа, Финансы в IT] OpenAI и Microsoft организовали фонд на $ 100 млн для инвестиций в стартапы ИИ
- [JavaScript, Программирование, ReactJS] 7 лучших библиотек для создания молниеносно быстрых приложений ReactJS (перевод)
- [JavaScript, Google API] Google документы станут полновесными с 1 июня. Пишем скрипт для обхода этого ограничения
- [Open source, Виртуализация, Kubernetes, Openshift] Представляем OpenShift Pipelines
- [Open source, Машинное обучение, Искусственный интеллект, Голосовые интерфейсы] Golos — самый большой русскоязычный речевой датасет, размеченный вручную, теперь в открытом доступе
- [API] Бесплатный API диалоговой модели на ruGPT-3
Теги для поиска: #_java, #_scala, #_api, #_apache, #_natural_language_processing, #_apache, #_open_source, #_natural_language_processing, #_nlp, #_nlpcraft, #_intenty (интенты), #_java, #_scala, #_api, #_apache, #_natural_language_processing
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:00
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Данная статья является продолжением заметки “Проектируем интенты с Apache NlpCraft” и содержит детальное описание возможностей языка определения интентов NlpCraft IDL, созданного для использования в NLP проектах основанных на системе Apache NlpCraft. Поддержка NlpCraft IDL добавлена в систему начиная с версии 0.7.5. Новая версия декларативного языка определения интентов, получившая название NlpCraft IDL (NlpCraft Intents Definition Language), значительно упростила процесс работы с интентами в диалоговых и поисковых системах, построенных на базе проекта Apache NlpCraft и вместе с тем расширила возможности системы. NlpCraft IDL - это декларативный язык, позволяющий создавать определения интентов для их последующего использования в моделях Apache NlpCraft.Начнем с примеров, демонстрирующих общие возможности языка, приведем необходимые пояснения, а далее опишем конструкции языка чуть более формально. Напомню, что в точке выбора интента, NLP системы как правило уже имеют на входе обработанный пользовательский запрос, включающий в себя все полученные при разборе запроса комбинации токенов и прочую сопутствующую информацию.Примеры интентов, определенных с помощью NlpCraft IDL intent=xa
flow="^(?:login)(^:logout)*$" meta={'enabled': true} term(a)={!(tok_id()) != "z"}[1,3] term(b)={ meta_intent('enabled') == true && month() == 1 } term(c)~{ @tokId = tok_id() @usrTypes = meta_model('user_types') (tokId == 'order' || tokId == 'order_cancel') && has_all(@usrTypes, list(1, 2, 3) && abs(meta_tok('order:size')) > 10 ) }
intent=xb
flow=/#flowModelMethod/ ordered=true term(a)=/org.mypackage.MyClass#termMethod/? fragment(frag)
fragment=p1
term={ meta_frag('a') && has_any(get(meta_frag('b'), 'Москва'), list(1, 2)) } intent=i1
fragment(p1, {'a': true, 'b': {'Москва': [1, 2, 3]}}) @NCIntentRef("timeIntent")
fun onTimeMatch( ctx: NCIntentMatch, @NCIntentTerm("t1") tok: NCToken ): NCResult { ... }
term(t2)={
@a = meta_model('a') @list = list(1, 2, 3, 4) (@a == 42 || @a == 44) && has_all(@list, list(3, 2)) } @NCIntent("intent=x
flow=/com.company.dialog.Flow#customFlow/ term~{tok_id() == 'some_id'}" ) def onX(): NCResult = { .. }
=========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:00
Часовой пояс: UTC + 5