AACsearch
AI Поиск

AI-ответы

Генерация одного абзаца AI-ответа над топ-результатами поиска, с цитированием исходных документов.

Эндпоинт AI answer прогоняет поиск, берёт top-результаты и просит LLM вернуть короткий ответ, опирающийся именно на эти результаты. Это абзац плюс список цитируемых документов из того же индекса — а не свободная генерация.

Эндпоинт

POST /api/search/ai/answer
Authorization: Bearer ss_search_<your-key>
Content-Type: application/json

Реализация — packages/api/modules/search/ai-search-public.ts. Эндпоинт проходит через тот же гейт, что и /api/search (rate limiting, проверка scoped-token, tenant isolation).

Запрос

{
  query: string;              // ≤ 2000 символов, обрезается по бокам
  indexSlug?: string;         // default: "products"
  queryBy?: string;           // default: "title,description"
  filterBy?: string;          // стандартное filter-выражение
  perPage?: number;           // сколько хитов идёт в контекст; 1–20, default 5
}

Если вызывающий использует scoped token, который фиксирует indexSlug, любой mismatch вернёт 403 invalid_index.

Ответ

{
  answer: string;                  // 1–3 предложения (≤ 300 токенов)
  sources: Array<{
    id: string;
    title: string;
    url?: string;
    imageUrl?: string;
    price?: number | string;
  }>;
  searchTimeMs: number;            // время на keyword search
  totalTimeMs: number;             // wall-clock на весь вызов
}

sources — в порядке хитов, обрезан до perPage. Используйте sources, чтобы отрисовать чипы цитат. Документы вне топ-результатов в sources не попадают.

Цитирования и заземление

В промпт уходит top-5 хитовtitle + первые 300 символов description в виде нумерованных строк контекста:

[1] Bose QuietComfort 45: Noise-cancelling over-ear headphones with…
[2] Sony WH-1000XM5: Industry-leading active noise cancelling…

Системный промпт просит модель ответить 1–3 предложениями, опираясь только на этот контекст. Температура жёстко 0.3 — повторный запрос даёт стабильный ответ. max_tokens = 300 для предсказуемой латентности.

Модель возвращает обычный текст — система не требует от модели ставить [1]-маркеры. sources собирается из хитов поиска, что бы ни написала модель. Если модель выдумала бренд/продукт, которого нет в sources — это grounding failure: абзац ответа без чипов нельзя считать достоверным.

Всегда показывайте sources рядом с ответом. Уверенно звучащий абзац без цитирований — самый частый провал любого RAG.

Confidence

Текущий эндпоинт не возвращает явный confidence score. Используйте количество найденных документов как прокси:

foundЧто делать
0Не вызывайте AI вообще — отрисуйте no-results.
1–2Покажите ответ, но рассчитывайте на низкое покрытие; чипы выделите.
3+Стандартный рендер — модель видит хотя бы 3 разных контекстных строки.

Если ответ пришёл пустой (answer === ""), вызов OpenAI завершился ошибкой; эндпоинт всё равно возвращает хиты и освобождает резерв. Отрисуйте только список результатов.

Есть парный image-эндпоинт:

POST /api/search/ai/image

Прогоняет gpt-4o-mini по картинке, эмбеддит текстовое описание и делает вектор-поиск по индексу. Удобно для «найди похожие на это фото».

Входы:

{
  imageUrl?: string;   // ИЛИ
  imageBase64?: string;
  indexSlug?: string;
  perPage?: number;
}

Выход — стандартный поисковый ответ с vector_distance на каждом хите. Точная схема — ai-search-public.ts. Шейп стабилен, но image search пока в Beta.

Биллинг

AI-ответ метерится через AI Wallet (Инвариант 8):

  1. Reserve — до поиска система резервирует CREDIT_RATES.ai_answer копеек на кошельке org. Не хватает → 402 Payment Required; эндпоинт не выполняется.
  2. Commit / release — на успехе резерв коммитится; на любой ошибке (плохой вход, ошибка LLM, mismatch scoped-token) резерв освобождается, org не тарифицируется.

Тарифы — packages/api/modules/entitlements/credit-rates.ts. Выводите цену вызова в виджете, чтобы оператор мог расчитать бюджет.

Rate limiting

Эндпоинт переиспользует public-search rate limit (SearchRateLimitBucket). 429 значит «организация исчерпала квоту тарифа в текущем окне», а не «AI-сервис перегружен». Тело 429 — стандартное { error: "rate_limit_exceeded", retryAfter: number }, никогда не сырой ответ upstream (Инвариант 6).

Ограничения

  • Латентность. Ожидайте +500–2000 мс к поиску. Покажите хиты сразу, ответ — потом / стримом.
  • Язык. Дефолтный промпт — англоязычный. Для не-английских каталогов сужайте queryBy / filterBy: "locale:=ru", чтобы хиты были моноязычными; модель пойдёт за языком контекста.
  • Hallucination floor. Даже с заземлением модель может «округлять» («Отличный продукт…»). Митигация — ограничить ответ продуктовыми вопросами, не free-form рекомендациями.
  • Без стриминга. /api/search/ai/answer отдаёт ответ целиком. Для длинных ответов по вашим документам используйте Knowledge RAG streaming (knowledge.askStream).
  • Один индекс. Эндпоинт ищет в одном индексе. Federated — через multi-search, склейку делаете сами.

Связанные страницы

On this page