Получение данных

Основой работы получения данных из таблиц Савви является специальный динамический генератор запросов (Dynamic SQL Generator - DSG). Это механизм позволяющий конвертировать запросы клиентов в SQL-запросы к таблице, таким образом получая возможность работать с неограниченными по длине таблицами не перегружая контекст модели и получая максимально точные ответы.

Что позволяет?

Использование таблиц обычно необходимо для получения:

  • актуальных цен на товары или услуги

  • информации об остатках товаров

  • списка актуальных предложений

  • динамической информации (акции, промо-коды и т.д.)

и т.д.

Требования к таблице

Основные требования по формату таблицы для ее корректного подключения следующие:

  1. Первая строка таблицы должна быть заполнена заголовками колонок таблицы

  2. Таблица не должна содержать объединение строк (такие таблицы называют обычно простыми или нормализованными).

Почему важно, чтоб таблица была простой (без объединения) - чтобы корректно работали запросы к ее данным.

Приведем пример правильной и не правильной таблицы:

Пример неправильной таблицы

Пример правильной таблицы

Подключение таблицы

Для подключения таблицы необходимо перейти в раздел Таблицы в настройках бота и выбрать один из вариантов подключения:

  • загрузка таблицы из CSV-файла

  • загрузка из файла Excel

  • подключение Google-таблицы

При подключении таблицы из CSV-файла важно, чтобы файл был сохранен в кодировке UTF-8 с разделителями - запятые.

Фундаментально процесс подключения практически идентичен, за исключением прохождения подключения Google-авторизации при подключении Google-таблицы.

При подключении статичной таблицы (CSV / XLS) необходимо просто выбрать файл.

А если речь идет о Google-таблице - нужно авторизоваться и выбрать нужную таблицу:

После выбора, откроется форма создания таблицы:

Название таблиц

Название для отображения в списке

Лист

Возможность выбора листа Google-таблицы

Частота обновления таблицы (минуты)

Время за которое таблица обновляется для ответов Савви. По умолчанию - 1440 минут - или раз в 24 часа. Кнопка обновления позволяет обновить данные в любой момент.

Использовать

Параметр определяющий будет Савви видеть таблицу или нет. По умолчанию - выключено.

Имя функции

имя функции по которой Савви будет обращаться к таблице. Подробнее о функциях в разделе "Функции"

Описание таблицы

Основная информация описывающая значение таблицы и данных хранящихся в ней данные. По описанию Савви будет понимать, когда нужно вызывать таблицу, при каких запросах.

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

Предварительный SQL-запрос

Заранее подготовленный запрос к таблице, выполняется перед запросом от нейросети. Может быть использован как предварительный фильтр. Например: Вы заранее знаете, что при любом запросе вам нужно получить из таблицы только строки, где колонка "Доступность" = "ДА". В таком случае, вы можете прописать это в предварительном запросе вместо того, чтобы говорить боту писать это.

Функции

Параметры колонок

При заполнении колонок таблицы важно соблюдать несколько правило - наименование должно быть без пробелов и должно отражать суть значений в колонке.

В таблице отображается первые 5 строк таблицы - просто для понимания какие данные в ней хранятся.

Поиск по части строки - позволяет находить данные в таблицы даже если было часть текста из колонки.

Не учитывать регистр - позволяет не учитывать регистр слова (заглавная или строчная) и находить названия написанные заглавными буквами даже если отбор сделан по слову со строчной буквы.

Всегда строка - позволяет работать с числами как со строкой.

Работа с таблицей

Первое, что важно знать - Савви понимает в какой момент нужно взять данные из таблицы по описанию таблицы.

Кроме того, всегда есть возможность обращаться к таблице как к функции из основной инструкции:

Например, для того, чтобы обратиться к таблице мы можем использовать конструкцию:

"Если клиент.......вызови функцию <название фукнции таблицы>", где <название фукнции таблицы> - конкретное название функции из таблицы, которое было создано при создании таблицы.

#ИНФОРМАЦИЯ ПО СТРОЙМАТЕРИАЛАМ
Если клиент спрашивает стоимость стройматериалов выполни следующие действия:
1. Обязательно уточни у клиента наименование материала и цвет.
2. Далее вызови функцию list_of_materials, и передай туда материал и цвет.

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

При вызове таблицы, если мы занимаемся отладкой (подробнее об отладке ниже), мы можем увидеть, что Савви создает специальный SQL-запрос к таблице для того, чтобы получить конкретные данные:

Отладка инструкций

Савви сам создает SQL-запросы при помощи специального движка (DSG), но неплохо в целом понимать принципы языка SQL-запросов, поэтому, если язык вам еще не знаком, рекомендуем почитать блок ниже:

SQL (Structured Query Language)

SQL (Structured Query Language) — это язык, который используется для работы с базами данных. Представь базу данных как большую таблицу в Excel, где хранятся всевозможные данные — например, информация о клиентах магазина, товарах, заказах и так далее. С помощью SQL мы можем добавлять данные в таблицы, извлекать их, изменять или удалять — и всё это быстро и эффективно.

Вот основные принципы и операторы, которые помогут понять, что такое SQL:

  1. SELECT — это оператор, который позволяет "достать" нужные данные из таблицы. Например, если у нас есть таблица с клиентами, и мы хотим узнать все их имена, мы пишем запрос:

    SELECT имя FROM клиенты;

    Это примерно как выбрать только одну колонку в Excel.

  2. FROM — указывает, откуда мы берем данные. В предыдущем примере мы выбрали колонку "имя" из таблицы "клиенты".

  3. WHERE — оператор для фильтрации данных. Например, если нас интересуют только те клиенты, которые живут в Москве:

    SELECT имя FROM клиенты WHERE город = 'Москва';

    Это помогает отобрать только те строки, которые соответствуют нашим условиям.

  4. INSERT INTO — позволяет добавить новую информацию в таблицу. Например, добавим нового клиента:

    INSERT INTO клиенты (имя, город) VALUES ('Иван', 'Москва');

    Это как добавить новую строку в таблицу.

  5. UPDATE — используется для изменения данных. Например, если Иван переехал из Москвы в Санкт-Петербург, то мы можем обновить его данные:

    UPDATE клиенты SET город = 'Санкт-Петербург' WHERE имя = 'Иван';
  6. DELETE — удаляет данные из таблицы. Если Иван больше не наш клиент, мы можем удалить его:

    DELETE FROM клиенты WHERE имя = 'Иван';
  7. Основные принципы SQL заключаются в том, что он работает с таблицами, состоящими из строк и колонок. Строки — это отдельные записи (например, данные конкретного клиента), а колонки — это свойства записей (например, имя, возраст, город).

SQL также может объединять таблицы. Например, у нас есть таблица с заказами и таблица с клиентами, и мы можем объединить их, чтобы увидеть, какие клиенты сделали какие заказы.

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

Отборы на запросы к таблице

Если мы говорим про пункт 1, то накладывать отбор на запросы можно путем указания того, что мы должны передать в таблицу, в рассматриваемом выше примере это был отбор по наименованию и цвету. Цвет в данном случае позволяет сужать поиск.

Пример числового отбора

Кроме того, мы можем накладывать отборы на поля с типом Дата и число.

К примеру, если мы хотим указать, чтобы Савви предоставил материалы только там, где количество больше 60, мы можем сделать это через промпт/инструкцию таким образом:

#ИНФОРМАЦИЯ ПО СТРОЙМАТЕРИАЛАМ
Если клиент спрашивает стоимость стройматериалов выполни следующие действия:
1. Обязательно уточни у клиента наименование материала и цвет.
2. Далее вызови функцию list_of_materials, и передай туда материал и цвет и 
только те, где количество > 60.

В этом случае в SQL-запрос к таблице добавится дополнительное условие и мы получим выборку с учетом дополнительного отбора:

Пример отбора с использованием LIMIT

Бывает так же, что несмотря на отборы по колонкам все равно в выборка получается большой, тем самым перегружает контекст и увеличивает стоимость запроса.

В этом случае дополнительном мы можем применять искусственное ограничение по количеству выбираемых записей из таблицы используя оператор LIMIT.

Например формулируя промпт таким образом:

#ИНФОРМАЦИЯ ПО СТРОЙМАТЕРИАЛАМ
Если клиент спрашивает стоимость стройматериалов выполни следующие действия:
1. Обязательно уточни у клиента наименование материала и цвет.
2. Далее вызови функцию list_of_materials, и передай туда материал и цвет и 
только те, где количество > 60, но не более 1 запись.

В этом случае фраза "не более N записей" позволяет наложить отбор на таблицу и получить первые N подходящие записи.

Вот что вернул отбор таблицы, здесь только одна запись:

В случае, если такой промт работает не стабильно, можно дополнительно указать в текст в скобочках подсказку для модели:

#ИНФОРМАЦИЯ ПО СТРОЙМАТЕРИАЛАМ
Если клиент спрашивает стоимость стройматериалов выполни следующие действия:
1. Обязательно уточни у клиента наименование материала и цвет.
2. Далее вызови функцию list_of_materials, и передай туда материал и цвет и 
только те, где количество > 60, но не более 3 записей (оператор LIMIT).

Предварительный SQL-запрос

Бывают случаи, когда в значениях колонки мы хотим работать с конкретными значениями. Они нам заранее известны.

Например, колонка имеет такие значение городов:

  • Москва

  • Санкт-Петербург

  • Волгоград

  • Зеленогорск

  • Тюмень

Но мы знаем, что согласно условиям задачи нам требуется находить данные только по значениям

  • Санкт-Петербург

  • Волгоград

  • Зеленогорск

Исходя из того, что мы обсуждали ранее, мы можем описать эти отборы в промте, например:

При обращении к функции <функция таблицы> находи значения только по городам "
Санкт-Петербург, Волгоград, Зеленогорск.

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

Лучшие практики

Поэтому здесь к нам на помощь приходит механизм предварительного отбора к таблице, который задается через поле Предварительный SQL-запрос. Прописав в нем предварительный запрос к таблице, мы сразу получаем готовую выборку только по этим городам без дополнительной необходимости накладывать его внутри инструкции и увеличивая тем самым контекст и нагрузку на модель:

Работа с кросс-таблицами

Существует такой тип таблиц, который называется кросс-таблицами или матрицами данных.

В этой таблице поиск данных происходит на пересечении значений первой колонки (обычно представляющей категории) и остальных колонок (представляющих другие измерения данных).

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

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

Может возникнуть вопрос, как в этом случае составлять отборы и может ли Савви сам получить данные по таким таблицам?

Да! Может!

Во-первых, даже если мы ничего не будем принудительно описывать - он с справится с задачей используя простой промпт:

1. Уточни у клиента материал и в каких городах интересует информация.
2. Обратись к таблице материалов вызвав функцию list_of_materials и 
передай туда материал и список городов.

Результат мы получим такой:

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

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

Мы можем добавить внутри описания таблицы следующий пример инструкции:

Используй этот шаблон для поиска данных по материалам и городам:
```sql
SELECT <города> FROM data WHERE наименование = <наименование материала>
Поменяй <города> and <наименование материала> с вашими критериями поиска.
```

Четко заданный шаблон при больших основных инструкциях будет давать лучшую точность.

Смысловой поиск

Платформа "Савви" позволяет реализовать поиск данных по таблице, не только с использованием типовых отборов SQL, но и через дополнительную функцию, в основе которой лежит технология векторного поиска, аналогичная поиску при работе с большими файлами.

Данный способ поиска подходит в тех случаях, когда нам надо наложить отбор на таблицу не по фиксированному значению или маске, а по смыслу, то есть найти все строки у которых содержание в колонке поиска соответствует смыслу поискового запроса. Например, на базе данной технологии реализован блок работы с Wildberries. В подсистеме WB пользователи подгружают таблицу, с типовыми вопросами клиентов и необходимыми ответами на них, а система, при получении реального вопроса клиента, уже по смыслу находит подходящие варианты и формирует ответ.

Как настроить?

Рассмотрим порядок настройки поиска по смыслам, на примере бота для автосервиса. Задачей бота является предоставление информации клиентам по стоимости услуг по ремонту автомобиля. У организации существует прайс-лист на услуги, в разрезе моделей и наименований ремонтных работ:

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

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

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

После того как мы заполнили аргументы, добавляем шаг - "вызов таблицы"

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

Примеры запросов указанные на картинке выше являются запросами со смысловым поиском. За смысловой поиск по таблице в платформе отвечает функция 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?