ym88659208ym87991671
Подсказки | Документация для разработчиков

Подсказки

Обновлено 24 апреля 2026

Подсказки (suggests) — кнопки с вариантами продолжения диалога, которые появляются после ответа агента.

Подсказки добавляются с помощью узла графа — suggests:

  1. Узел suggests вызывает LLM с историей диалога и описанием инструментов.
  2. LLM возвращает JSON-объект с вариантами продолжения диалога.
  3. Подсказки прикрепляются к последнему AI-сообщению с помощью additional_kwargs.suggests.
  4. Веб-интерфейс GigaLab отображает подсказки в виде интерактивных кнопок.

Генерация подсказок

При генерации подсказок в llm.invoke() обязательно нужно передавать массив callbacks: []. В противном случае LangGraph-компонент StreamMessagesHandler будет передавать подсказки в потоке токенов как обычное сообщение в формате SSE (Server Sent Events). При этом в веб-интерфейсе появится JSON-текст, который потом пропадет.

Кроме этого, для корректного получения JSON-объекта с подсказками, нужно отключить потоковую передачу streaming: false при инициализации GigaChat.

Пример генерации подсказок:

export async function generateSuggests(
messages: BaseMessage[],
systemPrompt: string,
agentCapabilities: string,
maxSuggests = 3,
): Promise<Array<Record<string, any>>> {
const conversation = formatConversation(messages);
const instruction = SUGGEST_INSTRUCTION_TEMPLATE
.replace("{MAX_SUGGESTS}", String(maxSuggests))
.replace("{CONVERSATION}", conversation)
.replace("{CAPABILITIES}", agentCapabilities);

const llm = new GigaChat({
model: process.env.GIGACHAT_MODEL || "GigaChat-Max",
baseUrl: process.env.GIGACHAT_BASE_URL,
temperature: 0.3,
streaming: false, // Отключение потоковой передачи для корректной обработки JSON-вывода
});

await ensureFreshToken(llm, tokenOpts);

// callbacks: [] нужно передавать обязательно
const rawMessage = await llm.invoke(promptMessages, { callbacks: [] });
// ... парсинг JSON ...
}

Прикрепление к сообщению

Подсказки прикрепляются к последнему сообщению агента (тип ai). Для определения типа используется функция _getType(), которая корректно определяет тип сообщения. Это связанно с тем, что метод instanceof AIMessage вернет false для экземпляра AIMessageChunk. Так как в LangChain JS классы AIMessageChunk и AIMessage наследуются от BaseMessage.

Пример прикрепления подсказки к сообщению:

export function attachSuggestsToLastMessage(
messages: BaseMessage[],
suggests: Array<Record<string, any>>,
): void {
if (!suggests.length || !messages.length) return;

const last = messages[messages.length - 1];

// Вместо `instanceof AIMessage` использется метод `_getType()`
if (last._getType() !== "ai") {
console.warn(`Last message is not AI type (type=${last._getType()})`);
return;
}

const additional = { ...(last.additional_kwargs || {}) };
additional.suggests = [...suggests];
last.additional_kwargs = additional;
}

Узел suggests в графе

Пример создания узла suggests в графе агента:

async function suggestNode(
state: typeof MessagesAnnotation.State,
) {
try {
const suggests = await generateSuggests(
state.messages,
buildSystemPrompt(),
AGENT_CAPABILITIES,
);

attachSuggestsToLastMessage(state.messages, suggests);

return { messages: [state.messages[state.messages.length - 1]] };
} catch (e: any) {
console.warn(`[suggests] Failed: ${e.message}`);
return {}; // Не ломаем диалог при ошибке
}
}

Формат suggests

JSON-схема массива подсказок:

{
"additional_kwargs": {
"suggests": [
{
"label": "Текст кнопки для пользователя",
"prompt": "Полный текст команды при нажатии",
"position": 0
}
]
}
}
ПолеТипОписание
labelstringКороткий текст кнопки. Необязательное поле
promptstringКоманда, которую выполнит агент
positionnumberПорядок отображения. Необязательное поле. Первый элемент — 0

Разбор JSON-ответа

Модель может вернуть JSON-объект с лишним текстом или внутри markdown-разметки.

Пример разбора JSON-ответа:

function loadSuggestsFromText(raw: string): SuggestsOutput | null {
const cleaned = raw.replace(/\{\{/g, "{").replace(/\}\}/g, "}").trim();
try {
return SuggestsOutputSchema.parse(JSON.parse(cleaned));
} catch {
// Извлечь JSON из текста
const start = cleaned.indexOf("{");
const end = cleaned.lastIndexOf("}");
if (start === -1 || end === -1) return null;
return SuggestsOutputSchema.parse(JSON.parse(cleaned.slice(start, end + 1)));
}
}

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней

ПАО Сбербанк использует cookie для персонализации сервисов и удобства пользователей. Вы можете запретить сохранение cookie в настройках своего браузера.