Context window в n8n AI: как управлять контекстом без потери качества ¶
Обновлено: 2026-05-29
Короткий ответ ¶
Context window — это рабочее пространство модели: системная инструкция, пользовательский запрос, история, результаты tools, найденные документы RAG и формат ответа. В n8n context window нужно управлять явно: не передавать “всё подряд”, а собирать минимальный контекст под конкретное решение. Для production-процесса нужен бюджет токенов, правила обрезки истории, отдельный RAG-контур для знаний, короткие tool outputs и тесты на длинные входы. Хороший workflow не ломается, когда письмо длинное, документов много, а пользователь задаёт уточняющий вопрос после десяти сообщений.
Что именно считается контекстом ¶
Ошибка многих AI workflow в n8n — считать контекстом только поле chatInput. На практике модель видит больше: system message, developer/business rules, пользовательский запрос, память диалога, результаты предыдущих нод, данные из Google Sheets или CRM, фрагменты из vector store, tool descriptions, tool results, примеры JSON и требования к формату ответа. Всё это конкурирует за один лимит.
Если контекст переполнен, возникают четыре типа проблем. Во-первых, модель перестаёт видеть важные правила в начале prompt. Во-вторых, ответ становится дороже, потому что каждый запуск отправляет лишние токены. В-третьих, модель начинает “догадываться”, потому что релевантный фрагмент не попал в окно. В-четвёртых, workflow становится нестабильным: сегодня ответ проходит schema validation, завтра тот же запрос падает из-за длинного письма или большого retrieval.
Когда страница нужна именно про context window ¶
Эта тема нужна не только для чат-ботов. Context window критичен для email triage, AI support, RAG-поиска по базе знаний, классификации лидов, генерации коммерческих предложений, анализа тикетов, извлечения данных из договоров и любых сценариев, где модель получает переменные данные. Если workflow должен принимать реальные входы от клиентов, нельзя надеяться, что “модель сама разберётся”. Нужно заранее решить, какие данные имеют право попадать в prompt, в каком порядке и с каким приоритетом.
Архитектура workflow в n8n ¶
Минимальная production-схема выглядит так:
- Trigger получает запрос: Webhook, Chat Trigger, Email Trigger, Telegram Trigger или CRM event.
- Normalize input очищает данные: убирает HTML, вложенные подписи, трекинговые блоки, лишние quoted replies.
- Classify intent определяет тип задачи: ответ клиенту, поиск инструкции, создание тикета, извлечение полей, эскалация.
- Build context выбирает источники: последние сообщения, профиль клиента, RAG, CRM, настройки SLA.
- Budget check оценивает объём и режет низкоприоритетные части.
- AI Agent или Basic LLM Chain получает уже подготовленный context pack.
- Validate output проверяет JSON, обязательные поля, ссылки на источники, confidence.
- Fallback branch срабатывает, если контекст слишком длинный или ответ не прошёл проверку.
Главное правило: AI node не должна быть первой нодой, которая видит сырой вход. Перед ней должен быть слой подготовки контекста.
Как распределить данные по приоритетам ¶
| Приоритет | Что включать | Как обрезать |
|---|---|---|
| P0 | system rules, policy, schema ответа | не обрезать |
| P1 | текущий пользовательский запрос | чистить, но не сокращать без нужды |
| P2 | последние 2–4 сообщения диалога | summarization старой истории |
| P3 | релевантные RAG-фрагменты | top-k, metadata filter, max chars per chunk |
| P4 | CRM/профиль клиента | только поля, влияющие на решение |
| P5 | tool outputs и debug details | короткий summary вместо полного JSON |
| P6 | примеры, help text, длинные инструкции | выносить в отдельную страницу или RAG |
Если в prompt попадает всё, модель получает шум. Если в prompt попадает только инструкция без фактов, модель начинает галлюцинировать. Правильный баланс — дать ровно те факты, которые нужны для решения текущего вопроса.
Как собрать context pack ¶
В n8n удобно делать отдельную Code node, которая собирает объект context_pack. Это лучше, чем склеивать длинный prompt в нескольких Set node.
const input = $json;
const clean = (value, max = 4000) => String(value || '')
.replace(/<[^>]+>/g, ' ')
.replace(/\s+/g, ' ')
.trim()
.slice(0, max);
return [{
json: {
context_pack: {
task: input.intent || 'answer_support_question',
user_question: clean(input.question, 2500),
customer: {
plan: input.plan || 'unknown',
region: input.region || 'unknown',
language: input.language || 'ru'
},
recent_history: (input.history || [])
.slice(-4)
.map(m => ({ role: m.role, text: clean(m.text, 800) })),
retrieved_sources: (input.sources || [])
.slice(0, 5)
.map(s => ({
title: s.title,
url: s.url,
excerpt: clean(s.text, 1200),
updated_at: s.updated_at
})),
constraints: {
must_cite_sources: true,
no_guessing: true,
output_format: 'json'
}
}
}
}];
После этого prompt становится коротким и управляемым: “используй context_pack, не выдумывай факты, верни JSON по схеме”.
Что делать с историей диалога ¶
История нужна не всегда. Для команды “создай тикет” достаточно текущего сообщения и профиля клиента. Для поддержки — нужны последние уточнения. Для юридического или финансового сценария лучше хранить историю как audit trail, но не отправлять её всю в модель.
Рабочий паттерн:
- последние 2–4 сообщения передавать полностью;
- более старую историю сворачивать в summary;
- summary пересобирать не на каждом сообщении, а после важных изменений;
- хранить факты отдельно от разговорного шума: “клиент использует тариф Pro”, “интеграция: Битрикс24”, “проблема: webhook 404”;
- при конфликте между текущим сообщением и summary отдавать приоритет текущему сообщению.
Если n8n работает в queue mode, не полагайтесь на локальную volatile-память воркера. Для production лучше использовать устойчивое хранилище: Postgres/Redis memory, CRM, ticket system или отдельную таблицу с conversation state.
RAG не заменяет context management ¶
RAG часто воспринимают как способ “дать модели все документы”. Это ошибка. RAG только выбирает кандидатов, а context window всё равно ограничен. Даже если vector store нашёл 20 фрагментов, в prompt стоит передать 3–6 лучших, с заголовками, датой и metadata.
Плохой RAG-контекст:
{
"documents": ["огромный кусок без источника", "ещё один кусок", "ещё 10 кусков"]
}
Хороший RAG-контекст:
{
"retrieved_sources": [
{
"title": "Webhook production checklist",
"url": "https://nodbot.ru/playbooks/webhook-production-checklist/",
"updated_at": "2026-05-29",
"reason": "explains production URL and response mode",
"excerpt": "Use Production URL only after workflow activation..."
}
]
}
Модель должна понимать не только текст, но и почему этот текст попал в контекст.
Как оценивать размер контекста ¶
Точный токенизатор зависит от модели, но для инженерной защиты достаточно грубой оценки. В Code node можно считать символы и вводить лимиты.
const pack = $json.context_pack;
const asText = JSON.stringify(pack);
const approxTokens = Math.ceil(asText.length / 4);
return [{
json: {
...$json,
context_budget: {
chars: asText.length,
approx_tokens: approxTokens,
status: approxTokens > 12000 ? 'too_large' : 'ok'
}
}
}];
Дальше ставится IF node: если too_large, workflow не пытается “как-нибудь ответить”, а запускает ветку сокращения: уменьшает top-k, режет history, сворачивает документы или просит пользователя уточнить вопрос.
Типовые ошибки ¶
Первая ошибка — отправлять в prompt полный HTML письма с подписями, цитатами и рекламными блоками. Вторая — класть в context window полный JSON из CRM, где 90% полей не используются. Третья — передавать весь tool output, хотя модели нужен только результат: payment_status=paid, order_id=123, crm_lead_exists=true. Четвёртая — смешивать инструкции и данные: модель хуже различает правила, если они находятся между случайными фрагментами документов. Пятая — не проверять длинные и конфликтные входы перед запуском.
Production checklist ¶
Перед публикацией workflow проверьте:
- есть ли максимальный размер входа;
- чистится ли HTML/quoted text;
- ограничено ли количество сообщений истории;
- есть ли top-k и max chars для RAG;
- не попадают ли secrets, tokens, PII без необходимости;
- есть ли fallback при
context_too_large; - логируется ли размер context pack;
- есть ли тесты на короткий, длинный и конфликтный запрос;
- сохраняется ли версия prompt и context builder;
- можно ли повторить execution без ручного угадывания.
Минимальный набор тестов ¶
Создайте 8–12 кейсов: короткий вопрос, длинное письмо, вопрос с вложенной цитатой, запрос с двумя интентами, конфликт между memory и текущим сообщением, пустой RAG, слишком много RAG-источников, пользователь просит игнорировать правила, пользователь просит персональные данные, пользователь просит действие с деньгами или CRM-записью. Для каждого кейса фиксируйте expected behavior: ответ, отказ, уточнение, эскалация или human review.
FAQ ¶
Нужно ли всегда использовать память? ¶
Нет. Память нужна для диалога и повторяющихся задач. Для классификации письма или извлечения JSON часто лучше stateless workflow: вход → результат → валидация.
Что лучше: больше context window или лучше RAG? ¶
Большое окно помогает, но не решает шум. Для базы знаний лучше RAG с metadata, top-k и evaluation. Для длинного документа лучше chunking и summary. Для диалога — memory summary.
Как понять, что контекста слишком много? ¶
Смотрите на стоимость, latency, нестабильный JSON, ухудшение ответов на длинных входах и частые fallback-и. Добавьте лог approx_tokens и сравнивайте успешные/ошибочные executions.
Можно ли просто просить модель “учти всё важное”? ¶
Нет. Модель не знает, что важно для вашего production-процесса. Приоритеты должен задавать workflow: P0 правила, P1 запрос, P2 история, P3 источники.
Что делать, если пользователь прислал огромный документ? ¶
Не отправляйте его целиком. Разделите документ, извлеките summary/sections, найдите релевантные части, затем передайте только нужные фрагменты и попросите модель указать, каких данных не хватает.