Filler


Filler (филлер) - сущность DSL, которая используется в механизме slot-filling и заполняет слот (field) конкретным значением. Filler входит в состав сущности Field.

Примеры Filler

Ниже представлено описание основных параметров Filler, которые передаются в поле type.

Type Описание
intersection

Используется для заполнения поля одним из перечисленных в key значений. Если в нормализованном виде все слова запроса включают в себя хотя бы один пример из value, то поле примет значение key.

Используемые параметры:

  • cases - dictionary. Словарь, который может содержать в себе следующие вложения:
    • key - значение, которым будет заполнено поле. Представляет собой строку, число или булеву переменную (true/false).
    • value - список строк, с которыми проверяется совпадение.
  • default - значение по умолчанию, которым будет заполнено поле. 
{
	"type": "intersection",
	"cases": {
		"salty": [
			"соленый",
			"несладкий"
		],
		"sweet": [
			"сладкий сет",
			"карамельный"
		]
	}
}
intersection_original_text

Используется для заполнения поля одним из перечисленных в key значений. В отличие от intersection слова запроса не нормализуются, т.е. если все слова запроса включают в себя все слова хотя бы одного примера из value, то поле примет значение key.

Используемые параметры:

  • cases - dictionary. Словарь, который может содержать в себе следующие вложения:
    • key - значение, которым будет заполнено поле. Представляет собой строку, число или булеву переменную (true/false).
    • value - список строк, с которыми проверяется совпадение.
{
	"type": "intersection_original_text",
	"cases": {
		"salty": [
			"соленый",
 			"несладкий"
 		],
 		"sweet": [
			"сладкий сет",
 			"карамельный"
 		]
	}
}
number_first

Извлекает первый из токенов, который имеет token_type = NUM_TOKEN (число)

{
	"type": "number_first"
}
currency_first

Извлекает первый из токенов, который имеет token_type = CCY_TOKEN (валюта)

{
	"type": "currency_first"
}
geo

Извлекает первый из токенов, который имеет token_type = GEO_TOKEN (геолокация)

{
	"type": "geo"
}

Например, на "Нахожусь в Петербурге", филлер вернет следующее:

{
  'value': 'Санкт-Петербург',
  'locality_type': 'CITY',
  'latitude': 59.93863,
  'longitude': 30.31413,
  'capital': None,
  'locative_value': {
    'CITY': 'в Санкт-Петербурге'
  },
  'timezone': [
    [
      None,
      3.0
    ]
  ],
  'currency': [
    'RUB',
    'российский рубль'
  ],
  'country': 'Россия',
  'country_hidden': False
}
organisation

Извлекает первый из токенов, который имеет token_type = ORG_TOKEN (организация)

{
	"type": "organisation"
}
user_id

Заполняет поле текущим id пользователя: user_id.

{
	"type": "user_id"
}
external

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

  1. В references/fillers/external_fillers.json создать словарь филлеров.
  2. Зарегистрировать их согласно описанию в Расширении фреймворка (SmartAppResources - регистрация сущностей).

Используемые параметры:

  • filler - ключ Миллера.
{
	"type": "external",
	"filler": "yes_no_hard_filler"
}
regexp

Заполняет поле регулярным выражением. Применяется к оригинальному запросу клиента. Все вхождения склеиваются в строку через delimiter.

Используемые параметры:

  • exp - string. Регулярное выражение.
  • delimiter - string. Разделитель данных. По умолчанию имеет значение ","
{
	"type": "regexp",
	"exp": "\\d",
	"delimiter": ""
}
all_regexps

Заполняет поле всеми вхождениями регулярного выражения. Применяется к оригинальному запросу клиента. Все вхождения склеиваются в строку через delimiter.

Используемые параметры:

  • exps - list of string. Регулярное выражение.
  • delimiter - string. Разделитель данных. По умолчанию имеет значение ",".
  • original_text_lower - bool. Необходимость перевода текста клиента в нижний регистр. По умолчанию имеет значение False.
{
	"type": "all_regexps",
	"exps": [
		"номер[а-я]*\.?\s?(\d+)",
		"N\.?\s?(\d+)"
	],
	"delimiter": "/"
}
regexp_string_operations

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

Используемые параметры:

  • exp - string. Регулярное выражение.
  • delimiter - string. Разделитель данных. По умолчанию имеет значение ",".
  • operations - list of dictionary. Доступные type в operations: strip, rstrip, lstrip, upper, lower.
{
  "type": "regexp_string_operations",
  "exp": "1-[A-Z0-9]{7}",
  "operations": [
   {
     "type": "upper"
   },
   {
     "type": "rstrip",
     "amount": "!) "
   }
  ]
}
composite

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

Используемые параметры:

  • fillers - список филлеров.
{
	"type": "composite",
	"fillers": [
		{
			"type": "external",
			"filler": "some_filler_name"
		},
		{
			"type": "all_regexps",
	        "exps": ["номер[а-я]*\.?\s?(\d+)",
                      "N\.?\s?(\d+)"],
	        "delimiter": "/"
		}
	]
}
previous_messages_filler

Филлер-обёртка над другими филлерами. Поле заполняется при помощи filler, который применяется сначала к последнему, затем к предыдущим сообщениям до тех пор, пока поле не заполнится. Всего перебирается count последних сообщений. 

Используемые параметры:

  • filler - филлеры.
  • count - integer. Количество сообщений, которые необходимо перебрать, чтобы заполнить поле. Целое число от 1 до 5
{
	"type": "previous_messages_filler",
 	"count": 3,
 	"filler": {
		"type": "date"
 	}
}
requirement

Филлер, который вызывается только после выполнения условия requirement.

{
	"type": "requirement",
	"filler": {
		"type": "phone_number_first"
	},
	"requirement": {
    	"type": "random",
    	"percent": 10
  	}
}
else

Филлер, который срабатывает при выполнении requirement. В противном случае - срабатывает фильтр else_item. Использование else_filler не обязательно, ключ может быть пропущен.

{
	"type": "else",
	"requirement": {
    	"type": "random",
    	"percent": 10
  	},
  	"filler": {
    	"type": "number_first"
 	},
  	"else_filler": {
    	"type": "currency_first"
 	}
}
choice

Срабатывание филлеров при их доступности. При запуске по порядку проверяется requirement:

  • если он вернул True, то филлер срабатывает. Остальные requirement_fillers в этом случае не выполняются;
  • если он вернул False, то идет переход на следующий requirement.

Если не выполнен ни один из requirement_fillers и при этом указан else_filler, то будет выполнен else_filler (его использование необязательно, ключ может быть пропущен).

{
	"type": "choice",
	"requirement_fillers": [
		{
 			"type": "requirement",
    		"filler": {
      			"type": "phone_number_first"
 			},
    		"requirement": {
      			"type": "random",
      			"percent": 10
 			}
		},
  		{
 			"type": "requirement",
    		"filler": {
      			"type": "currency_first"
			},
    		"requirement": {
      			"type": "external",
      			"requirement": "some_requirement"
 			}			
  		}],
 	"else_item": {
    	"type": "number_first"
 	}
}
available_info_filler

Филлер для заполнения поля значениями, которые хранятся в полях, описанных в Parametrizer.

Используемые параметры:

  • value - строка для генерации Jinja-шаблона, в который подставляются доступные данные из полей, описанных в Parametrizer._get_user_data.
{
	"type": "available_info_filler",
	"value": "{{nlpp.payload.personInfo.inn}}"
}
get_first_person

Филлер, который возвращает ФИО из текста в нормализованном виде. 

"filler": {
	"type": "get_first_person"
}

Например, на "Расскажи про Иванову Ольгу Михайловну", филлер вернет следующее:

{
    "surname": "иванова",
    "name": "ольга",
    "patronymic": "михайловна"
}
approve

Заполнение полей подтверждения, не строгое.

True, если в нормализованном виде запрос совпадает с одним из нормализованных значений yes_words. Иначе проверяется вхождение в список нормализованных no_words, если есть вхождение - возвращается False. Иначе - None.

Можно использовать подготовленный переиспользуемый yes_no_soft_filler.

"filler": {
  "type": "approve",
  "yes_words": [
    "yes",
    "yep",
    "sure",
    "да",
    "ага",
    "угу",
    "👌",
    "👍"
 ],
  "no_words": [
    "нет",
    "no",
 ]
}
approve_strictly

Заполнение полей подтверждения, строгое.

  • Оригинальный текст запроса приводится к нижнему регистру. У каждого слова с правой стороны удаляются символы ".", "!" и ")".
  • yes_words и no_words не изменяются никак.

True, если original_text совпадает с одним из значений yes_words. Иначе проверяется вхождение в список no_words, если есть вхождение - возвращается False. Иначе - None. Можно использовать подготовленный переиспользуемый yes_no_hard_filler

"filler": {
  "type": "approve_strictly",
  "yes_words": [
    "да",
    "подтверждаю"
 ],
  "no_words": [
    "нет",
    "no",
    "отмена"
 ]
}
classifier

Заполняет поле одним из перечисленных в intents значений, которое выдает модель классификации.

Запрос клиента проходит классификацию на основе внешнего классификатора (название классификатора указывается в classifier), после чего в качестве ответа берётся класс с максимальной вероятностью.

{
    "type": "classifier",
    "intents": ["да", "нет"],
    "classifier": {
        "type": "external",
        "classifier": "classifier_name_from_classifiers_json_file"
    }
}

Как добавить свой Filler

Для добавления своего филлера необходимо:

  1. Реализовать новый Filler, производный от класса scenarios.scenario_models.field.field_filler_description.FieldFillerDescription. При этом необходимо реализовать метод extract, который вызывается для извлечения объекта, заполняющего слот (Field):

    extract(self, text_preprocessing_result: TextPreprocessingResult, user: User,
    params: Dict[str, Any] = None) -> Optional[str]
  2. Создать класс SmartAppResources (подробнее в Расширении фреймворка).
  3. Добавить в метод SmartAppResources.init_field_filler_description следующую строку:

    field_filler_description["my_filler_name"] = MyFiller

    где my_filler_name - это тип (type), с помощью которого можно вызывать объект в DSL.

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней