AACSearch
Руководства

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, берите попадания и стройте промпт сами. Тогда контракт платформы заканчивается на извлечении — часто это и есть правильная граница.

On this page