---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.3
alternate:
  - https://yandex.ru/support/neurosupport/ru/api-recommendations.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/support/neurosupport/ru/llms.txt

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

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

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

## Загрузка базы знаний {#knowledge-base-upload}

Перед выгрузкой базы знаний проверьте ее на соответствие пункту [Рекомендации по формату базы знаний](https://yandex.ru/support/neurosupport/ru/answers-recommendations.md#base-rcmnd). Соблюдение этих рекомендаций может существенно повысить качество получаемых генеративных ответов.

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

   - `10_company_archive`
   - `10_company_1`
   - `10_company_answers_and_recommendations`
   
   {% cut "**Пример запроса для метода `Documents Post`**" %}
   
   ```json
   {
     "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"
         }
       }
     ]
   }
   ```
   
   {% endcut %}

1. В дальнейшем данный `index_name` потребуется использовать для получения генеративных ответов. Можно использовать разные индексы для разных баз знаний, если при формировании ответа информация из них не должна пересекаться. Например, в разные индексы можно загрузить базы знаний для внутренней и для внешней поддержки или отдельно базу знаний для автоответов и отдельно — для подсказок оператору.

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

1. Проверить результат загрузки можно с помощью метода `Get Index Documents`, а список доступных индексов — с помощью метода `Get Indexes List`. Удалить документы можно с помощью метода `Delete Index Documents`, а индекс целиком с помощью метода `Delete Index`. Как работать с разными версиями индекса, описано в разделе [Работа с версиями индексов](#working-index-versions).

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

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

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

### Работа с версиями индексов {#working-index-versions}

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

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

Например:

1. Создадим индекс `10_company_archive`, для этого загрузим документы с помощью метода `Documents Post` . `diff` не указываем, т.&nbsp;к. создается новая версия индекса.
   - Версия индекса: `1`.
   - Родительская версия: `null`.
   - Версия для генерации ответов: `1`.

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

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

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

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


## Запрос генеративного ответа {#request-generative-response}

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

{% note alert %}

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

{% endnote %}

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

{% cut "**Пример запроса**" %}

```json
{
  "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"
      ]
    }
  }
}
```

{% endcut %}

### Роли {#roles}

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

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

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

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

### Метаданные {#metadata}

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

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

```text
<Название_поля_на_русском_языке_1>: <значение поля (если текст, то на русском)>
<Название_поля_на_русском_языке_2>: <значение поля (если текст, то на русском)>
…
<Название_поля_на_русском_языке_N>: <значение поля (если текст, то на русском)>
```

{% cut "**Пример**" %}

```text
Номер заказа: 123
Регион: Москва
Метод оплаты: Наличные
```

{% endcut %}

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

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

## Гибкая фильтрация по метаданным {#flexible-metadata-filtering}

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

{% cut "**Примеры использования API**" %}

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

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

```json
{
    "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"
    }
}
```

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

```json
{
    "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]"
                    },
                ]
            }
        }
    ]
}
```

{% endcut %}

{% cut "**Синтаксис запроса**" %}

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

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

### Поддерживаемые операторы {#supported-operators-meta}

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

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

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

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

Специальные операторы предназначены для работы с массивами и строками. Операторы чувствительны к регистру. Например, оператор `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]`).


### Типы {#types-meta}

#|
|| **Название типа** | **Соответствие в 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]`
||
|#

### Примеры рабочих запросов {#example-work-request-meta}

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

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

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

### Ограничения {#limitations-meta}

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

{% endcut %}


## Настройки API {#api-settings}

### Формирование промпта {#transfer-custom-promt}

Чтобы передать в сервис свой шаблон промпта в теле запроса, используйте блок `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: Сформируй ответ на проблему пользователя в соответствии с найденной информацией.
- Укажите четкие требования к ответу (редакционная политика): напишите, как модель может, а как не может отвечать, какие есть правила и ограничения для ответов.
- Сформулируйте правила общения для модели в крайних случаях:
    - Закрывающие сообщения для случаев, когда все проблемы пользователя уже решены, и надо попрощаться с пользователем.
    - Уточняющие сообщения для случаев, когда пользователь нечетко сформулировал запрос, и нужно попросить его конкретизировать.
    - Отказы от ответа для ситуаций, в которых вы не хотите, чтобы модель отвечала автоматически (также допускается и в Базе Знаний).
- Допишите важную информацию, которую модели необходимо знать для ответа на запрос пользователя, и которая универсальна для всех запросов.
    Примеры:
    - Словарь общих понятий, специфичных для вашего домена.
    - Общая справочная информация.

{% cut "**Пример шаблона**" %}

```markdown
Ты лучший оператор технической поддержки <Название вашей компании или сервиса>. Твоя задача - давать ответы на запросы пользователя в чате поддержки

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

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

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

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

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

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

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

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

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

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

{% endcut %}


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

- [Рекомендации по использованию YandexGPT](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/popular-problems-solving)
- [Параметры LLM](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/introduction/llm-settings)
- [Основы работы с промптами](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/introduction/basics)
- [Элементы промпта](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/introduction/elements)
- [Общие советы для создания промптов](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/introduction/general-tips)
- [Примеры промптов](https://yandex.cloud/ru/docs/ai-studio/gpt-prompting-guide/introduction/examples)


### Скоринг {#api-scoring}

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

{% note alert %}

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

{% endnote %}

### Количество чанков документов, которые передаются в модель {#number-document-chunks-model}

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

{% cut "**Пример запроса**" %}

```json
{
  "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}"
  }
}
```

{% endcut %}

## Ограничения API {#api-limitations}

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