> For the complete documentation index, see [llms.txt](https://docs.nocodecloud.ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nocodecloud.ru/ai/vectorized-learning.md).

# Обучение ИИ векторному методу

**Искусственный интеллект стал надёжным помощником** в решении множества повседневных и профессиональных задач — от написания текстов до анализа данных. Наибольшую популярность обрели **Генеративные модели ИИ** благодаря своей способности создавать новые данные, опираясь на информацию, использованную в процессе их обучения. Объясняя простым языком, они могут создавать тексты, изображения, музыку или другие типы контента, имитируя стиль и структуру исходных данных, при этом формируя уникальные и оригинальные варианты ответа, не являющиеся дословным повторением исходного материала.

Одна из проблем, с которой часто сталкиваются пользователи, которые используют **Генеративную модель ИИ** – получение ложной или искаженной информации. Искусственный интеллект может "уверенно" отвечать неправильно, если не ограничен контекстом или не знает, где искать достоверный источник. Данное явление называют **"галлюцинацией ИИ"**.

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

Решением становится **метод подбора** — подход, при котором ИИ не "выдумывает" ответ, а **выбирает наиболее релевантный фрагмент из заранее подготовленной базы знаний**.

В данной инструкции мы подробно рассмотрим процесс **обучения ИИ методу подбора**.

### Что такое метод подбора?

{% hint style="warning" %}
**Метод подбора** — это способ, с помощью которого искусственный интеллект **находит наиболее подходящий объект** из множества возможных, основываясь на определённой логике или метрике сходства. Такой подход позволяет извлекать наиболее релевантные данные из подготовленного набора, минимизируя риск ошибки.
{% endhint %}

### Для обучения нам понадобятся следующие платформы и сервисы:

* NocoDB
* n8n
* Pinecone
* OpenAI

## Формирование базы данных

В первую очередь нам необходимо подготовить данные для загрузки в **ИИ** и сформировать базу данных в формате **вопрос-ответ**. Сделать это можно на платформе **NocoDB**, однако быстрее и проще будет создать подходящий список в **Google Sheets**.

1. Открываем **Google Sheets** и создаем таблицу в нем:

   <figure><img src="/files/D3JNX9WLPbxAK9OlyAMK" alt=""><figcaption></figcaption></figure>

   1. В созданной таблице создаем две колонки – **question** (вопрос) и **answer** (ответ).
2. Берем интересующий материал и перерабатываем его в виде вопросов и ответов на него.

   <figure><img src="https://cdn2.buildin.ai/s3/da5e416c-c9e6-40f2-97de-1d9a540f5ea4/image.png?time=1757568600&#x26;token=6e7876d601db70d0019f6eeda52df6c8&#x26;role=free" alt=""><figcaption></figcaption></figure>

   \
   \&#xNAN;**!Важно:** Чем больше будет синонимичных вопросов, тем более точно **ИИ** будет подбирать ответ. Лучше сделать минимум вопросов 10 на каждый ответ. **Один вопрос – одна строка.**

   Также советуем делать в **Google Sheet** не более **150 строчек** на каждом листе, чтобы в будущем при загрузке в базу **NocoDB** у нас не возникло проблем с импортированием.
3. После формирования базы вопросов и ответов скачиваем каждый лист в формате **CSV**.

   <figure><img src="/files/F5ihMoev0x47ZHafIF8X" alt=""><figcaption></figcaption></figure>
4. Открываем **NocoDB** и создаем в нем новую базу, для этого нажимаем на кнопочку **Create Base**.

   <figure><img src="/files/x3oCOStxUmAw1CqcPeJC" alt=""><figcaption></figcaption></figure>
5. В открывшемся окошке даем наименование и еще раз жмем на кнопку **Create Base**.

   <figure><img src="/files/QCu9QJVjQUiuATR7AvZY" alt=""><figcaption></figcaption></figure>
6. Перед импортированием таблицы из **Google Sheet** мы создаем новую таблицу.

   <figure><img src="/files/pwgMPmzYiALP1vOWk5aM" alt=""><figcaption></figcaption></figure>
7. Присваиваем ей наименование и жмем **Create Table**.

   <figure><img src="/files/m0SLZdvpgKa0klBtsxHr" alt=""><figcaption></figcaption></figure>

   \
   У нас по умолчанию открывается вот такое поле:

   <figure><img src="/files/dXhVoZkQVrkz3tun8AAB" alt=""><figcaption></figcaption></figure>
8. Поскольку таблица у нас пустая, мы должны ее заполнить колонками и выбрать в них необходимый тип данных для записи. Для начала переименуем по умолчанию созданную колонку с названием **Title**. Сделать это можно, нажав на стрелочку вниз.

   <figure><img src="/files/40nF4J3PDDPoJBMjRUG1" alt=""><figcaption></figcaption></figure>
9. Данная кнопочка развернет параметры колонки. В раскрывшемся списке действий выбираем **Edit field**.

   <figure><img src="/files/awh4MyM5fsn9eX4Cvtq9" alt=""><figcaption></figcaption></figure>
10. После этого появится окошко редактирования названия столбца и типа данных.

    <figure><img src="/files/zcKofoxVlxgOqhD8VyPc" alt=""><figcaption></figcaption></figure>

    \
    В нашем случае лучше выбрать **Long text**, чтобы было удобнее просматривать таблицу.

    <figure><img src="/files/uvJDCSJY62AI2KiOCeHv" alt=""><figcaption></figcaption></figure>
11. Сохраняем название и тип данных по кнопке **Update Field**

    <figure><img src="/files/2LbvqIpELT10ttcDuUcc" alt=""><figcaption></figcaption></figure>
12. Теперь нам нужно создать еще 4 колонки. Сделать это можно по кнопке "+"

    <figure><img src="/files/mKEHFDvzXU8sYsBGLrSH" alt=""><figcaption></figcaption></figure>

    \
    Всего у нас должно получиться 5 колонок со следующим типом данных:

    1. **question**

       Field type – Long text
    2. **answer**

       Field type – Long text
    3. **emdedded**

       Field type – Checkbox
    4. **to\_embed**

       Field type – Checkbox

       А еще в значении **Defalut value** должна стоять галочка

       <figure><img src="/files/VjQhzmXw7LBOXFYBQCrU" alt=""><figcaption></figcaption></figure>
    5. **to\_delete**

       Field type – Checkbox

    В конечном итоге у нас должно это выглядеть так:

    <figure><img src="/files/U48FGjkxah0YJ5qWFZeG" alt=""><figcaption></figcaption></figure>
13. Импортируем данные. Для того чтобы загрузить нашу имеющуюся таблицу с вопросами и ответами, нам необходимо нажать на три вертикальных строчки в верхней панели, затем **Upload → Upload CSV**

    <figure><img src="/files/F1BqL3ZplPGrXY5X7YoB" alt=""><figcaption></figcaption></figure>
14. Перед нами откроется окошко загрузки файлов. Перетягиваем таблицу из загрузок, либо загружаем по кнопке из внутреннего хранилища компьютера.

    <figure><img src="/files/POtekwH327YjxRjS7jve" alt=""><figcaption></figcaption></figure>
15. Нажимаем **Import**.

    <figure><img src="/files/zxrdT1ldohLfsS8YdT3b" alt=""><figcaption></figcaption></figure>
16. **Важно: Названия колонок в обеих таблицах должны совпадать!** Либо необходимо вручную выбрать, какой столбец из **Google Sheets** соответствует столбцу в **NocoDB**. Нажимаем **Import** еще раз, если все верно.

    <figure><img src="/files/8E7lCDxAmZSi1TgLdbhH" alt=""><figcaption></figcaption></figure>
17. При успешном импортировании должен получиться такой результат:

    <figure><img src="/files/xbAaVgTpCYOpDqLeTPLA" alt=""><figcaption></figcaption></figure>

## Создание индексов в Pinecone

**Pinecone** — это облачная векторная база данных, которую мы будем использовать для работы с искусственным интеллектом.

Когда мы передаём в ИИ текст (например, вопрос или описание), он преобразует его в **вектор** – массив чисел, который отражает смысл и контекст данного текста. Эти векторы можно сравнивать между собой: чем они ближе друг к другу в многомерном пространстве, тем более **они схожи** с текстами, из которых были получены.

При работе с большим объёмом векторных данных важно **эффективно находить похожие объекты**. Для этого используется **индекс** – специальная структура данных, оптимизированная для быстрого поиска схожих векторов.

1. Откроем интерфейс **Pinecone** и нажмем кнопку **Create index**.

   <figure><img src="/files/MT71r0Uj8TVx4KBygCPY" alt=""><figcaption></figcaption></figure>
2. После нажатия кнопки откроется окошко с настройками индекса. Здесь мы пишем название нашего индекса и ставим галочку на Custom settings.

   <figure><img src="/files/xEQVdO9dZMDDSVaWhkmr" alt=""><figcaption></figcaption></figure>
3. В разделе **Configuration** указываем размерность:\
   В поле **Dimension** вводим значение – 3072.

   <figure><img src="/files/MZTu0lSzzCDXI7q1JVxr" alt=""><figcaption></figcaption></figure>
4. Затем нажимаем **Create index**.

   <figure><img src="/files/jKA580AHC2bifc5sqjTN" alt=""><figcaption></figcaption></figure>
5. После создания индекс появится в списке. Скопируйте его ссылку – она потребуется в дальнейшем.

   <figure><img src="/files/7tcfBIuLKlVP4eFfgRmo" alt=""><figcaption></figcaption></figure>

## Обучение ИИ по базе знаний

1. Открываем **n8n** и создаем в нем новый **Workflow**
2. Наша цепочка будет выглядеть следующим образом:

   <figure><img src="/files/ksRRw6dE1xVUfFvJt9Oi" alt=""><figcaption></figcaption></figure>

### Краткое описание узлов цепочки:

**Schedule Trigger** — запускает процесс по расписанию.

**NocoDB** — получает данные из таблицы NocoDB (вопросы и ответы).

**HTTP Request** — отправляет запрос к OpenAI для генерации эмбеддингов.

**Embeddings** — формирует массив векторов.

**50 Vectors** — подготавливает массив из 50 векторов для загрузки.

**Upsert** — загружает векторы в Pinecone.

**Mark as Embedded** — помечает обработанные строки в базе как embedded.

### Рассмотрим параметры каждого узла более детально:

#### **Schedule Trigger**

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

<figure><img src="/files/g1TOSsixck8TVEhFXRkY" alt=""><figcaption></figcaption></figure>

#### **NocoDB1**

<div><figure><img src="/files/rqBptOv9mRK51y63dQcZ" alt=""><figcaption></figcaption></figure> <figure><img src="https://cdn2.buildin.ai/s3/4c33529c-9733-4b8e-bbd3-0062fc5221dc/image.png?time=1757586600&#x26;token=9f452b6b1651499c81429e161301d8c0&#x26;role=free" alt=""><figcaption></figcaption></figure></div>

{% hint style="warning" %}
**!Важный момент.** В **n8n** у вас должны быть созданы **Credential** с **NocoDB** и **Pinecone**. При создании **Credential** для **NocoDB** требуется указать **Название** и **API Token** А при создании **Credential** для **Pinecone** требуется **Название**, **Ключ API**

**Это нужно для получения доступа к сервисам.**
{% endhint %}

В текущем узле мы выбираем нужный **Credential**, **Project Name** и **Table name** (пространство в NocoDB, база в NocoDB и таблица)

В разделе **Options** в поле **Fields** пишем - I**d,question,answer**. В поле **Filter by Formula** устанавливаем фильтр:

```json
(embedded,eq,false)~and(to_embed,eq,true)~and(question,neq,)~and(question,isnot,null)~and(answer,neq,)~and(answer,isnot,null)~and(to_delete,eq,false)
```

#### HTTP-request

В данном узле мы заполняем параметры для отправки запроса, выбираем метод, пишем адрес. В **Header Parameters** пишем название заголовка **Authorization** и значение **API-ключа**, используемого для доступа к **OpenAI** в формате **Bearar OPENAI\_KEY**.

<figure><img src="/files/Etxlpzrpr9cw0hgmPYa3" alt=""><figcaption></figcaption></figure>

В теле запроса в **Body Parameters** мы пишем:

**Name:** `input`

**Value:** `{{ $json.question }}`

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

**Name:** `model`

**Value:** `text-embedding-3-large`

<figure><img src="/files/DgaEcUP9jznVU7FYwypa" alt=""><figcaption></figcaption></figure>

#### Embeddings

<figure><img src="/files/McmZ2NAlu6SXxKtJ0mvw" alt=""><figcaption></figcaption></figure>

#### 50 vectors

В ноде **code** мы пишем код:

```json
const vectors = $input.all()

.map(i => i.json)

.map((vector,index) => {

return {

values: vector.data[0].embedding,

id: "Id-" + vector.Id.toString(),

metadata: {

question: vector.question,

answer: vector.answer

}

}

})

const mark_as_embedded = vectors.map(vector => ({Id: Number(vector.id.split('-')[1]), embedded: true}))

return [{vectors,mark_as_embedded}];
```

Данный код обрабатывает данные, полученные после создания эмбеддингов, и готовит их для загрузки в векторную базу **Pinecone**, а также для пометки в базе **NocoDB**, что эти строки уже были обработаны.

#### Upsert

Ранее мы создавали индекс в **Pinecone** и сохраняли ссылку. Ее мы вставляем в поле **URL** и дописываем в адресе **/vectors/upsert**, чтобы у нас получилось:

<mark style="color:red;">https\://\<cсылка\_на\_pinecone></mark>**/vectors/upsert**

Установим следующие параметры:

* **Method:** `POST`
* **URL:** <mark style="color:red;">https\://\<cсылка\_на\_pinecone></mark>**/vectors/upsert**
* **Authentication:** `Predefined`
* **Credential Type:** `PineconeApi`
* **PineconeApi:** Выбираем заранее сохранённый API-ключ **Pinecone** для авторизации.

<figure><img src="/files/6ZMjBaIq6Jl7jTZlEIJS" alt=""><figcaption></figcaption></figure>

В **Header Parameters:**

**Name:** `accept`

**Value:** `application/json`

<figure><img src="/files/HVxiADnJBvQwHLrjui1K" alt=""><figcaption></figcaption></figure>

В **Body Parameters**:

**Name:** `vectors`

**Value:** `{{ $json.vectors }}`&#x20;

<figure><img src="/files/nTNDHbG2Ij8msCHUH7Oz" alt=""><figcaption></figcaption></figure>

#### **Mark as Embedded**

В заключительном узле цепочки обновляем данные таблицы **NocoDB**. Для этого в **URL** указываем адрес базы **NocoDB** со следующей структурой:

https\://<mark style="color:red;"><Адрес\_nocodb></mark>/api/v2/tables/<mark style="color:red;"><айди\_таблицы></mark>/records.

**Выбираем следующие значения:**

* **Method:** `PATCH`
* **URL:** https\://<mark style="color:red;"><Адрес\_nocodb></mark>/api/v2/tables/<mark style="color:red;"><айди\_таблицы></mark>/records.
* **Authentication:** `Predefined Credential type`
* **Credential Type**: `NocoDB API Token`

  &#x20;

  <figure><img src="/files/XDiDmdrjqGys2KFMfJme" alt=""><figcaption></figcaption></figure>
* &#x20;**NocoDB API Token:** (выбираем **Credential** нужной базы **NocoDB)**

В **Header Parameters** указываем:

**Name:** `accept`

**Value:** `application/json`

В **Body** пишем в поле **JSON**, меняя тип с **Fixed** на **Expression**:

```json
{{ JSON.stringify($('50 Vectors').first().json.mark_as_embedded) }}
```

<figure><img src="/files/lbh0nhevZ084W51xqyFH" alt=""><figcaption></figcaption></figure>

3. Сохраняем **Workflow** в **n8n**
4. Нажимаем на кнопочку запуска

   <figure><img src="/files/OpuM1B9uB38asOc9WcWP" alt=""><figcaption></figcaption></figure>
5. После запуска цепочки в таблице появятся галочки в колонке **embedded**. Это значит, что данные вопросы и ответы были загружены в векторную базу **Pinecone**

   <figure><img src="/files/Mr2ezScGqle0zMd9o5xP" alt=""><figcaption></figcaption></figure>

## Настройка сценария в Smartbot

1. Заходим в личный кабинет **Smartbot** и переходим в раздел **"Сценарии"**.

   <figure><img src="/files/nLvg9vbeBcOsoJK1nhyC" alt=""><figcaption></figcaption></figure>
2. Нажимаем на кнопку **"Создать сценарий"**

   <figure><img src="/files/znjo6uhdPy7uzMZL5cZO" alt=""><figcaption></figcaption></figure>
3. В открывшемся окошке пишем название сценария, затем нажимаем **"Создать"**

   <figure><img src="/files/J6VlOTASqFg8uizAGFzM" alt=""><figcaption></figcaption></figure>
4. **Рассмотрим схематически, как должен выглядеть сценарий, и разберем каждый блок по отдельности:**

   <figure><img src="/files/hz3OJNfGzgO5Y4S8jgHo" alt=""><figcaption></figcaption></figure>

**Наш сценарий будет состоять из 7 блоков:**

1. Нет подходящего сценария
2. Выполнить SmartQuery
3. Выполнить SmartQuery
4. Отправить HTTP-запрос
5. Webhook
6. Выполнить SmartQuery
7. Отправить сообщение

#### Блок 1: Нет подходящего сценария

Реагирует на любое сообщение пользователя в боте. Он запускает всю цепочку сценария.

<figure><img src="/files/iaG5VUTRyqfSSJffovaN" alt=""><figcaption></figcaption></figure>

#### Блок 2: Выполнить SmartQuery

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

<figure><img src="/files/qUnXs3qRkfZXFB3pCbYi" alt=""><figcaption></figcaption></figure>

#### Блок 3: Выполнить SmartQuery

В данном блоке мы подготавливаем данные, создаем URL и тело запроса.

<figure><img src="/files/BQEBNev1RKC60bXWWRD5" alt=""><figcaption></figcaption></figure>

```json
%string_temp% = %n8n_url% + "/webhook/test_new_request"

%body% = {
    "question": %message_text%,
    "user_id": %user_id%
}

%response_data% = {}
%response_data_status% = 0
```

**Используемые переменные:**

`%string_temp%` — (тип: строка) итоговый **URL**.

`%body%` — (тип: словарь) передаём вопрос и **ID** пользователя.

`%n8n_url%` — (тип: строка) переменная со ссылкой на ваш сервер **n8n**.

**!Важно:** **URL** должен совпадать с **URL** вызова вебхука в **n8n.**

#### Блок 4: Отправить HTTP-запрос

<figure><img src="/files/NdVF9CXuEzKaXzHz5FVt" alt=""><figcaption></figcaption></figure>

Устанавливаем следующие параметры:

* **Метод:** `POST`
* **URL:** `%string_temp%`
* **Тип тела:** `Текст`
* **Значение тела:** `{{ %body% | to_json }}`

<figure><img src="/files/iHEn3tfeLDpbCn9nu13F" alt=""><figcaption></figcaption></figure>

**В заголовках:**

* **Наименование:** content-type
* **Значение:** `application/json`&#x20;

#### &#x20;**Блок 5: Webhook**

Через этот блок мы получаем ответ из **n8n.** Чтобы он работал, мы должны создать **API-токен,** либо выбрать уже существующий.&#x20;

<figure><img src="/files/5gJlcoBZmh7rV8bVhr2u" alt=""><figcaption></figcaption></figure>

В **API-токены** выбираем **"Создать токен".**

<figure><img src="/files/aXfWLXeKYKpd2Coa6ZjO" alt=""><figcaption></figcaption></figure>

В открывшемся окошке нажимаем на кнопку **"Cоздать токен".**

<figure><img src="/files/gayl9oc7DJEcYt4W6yBP" alt=""><figcaption></figcaption></figure>

Придумываем название и создаем токен.

<figure><img src="/files/rpf2ZTPuyVKVzbMmWxs3" alt=""><figcaption></figcaption></figure>

Выбираем созданный токен и канал.

<figure><img src="/files/DlKHlUJP6FYgIXXWvs0C" alt=""><figcaption></figcaption></figure>

Данные из **Webhook** нам понадобятся в дальнейшей настройке **Workflow** в **n8n.**

#### Блок 6: Выполнить SmartQuery

Извлекаем текст ответа из **Webhook** и сохраняем его в переменную `%bot_message%`.

```json
%bot_message% = %public_api_data%['answer']
```

<figure><img src="/files/k6A34GSLnTDMiYqx3p4a" alt=""><figcaption></figcaption></figure>

#### **Блок 7: Отправить сообщение**

Выводим значение переменной `%bot_message%`в блоке **"Отправить сообщение"**.

<figure><img src="/files/ZITuYF4I3zVNzQNOgQXN" alt=""><figcaption></figcaption></figure>

## **Отправка ответа из Pinecone в Smartbot**

В данной части инструкции мы по шагам разберём, **как настроить рабочий процесс в n8n**, который будет:

* принимать запрос от пользователя через **Smartbot**
* искать наиболее подходящий ответ через **Pinecone** (векторную БД)
* отправлять его обратно пользователю

**Создаём Workflow в n8n**

1. Открываем **n8n**. Создаем новый **workflow**.
2. Наша логика будет выглядеть следующим образом:

   <figure><img src="/files/9mgRxVDthDWMoI2dZB5H" alt=""><figcaption></figcaption></figure>

**Краткое описание узлов цепочки:**

**Webhook** — принимает запрос от Smartbot (вопрос пользователя).

**Get vectorized** — отправляет вопрос в OpenAi для получения вектора.

**Get the nearest reply** — ищет наиболее близкие к вопросу вектора (совпадения) в Pinecone.

**if** — проверяет, нашлось ли совпадение.

**Code (успех)** — формирует тело ответа из Pinecone.

**HTTP Request (успех)** — отправляет ответ пользователю в Smartbot.

**Code (неудача)** — формирует тело ответа в случае отсутствия совпадения.

**HTTP Request (неудача)** — отправляет ответ в Smartbot.

### Рассмотрим параметры каждого узла более детально:

#### Webhook

Данный узел запускает весь **workflow**. Через него мы принимаем данные из **Смартбота**, а именно, вопрос пользователя и его **ID**.

<figure><img src="/files/3ocoaSfiXmAXU1EPSEBB" alt=""><figcaption></figcaption></figure>

**Параметры узла:**

* **Method:** `POST`
* **Path:** (часть **URL**, по которой по которой вызывается этот **Webhook**)
* **Respond:** `Immediately`

**!Важный момент:** **Path** должен быть идентичен тому, который мы указывали в **Смартботе** ранее.

<figure><img src="/files/2bRN51uP51Gbq9AZZbyA" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gR91RpXMNSzko5I0qzuI" alt=""><figcaption></figcaption></figure>

#### **Get vectorized**

Отправляет вопрос в OpenAI и получает его векторное представление.

**Параметры узла:**

* **Method**: `POST`
* **URL**: `https://api.openai.com/v1/embeddings`
* **Authentication**: `Predefined Credential Type`
* **Credential Type**: `OpenAi`
* **OpenAi:** (Выбираем нужный Credential OpenAi)
* **Model**: `text-embedding-3-large`

<figure><img src="/files/LrdwFohl5VYlxGP3duky" alt=""><figcaption></figcaption></figure>

В **Body Parameters:**

**Name:** `input`

**Value:** `{{ $json.question }}`

Передаем вопрос и данные модели ИИ.

**Name:** `model`

**Value:** `text-embedding-3-large`

<figure><img src="/files/fV7iKKNzmUPRGR1r87nv" alt=""><figcaption></figcaption></figure>

#### **Get the nearest reply**

Формируем запрос в векторную базу **Pinecone**, для поиска совпадений вектора вопроса с векторами из базы данных. Для этого заполняем следующие параметры:

* **Method:** `POST`
* **URL:** [https://наpinecone>/query](https://docs.nocodecloud.ru/ai/https:/наpinecone>/query)
* **Authentication:** `Predefined`
* **Credential Type:** `PineconeApi`
* **PineconeApi:** Выбираем заранее сохранённый API-ключ **Pinecone** для авторизации.

<figure><img src="/files/W2VFsv9Q2wX5DX0k0sAu" alt=""><figcaption></figcaption></figure>

**Header Parameters:**

**Name:** `accept`

**Value:** `application/json`

**Body Parameters:**

**Name:** `vector`

**Value:** `{{ $json.data[0].embedding }}`

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

**Name:** `topK`

**Value:** `10`

Указываем, сколько **самых близких векторов** (записей) мы хотим получить в ответ. В нашем случае - 10.

**Name:** `includeMetadata`

**Value:** `{{ true }}`

Указываем, что хотим получить из вектора **Pinecone** метаданные о вопросе и ответе.

#### **If**

**Проверяем, были ли найдены совпадения:**

```json
{{ $('Get the nearest reply').first().json.matches }}
```

**=** is not empty

#### **Code**

Создаем **тело (body)** для отправки данных в **Smartbot**.

```json
var data = {
  "answer": $('Get the nearest reply').first().json.matches[0].metadata.answer,//.replaceAll('"', '\"').replaceAll('\n', '\\n'),
  "score": $('Get the nearest reply').item.json.matches[0].score
}

/*Создаем переменную data, чтобы передать: ответ, найденный через Pinecone (answer) и оценку совпадения (score)
*/

var body = {
  "access_token": "d_RzF82z4TXML5_ZnMcrdJS2Y_K8kQNZNzkJZ-ORgI24v1STJEt55EgFXGEaILR6",
  "v": "0.0.1",
  "channel_id": "7779600502",
  "block_id": "6808dbe10aa22020da97a62f",
  "peer_id": $('Webhook').first().json.body.user_id,
  "data": data
}

return {
  body
}
```

В тело запроса добавляем тело вебхука из **Смартбота**:

<div><figure><img src="/files/y1gMdZ1cGZJi2HeeqEfU" alt=""><figcaption></figcaption></figure> <figure><img src="https://cdn2.buildin.ai/s3/6a5313e5-bfb2-4721-9144-b8120f88020a/image.png?time=1757586600&#x26;token=e0fef1b58a115333cc704b119f51817b&#x26;role=free" alt="" width="375"><figcaption></figcaption></figure></div>

#### **HTTP Request:**

Устанавливаем параметры для отправки подобранного ответа в **Smartbot**:

* **Method:** `POST`
* **URL:** `https://api.smartbotpro.ru/blocks/execute`
* **Authentication:** `None`
* **Body Content Type**: `JSON`
* **Body Parameters:**`{{ JSON.stringify($json.body) }}`

<div><figure><img src="/files/5jCYOg1QFFSSqLMJ31UM" alt="" width="227"><figcaption></figcaption></figure> <figure><img src="https://cdn2.buildin.ai/s3/53f20050-11cd-49bb-b184-f44c8ae0fe8b/image.png?time=1757586600&#x26;token=9e1c2ace6ec3fd0b03fe2699f165a099&#x26;role=free" alt=""><figcaption></figcaption></figure></div>

#### **Code1 (совпадений не найдено)**

Отправляем ответ в случае отсутcтвия совпадений по векторам.

```json
var data = {
  "answer": 'Ответ не найден',
  "score": 0.00
}

var body = {
   "access_token": "d_RzF82z4TXML5_ZnMcrdJS2Y_K8kQNZNzkJZ-ORgI24v1STJEt55EgFXGEaILR6",
    "v": "0.0.1",
    "channel_id": "7779600502",
    "block_id": "6808dbe10aa22020da97a62f",
    "peer_id": $('Webhook').first().json.body.user_id,
    "data": data
}

return {
  body
}
```

<figure><img src="/files/NAu7lAnsaXVk7DGMfP6l" alt=""><figcaption></figcaption></figure>

#### **HTTP Request1 (совпадений не найдено)**

Устанавливаем параметры для отправки ответа в **Smartbot**:

* **Method:** `POST`
* **URL:** `https://api.smartbotpro.ru/blocks/execute`
* **Authentication:** `None`
* **Body Content Type**: `JSON`
* **Body Parameters:**`{{ JSON.stringify($json.body) }}`

<div><figure><img src="/files/OsxY2z9IyzTTo200RZiQ" alt="" width="227"><figcaption></figcaption></figure> <figure><img src="https://cdn2.buildin.ai/s3/3b34734d-eba3-4ab6-bea8-398d2f4a31b0/image.png?time=1757586600&#x26;token=781605da59584c082a3401a2aa21b155&#x26;role=free" alt=""><figcaption></figcaption></figure></div>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nocodecloud.ru/ai/vectorized-learning.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
