RAG-ассистент
Ответы со ссылками на источники, диалоговый ассистент со стримингом и нативная беседа на стороне движка.
Платформа предлагает три способа превратить результаты поиска в текст, и все они опираются только на индекс тенанта:
| Эндпоинт | Формат | Состояние |
|---|---|---|
POST /indexes/{slug}/answer | Один вопрос — один ответ со ссылками | Без состояния |
POST /indexes/{slug}/assistant | Шаг диалога, история сохраняется | Есть conversation_id |
POST /indexes/{slug}/assistant/native | Модель диалога движка, история на стороне платформы | Ведёт движок |
Все три извлекают документы одним и тем же поиском с фильтром тенанта, поэтому модель не видит чужие документы: фильтрация происходит до сборки промпта.
Одиночные ответы
curl -sS -X POST "$AAC_API/indexes/documentation/answer" \
-H "Authorization: Bearer $AAC_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "Сколько стоит тариф pro и что в него входит?", "per_page": 4 }'{
"index": "documentation",
"answer": "Тариф Pro стоит 29 USD в месяц и включает 500 000 поисков [1].",
"citations": [
{
"index": 1,
"id": "pricing",
"title": "Тарифы",
"url": "https://example.com/pricing",
"snippet": "Pro стоит 29 USD в месяц и включает 500 000 поисков."
}
],
"found": 4,
"model": "gpt-4o-mini",
"tokens": 218,
"took_ms": 640,
"request_id": "req_2c4e6a8b0d2f4a6c8e0b2d4f"
}citations[].index совпадает с маркерами [n] в тексте ответа, поэтому интерфейс может отрисовать нумерованные сноски без разбора прозы.
Что важно знать:
- Извлечение берёт не более 6 документов (
per_pageв запросе ограничивается десятью, контекст — шестью). - Отсутствие совпадений — не ошибка. Приходит
found: 0, пустые ссылки и фразаNo documents matched this question, so there is nothing to summarise.Правдивый пустой ответ лучше выдуманного. answerтребует провайдера: безOPENAI_API_KEYбудет503 AI_NOT_CONFIGURED.- Нужна функция тарифа
aiAnswer; она входит во все тарифы, включая Free — с небольшим жёстко ограниченным объёмом 10 000 AI-токенов в месяц (без превышения: сверх лимита будет429 QUOTA_EXCEEDED). - AI-токены списываются с квоты
ai_tokens.
С question можно передать любой параметр поиска, полезнее всего filter_by и query_by:
{
"question": "что изменилось в 1.8?",
"filter_by": "tags:=[changelog]",
"query_by": "title,content"
}Диалоговый ассистент
curl -sS -X POST "$AAC_API/indexes/documentation/assistant" \
-H "Authorization: Bearer $AAC_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "Сколько стоит pro?", "conversation_id": "conv_01HZYB" }'{
"conversation_id": "conv_01HZYB",
"answer": "Pro стоит 29 USD в месяц и включает 500 000 поисков [1].",
"mode": "llm",
"model": "gpt-4o-mini",
"citations": [
{
"n": 1,
"id": "pricing",
"title": "Тарифы",
"url": "https://example.com/pricing",
"snippet": "Pro стоит 29 USD в месяц и включает 500 000 поисков."
}
],
"found": 4,
"tokens": 231,
"latency_ms": 702,
"request_id": "req_8b0d2f4a6c8e0b2d4f6a8c0e"
}Не передавайте conversation_id, чтобы начать новый диалог: идентификатор из ответа идёт в следующий вызов. Он же возвращается в заголовке x-aac-conversation. Сообщения сохраняются, а токены учитываются как ai_tokens.
mode показывает, как получен ответ:
llm— модель ответила по найденным источникам (нуженOPENAI_API_KEY);extractive— модели нет, поэтому ассистент вернул структурированную выжимку из найденных фрагментов со списком источников. Эндпоинт продолжает работать, просто текст собирается, а не генерируется.
История диалога:
curl -sS "$AAC_API/indexes/documentation/assistant" -H "Authorization: Bearer $AAC_KEY"{
"conversations": [
{
"id": "conv_01HZYB",
"title": "Сколько стоит pro?",
"messageCount": 2,
"createdAt": "2026-10-23T10:12:00.000Z",
"updatedAt": "2026-10-23T10:12:04.000Z"
}
]
}curl -sS "$AAC_API/indexes/documentation/assistant/conv_01HZYB" \
-H "Authorization: Bearer $AAC_KEY"{
"conversation": {
"id": "conv_01HZYB",
"title": "Сколько стоит pro?",
"created_at": "2026-10-23T10:12:00.000Z",
"messages": [
{
"id": "msg_1",
"role": "user",
"content": "Сколько стоит pro?",
"citations": [],
"created_at": "2026-10-23T10:12:00.000Z"
},
{
"id": "msg_2",
"role": "assistant",
"content": "Pro стоит 29 USD в месяц…",
"citations": [{ "n": 1, "id": "pricing", "title": "Тарифы" }],
"created_at": "2026-10-23T10:12:04.000Z"
}
]
}
}Идентификатор диалога, принадлежащего другому индексу, даёт 404 CONVERSATION_NOT_FOUND: поиск ограничен индексом, а не только тенантом.
Стриминг
curl -N -sS -X POST "$AAC_API/indexes/documentation/assistant/stream" \
-H "Authorization: Bearer $AAC_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "А какие лимиты?" }'data: {"type":"citations","payload":{"citations":[...],"conversation_id":"conv_01HZYB"}}
data: {"type":"delta","payload":{"text":"Один API-ключ может "}}
data: {"type":"delta","payload":{"text":"делать 600 запросов в минуту."}}
data: {"type":"done","payload":{"conversation_id":"conv_01HZYB","tokens":204,"latency_ms":688}}Четыре типа событий: сначала citations (чтобы интерфейс сразу показал источники), затем фрагменты delta, затем done; сбой посреди потока приходит как error с сообщением. Поток имеет тип text/event-stream и cache-control: no-cache, no-transform. Каждый кадр — одна строка data: и пустая строка после неё; SDK разбирают именно это.
Нативные беседы движка
curl -sS -X POST "$AAC_API/indexes/documentation/assistant/native" \
-H "Authorization: Bearer $AAC_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "Опиши модель биллинга", "conversation_id": "conv_engine_1" }'{
"index": "documentation",
"answer": "Биллинг считается по поискам, документам, AI-токенам и переиндексациям…",
"conversation_id": "conv_engine_1",
"mode": "native",
"request_id": "req_4f6a8c0e2b4d6f8a0c2e4b6d"
}Этот путь использует собственную модель диалога движка (настроенная модель или model_id из запроса) и держит историю на стороне платформы. Он отвечает на вопросы, но не возвращает массив ссылок — берите /answer или /assistant, если источники нужно показывать.
Список моделей узла (право settings:write):
curl -sS "$AAC_API/indexes/documentation/conversation-models" \
-H "Authorization: Bearer $AAC_KEY"Что выбрать
- FAQ на сайте, вопросы по документации →
/answer. Просто, без состояния, ссылки сразу. - Чат поддержки, который должен помнить нить →
/assistantсо стримингом. История, ссылки, извлекающий режим как запасной. - Диалог уже живёт в движке, нужен только прокси →
/assistant/native. - Нужен полный контроль над промптом → вызывайте
/search, берите попадания и стройте промпт сами. Тогда контракт платформы заканчивается на извлечении — часто это и есть правильная граница.