О себе Портфолио Кейсы Услуги Блог Контакт 🎙 Поговорить с AI
EN DE RU
🎙 Поговорить с AI
October 20, 2026 · 4 min read

AI-кодинг-агенты сжигают контекст и токены: как сократить шум tool output на 98% и не терять память между сессиями

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я строю production AI-системы для DACH B2B на стеке Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая дорогая поломка в coding-agent пайплайне у меня обычно не в модели, а в том, что агент за 20 минут сжигает контекст на мусоре из tool output, а потом забывает, почему вообще менял файл. В regulated среде это быстро превращается не просто в лишние токены, а в потерю трассируемо

Denis Shokhirev
Denis Shokhirev
Agentic AI Systems Architect
Telegram LinkedIn

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я строю production AI-системы для DACH B2B на стеке Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая дорогая поломка в coding-agent пайплайне у меня обычно не в модели, а в том, что агент за 20 минут сжигает контекст на мусоре из tool output, а потом забывает, почему вообще менял файл. В regulated среде это быстро превращается не просто в лишние токены, а в потерю трассируемости решений между сессиями.

Проблема выглядит знакомо: агент запускает grep, semgrep, bandit, gitleaks, тесты, линтеры, diff, читает 15 файлов подряд и тащит обратно в prompt почти все. Через несколько ходов история уже состоит не из намерения и решений, а из простыней stdout. В итоге следующая сессия стартует с нуля, хотя фактически работа уже была сделана.

Где именно умирает контекст

Я вижу 3 типовых источника потерь:

Источник шумаЧто происходитПоследствие
Сырые tool outputsВ prompt попадает полный stdout/stderrКонтекст забит логами вместо решений
Повторное чтение файловАгент снова и снова тянет одни и те же кускиЛишние токены и дрейф внимания
Нет session memoryПосле рестарта нет сжатой истории решенийПовторные шаги и расхождение по архитектуре

Anthropic в документации по prompt engineering и tool use постоянно подталкивает к структурированию контекста, а не к бесконтрольной передаче сырых инструментальных ответов. Это не академическая тонкость, а практический предел окна контекста. В OpenAI Cookbook в паттернах работы с длинным контекстом и retrieval тоже та же идея: передавать модели только релевантное сжатое состояние, а не весь журнал операций. Источники: Anthropic Docs, 2024–2025, https://docs.anthropic.com/ ; OpenAI Cookbook, 2024, https://cookbook.openai.com/.

На моих последних агентных внедрениях сокращение объема tool output, который реально попадал обратно в модель, доходило примерно до 98%. Не потому что инструментов стало меньше, а потому что в контекст шел не лог, а результат в нормализованной форме: статус, измененные файлы, найденные проблемы, следующий шаг.

Что хранить в prompt, а что выносить наружу

1. В prompt — только decision state

Модели нужен не полный stdout bandit, а 4 вещи: какие файлы затронуты, какие риски найдены, что уже исправлено, где нужен следующий вызов инструмента. Все остальное должно жить вне prompt.

2. Сырые артефакты — в Postgres или Supabase

Я обычно складываю полные outputs инструментов в Postgres: по run_id, tool_name, file_path, severity, raw_output, summary. В prompt попадает только summary. Если нужно обоснование, агент может точечно запросить первоисточник.

3. Межсессионная память — это не chat history

Session memory для coding agents — это не полный лог диалога. Это сжатое состояние задачи: цель, принятые решения, ограничения, открытые риски, последние измененные файлы, known bad paths. Такой объект можно передавать между сессиями без потери хода мысли.

from dataclasses import dataclass, asdict
import json

@dataclass
class SessionMemory:
    task_goal: str
    decisions: list[str]
    touched_files: list[str]
    open_risks: list[str]
    next_step: str

def compact_memory(memory: SessionMemory) -> str:
    payload = asdict(memory)
    return json.dumps(payload, ensure_ascii=False, separators=(",", ":"))

memory = SessionMemory(
    task_goal="Fix SQL query parameterization",
    decisions=["Use parameterized queries", "Keep repository API stable"],
    touched_files=["db/repo.py", "tests/test_repo.py"],
    open_risks=["Legacy helper still interpolates SQL"],
    next_step="Inspect legacy helper and patch tests"
)

Паттерн, который реально работает в production

Я использую простой цикл из 4 фаз: execute, normalize, persist, recall.

Execute

Инструмент выполняется как обычно: semgrep, bandit, gitleaks, тесты, git diff. Но агент не получает право без фильтра тащить все обратно в контекст.

Normalize

Каждый output сводится к короткой записи фиксированной формы. Например: tool=bandit, status=fail, findings=2, files=[...], top_risk=CWE-89 pattern, next_action=patch SQL call. Это дисциплинирует агента сильнее, чем любые разговоры про “будь кратким”.

Persist

Нормализованное состояние и сырые артефакты сохраняются отдельно. Для regulated клиентов это помогает с аудитом: можно показать не только итоговый код, но и цепочку решений.

Recall

Новая сессия поднимает не весь чат, а компактную memory plus точечные артефакты по запросу. Так агент продолжает работу, а не пересобирает картину мира заново.

type ToolSummary = {
  tool: string
  status: "ok" | "fail"
  findings: number
  files: string[]
  nextAction: string
}

function summarizeBandit(raw: string): ToolSummary {
  const findings = (raw.match(/>> Issue:/g) || []).length
  const files = [...raw.matchAll(/Location:\s+(.+):\d+/g)].map(m => m[1])
  return {
    tool: "bandit",
    status: findings > 0 ? "fail" : "ok",
    findings,
    files: [...new Set(files)].slice(0, 10),
    nextAction: findings > 0 ? "patch flagged Python paths" : "continue"
  }
}

Почему это важно для безопасности и аудита

Когда coding agent тонет в логах, он начинает пропускать важное. Для кода это быстро упирается в CWE и OWASP-классы ошибок. OWASP регулярно указывает, что избыточная сложность и отсутствие контроля над цепочкой обработки данных повышают риск уязвимостей в приложениях. Для AI-кода риск тот же, только скорость выше: агент генерирует, правит и подтверждает себя сам, если вы не добавили внешние проверки. Источник: OWASP Top 10, 2021, https://owasp.org/www-project-top-ten/.

Поэтому у меня нормой стали внешние проверки перед тем, как что-то считать “сделанным”: semgrep для паттернов, bandit для Python, gitleaks для секретов, плюс тесты. Но критично то, что в модель возвращается только итог проверки в компактной форме.

#!/usr/bin/env bash
set -euo pipefail

semgrep --config auto --json > /tmp/semgrep.json || true
bandit -r . -f json -o /tmp/bandit.json || true
gitleaks detect --report-format json --report-path /tmp/gitleaks.json || true

python scripts/store_tool_results.py \
  --run-id "$RUN_ID" \
  --semgrep /tmp/semgrep.json \
  --bandit /tmp/bandit.json \
  --gitleaks /tmp/gitleaks.json

Минимальная реализация без лишней сложности

Если у вас уже есть Claude Code, Anthropic SDK, n8n или просто собственный orchestrator, не надо перестраивать все. Достаточно ввести 3 объекта:

ОбъектГде хранитьНазначение
tool_runsPostgres / SupabaseСырые outputs и метаданные
session_memoryPostgres / SupabaseСжатое состояние задачи
recall_policyКод orchestratorЧто можно вернуть в prompt

В n8n это обычно один узел для запуска проверки, один для нормализации JSON, один для записи в базу и один для сборки compact prompt перед следующим вызовом модели. Главная мысль простая: tool output — это журнал, а не prompt.

FAQ

Нужно ли сохранять всю историю чата?

Нет. Для coding agents полная история обычно хуже полезного состояния. Храните решения, ограничения, артефакты и ссылки на полные логи.

Когда RAG уместен, а когда нет?

RAG уместен для поиска по кодовой базе, документации и прошлым run. Но session memory лучше держать как отдельный структурированный объект, а не пытаться каждый раз “искать” собственное состояние.

Можно ли обойтись без Supabase?

Да. Обычный Postgres закрывает задачу полностью. Supabase просто ускоряет API-слой и удобен, если у вас уже есть этот контур.

Почему недостаточно просто увеличивать окно контекста?

Потому что проблема не только в размере, но и в качестве сигнала. Если вы заливаете в модель 200 KB логов, она не становится внимательнее к 3 важным решениям.

Как измерить эффект?

Смотрите 4 метрики: tokens per successful task, число повторных чтений файла, доля restart sessions без деградации результата и время до фикса после рестарта. На практике именно они показывают, что память стала рабочей.

Если у вас coding agent уже в production, на каком этапе у вас больше всего теряется качество после длинной цепочки вызовов — на сырых tool outputs, на повторном чтении файлов или на отсутствии нормальной межсессионной памяти? Я правда хочу это сравнить с тем, что вижу у своих клиентов.

Я провожу бесплатный 30-минутный stack audit для DACH founders, которые строят AI в regulated markets. Напишите мне в LinkedIn или в @ger_dennis_ai.

Читать дальше
MCP-зоопарк уже ломает команды: как выбрать один runtime для агентов вместо 10 несовместимых тулов
AI-ассистент для Blender: как интеграция мультиагентных рабочих процессов экономит недели ручной 3D-работы
Почему ваши AI-агенты падают в проде: как Trigger.dev решает проблему надёжности и оркестрации
Контекстное окно для AI-агентов: как сократить расходы на память и ускорить цепочки задач
Все статьи →
Где это применяется
Услуги — что мы делаем
Поговорить с голосовым агентом
Кейсы
Готовы к следующему шагу?

Превратить процесс в систему, которая работает

Продакшн-качество, а не демо.

Обсудить проект → ← Все статьи