AACSearch / руководство
Ассистенты (RAG)
Создайте ассистента, который отвечает по вашим коллекциям, задавайте ему вопросы с сервера или из браузера, получайте ответ потоком, продолжайте диалоги и контролируйте стоимость.
Ассистент отвечает на вопросы по одной или нескольким вашим коллекциям. На каждом ходе он находит подходящие документы, передаёт их модели и возвращает ответ вместе с документами, на которых он основан. Это retrieval-augmented generation (RAG), который вы настраиваете, а не строите.
Из вашего приложения или виджета
По коллекциям ассистента
Читает документы, пишет ответ
Каждое утверждение ссылается на документ
Ответ основан на найденных документах, поэтому он ровно настолько хорош, насколько хорош поиск: возвращённые источники — первое, что стоит проверить, если ответ выглядит неверным.
Создание и изменение ассистентов требует полного ключа. Задавать вопросы можно и с поисковым ключом из браузера (см. Из браузера). Для понимания запроса внутри обычного поиска вместо чата — разбор обычного языка в фильтры или цикл уточнений с вашей собственной моделью — см. поиск на естественном языке и модели диалога.
Создание ассистента
createAssistant — POST /assistants:
const assistant = await client.assistants.createAssistant({
name: "Store help",
system_prompt: "Ты помогаешь покупателям выбрать инструмент. Отвечай только по источникам.",
collections: [
{
name: "products",
query_by: "name,description",
filter_by: "in_stock:true",
k: 5,
include_fields: "id,name,price,url",
},
],
max_sources: 6,
retrieval_mode: "single",
});
// assistant.id — нужен для каждого вызова чата| Поле | Значение |
|---|---|
name | обязательно |
collections[] | обязательно, хотя бы одна: name, query_by (добавьте поле с автоэмбеддингом для гибридного поиска), filter_by, k (документов из этой коллекции, по умолчанию 5, максимум 20), include_fields (что видит модель и что возвращается в sources), exclude_fields (векторы, внутренние id) |
system_prompt | инструкции, добавляемые в начало каждого диалога |
max_sources | верхняя граница документов на ответ по всем коллекциям — по умолчанию 5, 1–40 |
retrieval_mode | single (по умолчанию): переформулировать вопрос один раз и искать. agentic: может выполнить ещё один поиск по ключевым словам, если первые источники выглядят неполными, — выше задержка и расход кредитов |
memory_ttl_seconds | сколько можно продолжать диалог — по умолчанию 86400, минимум 60 |
model | provider (workers_ai), name (модель, которую каталог платформы предлагает для чата; по умолчанию @cf/meta/llama-3.3-70b-instruct-fp8-fast), temperature (0–2), max_output_tokens (до 4096) |
listAssistants, getAssistant и deleteAssistant делают то, что следует из
названий. updateAssistant (PUT /assistants/{assistantId}) принимает то же тело,
что и создание, поэтому отправляйте конфигурацию целиком.
Вопрос
createChatCompletion — POST /assistants/{assistantId}/chat/completions:
curl -X POST "https://api.aacsearch.com/v1/assistants/$ASSISTANT_ID/chat/completions" \
-H "X-NOVA-API-KEY: $NOVA_API_KEY" -H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Какая дрель лучше для бетона?"}]}'Запрос:
| Поле | Значение |
|---|---|
messages | обязательно — новые сообщения этого хода (role: system, user или assistant; content) |
conversation_id | продолжить существующий диалог; прошлые ходы загружаются из него |
filter_by | дополнительный фильтр поиска для этого хода, объединяется с фильтром каждой коллекции — например, категория, которую смотрит покупатель |
max_sources, retrieval_mode | переопределить настройки ассистента на этот ход |
user_id | ваш id конечного пользователя, для аналитики |
Ответ:
{
"id": "…",
"conversation_id": "…",
"message": { "role": "assistant", "content": "Для бетона выберите ударную дрель [1] …" },
"sources": [
{ "collection": "products", "document": { "id": "42", "name": "Ударная дрель, 18 В" }, "score": 0.91, "snippet": "…" }
],
"usage": { "input_tokens": 1830, "output_tokens": 164 },
"model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}sources идут в том порядке, в каком их видела модель, поэтому [1], [2] в
ответе указывают на sources[0], sources[1]. Показывайте их ссылками: именно
они делают ответ проверяемым.
Ответ потоком
streamChatCompletion — POST /assistants/{assistantId}/chat/completions/stream
— принимает то же тело и отвечает Server-Sent Events. Каждое событие — это
ChatChunk с полем type:
type | Содержит |
|---|---|
sources | документы и conversation_id — покажите их до того, как придёт текст |
delta | следующий фрагмент ответа |
usage | input_tokens, output_tokens |
done | conversation_id |
error | message |
const stream = await client.assistants.streamChatCompletion({
assistantId: assistant.id,
body: { messages: [{ role: "user", content: question }] },
});
let conversationId: string | undefined;
for await (const chunk of stream) {
if (chunk.type === "delta") process.stdout.write(chunk.delta ?? "");
if (chunk.type === "done") conversationId = chunk.conversation_id;
}Диалоги
Передавайте conversation_id из предыдущего ответа (или из события done) со
следующим ходом и только новое сообщение — историю ассистент загрузит сам. Диалог
можно продолжать в течение memory_ttl_seconds после последнего обращения.
getConversation—GET /assistants/{assistantId}/conversations/{conversationId}возвращает историю.deleteConversation— тот же путь сDELETE, например когда покупатель нажимает «начать заново».
Из браузера
createChatCompletion, streamChatCompletion, getConversation и
deleteConversation доступны поисковой области, поэтому витрина вызывает их
напрямую с поисковым ключом или короткоживущим браузерным ключом, который выпускает
ваш сервер (см. ключи виджета). С поисковым ключом:
X-NOVA-SESSION-IDобязателен (без него400) — один id на вкладку браузера.- Диалог принадлежит сессии, которая его начала; другая сессия получит
403. - AI-вызовы ограничены на сессию посетителя; сверх лимита API отвечает
429, сRetry-After, когда известно, сколько ждать.
Чат поддержки aacsearch-ui и лёгкий виджет отправляют заголовок сессии сами.
Стоимость
Каждый ход оплачивается кредитами из кошелька организации по входящим и исходящим
токенам, каким бы ключом ни был сделан запрос (см.
кредиты). Если кошелёк не покрывает ход,
API отвечает 402 с message, available и requested. Чтобы тратить меньше на
ход, уменьшите max_sources или model.max_output_tokens, оставьте в
include_fields только нужное для ответа и используйте retrieval_mode: "single".
Программные SEO-страницы
Превратите фасет в индексируемые посадочные страницы с шаблонными метатегами, сгенерируйте их из живого индекса, проверьте результат и экспортируйте sitemap.
Поиск на естественном языке и модели диалога
Регистрация моделей для nl_query (разбор обычного языка в фильтры) и conversation (многоходовая память поверх поиска) — собственное понимание запроса движком, а не RAG ассистентов.