Диалоговый поиск позволяет 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 в таком порядке:
- Buddy загружает чат-модель.
- Buddy загружает историю беседы для переданного UUID беседы. Если UUID не передан, он создается.
- Buddy анализирует целевую таблицу и выбирает поле
FLOAT_VECTOR. - LLM решает, как обработать сообщение: выполнить новый поиск, ответить на основе предыдущего поискового контекста или ответить без извлечения.
- Когда требуется извлечение, Buddy выполняет KNN-поиск по выбранному векторному полю.
- Buddy строит контекст для LLM из исходных полей
from='...'векторного поля. - Настроенная LLM генерирует ответ на основе извлеченного контекста и любых инструкций
custom_prompt. - Buddy сохраняет сообщение пользователя и ответ ассистента в истории беседы.
Пятый аргумент CALL CHAT внутри называется fields, но для диалогового поиска это означает векторное поле, используемое knn(...). Это не список полей для возврата. Buddy выбирает строки через SELECT *, а затем убирает векторные столбцы из полезной нагрузки sources, чтобы ответ не включал большие значения embedding.
В таблице должно быть как минимум одно поле FLOAT_VECTOR, настроенное для автополучения embeddings. Векторное поле должно содержать from='...', потому что Buddy использует эти исходные поля как контекст для LLM.
В примерах ниже используется onnx-models/all-MiniLM-L12-v2-onnx, который работает через рекомендуемый путь ONNX и не требует ключа API для embeddings.
- SQL
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, идентификатор модели и настройки извлечения.
- SQL
- JSON
CREATE CHAT MODEL assistant (
model='openai:gpt-4o-mini'
);Также можно задать параметры провайдера и лимиты извлечения:
- SQL
- JSON
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 |
Нет | Сохраненное описание. |
custom_prompt |
Нет | Инструкции промпта, используемые для построения ответа на основе извлеченного контекста и истории беседы. Если задано, значение должно быть непустым и не превышать 32768 байт. |
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 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. Аргумент векторного поля должен быть обычным идентификатором поля.
Когда Buddy отправляет запрос в LLM, он объединяет инструкции для ответа с блоками данных, содержащими текущую историю беседы, извлеченный контекст и запрос пользователя. По умолчанию Buddy использует собственные инструкции для ответа. Задайте custom_prompt в CREATE CHAT MODEL, чтобы заменить эти стандартные инструкции своими. Значение должно содержать непустой текст без пробельных символов и не должно превышать 32768 байт. Buddy по-прежнему добавляет после ваших пользовательских инструкций блоки истории, контекста и запроса, поэтому пишите промпт так, чтобы он объяснял, как LLM должна использовать эти разделы.
Например, чтобы каждый элемент ответа указывал строку-источник, которая его подтверждает, создайте модель с таким промптом:
CREATE CHAT MODEL cited_assistant (
model='openai:gpt-4o-mini',
custom_prompt='You are a context-only answer writer.
Answer using only the provided context. Do not use outside knowledge, memory, assumptions, or unsupported facts.
Keep the answer concise and under 4096 tokens.
Citation rules:
- Every item must end with a citation.
- Never include a reference ID within the item itself.
- In the end of the item, append the reference context ID (`context[].id`) in the format `[ref:<id>]`.
- Do not duplicate the references in the end of the whole answer.
If the provided context does not contain enough information, answer exactly:
I don\'t have enough information in the provided context to answer.'
);
Используйте CALL CHAT с запросом, таблицей и чат-моделью.
- SQL
- HTTP
CALL CHAT(
'What is vector search?',
'docs',
'assistant'
);Чтобы продолжить беседу, передайте тот же UUID беседы:
- SQL
- HTTP
CALL CHAT(
'Can you explain it with an example?',
'docs',
'assistant',
'docs-chat-001'
);Чтобы искать по конкретному векторному полю, передайте его в качестве пятого аргумента:
- SQL
- HTTP
CALL CHAT(
'Find documents where the title is about vector search',
'docs',
'assistant',
'',
'title_embedding'
);Если пятый аргумент присутствует, Buddy проверяет, что поле существует и имеет тип FLOAT_VECTOR. Если аргумент опущен, Buddy определяет первое поле FLOAT_VECTOR из SHOW CREATE TABLE.
Вызовы беседы доступны по HTTP JSON через стандартный endpoint /search.
Задайте вопрос:
- HTTP
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.
Ответы HTTP JSON для беседы содержат те же логические столбцы, что и CALL CHAT: conversation_uuid, user_query, search_query, response и 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. |
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...",
"sources": "[{\"id\":1,\"title\":\"Vector Search\",\"content\":\"...\",\"knn_dist\":0.12}]"
}
Векторные поля не включаются в sources. Если вам нужны цитаты источников, добавьте инструкции по цитированию в custom_prompt; id строки-источника доступен в контексте и в payload sources.
Список моделей:
- SQL
- JSON
SHOW CHAT MODELS;Описание модели:
- SQL
- JSON
DESCRIBE CHAT MODEL assistant;Удаление модели:
- SQL
- JSON
DROP CHAT MODEL assistant;Безопасное удаление:
- SQL
- JSON
DROP CHAT MODEL IF EXISTS assistant;SHOW CHAT MODELS возвращает name, model и created_at. DESCRIBE CHAT MODEL возвращает property и value; сохраненные API-ключи показываются как HIDDEN.
Удаление чат-модели также удаляет таблицу истории бесед этой модели. История бесед хранится отдельно для каждой модели и записывается с TTL 30 дней.