manual/russian/Searching/Conversational_search.md
Диалоговый поиск позволяет Manticore Buddy отвечать на вопросы по уже векторизованной таблице. Buddy извлекает самые релевантные строки через KNN-поиск, превращает эти строки в контекст и отправляет контекст вместе с историей беседы в LLM.
Им управляют из SQL с помощью:
CREATE CHAT MODELSHOW CHAT MODELSDESCRIBE CHAT MODELDROP CHAT MODELCALL CHATВызовы Conversation также доступны через HTTP JSON-эндпоинт /search. Управление чат-моделями по-прежнему доступно только через SQL.
Вам нужна векторизованная таблица и провайдер LLM. Требования к таблице описаны ниже. Учетные данные провайдера можно задать в CREATE CHAT MODEL через api_key либо передать через соответствующую переменную окружения, например OPENAI_API_KEY.
Когда запускается CALL CHAT, Buddy строит ответ с retrieval-augmented generation в таком порядке:
FLOAT_VECTOR.from='...' векторного поля.[ref:<id>], когда использует извлеченные источники.Пятый аргумент CALL CHAT внутри называется fields, но для диалогового поиска это означает векторное поле, используемое knn(...). Это не список полей для возврата. Buddy выбирает строки через SELECT *, а затем убирает векторные столбцы из полезной нагрузки sources, чтобы ответ не включал большие значения embedding.
В таблице должно быть как минимум одно поле FLOAT_VECTOR, настроенное для автополучения embeddings. Векторное поле должно содержать from='...', потому что Buddy использует эти исходные поля как контекст для LLM.
В примерах ниже используется onnx-models/all-MiniLM-L12-v2-onnx, который работает через рекомендуемый путь ONNX и не требует ключа API для embeddings.
CREATE TABLE docs (
id BIGINT,
title TEXT,
content TEXT,
embedding FLOAT_VECTOR
knn_type='hnsw'
hnsw_similarity='cosine'
model_name='onnx-models/all-MiniLM-L12-v2-onnx'
from='title,content'
) TYPE='rt';
INSERT INTO docs(id, title, content) VALUES
(1, 'Vector search', 'Vector search compares embeddings to find semantically similar documents.'),
(2, 'Full-text search', 'Full-text search matches terms and phrases in indexed text.');
Если CALL CHAT не указывает векторное поле, Buddy использует первое поле FLOAT_VECTOR, найденное в определении таблицы.
Используйте CREATE CHAT MODEL, чтобы сохранить провайдера LLM, идентификатор модели и настройки извлечения.
CREATE CHAT MODEL assistant (
model='openai:gpt-4o-mini'
);
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "CREATE CHAT MODEL assistant (model='openai:gpt-4o-mini')"
Также можно задать параметры провайдера и лимиты извлечения:
<!-- example conversational_search_create_model_extended --> <!-- intro -->CREATE CHAT MODEL support_assistant (
model='openai:gpt-4o-mini',
api_key='your-provider-api-key',
base_url='http://host.docker.internal:8787/v1',
timeout=60,
retrieval_limit=5,
max_document_length=3000
);
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "CREATE CHAT MODEL support_assistant (model='openai:gpt-4o-mini', api_key='your-provider-api-key', base_url='http://host.docker.internal:8787/v1', timeout=60, retrieval_limit=5, max_document_length=3000)"
Обычные параметры:
| Параметр | Обязателен | Описание |
|---|---|---|
model | Да | Идентификатор модели LLM в формате provider:model. |
description | Нет | Сохраненное описание. |
api_key | Нет | Ключ API провайдера, передаваемый расширению llm. |
base_url | Нет | Базовый URL провайдера или прокси. |
timeout | Нет | Тайм-аут запроса к LLM, 1..65536. |
retrieval_limit | Нет | Число документов, запрашиваемых через KNN, 1..50; по умолчанию 5. |
max_document_length | Нет | Лимит контекста на документ. 0 отключает усечение; 100..65536 усекaет; по умолчанию 2000. |
Имена чат-моделей могут содержать только буквы, цифры и символы подчеркивания.
Параметр model должен использовать формат provider:model:
model='openai:gpt-4o-mini'
Параметр api_key провайдера необязателен, если ключ провайдера уже доступен в окружении Buddy. Например, сервис Docker Compose может передавать ключи провайдера так:
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
Если api_key не задан в CREATE CHAT MODEL, расширение llm может использовать соответствующую переменную окружения провайдера. Задавайте api_key в чат-модели только если этой модели нужен другой ключ.
CALL CHATCALL CHAT(
'query',
'table',
'model_name',
'conversation_uuid',
'vector_field'
);
Аргументы только позиционные:
| Позиция | Аргумент | Обязателен | Описание |
|---|---|---|---|
| 1 | query | Да | Вопрос пользователя. |
| 2 | table | Да | Таблица для поиска. |
| 3 | model_name | Да | Имя чат-модели. |
| 4 | conversation_uuid | Нет | UUID существующей беседы или пустая строка. |
| 5 | fields / vector field | Нет | Поле FLOAT_VECTOR, используемое в knn(...). |
Аргумент таблицы должен быть обычным идентификатором таблицы, при необходимости с квалификацией database.table. Аргумент векторного поля должен быть обычным идентификатором поля.
Используйте CALL CHAT с запросом, таблицей и чат-моделью.
CALL CHAT(
'What is vector search?',
'docs',
'assistant'
);
curl -s -X POST http://localhost:9308/search \
-H 'Content-Type: application/json' \
-d '{
"chat": {
"query": "What is vector search?",
"table": "docs",
"model_name": "assistant"
}
}'
Чтобы продолжить беседу, передайте тот же UUID беседы:
<!-- example conversational_search_continue_chat --> <!-- intro -->CALL CHAT(
'Can you explain it with an example?',
'docs',
'assistant',
'docs-chat-001'
);
curl -s -X POST http://localhost:9308/search \
-H 'Content-Type: application/json' \
-d '{
"chat": {
"query": "Can you explain it with an example?",
"table": "docs",
"model_name": "assistant",
"conversation_uuid": "docs-chat-001"
}
}'
Чтобы искать по конкретному векторному полю, передайте его в качестве пятого аргумента:
<!-- example conversational_search_vector_field --> <!-- intro -->CALL CHAT(
'Find documents where the title is about vector search',
'docs',
'assistant',
'',
'title_embedding'
);
curl -s -X POST http://localhost:9308/search \
-H 'Content-Type: application/json' \
-d '{
"chat": {
"query": "Find documents where the title is about vector search",
"table": "docs",
"model_name": "assistant",
"conversation_uuid": "",
"vector_field": "title_embedding"
}
}'
Если пятый аргумент присутствует, Buddy проверяет, что поле существует и имеет тип FLOAT_VECTOR. Если аргумент опущен, Buddy определяет первое поле FLOAT_VECTOR из SHOW CREATE TABLE.
Вызовы Conversation также доступны по HTTP JSON через стандартный эндпоинт /search.
Задайте вопрос:
<!-- example conversational_search_http_chat --> <!-- intro -->curl -s -X POST http://localhost:9308/search \
-H 'Content-Type: application/json' \
-d '{
"chat": {
"query": "What is vector search?",
"table": "docs",
"model_name": "assistant",
"conversation_uuid": "docs-chat-001",
"vector_field": "embedding"
}
}'
Обязательные поля в объекте chat — query, table и model_name. Необязательные поля — conversation_uuid и vector_field. vector_field — это имя поля HTTP JSON для пятого аргумента SQL CALL CHAT. Устаревшее имя поля JSON fields принимается как псевдоним, но запрос не должен содержать одновременно vector_field и fields.
Ответы Conversation в HTTP JSON содержат те же логические столбцы, что и CALL CHAT: conversation_uuid, user_query, search_query, response, response_with_refs и sources. sources возвращается как JSON-строка, содержащая извлеченные строки-источники.
Когда Buddy требуется извлечение, он выполняет KNN-поиск по выбранному векторному полю и возвращает до retrieval_limit строк. Значение порога расстояния по умолчанию равно 0.8.
Buddy использует извлеченные строки как контекст для LLM. Те же строки возвращаются в sources, при этом knn_dist включается, а столбцы FLOAT_VECTOR удаляются.
max_document_length ограничивает объем текста из каждой исходной строки, который можно передать в LLM. Используйте 0, чтобы отключить усечение; иначе задайте значение от 100 до 65536.
CALL CHAT возвращает одну строку:
| Столбец | Описание |
|---|---|
conversation_uuid | Существующий или сгенерированный UUID беседы. |
user_query | Исходный запрос пользователя. |
search_query | Самостоятельный поисковый запрос, использованный для извлечения. |
response | Ответ LLM без встроенных ссылок. |
response_with_refs | Ответ LLM в том виде, в каком он был сгенерирован, включая встроенные ссылки [ref:<id>] на строки в sources. |
sources | Строка JSON с извлеченными исходными строками. |
Пример формы ответа:
{
"conversation_uuid": "docs-chat-001",
"user_query": "What is vector search?",
"search_query": "vector search, embeddings, similarity search",
"response": "Vector search finds similar items by comparing embeddings...",
"response_with_refs": "Vector search finds similar items by comparing embeddings... [ref:1]",
"sources": "[{\"id\":1,\"title\":\"Vector Search\",\"content\":\"...\",\"knn_dist\":0.12}]"
}
В sources векторные поля не включаются. Встроенные ссылки используют id строки-источника, а не заголовок или текст источника. Используйте response для обычного ответа и response_with_refs, когда нужно показать цитаты.
Список моделей:
<!-- example conversational_search_show_models --> <!-- intro -->SHOW CHAT MODELS;
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "SHOW CHAT MODELS"
Описание модели:
<!-- example conversational_search_describe_model --> <!-- intro -->DESCRIBE CHAT MODEL assistant;
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "DESCRIBE CHAT MODEL assistant"
Удаление модели:
<!-- example conversational_search_drop_model --> <!-- intro -->DROP CHAT MODEL assistant;
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "DROP CHAT MODEL assistant"
Безопасное удаление:
<!-- example conversational_search_drop_model_if_exists --> <!-- intro -->DROP CHAT MODEL IF EXISTS assistant;
curl -s -X POST 'http://localhost:9308/sql?mode=raw' \
-H 'Content-Type: text/plain' \
-d "DROP CHAT MODEL IF EXISTS assistant"
SHOW CHAT MODELS возвращает name, model и created_at. DESCRIBE CHAT MODEL возвращает property и value; сохраненные API-ключи показываются как HIDDEN.
Удаление чат-модели также удаляет таблицу истории бесед этой модели. История бесед хранится отдельно для каждой модели и записывается с TTL 30 дней.