Conversation API

Conversation API

HTTP API для private dialogue layer: текст, изображения, голос, память по user_id, глобальный persona profile на ключ и knowledge-driven ответы через custom KB.

Single endpointPrivate deploymentPersona profilePer-user memoryKB / RAG

1. Концепция

  • Один endpoint: POST /api/v1/conversation.
  • Для каждого API key хранится общий persona profile — роль, стиль и позиционирование.
  • Для каждого user_id под тем же ключом ведется отдельная память и своя история диалога.
  • Каждое внедрение работает в private deployment со своим base URL и отдельным execution-контуром.

2. Endpoint & authentication

Conversation API живет внутри private deployment. Вы получаете отдельный base URL и используете один endpoint для всех диалоговых сценариев.

URL

POST https://<PRIVATE_DEPLOYMENT_URL>/api/v1/conversation

Authentication headers

  • Authorization: Bearer YOUR_API_KEY
  • X-API-Key: YOUR_API_KEY
  • Idempotency-Key: optional-request-key

Runtime факты

image limit

≈ 5 MB decoded

voice limit

≈ 25 MB decoded

default key limit

60 RPM

default IP limit

360 RPM

3. Request body

user_id обязателен. Нужно передать хотя бы одно из: message, image_b64 или voice_b64. Если одновременно отправить message и voice_b64, текст считается основным входом, а голос остается дополнительным контекстом.

ПолеTypeОбязательностьОписание
user_idstring (1..128)YesСтабильный идентификатор пользователя в вашей системе. Он используется как ключ памяти.
messagestring (1..4000)NoТекстовый запрос. Может использоваться отдельно или вместе с картинкой.
image_b64base64 stringNoИзображение без data:-префикса. Поддерживаются image/jpeg, image/jpg, image/png, image/webp.
image_mimestringWith image_b64MIME-тип изображения. Если image_mime передан без image_b64, запрос отклоняется.
voice_b64base64 stringNoГолосовой вход. Если message отсутствует, сервис пытается транскрибировать аудио в текст.
voice_mimestringRecommendedПоддерживаются audio/aac, audio/m4a, audio/mp3, audio/mp4, audio/mpeg, audio/ogg, audio/opus, audio/wav, audio/webm, audio/x-wav.
personaobjectNoОбновляет глобальный persona profile для API key. Частичные поля сливаются с существующим профилем.

4. Persona profile

persona — это общий профиль на API key. Он задает роль, стиль и позиционирование, а поверх него система ведет индивидуальную историю по каждому user_id.

  • Отправьте persona один раз при инициализации или обновляйте частями по мере развития сценария.
  • Глобальный профиль разделяется между всеми user_id под одним ключом.
  • Память и история диалога при этом остаются изолированными по user_id.
  • role лучше заполнять как короткое рабочее описание роли, знаний, ограничений и тона, а не как лозунг.
ПолеTypeОписание
namestring (1..64)Имя профиля.
ageinteger 1..120Стилистический нюанс, а не бизнес-правило.
gendermale | femaleПол профиля.
zodiac12 fixed valuesAries..Pisces.
temperamentobjectВесы для sanguine / choleric / phlegmatic / melancholic; внутри движка нормализуются.
socialityintrovert | ambivert | extrovertСоциальный вектор поведения.
archetypesarray up to 16 enum valuesНапример: Sage, Explorer, Creator, Caregiver.
rolestring (1..1000)Главное рабочее описание роли, экспертизы, ограничений и тона.

5. Response

Успешный ответ содержит текст reply, latency_ms для SLA-наблюдения, latency_breakdown для детальной трассировки и request_id для инцидентов.

Пример ответа

{
  "reply": "Для старта чаще всего подходит Basic: он закрывает типовые задачи без лишнего объема. Если важны приоритетная поддержка и более высокий лимит запросов, тогда стоит смотреть Pro.",
  "latency_ms": 842,
  "latency_breakdown": {
    "queue_latency_ms": 44,
    "worker_latency_ms": 798,
    "total_latency_ms": 842
  },
  "request_id": "4611686018427387904-7-a1b2c3"
}

6. Errors

Все ошибки используют envelope { detail: { code, message, request_id? } }. В части ранних 4xx request_id может отсутствовать.

HTTPcodeОписаниеПовтор
401missing_api_keyAPI-ключ не передан.No
401invalid_api_keyКлюч невалиден или деактивирован.No
402no_requestsНедостаточно request balance для API-использования.After refill
400invalid_payloadНеверная форма запроса, неправильные комбинации полей или broken base64.After fix
400invalid_voice_format / invalid_voice_mime / voice_transcription_failedГолосовой payload не поддерживается, не распознан или не был транскрибирован.After fix
409idempotency_in_flight / idempotency_key_reused_with_different_payloadКлюч идемпотентности уже в работе или использован с другим payload.Carefully
429rate_limited / rate_limited_ipПревышен лимит по ключу или IP. Возвращается Retry-After: 60.Yes
503queue_unavailable / rate_limiter_unavailable / idempotency_unavailableВременная недоступность очереди, rate limiter или idempotency storage.Yes
504upstream_timeoutWorker или модель не ответили вовремя.Yes
500internal_errorВнутренняя ошибка.Yes

7. Request examples

Ниже — базовые примеры для private deployment. В production вы меняете только base URL и API key.

Request example

{
  "user_id": "usr-42",
  "message": "Помоги выбрать стартовый тариф и кратко объясни разницу с Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}

cURL · bash

curl -X POST "https://<PRIVATE_DEPLOYMENT_URL>/api/v1/conversation" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: req-usr-42-001" \
  -H "Content-Type: application/json" \
  -d '{
  "user_id": "usr-42",
  "message": "Помоги выбрать стартовый тариф и кратко объясни разницу с Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}'

JavaScript / fetch · ts

const API_URL = 'https://<PRIVATE_DEPLOYMENT_URL>';
const API_KEY = 'YOUR_API_KEY';

const body = {
  "user_id": "usr-42",
  "message": "Помоги выбрать стартовый тариф и кратко объясни разницу с Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
};

const response = await fetch(`${API_URL}/api/v1/conversation`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'req-usr-42-001'
  },
  body: JSON.stringify(body)
});

console.log(response.status, await response.json());

Python / requests · py

import requests

API_URL = 'https://<PRIVATE_DEPLOYMENT_URL>'
API_KEY = 'YOUR_API_KEY'

payload = {
  "user_id": "usr-42",
  "message": "Помоги выбрать стартовый тариф и кратко объясни разницу с Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}

resp = requests.post(
    f"{API_URL}/api/v1/conversation",
    headers={
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json',
        'Idempotency-Key': 'req-usr-42-001',
    },
    json=payload,
    timeout=30,
)
print(resp.status_code, resp.json())

8. Custom KB & RAG

KB привязана к API key и автоматически применяется ко всем user_id под этим ключом. Сейчас KB управляется вне HTTP endpoint: вы загружаете JSON, а индекс перестраивается в фоне.

  • Одна активная knowledge base на API key.
  • KB не передается в POST /conversation; она работает как доменный слой поверх persona profile.
  • Ожидаемый формат: JSON array of objects с text, optional id, optional category и tags[].
  • Ретривер использует семантический поиск и подмешивает релевантные фрагменты в ответ.

KB JSON example

[
  {
    "id": "faq-billing-1",
    "category": "support",
    "tags": ["оплата", "billing", "как оплатить", "тариф"],
    "text": "Оплата проходит после подтверждения заказа. Если вопрос связан с возвратом или спорным списанием, сначала собери контекст и передай кейс человеку."
  },
  {
    "id": "faq-plan-basic",
    "category": "sales",
    "tags": ["basic", "стартовый тариф", "для начала"],
    "text": "Basic подходит для первого запуска и типовой нагрузки. Сначала объясни сценарий, затем коротко сравни Basic и Pro по ограничениям и поддержке."
  }
]

Нужен private deployment под ваш продукт?

Покажем, как развернуть Synchatica под ваш контур, какие поля persona и KB лучше задать и где имеет смысл включать модерацию, handoff и request tracing.