Расширенные элементы паттернов
$pattern_name
$название-паттерна
— ссылка на именованный паттерн.
Использование в сценарии
Объявление паттерна:
patterns:
$thanks = (спасибо [и] [тебе|вам] [большое]|благодар*|спс|супер|супир|ура|отлично|молод*|умни*|пасиб*)
$ok = (окей|ок|okey|okay|o key|ok)
$you = (ты|вы|тебе|вам|тебя|тя|тибя|вас)
$my = (мой|моя|мое|моё|мае|маё|мне|мои|маи|мою|маю|моне|мане|манё|монё|меня|миня|моих|маих|моим|маим|моем|маем|моём|маём|мя|ма|мня|[со] мной)
Использование паттерна в сценарии:
state: Thanks
q!: * $thanks
q!: * $ok *
q!: * {мне (понятно|понятненько|ясно|ясненько) [все|всё]} *
q!: * {(понятно|понятненько|ясно|ясненько) (все|всё)} *
q!: * [премного] благодарн* *
script:
$reactions.answer("Рад помочь.\nОстались ли у вас еще вопросы?")
~lemma
~lemma
проверяет все формы слова. Слово после тильды должно стоять в словарной форме.
Например, в паттерн ~яблоко
попадут слова: яблоки
, яблок
и др.
Правило срабатывает на всех словоформах всех омонимов: слов, которые звучат и пишутся одинаково, но имеют разные значения или морфологическую форму.
Например, паттерн ~печь
сработает на словоформах существительного печь
(печи
, печью
) и глагола печь
(пеку
, печешь
).
Использование в сценарии
state: Delivery
q!: * {(заказать/заказывать/заказ/~доставка/доставляете) [~еда] * [$cafe]} * $City *
q: * $City *
script:
if (!$session.address) {
$session.address = {};
}
$session.address.city = $parseTree.City[0].value.name;
go!: ../../Delivery
$morph
Элемент $morph<свойство>
проверяет совпадение по слову с определенными грамматическими свойствами.
Список поддерживаемых свойств зависит от того, какой диалоговый движок использует проект.
botEngine: v1
Устарело
На первой версии диалогового движка для морфологического анализа используется парсер AOT. Используйте для грамматических свойств условные обозначения для русского и английского языка. Указывайте их внутри угловых скобок через пробел.
Кроме того, на этой версии $morph
позволяет проверить совпадение по одному или сразу по нескольким свойствам.
Например, элемент $morph<С им ед>
(существительное в именительном падеже и единственном числе) даст совпадения со словами кошка, банк, условие и т. д.
botEngine: v2
На второй версии диалогового движка через элемент $morph
можно указать только совпадение по частям речи.
Другие грамматические свойства не поддерживаются.
Формат обозначений для частей речи зависит от того, какой движок токенизации использует проект. Обозначения, указанные под один движок, в большинстве случаев не будут работать для другого.
Токенизатор | Ссылка на описание формата |
---|---|
kaznlp | kaznlp |
morphsrus | pymorphy2 |
mystem | mystem |
pinyin | Движок не поддерживает частеречную разметку. |
spacy | Universal Dependencies |
udpipe | Universal Dependencies |
Использование в сценарии
Элемент $morph
обычно используется для поиска совпадений по специфическим словосочетаниям.
Их сложно описать простым перечислением слов или корней слов, которые могут в них входить.
patterns:
# Паттерн для обозначений улиц
$street = (
# Первая Советская
@duckling.number $morph<П>
# Большая Ордынка
| $morph<П им> $morph<С им>
# 70 лет (Великого) Октября / ВЛКСМ
| @duckling.number лет [$morph<П>] ($morph<рд>/$morph<аббр>)
)
theme: /Jokes
state: Address
q!: * [я] живу на * $street *
a: Здорово! А я на Большой Серверной.
$regexp и $regexp_i
С помощью $regexp<шаблон>
или $regexp_i<шаблон>
вы можете использовать регулярные выражения.
Укажите в элементе шаблон, описывающий некий набор строк. Шаблон состоит из литералов и метасимволов — символов со специальным, а не буквальным значением.
Элементы срабатывают на все строки, которые соответствуют шаблону. Особенности работы элементов:
$regexp
— чувствительный к регистру букв. Также доступен под названием$regex
.$regexp_i
— нечувствительный к регистру букв.- Элементы игнорируют разницу между
е
иё
. - По умолчанию элементы игнорируют спецсимволы и знаки пунктуации до и после шаблона.
Например, элемент
$regexp<Привет>
сработает на строкуПривет!
. Вы можете изменить это поведение в конфигурационном файлеchatbot.yaml
Использование в сценарии
Объявление паттерна для обнаружения любого слова в запросе:
patterns:
$anyWord = $regexp<.+>
Объявление паттерна для обнаружения процентного значения:
patterns:
$percent = $regexp<\b([0-9][0-9]?%?)\b|\b100%?\b>
$entity
$entity<именованная сущность>
преобразует в паттерн именованную сущность.
Использование в сценарии
Объявление именованного паттерна:
$roamingRegion = $entity<RoamingRegions> || converter = RoamingRegionTagConverter
Если паттерн создан с помощью $entity<>
и converter
, его название не должно совпадать с названием сущности NLU-ядра.
Например, если в проекте есть паттерн $Example
и сущность Example
, то это может привести к ошибкам при выполнении сценария.
Использование в сценарии:
state: Проблемы
q!: *{$problems * роуминг*}*
q!: *{$someProblems * $roamingRegion}*
script:
$temp.messageForOperator = 'Пользователь испытывает проблемы с роумингом';
a: По этому вопросу Вас может проконсультировать специалист.
go!: /ПереключениеНаОператора
Здесь RoamingRegions
— название справочника, RoamingRegionTagConverter
— название конвертера.
$parseTree
появляется элемент value
, куда обычно записывается id или значение из справочника.$entity
записывает в value
только идентификатор сущности, а список ассоциированных значений содержится в справочнике.$Pattern: Alias
$Pattern::Alias
— позволяет задать псевдоним для токена, под которым токен будет помещен в $parseTree
.
Использование в сценарии
Рассмотрим пример $Number::Hour
: паттерн $Number
будет интерпретироваться в parseTree
как Hour
.
Сценарий:
q!: я приду в $Number::Hour
Запрос пользователя:
Я приду в 7
Дерево разбора:
{
"tag": "root",
"pattern": "root",
"text": "я приду в 7",
"words": [
"я",
"приду",
"в",
"7"
],
"Hour": [
{
"tag": "Hour",
"pattern": "Number",
"text": "7",
"words": [
"7"
]
}
],
"_Hour": "7",
}
Дерево разбора без использования псевдонима для сценария q!: я приду в $Number
имеет вид:
{
"tag": "root",
"pattern": "root",
"text": "я приду в 7",
"words": [
"я",
"приду",
"в",
"7"
],
"Number": [
{
"tag": "Number",
"pattern": "Number",
"text": "7",
"words": [
"7"
]
}
],
"_Number": "7",
}
Практичный прием использования $Pattern::Alias
:
state: Example
q!: сколько будет $Number::minuend минус $Number::subtrahend
q!: вычти $Number::subtrahend из $Number::minuend
a: {{ $parseTree._minuend - $parseTree._subtrahend }}
Здесь смысл $Number
зависит от положения в запросе: вычитаемое может быть названо первым или вторым числом.
(один: 1 | два: 2 …)
(один:1 | два:2 …)
— соответствие различных семантик, позволяет задать значение для той или иной фразы.
Указанное значение записывается в поле value
для $parseTree
того паттерна, в котором соответствие объявлено.
Использование в сценарии
Объявление паттерна:
$price = ((бесплатн*|ноль|0):0|(семь|7):7|(двести|200):200) [руб*]
Сценарий:
q!: {подключить услугу [за] $price}
Запрос пользователя:
Подключить бесплатную услугу
Дерево разбора:
{
"tag": "root",
"pattern": "root",
"text": "Подключить бесплатную услугу",
"words": [
"подключить",
"бесплатную",
"услугу"
],
"price": [
{
"tag": "price",
"pattern": "price",
"text": "бесплатную",
"words": [
"бесплатную"
],
"value": "0"
}
]
}
$repeat
$repeat<именованный паттерн>
— вложенный паттерн может повторяться в тексте неограниченное количество раз.
Repeat can contain only named pattern like $repeat<$Number>.
Использование в сценарии
patterns:
$color = (красный/белый/синий/зеленый/желтый/черный)
theme: /
state: asd
q!: (мой/мои) любимы* цвет* это $repeat<$color>
if: $parseTree.color.length > 1
a: Ого! Целых {{ $parseTree.color.length }}
else:
a: Почему именно {{ $parseTree._color }}?
$oneWord
$oneWord
— любое слово, число или символ.
Этот именованный паттерн доступен в любом проекте без объявления.
Использование в сценарии
state: Dialog
q!: * $you * [меня] * не (понимае*|поняла|поняли) * !
q!: [$oneWord] не то
go!: /CatchAll/CatchALLState
$nonEmptyGarbage
$nonEmptyGarbage
— произвольный текст.
Отличие от паттерна *
в том, что текст не может быть пустым, а также знаком препинания.
Этот именованный паттерн доступен в любом проекте без объявления.
Использование в сценарии
$Text = * $nonEmptyGarbage * || converter = $converters.textConverter
state: Action
q: $nonEmptyGarbage
go!: /NextStep