Получение данных
Основой работы получения данных из таблиц Савви является специальный динамический генератор запросов (Dynamic SQL Generator - DSG). Это механизм позволяющий конвертировать запросы клиентов в SQL-запросы к таблице, таким образом получая возможность работать с неограниченными по длине таблицами не перегружая контекст модели и получая максимально точные ответы.
Что позволяет?
Использование таблиц обычно необходимо для получения:
актуальных цен на товары или услуги
информации об остатках товаров
списка актуальных предложений
динамической информации (акции, промо-коды и т.д.)
и т.д.
Требования к таблице
Основные требования по формату таблицы для ее корректного подключения следующие:
Первая строка таблицы должна быть заполнена заголовками колонок таблицы
Таблица не должна содержать объединение строк (такие таблицы называют обычно простыми или нормализованными).
Почему важно, чтоб таблица была простой (без объединения) - чтобы корректно работали запросы к ее данным.
Приведем пример правильной и не правильной таблицы:
Пример неправильной таблицы
Пример правильной таблицы
Подключение таблицы
Для подключения таблицы необходимо перейти в раздел Таблицы в настройках бота и выбрать один из вариантов подключения:
загрузка таблицы из CSV-файла
загрузка из файла Excel
подключение Google-таблицы
При подключении таблицы из CSV-файла важно, чтобы файл был сохранен в кодировке UTF-8 с разделителями - запятые.
Фундаментально процесс подключения практически идентичен, за исключением прохождения подключения Google-авторизации при подключении Google-таблицы.
При подключении статичной таблицы (CSV / XLS) необходимо просто выбрать файл.
А если речь идет о Google-таблице - нужно авторизоваться и выбрать нужную таблицу:
После выбора, откроется форма создания таблицы:
Название таблиц
Название для отображения в списке
Лист
Возможность выбора листа Google-таблицы
Частота обновления таблицы (минуты)
Время за которое таблица обновляется для ответов Савви. По умолчанию - 1440 минут - или раз в 24 часа. Кнопка обновления позволяет обновить данные в любой момент.
Использовать
Параметр определяющий будет Савви видеть таблицу или нет. По умолчанию - выключено.
Имя функции
имя функции по которой Савви будет обращаться к таблице. Подробнее о функциях в разделе "Функции"
Описание таблицы
Основная информация описывающая значение таблицы и данных хранящихся в ней данные. По описанию Савви будет понимать, когда нужно вызывать таблицу, при каких запросах.
Описание очень важная составляющая, т.к. она определяет поведение и запрос, который будет формироваться к таблице.
Предварительный SQL-запрос
Заранее подготовленный запрос к таблице, выполняется перед запросом от нейросети. Может быть использован как предварительный фильтр. Например: Вы заранее знаете, что при любом запросе вам нужно получить из таблицы только строки, где колонка "Доступность" = "ДА". В таком случае, вы можете прописать это в предварительном запросе вместо того, чтобы говорить боту писать это.
Не рекомендуем ставить обновление чаще, чем раз в 30 минут, т.к. каждый раз происходит скачивание таблицы, если она слишком большая, это может вызывать нагрузку на учетную запись Google, что может привести к ограничению доступа к ней.
Параметры колонок
При заполнении колонок таблицы важно соблюдать несколько правило - наименование должно быть без пробелов и должно отражать суть значений в колонке.
В таблице отображается первые 5 строк таблицы - просто для понимания какие данные в ней хранятся.
Поиск по части строки - позволяет находить данные в таблицы даже если было часть текста из колонки.
Не учитывать регистр - позволяет не учитывать регистр слова (заглавная или строчная) и находить названия написанные заглавными буквами даже если отбор сделан по слову со строчной буквы.
Всегда строка - позволяет работать с числами как со строкой.
Работа с таблицей
Первое, что важно знать - Савви понимает в какой момент нужно взять данные из таблицы по описанию таблицы.
Кроме того, всегда есть возможность обращаться к таблице как к функции из основной инструкции:
Например, для того, чтобы обратиться к таблице мы можем использовать конструкцию:
"Если клиент.......вызови функцию <название фукнции таблицы>", где <название фукнции таблицы> - конкретное название функции из таблицы, которое было создано при создании таблицы.
Как видно из промпта, мы сначала запросили у клиента необходимые параметры, а далее передали в функцию конкретные пункты по которым нам требуется сделать отбор.
При вызове таблицы, если мы занимаемся отладкой (подробнее об отладке ниже), мы можем увидеть, что Савви создает специальный SQL-запрос к таблице для того, чтобы получить конкретные данные:
Савви сам создает SQL-запросы при помощи специального движка (DSG), но неплохо в целом понимать принципы языка SQL-запросов, поэтому, если язык вам еще не знаком, рекомендуем почитать блок ниже:
Отборы на запросы к таблице
Важно Поскольку таблицы могут содержать довольно большое количество данных и за одно обращение Савви может получать множество строк из таблицы, очень важно:
Предварительно накладывать максимально возможный отбор на запрос к таблице.
Использовать искусственное ограничение на количество выбираемых данных
Если мы говорим про пункт 1, то накладывать отбор на запросы можно путем указания того, что мы должны передать в таблицу, в рассматриваемом выше примере это был отбор по наименованию и цвету. Цвет в данном случае позволяет сужать поиск.
Пример числового отбора
Кроме того, мы можем накладывать отборы на поля с типом Дата и число.
К примеру, если мы хотим указать, чтобы Савви предоставил материалы только там, где количество больше 60, мы можем сделать это через промпт/инструкцию таким образом:
В этом случае в SQL-запрос к таблице добавится дополнительное условие и мы получим выборку с учетом дополнительного отбора:
Пример отбора с использованием LIMIT
Бывает так же, что несмотря на отборы по колонкам все равно в выборка получается большой, тем самым перегружает контекст и увеличивает стоимость запроса.
В этом случае дополнительном мы можем применять искусственное ограничение по количеству выбираемых записей из таблицы используя оператор LIMIT.
Например формулируя промпт таким образом:
В этом случае фраза "не более N записей" позволяет наложить отбор на таблицу и получить первые N подходящие записи.
Вот что вернул отбор таблицы, здесь только одна запись:
В случае, если такой промт работает не стабильно, можно дополнительно указать в текст в скобочках подсказку для модели:
Предварительный SQL-запрос
Бывают случаи, когда в значениях колонки мы хотим работать с конкретными значениями. Они нам заранее известны.
Например, колонка имеет такие значение городов:
Москва
Санкт-Петербург
Волгоград
Зеленогорск
Тюмень
Но мы знаем, что согласно условиям задачи нам требуется находить данные только по значениям
Санкт-Петербург
Волгоград
Зеленогорск
Исходя из того, что мы обсуждали ранее, мы можем описать эти отборы в промте, например:
И это будет работать, НО, наша задача всегда повышать качество ответов и снижать вероятность ошибок. Как мы ранее описывали в разделе "Лучшие практики" основой повышения качества является уменьшение инструкции и там где это возможно использование алгоритмических механизмов.
Поэтому здесь к нам на помощь приходит механизм предварительного отбора к таблице, который задается через поле Предварительный SQL-запрос. Прописав в нем предварительный запрос к таблице, мы сразу получаем готовую выборку только по этим городам без дополнительной необходимости накладывать его внутри инструкции и увеличивая тем самым контекст и нагрузку на модель:
Работа с кросс-таблицами
Существует такой тип таблиц, который называется кросс-таблицами или матрицами данных.
В этой таблице поиск данных происходит на пересечении значений первой колонки (обычно представляющей категории) и остальных колонок (представляющих другие измерения данных).
Кросс-таблицы очень удобны для представления информации, когда нужно визуализировать зависимость между двумя или более переменными, что часто используется в статистике и аналитике.
Для конкретного примера представьте, что у вас есть таблица с данными о продажах товаров, где первая колонка — это названия товаров, а остальные колонки — продажи в различных регионах. Тогда каждое значение внутри таблицы представляет собой количество продаж конкретного товара в конкретном регионе:
Может возникнуть вопрос, как в этом случае составлять отборы и может ли Савви сам получить данные по таким таблицам?
Да! Может!
Во-первых, даже если мы ничего не будем принудительно описывать - он с справится с задачей используя простой промпт:
Результат мы получим такой:
Как видно, он понял в каких колонках что находится и вызвал верные отборы.
Однако, когда речь идет о больших инструкциях, и если мы говорим о качестве и стабильности ответов, можно использовать дополнительные приемы.
Мы можем добавить внутри описания таблицы следующий пример инструкции:
Четко заданный шаблон при больших основных инструкциях будет давать лучшую точность.
Смысловой поиск
Как настроить?
Рассмотрим порядок настройки поиска по смыслам, на примере бота для автосервиса. Задачей бота является предоставление информации клиентам по стоимости услуг по ремонту автомобиля. У организации существует прайс-лист на услуги, в разрезе моделей и наименований ремонтных работ:
Сохраняем настройки таблицы и переходим на закладку действия. Добавляем новое, заполняем название функции и ее описание. Описание является инструкцией для бота, в каких случаях и для чего данная функция должна применяться.
Так как функция у нас должна будет производить поиск по запросу клиента, то мы должны в действие передать этот запрос, а также передать модель которой интересуется клиент.
После того как мы заполнили аргументы, добавляем шаг - "вызов таблицы"
Далее необходимо указать таблицу к которой будут выполняться запросы и сами запросы. Платформа позволяет задать не один запрос, а несколько. Они будут выполняться последовательно. В нашем примере было использовано два запроса. Первый запрос находил все строки по указанной клиентом модели, а второй запрос искал уже услугу.
Примеры запросов указанные на картинке выше являются запросами со смысловым поиском. За смысловой поиск по таблице в платформе отвечает функция VECTOR_SEARCH. Она имеет следующий формат:
VECTOR_SEARCH(ИмяКолонки, ПоисковыйЗапрос) >= ТочностьПоиска
Имя колонки - колонка по которой будет осуществляться смысловой поиск. Имя колонки задается при подключении таблицы, в разделе "Таблицы";
Поисковый запрос - это запрос, полученный от клиента, то есть то, что мы будем искать в таблице. Поисковой запрос передается ботом в аргумент функции. В нашем случае это аргумент "model" или "question";
Точность поиска - это число, от 0 до 1, которое задает точность поиска. Чем выше значение тем более строгим будет поиск, то есть при 1 должно быть практически полное совпадение запроса клиента и значения в поисковой колонке. Мы рекомендуем использовать значения от 0.5 до 0.8, в зависимости от условий. На примере выше поиск по модели требуется максимально строгий, поэтому стоит значение 0.8, а поиск по услугам должен возвращать все близкие по смыслу варианты - поэтому точность стоит уже ниже - 0.6.
Ниже приведем пример запроса, его можно использовать один в один, заменяя только имя колонки и имя аргумента функции (если у Вас оно указано другое):
SELECT * FROM data WHERE VECTOR_SEARCH(вопрос_по_автоработе, 'question') >= 0.6
Оптимизация цепочек запросов
Как мы упомянули выше, платформа позволяет задать не один запрос, а сразу несколько, как и сделано в описанном выше примере. Также мы видим, что в цепочке запросов, оба запроса использовали функцию векторного поиска - поиска по смыслам. Необходим отметить, что данный поиск не является быстрым и если возможно его заменить типовым поиском SQL, это надо всегда делать. В нашем примере, если мы боту дадим инструкцию узнавать у клиента точное название модели и передавать его в запрос, мы можем выполнить поиск по моделям используя оператор like (поиск по маске), и не использовать функцию векторного поиска. Это будет работать гораздо быстрее и лучше:
Last updated
Was this helpful?