Кэширование контекста AI-агента в markdown: экономия 70% токенов | AiManual
AiManual Logo Ai / Manual.
19 Апр 2026 Гайд

Как оптимизировать расход токенов AI-агента: метод кэширования контекста с помощью markdown-файлов

Пошаговый гайд по оптимизации расходов на токены AI-агентов через кэширование контекста в markdown-файлах. Работает с Claude 3.7, GPT-5, Gemini 3.0.

45 миллионов токенов в трубу - и как этого избежать

Вы помните историю OpenCode? Команда запустила код-агента в продакшен, а через неделю получила счет за 45 миллионов токенов. Несколько тысяч долларов сгорели из-за одной архитектурной ошибки, которую повторяют 90% разработчиков.

Каждый запрос пользователя отправлял в модель Gemini 2.0 Pro ВЕСЬ контекст репозитория. Весь код, всю историю чата, все системные промпты. Снова и снова.

Это как пересылать энциклопедию Британника почтой каждый раз, когда нужно узнать столицу Франции.

На 19.04.2026 цены на токены не стали ниже. GPT-5 Turbo стоит $0.002/1K токенов ввода, Claude 3.7 Sonnet - $0.003/1K. Каждая тысяча диалогов с полным контекстом легко сжигает $50-100. Умножьте на команду из 10 разработчиков.

Почему ваши агенты едят токены как драконы

Проблема в шаблонном мышлении. Берем пример из документации OpenAI, где в чат отправляется массив сообщений: user, assistant, system. И думаем: "Так и надо".

Но в продакшене этот массив растет как снежный ком. Каждый turn диалога - это вся предыдущая история плюс новый запрос.

Если ваш агент анализирует код, то с каждым шагом контекст пухнет. Через 10 turns вы отправляете 10 версий одного и того же файла. Модель платит за обработку одинаковых данных многократно.

Это не просто дорого - это технически тупо.

💡
Контекстное окно - это не склад для хранения всего подряд. Это оперативная память. Вы же не копируете всю базу данных в RAM при каждом запросе? С агентами та же логика.

И вот здесь многие идут по пути выгорания, пытаясь вручную обрезать контекст или изобретать хитрые схемы. Есть способ проще.

Markdown-кэш: не магия, а просто умный кэш

В конце 2025 года Google анонсировал context_caching для Gemini API. OpenAI добавила аналогичное в GPT-4.5. Суть: вы отправляете часть контекста один раз, а модель запоминает его для последующих запросов.

Но есть проблема - эти встроенные системы кэширования работают только на уровне одной сессии. Перезапустили агента - кэш сбросился.

Мое решение: внешнее кэширование в markdown-файлах. Почему markdown?

  • Текстовый формат, который отлично понимают все современные LLM
  • Поддерживает структурирование через заголовки и списки
  • Легко читается человеком (можно проверить, что там внутри)
  • Минимальные накладные расходы на токенизацию
  • Совместим с любой моделью: GPT-5, Claude 3.7, Gemini 3.0, Qwen 2.5-32B

Исследование ETH Zurich в 2025 году показало, что неправильно сформированные контекстные файлы ухудшают работу AI-агентов на 3%. Но правильно организованные - ускоряют на 40% и сокращают расход токенов на 70%.

Вот как это работает на практике.

1Анализируем, что действительно нужно кэшировать

Первая ошибка - пытаться кэшировать всё подряд. Это бесполезно и даже вредно.

Откройте логи вашего агента. Посмотрите, какие части контекста повторяются в 80% запросов:

  • Системные промпты (роль агента, правила поведения)
  • Структура проекта (папки, основные файлы)
  • Документация API, которую вы используете постоянно
  • Конфигурационные файлы (docker-compose, package.json, .env.example)

А что НЕ нужно кэшировать:

  • Код, который меняется с каждым запросом
  • Временные ответы модели
  • Контекст, уникальный для конкретной задачи

Не делайте как в том самом исследовании про CLAUDE.md. Там разработчики клали в кэш ВЕСЬ код проекта, а потом удивлялись, почему агент работает хуже. Кэш - это сжатая выжимка, а не копия репозитория.

2Создаем структуру markdown-кэша

Забудьте про один огромный CONTEXT.md. Это антипаттерн.

Создайте иерархическую структуру:

ai_context_cache/
├── system_prompt.md      # Роль агента, правила
├── project_structure.md  # Папки и основные файлы
├── api_docs/
│   ├── backend_api.md
│   └── third_party_apis.md
├── configs/
│   ├── docker_setup.md
│   └── environment.md
└── knowledge/
    ├── business_rules.md
    └── common_patterns.md

Каждый файл должен быть сфокусирован на одной теме. Максимальный размер - 500-1000 токенов. Если нужно больше - разбивайте на подфайлы.

Вот пример system_prompt.md:

# Системная роль: Senior DevOps инженер

## Основные правила
1. Всегда предлагать решение с учетом лучших практик DevOps
2. Писать код с обработкой ошибок и логгированием
3. Предлагать варианты для разных окружений (dev/stage/prod)

## Стиль кода
- Использовать Python 3.11+ features где уместно
- Добавлять type hints для всех функций
- Docker образы делать минимальными (Alpine-based)

## Безопасность
- Никогда не хардкодить пароли или ключи
- Предлагать использовать секреты из vault
- Проверять входные данные на инъекции

Обратите внимание на структуру: заголовки, списки, четкие правила. Модели отлично парсят markdown.

3Реализуем загрузку кэша в агента

Теперь нужно научить агента читать эти файлы. Не загружать все сразу, а подгружать по необходимости.

Вот код на Python для агента, использующего OpenAI API (GPT-5 на 19.04.2026):

import os
from pathlib import Path
from openai import OpenAI

class ContextCacheAgent:
    def __init__(self, cache_dir="ai_context_cache"):
        self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
        self.cache_dir = Path(cache_dir)
        self.loaded_cache = {}
        
    def get_context_for_task(self, task_description):
        """Определяем, какой кэш нужен для задачи"""
        context_parts = []
        
        # Всегда добавляем системный промпт
        context_parts.append(self._load_cache_file("system_prompt.md"))
        
        # Анализируем задачу и добавляем релевантные части
        task_lower = task_description.lower()
        
        if any(word in task_lower for word in ["docker", "container", "image"]):
            context_parts.append(self._load_cache_file("configs/docker_setup.md"))
            
        if any(word in task_lower for word in ["api", "endpoint", "request"]):
            context_parts.append(self._load_cache_file("api_docs/backend_api.md"))
            
        if any(word in task_lower for word in ["deploy", "infrastructure", "cloud"]):
            context_parts.append(self._load_cache_file("knowledge/common_patterns.md"))
        
        # Добавляем структуру проекта для задач, связанных с кодом
        if any(word in task_lower for word in ["file", "folder", "structure", "project"]):
            context_parts.append(self._load_cache_file("project_structure.md"))
        
        return "\n\n".join(context_parts)
    
    def _load_cache_file(self, file_path):
        """Ленивая загрузка файлов кэша"""
        if file_path in self.loaded_cache:
            return self.loaded_cache[file_path]
            
        full_path = self.cache_dir / file_path
        if full_path.exists():
            content = full_path.read_text(encoding="utf-8")
            self.loaded_cache[file_path] = content
            return content
        return ""
    
    def ask(self, question):
        """Основной метод для вопросов к агенту"""
        context = self.get_context_for_task(question)
        
        messages = [
            {"role": "system", "content": context},
            {"role": "user", "content": question}
        ]
        
        response = self.client.chat.completions.create(
            model="gpt-5-turbo",
            messages=messages,
            temperature=0.1
        )
        
        return response.choices[0].message.content

Ключевой момент: мы НЕ отправляем весь кэш каждый раз. Мы анализируем задачу и подгружаем только релевантные части.

💡
Этот подход сокращает контекст на 60-80% по сравнению с отправкой всей истории. Для диалога из 10 сообщений экономия составит тысячи токенов.

4Добавляем инвалидацию и обновление кэша

Статический кэш - это мертвый кэш. Когда меняется структура проекта или обновляется API, кэш должен обновляться.

Реализуем простую систему инвалидации:

import hashlib
from datetime import datetime, timedelta

class SmartContextCache(ContextCacheAgent):
    def __init__(self, cache_dir="ai_context_cache"):
        super().__init__(cache_dir)
        self.cache_metadata = {}
        self._load_metadata()
    
    def update_cache_if_needed(self, file_path, current_content):
        """Обновляем кэш, если контент изменился"""
        content_hash = hashlib.md5(current_content.encode()).hexdigest()
        
        if file_path not in self.cache_metadata:
            # Новая запись в кэше
            self._save_to_cache(file_path, current_content, content_hash)
            return True
            
        metadata = self.cache_metadata[file_path]
        
        # Проверяем по хэшу
        if metadata["hash"] != content_hash:
            print(f"Обновляю кэш для {file_path}")
            self._save_to_cache(file_path, current_content, content_hash)
            return True
            
        # Проверяем по времени (обновлять раз в неделю)
        last_updated = datetime.fromisoformat(metadata["last_updated"])
        if datetime.now() - last_updated > timedelta(days=7):
            print(f"Периодическое обновление кэша для {file_path}")
            self._save_to_cache(file_path, current_content, content_hash)
            return True
            
        return False
    
    def _save_to_cache(self, file_path, content, content_hash):
        """Сохраняем в markdown с метаданными"""
        full_path = self.cache_dir / file_path
        full_path.parent.mkdir(parents=True, exist_ok=True)
        
        # Добавляем мета-информацию в комментарий
        meta_comment = f"\n\n"
        full_path.write_text(meta_comment + content, encoding="utf-8")
        
        self.cache_metadata[file_path] = {
            "hash": content_hash,
            "last_updated": datetime.now().isoformat()
        }
        self._save_metadata()

Теперь вы можете автоматически обновлять кэш при изменении исходных файлов. Например, при коммите в git.

Ошибки, которые сведут на нет всю экономию

Я видел десятки реализаций. Вот что делают не так:

ОшибкаПоследствиеКак исправить
Кэшировать весь код проектаКонтекст становится больше оригиналаКэшировать только структуру и ключевые файлы
Нет инвалидации кэшаАгент работает с устаревшими даннымиДобавить проверку хэша и времени
Один файл на всёНевозможно подгрузить частичноРазбить на тематические файлы
Кэшировать вывод моделиБыстрое устаревание, бесполезные данныеКэшировать только статическую информацию

Самая опасная ошибка - забыть про контекстную амнезию. Если ваш агент работает долго (часы или дни), markdown-кэш становится его долговременной памятью. Но эта память должна быть релевантной.

Интеграция с существующими агентами

Вы уже используете Claude Code, Cursor, или свой кастомный агент? Внедрить markdown-кэш проще, чем кажется.

Для Claude Code создайте файл .claude_context в корне проекта:

# Контекст проекта

## Структура
- /src - исходный код
- /tests - тесты
- /docs - документация

## Важные файлы
- `src/main.py` - точка входа
- `src/config.py` - конфигурация
- `Dockerfile` - сборка контейнера

## Правила кода
1. Используйте async/await для IO операций
2. Добавляйте docstring ко всем функциям
3. Тестируйте с pytest, покрытие >80%

Claude автоматически учтет этот файл при работе с проектом.

Для Cursor используйте папку .cursor/rules. Создайте там markdown-файлы с контекстом.

Для кастомных агентов на LangChain или других фреймворках - добавьте middleware, который будет подгружать кэш перед отправкой в модель. Примерно как в моем коде выше.

Не повторяйте ошибку из статьи про сжатие вывода инструментов. Там пытались сжимать ВЕСЬ вывод, включая критичные данные. Кэшируйте только то, что действительно повторяется.

Сколько вы сэкономите на самом деле

Давайте посчитаем на примере типичного DevOps агента:

  • Без кэша: каждый запрос включает системный промпт (500 токенов) + история диалога (в среднем 2000 токенов) + контекст проекта (3000 токенов) = 5500 токенов
  • С кэшем: системный промпт загружен один раз в сессию + только релевантные части проекта (в среднем 1000 токенов) + история (только последние 3-4 сообщения, 800 токенов) = 1800 токенов

Экономия: 67% на каждом запросе.

При стоимости GPT-5 Turbo $0.002/1K токенов:

  • Без кэша: 1000 запросов × 5.5K токенов = 5.5M токенов = $11
  • С кэшем: 1000 запросов × 1.8K токенов = 1.8M токенов = $3.6
  • Экономия: $7.4 на 1000 запросов

Для команды из 5 разработчиков, каждый делает 50 запросов в день, 20 рабочих дней в месяце:

5 × 50 × 20 = 5000 запросов в месяц
Экономия: 5000 × $0.0074 = $37 в месяц
За год: $444

И это только на одном проекте. Если у вас несколько проектов или больше разработчиков - цифры растут кратно.

Что будет с кэшированием в 2027 году

Судя по roadmap крупных вендоров, встроенное кэширование контекста станет стандартом. OpenAI уже тестирует функцию "persistent context" в GPT-5, Anthropic работает над аналогичным для Claude 4.

Но markdown-кэш не умрет. Потому что:

  1. Он дает контроль над тем, ЧТО именно кэшируется
  2. Работает кросс-платформенно (один кэш для разных моделей)
  3. Позволяет версионировать и делиться контекстом между членами команды

Мой прогноз: к 2027 году мы увидим гибридные системы. Встроенное кэширование модели + внешние markdown-файлы для специфичного контекста проекта.

А пока - начинайте с простого. Создайте папку ai_context_cache, наполните её markdown-файлами с самым важным контекстом. Подключите к своему агенту. Через неделю проверьте счета за токены.

Разница вас удивит.

Подписаться на канал