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 среде это быстро превращается не просто в лишние токены, а в потерю трассируемости решений между сессиями.

Проблема выглядит знакомо: агент запускает 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.

Read more

Computer-Use-Agenten scheitern an Pixeln: wie Sie auf stabile UI-Referenzen über Accessibility Trees umstellen und fehleranfällige Desktop-Automatisierung nicht mehr ständig reparieren

von Denis Shokhirev, Enterprise AI Architect aus Freiburg im Breisgau Ich bin Denis Shokhirev, Agentic AI Systems Architect in Freiburg im Breisgau, Germany, und bei DennisCraft AI Studio setze ich produktive KI-Systeme für DACH-B2B-Kunden auf Basis von Claude, Supabase, n8n, Doppler und selbst betriebenem Postgres um. Die teuersten Fehler in

By Denis Shokhirev

Компьютерные агенты ломаются на пикселях: как перейти на stable UI refs через accessibility tree и перестать чинить flaky desktop automation

Я Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая дорогая поломка в desktop automation, которую я вижу у клиентов, почти никогда не связана с моделью: агент

By Denis Shokhirev