Рекомендации по использованию API

При использовании Нейросаппорт есть 2 ключевых шага:

  1. загрузка базы знаний;
  2. запрос генеративного ответа.

Загрузка базы знаний

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

  1. Для первичной загрузки документов базы знаний используйте метод Documents Post. Для формирования index_name используйте полученный ранее префикс, значение должно начинаться с него. Например, для префикса 10_company_ название индекса может быть:

    • 10_company_archive
    • 10_company_1
    • 10_company_answers_and_recommendations
    Пример запроса для метода Documents Post
    {
      "service": "your_service",
      "product": "your_product",
      "meta": {
        "source": "исходный источник данных, зависит от клиента",
        "description": "описание индекса"
      },
      "documents": [
        {
          "doc_id": "doc42",
          "title": "Инструкция по решению такой-то технической проблемы",
          "text": "Чтобы решить такую-то техническую проблему, надо предпринять такие-то действия",
          "meta": {
            "title": "заголовок документа",
            "source_id": "исходный источник документа такой-то",
            "some_another_key": "some_another_value"
          }
        }
      ]
    }
    
  2. В дальнейшем данный index_name потребуется использовать для получения генеративных ответов. Можно использовать разные индексы для разных баз знаний, если при формировании ответа информация из них не должна пересекаться. Например, в разные индексы можно загрузить базы знаний для внутренней и для внешней поддержки или отдельно базу знаний для автоответов и отдельно — для подсказок оператору.

  3. Для обновления базы знаний также используется метод Documents Post.

  4. Проверить результат загрузки можно с помощью метода Get Index Documents, а список доступных индексов — с помощью метода Get Indexes List. Удалить документы можно с помощью метода Delete Index Documents, а индекс целиком с помощью метода Delete Index. Как работать с разными версиями индекса, описано в разделе Работа с версиями индексов.

  5. Обратите внимание, что большие документы при загрузке разбиваются на части меньшего размера. Идентификатор каждой такой части будет (идентификатор документа)_(номер части). Например, объемный документ с "doc_id": "instructions" будет загружен частями с идентификаторами "doc_id": "instructions_0", "instructions_1" и т. д.

При вызове метода Documents Post рекомендуется заранее заполнять метаинформацию об индексе для дальнейшего упрощения процессов администрирования системы. Раздел метаинформации об индексе содержит следующие поля:

  • source — Исходный источник данных, зависит от клиента. Можно указать основной источник данных, на базе которого собирался индекс.
  • description — Описание, какие данные содержит индекс.

Работа с версиями индексов

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

  • Получить информацию о текущей версии индекса можно с помощью метода Get Index Info.
  • Для переключения версии, на основе которой генерируются ответы, используйте метод Switch Index Version.
  • Для получения и загрузки документов в конкретную версию нужно явно указывать параметр index_version.
  • Обратите внимание, что при удалении документов нужно самостоятельно переключить версию или использовать параметр auto_switch.
  • При обычной загрузке документов с помощью метода Documents Post новая версия индекса будет содержать только загруженные документы, родительская версия индекса для нее отсутствует (index_parent_version будет null). При дозагрузке документов на основе существующей версии с указанием параметра diff новая версия будет содержать и документы из родительской версии, и новые загруженные документы (уже имеющиеся документы в новой версии будут актуализированы). В таком случае будет указана родительская версия индекса.

Например:

  1. Создадим индекс 10_company_archive, для этого загрузим документы с помощью метода Documents Post . diff не указываем, т. к. создается новая версия индекса.

    • Версия индекса: 1.
    • Родительская версия: null.
    • Версия для генерации ответов: 1.
  2. Дозагрузим новые документы к уже имеющимся в индексе 10_company_archive. Метод Documents Post, diff равен True, т. к. документы загружаются к уже имеющимся.

    • Версия индекса: 2.
    • Родительская версия: 1.
    • Версия для генерации ответов: 2.
  3. Вернемся к предыдущей версии со старым набором документов для генерации ответов. Метод Switch Index Version, index_version равен 1.

    • Версия индекса: 1.
    • Родительская версия: null.
    • Версия для генерации ответов: 1.
  4. Удалим часть документов из версии за ненадобностью. Метод Delete Index Documents, явно указываем параметры index_version равным 1 и auto_switch равным True для переключения на новую версию индекса после удаления документов.

    • Версия индекса: 3.
    • Родительская версия: 1.
    • Версия для генерации ответов: 3.
  5. Для генерации ответов можно использовать любую из версий, переключившись на нее с помощью метода Switch Index Version, указав index_version.

Запрос генеративного ответа

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

Внимание

Передавайте реплики в правильном порядке по возрастанию времени и даты (вначале самая «старая» реплика, в конце — самая новая), при этом завершающей должна быть реплика клиента, на которую нужно сформировать ответ.

Для этого используется метод Answer Public. В запросе указываются ранее полученные параметры service и product, а также index_name, который загружали на этапе загрузки базы знаний.

Пример запроса
{
  "service": "your_service",
  "product": "your_product",
  "dialog": [
    {
      "role": "operator",
      "text": "Добрый день, чем я могу помочь?"
    },
    {
      "role": "client",
      "text": "Помогите решить такую-то техническую проблему"
    }
  ],
  "meta_features": {
    "user_name": "...",
    "user_created_date": "..."
  },
  "index_name": "your_index_name",
  "options": {
    "filter_settings": {
      "filter_by_meta": {
        "doc_meta_key1": [
          "doc_meta_value1",
          "doc_meta_value2"
        ],
        "doc_meta_key2": [
          "doc_meta_value3",
          "doc_meta_value4"
        ]
      },
      "document_ids": [
        "doc1",
        "doc45",
        "doc99"
      ]
    }
  }
}

Роли

В запросе в поле dialog → role рекомендуется использовать значения:

  • client — реплика или запрос клиента (того, кто обращается в техническую поддержку);

  • operator — ответ оператора (если требуется ответить на диалог, уже содержащий ответы оператора);

  • bot (также можно robot) — автоматические вопросы и ответы, которые дает чат-бот, например при определения тематики обращения или генерации каких-то стандартных ответов или сообщений (если требуется ответить на диалог, уже содержащий ответы робота).

Метаданные

Метаданные — это любая дополнительная информация, относящаяся к конкретному диалогу (и специфичная по отношению к данному диалогу). Метаданные необходимы для генерации корректного ответа.

Для передачи метаданных используется блок meta_features. В него рекомендуется передавать полностью русифицированный текст в виде списка «ключ: значение»:

<Название_поля_на_русском_языке_1>: <значение поля (если текст, то на русском)>
<Название_поля_на_русском_языке_2>: <значение поля (если текст, то на русском)>
…
<Название_поля_на_русском_языке_N>: <значение поля (если текст, то на русском)>
Пример
Номер заказа: 123
Регион: Москва
Метод оплаты: Наличные

Состав метаданных определяется исходя из потенциальной пользы для ответа на вопрос (и наличия этих данных на момент генерации ответа). Очень желательно не передавать в метаданных значений, которые никогда не будут использованы в ответах. Допустимо передавать общий список метаданных в каждом запросе, хотя в определенных тематиках/ситуациях потребуется использовать только часть. Не рекомендуется составлять список длиннее 3000 символов.

Если решаемая задача не подразумевает использование метаданных, рекомендуется оставлять это поле пустым.

Гибкая фильтрация по метаданным

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

Примеры использования API

Фильтрация при запросе ответа

Фильтр должен быть задан в поле filter_by_meta_query по пути /meta_features/filter_by_meta_query.

{
    "service": "test",
    "product": "test",
    "index_name": "test_index",
    "dialog": [
        {
            "role": "client",
            "text": "Какие популярные товары порекомендуете?"
        }
    ],
    "meta_features": {
    "filter_by_meta_query": "is_popular == true AND rating >= 4.5"
    }
}

Загрузка документов с метаданными

{
    "service": "test",
    "product": "test",
    "documents": [
        {
            "doc_id": "1",
            "text": "Описание товара",
            "title": "Товар 1",
            "typed_meta": {
                "params": [
                    {
                        "name": "is_popular",
                        "value": true,
                        "param_type": "bool"
                    },
                    {
                        "name": "rating",
                        "value": 4.7,
                        "param_type": "float"
                    },
                    {
                        "name": "str_arr",
                        "value": ["a", "b", "c"],
                        "param_type": "array[string]"
                    },
                    {
                        "name": "int_arr",
                        "value": [1, 2, 3],
                        "param_type": "array[int]"
                    },
                    {
                        "name": "bool_arr",
                        "value": [true],
                        "param_type": "array[bool]"
                    },
                ]
            }
        }
    ]
}
Синтаксис запроса

Запрос представляет собой строку, состоящую из условий, соединенных операторами AND и OR с возможностью группировки с помощью скобок.

Формат условия:
название_переменной оператор значение

Поддерживаемые операторы

Базовые операторы

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

  • > — больше;
  • < — меньше;
  • == — равно;
  • != — не равно;
  • >= — больше или равно;
  • <= — меньше или равно.

Специальные операторы

Специальные операторы предназначены для работы с массивами и строками. Операторы чувствительны к регистру. Например, оператор IN существует, а оператор in — нет.

  • IN — значение входит в массив (пример: x IN [1, 2]), работает для параметров типа int/string;
  • OUT — значение не входит в массив (пример: x OUT ["a", "b"]), работает для параметров типа int/string;
  • LIKE — сравнение строки с шаблоном (пример: name LIKE "%book%");
  • NOT LIKE — сравнение строки с шаблоном (пример: name NOT LIKE "%book%"), исключает все совпадения по паттерну;
  • CONTAIN ALL — массив содержит все элементы списка (пример: int_arr CONTAIN ALL [1, 2, 3]);
  • CONTAIN ANY — массив содержит любой элемент списка (пример: int_arr CONTAIN ANY [1, 2, 3]);
  • NOT CONTAIN ALL — массив не содержит хотя бы 1 элемент списка, по сути отрицание к условию CONTAIN ALL (пример: int_arr NOT CONTAIN ALL [1, 2, 3]);
  • NOT CONTAIN ANY — массив не содержит ни одного элемента списка, по сути отрицание к условию CONTAIN ANY (пример: int_arr NOT CONTAIN ANY [1, 2, 3]).

Типы

Название типа

Соответствие в PostgreSQL

Диапазоны значений / Формат

Примеры

bool

BOOLEAN

true, false

is_active == true
is_active == false

float

FLOAT

от 1E-307 до 1E+308, Infinity, -Infinity

rating > 4.5

int

BIGINT

от -2^63 до 2^63-1

avg_cost == 1400

string

TEXT

Любая строка в двойных кавычках ("...")

title == "Test1" zone != "центр"

date

TIMESTAMPTZ

Форматы:
%Y-%m-%d %H:%M:%S.%f
%Y-%m-%d %H:%M:%S
%Y-%m-%d
(в обратных кавычках `)

date >= `2022-01-01` 
date >= `2022-01-01 15:01:01`
date >= `2022-01-01 15:01:01.12`

array[int]

BIGINT[]

Целые числа в [ ]

ids CONTAIN ANY [1, 2, 3]
scores NOT CONTAIN ANY [100, 200, 300]

array[string]

TEXT[]

Строки в [ ] (в двойных кавычках)

names CONTAIN ALL ["Alice", "Bob"]
tags NOT CONTAIN ALL ["old", "archived"]

array[bool]

BOOLEAN[]

true/false в [ ]

flags CONTAIN ALL [true, false, true]
options NOT CONTAIN ANY [true]

Примеры рабочих запросов

  1. Простые условия:
    is_popular == true AND rating >= 4.0

  2. Комбинированные условия:
    (type IN [1, 2]) OR (name LIKE "%книга%") AND date >= `2025-06-18`

  3. Сложная логика с группировкой:
    (name != "устаревшая дока" AND (prev_version_name OUT ["легаси_1", "легаси_2"])) OR title LIKE "%доступно%"

Ограничения

  1. Не поддерживаются:
    • Отрицания перед выражениями (например, !(x >= 1));
    • Обратные условия (например, [x, y] IN [1, 2] или 1 IN [x, y]);
    • Смешанные типы в массивах (например, x IN ["1", 2]);
    • Пустые массивы (например, x IN []).
  2. Строгие требования к формату:
    • Строки всегда в двойных кавычках: "текст";
    • Даты всегда в обратных кавычках: `2025-01-01`;
    • Массивы содержат значения только одного типа [1, 2, 3].

Настройки API

Формирование промпта

Чтобы передать в сервис свой шаблон промпта в теле запроса, используйте блок meta_features с предзаданным ключом custom_prompt_template.

Внутри шаблона допускаются 4 плейсхолдера (другие значения не поддерживаются):

  • {dialog_str} — обязательный;
  • {prompt_header} — опциональный;
  • {meta_str} — опциональный;
  • {knowledge_str} — опциональный.

Если эти плейсхолдеры будут найдены в custom_prompt_template, то они будут заменены на другие значения на стороне сервиса.

Предусмотрены следующие замены:

  • {dialog_str} — заменяется на переработанный для модели диалог, который обязателен для передачи в запросе и приходит в блоке dialog.

  • {meta_str} — заменяется на переработанную мета-информацию о запросе, которая передается в блоке meta_feature. Если в запросе никакие метаданные не переданы (а значит, в модель ничего передавать не нужно), то этот плейсхолдер можно убрать из custom_prompt_template.

  • {knowledge_str} — заменяется на тексты наиболее релевантных запросу документов, найденных на стороне сервиса. Если не требуется, чтобы сервис вставлял в промпт тексты релевантных документов, по которым нужно формировать ответ (то есть ответ формируется только на основании диалога), то можно убрать этот плейсхолдер из custom_prompt_template.

  • {prompt_header} — заменяется на заголовок системного промпта, который по дефолту задан на стороне сервиса. Если пользователю нужно передать в модель другие инструкции в качестве системного промпта, можно отправить ее вместо этого плейсхолдера.

Примеры данных, которые можно передать в качестве custom_prompt_template:

  • "{prompt_header}\n\n### Метаинформация: \n{meta_str}\n\n### Тексты:\n{knowledge_str}\n\n### Диалог:\n{dialog_str}" — шаблон промпта с максимальной заменой на стороне сервиса, к которому будет присоединен универсальный заголовок промпта из ссылки выше, метаинформацию запроса, тексты релевантных документов и непосредственно диалог.

  • "Помоги пользователю решить техническую проблему \n\n### Метаинформация: \n{meta_str}\n\n ### Тексты:\n{knowledge_str}\n\n ### Диалог:\n{dialog_str}" — промпт, который отдает в модель кастомный заголовок вместо универсального заголовка от сервиса.

  • "Помоги пользователю решить техническую проблему \n\n### Метаинформация: \n{meta_str}\n\n ### Диалог:\n{dialog_str}" — промпт, который отдает в модель кастомный заголовок вместо универсального заголовка от сервиса, при этом найденные тексты документов не будут использоваться.

  • "Помоги пользователю решить техническую проблему \n\n### Диалог:\n{dialog_str}" — промпт, который отдает в модель кастомный заголовок вместо универсального заголовка от сервиса, при этом найденные тексты документов не будут использоваться, а также в промпт не войдут метаданные запроса (даже если они будут переданы).

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

  • Пропишите роль и задачу модели.
  • Сформулируйте четкий алгоритм взаимодействия с Базой Знаний.
    Пример:
    • Шаг 1: Определи проблему пользователя.
    • Шаг 2: Найди в базе знаний релевантную ответу информацию.
    • Шаг 3: Сформируй ответ на проблему пользователя в соответствии с найденной информацией.
  • Укажите четкие требования к ответу (редакционная политика): напишите, как модель может, а как не может отвечать, какие есть правила и ограничения для ответов.
  • Сформулируйте правила общения для модели в крайних случаях:
    • Закрывающие сообщения для случаев, когда все проблемы пользователя уже решены, и надо попрощаться с пользователем.
    • Уточняющие сообщения для случаев, когда пользователь нечетко сформулировал запрос, и нужно попросить его конкретизировать.
    • Отказы от ответа для ситуаций, в которых вы не хотите, чтобы модель отвечала автоматически (также допускается и в Базе Знаний).
  • Допишите важную информацию, которую модели необходимо знать для ответа на запрос пользователя, и которая универсальна для всех запросов.
    Примеры:
    • Словарь общих понятий, специфичных для вашего домена.
    • Общая справочная информация.
Пример шаблона
Ты лучший оператор технической поддержки <Название вашей компании или сервиса>. Твоя задача - давать ответы на запросы пользователя в чате поддержки

Чтобы ответить пользователю, выполни следующую последовательность действий:
- Шаг 1: Определи проблему пользователя
- Шаг 2: Найди в базе знаний релевантную ответу информацию
- Шаг 3: Сформируй ответ на проблему пользователя в соответствии с найденной информацией

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

## Правила общения
### Уточнения
Если проблема пользователя не ясна, то вместо ответа используй один из следующих шаблонов:
* Шаблон (Пользователь написал непонятный набор слов)
Я вас не очень понимаю. Пожалуйста, уточните, что Вы имели в виду?

### Завершение диалога
Если все проблемы пользователя были решены и новые он еще не озвучил, то вежливо попрощайся и вырази готовность помочь в дальнейшем

### Отказ от ответа
Если пользователь хамит и не идет на контакт, ответь "Я не могу с этим помочь."

## Контекст
### Словарь понятий
* Пользователь – это ваш собеседник, с которым ты ведешь диалог.
* Сервис – это название нашего сервиса. Если пользователь его упоминает, то он имеет в виду нас

### Общая справочная информация
Ссылка на личный кабинет: https://lk.servis-nash-servis.com
Коды регионов:
  - Москва: 77
  - Санкт-Петербург: 78

## Метаинформация
{meta_str}

## База знаний
{knowledge_str}

## История диалога с пользователем
{dialog_str}

Перед составлением собственного промпта можете ознакомиться с нашими общими рекомендациями по работе с LLM и промптами:

Скоринг

Скоринг (автоматическая система оценки качества ответа) выдает вещественное число в промежутке от 1 до 5. Оценка относительная и зависит от конкретной базы знаний и бизнес-кейса — в одной ситуации для конкретной базы знаний хороший ответ могут означать оценки выше 4, но для другой ситуации и другой базы знаний хорошими будут считаться ответы с оценкой выше 3.
На пороговое значение может повлиять сложность сценария ответа и базы знаний. Рекомендуется предварительно подобрать на тестовых примерах пороговое значение оценки, с которой можно пропускать автоответы.

Внимание

Включенный скоринг может увеличить время формирования ответа. По умолчанию скоринг отключен.

Количество чанков документов, которые передаются в модель

Для управления количеством чанков, которые передаются в модель, используется параметр candidates_top_k. По умолчанию значение равно 10.

Пример запроса
{
  "service": "your_service",
  "product": "your_product",
  "dialog": [
    {
      "role": "operator",
      "text": "Добрый день, чем я могу помочь?"
    },
    {
      "role": "client",
      "text": "Помогите решить такую-то техническую проблему"
    }
  ],
  "index_name": "your_index_name"
  "candidates_top_k": 3,
  "meta_features": {
    "custom_prompt_template": "{prompt_header}\n\n### Метаинформация: \n{meta_str}\n\n### Тексты:\n{knowledge_str}\n\n### Диалог:\n{dialog_str}"
  }
}

Ограничения API

  • в тестовом периоде: 10 запросов в минуту;
  • количество загружаемых индексов: не более 5;
  • в каждом индексе не более 1000 документов, объем одного документа не более 50 000 символов.