Встраивание чата на сайт
Диалог «Встроить на веб-страницу», iframe с shared_id и beta-токеном, публичные endpoint /chatbots, формат SSE и меры защиты публичного токена.
Ассистента можно показать на внешнем сайте или в корпоративном портале двумя способами: готовым iframe или собственным интерфейсом поверх публичных endpoint. В обоих случаях используется beta-токен, а не основной API-ключ.
Диалог «Встроить на веб-страницу»
- Создайте API-ключ на странице «API» в настройках: без него встраивание недоступно. Вместе с ключом создаётся beta-токен для публичного доступа.
- Откройте ассистента (или агента на холсте) и выберите «Встроить на веб-страницу».
- Скопируйте сгенерированный код iframe и вставьте его на страницу.
Адрес внутри iframe выглядит так:
<iframe
src="https://<ваш-адрес>/chat/share?shared_id=<dialog_id>&from=chat&auth=<beta>"
style="width: 100%; height: 100%; min-height: 600px"
frameborder="0">
</iframe>Параметры: shared_id является идентификатором ассистента (для агента используется адрес /agent/share и from=agent), auth содержит beta-токен. Виджет рисует приветствие ассистента, историю беседы и ответы с источниками.
Публичные endpoint
Если нужен собственный интерфейс, обращайтесь к публичным методам напрямую. Авторизация та же: Authorization: Bearer <beta>.
Сведения об ассистенте. GET /api/v1/chatbots/<dialog_id>/info возвращает название, аватар и приветствие (prologue). Для агента: GET /api/v1/agentbots/<agent_id>/inputs возвращает ещё и форму входных параметров.
Ответ ассистента. POST /api/v1/chatbots/<dialog_id>/completions с телом:
{"question": "Какой срок доставки?", "session_id": "<опционально>", "stream": true, "quote": false}Первый вызов без session_id не отвечает на вопрос, а создаёт беседу: возвращает приветствие и новый session_id. Сохраните его на клиенте и передавайте в следующих вызовах.
data: {"code": 0, "message": "", "data": {"answer": "Здравствуйте! ...", "reference": {}, "id": null, "session_id": "a1b2..."}}
data: {"code": 0, "message": "", "data": true}Последующие вызовы с session_id стримят ответ. Поле answer каждого события содержит накопленный текст, reference содержит фрагменты документов и агрегаты по документам, а завершающее событие содержит "data": true:
data: {"code": 0, "message": "", "data": {"answer": "Срок доставки составляет", "reference": {...}, "session_id": "a1b2..."}}
data: {"code": 0, "message": "", "data": {"answer": "Срок доставки составляет 3 рабочих дня.", "reference": {...}, "session_id": "a1b2..."}}
data: {"code": 0, "message": "", "data": true}При ошибке приходит событие с "code": 500 и текстом ошибки в message. С "stream": false метод возвращает один JSON с полным ответом. Параметр quote включает подстановку ссылок на источники в текст ответа. Для агентов аналогичный метод: POST /api/v1/agentbots/<agent_id>/completions.
Минимальный клиент на JavaScript:
const res = await fetch(`${base}/api/v1/chatbots/${dialogId}/completions`, {
method: 'POST',
headers: { Authorization: `Bearer ${beta}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ question, session_id: sessionId, stream: true }),
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
for (const line of buffer.split('\n\n')) {
if (!line.startsWith('data:')) continue;
const event = JSON.parse(line.slice(5));
if (event.data === true) return;
render(event.data.answer, event.data.reference);
sessionId = event.data.session_id;
}
buffer = buffer.slice(buffer.lastIndexOf('\n\n') + 2);
}Безопасность
Внимание
Beta-токен попадает в HTML страницы и считается публичным. Он даёт право задавать вопросы ассистенту от имени организации, но не управлять данными. Основной API-ключ в страницу не помещайте.
- Ротация. Beta-токен связан с API-ключом: удалите ключ и создайте новый, чтобы старый виджет перестал работать. Обновите iframe на сайте.
- Ограничение частоты. Ограничьте число запросов к
/api/v1/chatbots/*на обратном прокси (по IP и по сессии) и задайте лимит расхода токенов организации в консоли администратора: без этого публичный виджет может исчерпать бюджет модели. - Ограничение происхождения. Разрешайте встраивание только с ваших доменов (заголовки
Content-Security-PolicyиX-Frame-Optionsна входной службе) и проверяйтеRefererна прокси. - Содержимое ассистента. Публичному ассистенту подключайте только базы знаний, предназначенные для внешних читателей, и задайте текст ответа при отсутствии сведений. Ответ не должен раскрывать внутренние документы.
- Журнал. Обращения через виджет записываются в журнал с идентификатором сессии; при аномалиях отзовите токен.
Что дальше
- API-ключ и SDK: полный доступ к данным с серверной стороны.
- Агенты на холсте: агент с формой входных параметров как публичный сценарий.
Спросить Сему