API Platform RAG
Программный интерфейс сервиса Platform RAG — коллекции, приём документов, поиск.
Общая информация
Сервис: Platform RAG
Версия API: 1.0.0
Протокол: HTTP/1.1 + JSON
Базовый URL: https://rag.{env}.internal
Аутентификация: Bearer JWT (act-chain)
Сервис предоставляет четыре поверхности: collections, ingest,
query и eval. Все защищённые операции используют
actChain — HTTP Bearer токен формата JWT, через который пробрасывается
act-цепочка для авторизации уровня документа.
Аутентификация и авторизация
Все эндпоинты, кроме открытыхHealth-check, требуют действительный JWT-токен. Авторизация выполняется через SpiceDB с проверкой:
collection#readдля операций поиска;collection#writeдля операций приёма.
При недоступности службы авторизации возвращается ответ 503 (fail-closed).
Ошибки
| Код ответа | Значение | Тело ошибки |
|---|---|---|
401 | Нет/просрочен act-chain (fail-closed) | { "code": "unauthorized", "message": "...", "trace_id": "..." } |
403 | Нет прав на коллекцию (SpiceDB) | { "code": "forbidden", "message": "...", "trace_id": "..." } |
404 | Не найдено | { "code": "not_found", "message": "...", "trace_id": "..." } |
400 | Невалидный документ / пустой ACL в private | { "code": "invalid_document", "message": "...", "trace_id": "..." } |
503 | AuthZ/IdP недоступен — fail-closed | { "code": "authz_unavailable", "message": "...", "trace_id": "..." } |
Коллекции
Создать коллекцию
POST /v1/collections
Создаёт новую коллекцию с закреплённым профилем эмбеддинга, моделью ACL и стратегией чанкинга (COL-1/2).
Тело запроса CreateCollectionRequest:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
collection_id | string (UUID) | Нет | Идентификатор коллекции; генерируется сервером, если не указан |
name | string | Да | Имя коллекции |
description | string | Нет | Описание коллекции |
collection_type | string | Нет | Тип: knowledge_base, documents, files. По умолчанию: knowledge_base |
parent_id | string (UUID) | Нет | Идентификатор родительской коллекции |
visibility | string | Нет | Видимость: private или public. По умолчанию: private |
embedding_profile_id | string | Да | Идентификатор профиля эмбеддинга из Control Plane |
acl_model | string | Нет | Модель ACL: document или collection. По умолчанию: document |
chunking | object | Нет | Стратегия чанкинга: { "strategy": "recursive_text", "size": 800, "overlap": 120 } |
retrieval_defaults | object | Нет | Параметры поиска по умолчанию: { "mode": "hybrid", "top_k": 8 } |
empty_acl_policy | string | Нет | Политика пустого ACL: reject или strictest. По умолчанию: reject |
Ответ 201 Created — Collection
Получить коллекцию
GET /v1/collections/{collection_id}
Возвращает карточку коллекции (COL-4).
Параметры пути:
| Поле | Тип | Описание |
|---|---|---|
collection_id | string (UUID) | Идентификатор коллекции |
Ответ 200 OK — Collection
Получить список коллекций
GET /v1/collections
Возвращает список всех коллекций, доступных вызывающему (COL-4).
Ответ 200 OK — массив Collection
Переиндексация коллекции
POST /v1/collections/{collection_id}:reindex
Запускает версионируемую переиндексацию (COL-3). In-place изменение профиля эмбеддинга не допускается. Новая версия индекса создаётся атомарно.
Ответ 202 Accepted — Collection
Схема Collection
| Поле | Тип | Описание |
|---|---|---|
collection_id | string (UUID) | Идентификатор коллекции |
tenant_id | string | Идентификатор рабочего пространства |
name | string | Имя коллекции |
description | string | Описание |
collection_type | string | Тип коллекции |
parent_id | string (UUID) | Родительская коллекция |
visibility | string | Видимость: private / public |
embedding_profile_id | string | Профиль эмбеддинга |
acl_model | string | Модель ACL: document / collection |
chunking | object | Стратегия чанкинга |
retrieval_defaults | object | Параметры поиска по умолчанию |
empty_acl_policy | string | Политика пустого ACL |
status | string | Статус: created, populating, ready, deleted, error |
active_version | integer | Активная версия индекса |
doc_count | integer | Количество документов |
chunk_count | integer | Количество чанков |
created_at | string (date-time) | Дата создания |
updated_at | string (date-time) | Дата обновления |
Приём документов
submit_documents
POST /v1/documents:submit
Приём канонических документов от интеграционных сервисов (ING-1).
Тело запроса SubmitDocumentsRequest:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
documents | array | Да | Массив канонических документов |
Каждый документ в массиве соответствует схеме CanonicalDocument:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
op | string | Нет | Операция: upsert или delete. По умолчанию: upsert |
collection | string | Да | Имя или идентификатор коллекции |
tenant_id | string | Да | Идентификатор рабочего пространства |
doc_id | string | Да | Уникальный идентификатор документа в источнике |
content | object | Да (для upsert) | Содержимое: { "title": "...", "sections": [...], "tables": [...] } |
content_ref | object | Да (альтернатива content) | Ссылка на документ в object storage: { "uri": "s3://...", "content_hash": "..." } |
metadata | object | Нет | Метаданные: source, url, labels, valid_from, valid_until |
acl | object | Нет | ACL: { "groups": [...], "principals": [...], "scope": {...} } |
content_hash | string | Да | Хеш содержимого для дедупликации |
idempotency_key | string | Да | Ключ идемпотентности |
Важно: Для приватной коллекции пустой
aclнедопустим. Сервис отклоняет такой документ либо, при явном разрешении, индексирует его с самой строгой видимостью (ING-7).
Ответ 202 Accepted — SubmitDocumentsResponse:
| Поле | Тип | Описание |
|---|---|---|
jobs | array | Массив результатов обработки |
Каждый результат:
| Поле | Тип | Описание |
|---|---|---|
doc_id | string | Идентификатор документа |
job_id | string (UUID) | Идентификатор задания |
status | string | PENDING — задание принято, DEDUPLICATED — документ уже проиндексирован |
ingest_status
GET /v1/jobs/{job_id}
Возвращает статус задания из источника истины (PostgreSQL) (ING-2).
Параметры пути:
| Поле | Тип | Описание |
|---|---|---|
job_id | string (UUID) | Идентификатор задания |
Ответ 200 OK — IngestJob:
| Поле | Тип | Описание |
|---|---|---|
job_id | string (UUID) | Идентификатор задания |
collection | string | Имя коллекции |
tenant_id | string | Идентификатор рабочего пространства |
doc_id | string | Идентификатор документа |
op | string | Операция: upsert / delete |
content_hash | string | Хеш содержимого |
idempotency_key | string | Ключ идемпотентности |
status | string | PENDING, RUNNING, DONE, FAILED |
payload_uri | string | Ссылка на staging-объект в S3 (null для delete / dedup) |
payload_bytes | integer | Размер staging-объекта в байтах |
attempts | integer | Количество попыток обработки |
error | string | Сообщение об ошибке (null при успехе) |
trace_id | string | Идентификатор трассировки |
created_at | string (date-time) | Дата создания |
updated_at | string (date-time) | Дата обновления |
available_at | string (date-time) | Время доступности для поиска (null до DONE) |
Поиск
Гибридный поиск
POST /v1/query
Возвращает отфильтрованные по ACL результаты гибридного поиска (RET-1/2/3).
Тело запроса QueryRequest:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
collection | string | Да | Имя или идентификатор коллекции |
text | string | Да | Текст запроса |
mode | string | Нет | Режим поиска: hybrid, vector, bm25. По умолчанию: hybrid |
top_k | integer | Нет | Количество результатов. По умолчанию: 8 |
rerank | boolean | Нет | Включить реранк. По умолчанию: false |
rewrite | boolean | Нет | Включить переписывание запроса. По умолчанию: false |
filters | object | Нет | Дополнительные фильтры |
Ответ 200 OK — QueryResponse:
| Поле | Тип | Описание |
|---|---|---|
items | array | Массив цитат |
meta | object | Метаданные запроса |
Каждая цитата Citation:
| Поле | Тип | Описание |
|---|---|---|
doc_id | string | Идентификатор документа-источника |
chunk_id | string | Идентификатор чанка |
source_url | string | URL источника (null если отсутствует) |
title | string | Заголовок документа (null если отсутствует) |
content | string | Текст чанка |
score | number | Оценочный балл релевантности |
Метаданные QueryMeta:
| Поле | Тип | Описание |
|---|---|---|
mode | string | Режим поиска |
top_k | integer | Запрошенное количество результатов |
rerank | boolean | Был ли применён реранк |
hybrid_weights | object | Веса гибридного поиска |
trace_id | string | Идентификатор трассировки |
Упаковка контекста
POST /v1/retrieve_and_pack
Возвращает упакованный контекст под заданный бюджет токенов (RET-4).
Тело запроса RetrieveAndPackRequest:
Наследует все поля QueryRequest плюс:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
token_budget | integer | Да | Максимальный бюджет токенов для упакованного контекста |
Ответ 200 OK — PackedContext:
| Поле | Тип | Описание |
|---|---|---|
packed_context | string | Упакованный текстовый контекст |
token_count | integer | Количество токенов в контексте |
mode | string | Режим: full_document или relevance_search |
items | array | Массив цитат, вошедших в контекст |
meta | object | Метаданные запроса |
Канонический документ — JSON Schema
Все документы, передаваемые через submit_documents, должны соответствовать
схеме CanonicalDocument:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://platform-rag/contracts/canonical-document.schema.json",
"title": "CanonicalDocument",
"type": "object",
"required": ["collection", "tenant_id", "doc_id", "content_hash", "idempotency_key"],
"additionalProperties": false,
"properties": {
"op": { "type": "string", "enum": ["upsert", "delete"], "default": "upsert" },
"collection": { "type": "string", "minLength": 1 },
"tenant_id": { "type": "string", "minLength": 1 },
"doc_id": { "type": "string", "minLength": 1 },
"content": {
"type": "object",
"properties": {
"title": { "type": "string" },
"sections": {
"type": "array",
"items": {
"type": "object",
"required": ["text"],
"properties": {
"heading": { "type": "string" },
"text": { "type": "string" }
},
"additionalProperties": false
}
},
"tables": { "type": "array", "items": { "type": "object" } }
},
"additionalProperties": true
},
"content_ref": {
"type": "object",
"description": "Ссылка на уже загруженный канонический JSON в object storage (by-ref submit). Взаимоисключим с тяжёлым inline content на уровне API-лимита.",
"required": ["uri", "content_hash"],
"additionalProperties": false,
"properties": {
"uri": {
"type": "string",
"description": "s3://… или https presigned GET на CanonicalDocument JSON"
},
"content_hash": {
"type": "string",
"description": "Должен совпадать с корневым content_hash"
},
"bytes": { "type": "integer", "minimum": 1 }
}
},
"metadata": {
"type": "object",
"properties": {
"source": { "type": "string" },
"url": { "type": "string", "format": "uri" },
"labels": { "type": "array", "items": { "type": "string" } },
"valid_from": { "type": "string", "format": "date-time" },
"valid_until": { "type": "string", "format": "date-time" }
},
"additionalProperties": true
},
"acl": {
"type": "object",
"properties": {
"groups": { "type": "array", "items": { "type": "string" } },
"principals": { "type": "array", "items": { "type": "string" } },
"scope": { "type": "object", "additionalProperties": true }
},
"additionalProperties": false
},
"content_hash": { "type": "string", "minLength": 1 },
"idempotency_key": { "type": "string", "minLength": 1 }
}
}Примеры запросов
Создание коллекции
POST /v1/collections
{
"name": "handbook",
"description": "Корпоративный справочник",
"embedding_profile_id": "text-default-v1",
"acl_model": "document",
"chunking": {
"strategy": "recursive_text",
"size": 800,
"overlap": 120
},
"retrieval_defaults": {
"mode": "hybrid",
"top_k": 8
}
}Поиск
POST /v1/query
{
"collection": "handbook",
"text": "Правила оформления отпуска",
"mode": "hybrid",
"top_k": 5,
"rerank": true
}Упаковка контекста
POST /v1/retrieve_and_pack
{
"collection": "handbook",
"text": "Правила оформления отпуска",
"token_budget": 3000,
"rerank": true
}Приём документов
POST /v1/documents:submit
{
"documents": [
{
"op": "upsert",
"collection": "handbook",
"tenant_id": "acme",
"doc_id": "confluence:HR:12345",
"content": {
"title": "Отпуск",
"sections": [
{ "heading": "Правила", "text": "До 28 дней в год." }
]
},
"metadata": {
"source": "confluence",
"url": "https://.../HR/12345",
"labels": ["policy"]
},
"acl": {
"groups": ["group:hr"],
"principals": [],
"scope": { "confluence_space": "HR" }
},
"content_hash": "abc123...",
"idempotency_key": "confluence:12345:rev-88"
}
]
}