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

Паттерны графов

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

В этом разделе вы найдете примеры паттернов графов агентов sample-ts и ai-disrupt .

Полный агент с инструментами и подсказками

Паттерн из sample-ts : агент с инструментами, циклом вызовов и генерацией подсказок.

__start__ → agent → [tool_calls?] → tools → agent (цикл)
→ [нет tool_calls] → suggests → END
import { StateGraph, MessagesAnnotation, END } from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";

const workflow = new StateGraph(MessagesAnnotation)
.addNode("agent", agentNode)
.addNode("tools", new ToolNode(TOOLS))
.addNode("suggests", suggestNode)
.addEdge("__start__", "agent")
.addConditionalEdges("agent", routeNext, {
tools: "tools",
suggests: "suggests",
})
.addEdge("tools", "agent")
.addEdge("suggests", END);

export const graph = workflow.compile();

Маршрутизация

function routeNext(
state: typeof MessagesAnnotation.State,
): "tools" | "suggests" {
const last = state.messages[state.messages.length - 1] as any;
const hasToolCalls =
(last?.tool_calls && last.tool_calls.length > 0) ||
(last?.additional_kwargs?.function_call);
return hasToolCalls ? "tools" : "suggests";
}

Узел агента

Всегда передавайте config вторым аргументом в invoke() — это обеспечивает корректную работу потоковой передачи токенов и отслеживания (tracing):

async function agentNode(
state: typeof MessagesAnnotation.State,
config: LangGraphRunnableConfig,
) {
const systemPrompt = buildSystemPrompt();
const messages = [new SystemMessage(systemPrompt), ...state.messages];

await ensureFreshToken(llm, TOKEN_MANAGER_OPTS);
const llmWithTools = llm.bind({
tools: GIGACHAT_FUNCTIONS,
tool_choice: "auto",
} as any);
const response = await llmWithTools.invoke(messages, config);
return { messages: [response] };
}

Простой валидатор

Паттерн из ai-disrupt : один узел, без инструментов, structured output.

__start__ → validator → END
const workflow = new StateGraph(MessagesAnnotation)
.addNode("validator", validatorNode)
.addEdge("__start__", "validator")
.addEdge("validator", END);

export const graph = workflow.compile();

Узел валидатора с parsed JSON

Для валидатора отключайте потоковую передачу токенов streaming: false. В противном случае при обработке JSON-ответов парсер SSE может сломаться на экранированных кавычках:

async function validatorNode(
state: typeof MessagesAnnotation.State,
config: LangGraphRunnableConfig,
) {
const systemPrompt = getSystemPrompt() + STRUCTURED_OUTPUT_INSTRUCTION;
const messagesWithSystem = [new SystemMessage(systemPrompt), ...state.messages];

await ensureFreshToken(gigaChat, TOKEN_MANAGER_OPTS);
const response = await gigaChat.invoke(messagesWithSystem, config);

const responseText = typeof response.content === "string"
? response.content
: JSON.stringify(response.content);
const structuredOutput = parseStructuredOutput(responseText);

return {
messages: [
new AIMessage({
content: structuredOutput.summary,
additional_kwargs: { structuredOutput },
}),
],
};
}

State и типы

Используйте MessagesAnnotation для состояний графа:

import { MessagesAnnotation } from "@langchain/langgraph";

// Тип state в узлах:
state: typeof MessagesAnnotation.State
// Эквивалентно: { messages: BaseMessage[] }

Состояние автоматически аккумулирует сообщения с помощью add_messages.

Обработка ошибок

Если узел выбросит исключение, LangGraph запишет ошибку в checkpoint и вернет ее клиенту через SSE.

async function agentNode(state, config) {
try {
await ensureFreshToken(llm, TOKEN_MANAGER_OPTS);
const response = await llmWithTools.invoke(messages, config);
return { messages: [response] };
} catch (e: any) {
const errMsg = e?.message || String(e);
console.error(`[agent] LLM invoke failed: ${errMsg}`);
throw new Error(`LLM invoke failed: ${errMsg}`);
}
}

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

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

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