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

Один агент упёрся в лимит, второй потерял контекст: как собрать команду Claude Code + Codex без ручных перезапусков

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

Denis Shokhirev
Denis Shokhirev
Agentic AI Systems Architect
Telegram LinkedIn

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

Эта проблема возникает не потому, что модели слабые. Наоборот: обе полезны, но у них разные режимы отказа. Если относиться к ним как к двум независимым помощникам в одном терминале, вы получаете хаос. Если относиться к ним как к команде с журналом состояния, контрактами на вход и выход и автоматическим оркестратором, ручные handoff почти исчезают.

Где ломается связка Claude Code + Codex

В production я вижу 3 повторяющихся сбоя. Первый: квоты и rate limits приходят в самый неподходящий момент, обычно на длинной задаче с несколькими файлами. Второй: агент продолжает работу после обрезки контекста и начинает уверенно переписывать уже принятые решения. Третий: новый агент получает только prompt, но не получает фактическое состояние проекта — какие файлы уже тронуты, какие тесты упали, какой security gate не пройден.

Почему простое "передай prompt дальше" не работает

Prompt не равен состоянию. Состояние — это commit SHA, список изменённых файлов, результаты semgrep, bandit и gitleaks, открытые TODO, текущая ветка, статус миграций Postgres и последнее решение по архитектуре. Пока это не записано явно, второй агент не продолжает работу, а реконструирует её наугад.

Anthropic в документации по tool use и structured outputs в 2024 году прямо показывает ценность структурированных ответов для автоматических workflows, а не только для диалога: docs.anthropic.com. В похожем ключе OpenAI Cookbook в 2024 году показывает паттерны orchestration и state passing между шагами, а не надежду на длинный chat history: cookbook.openai.com. Это ровно тот случай.

Правильная модель: не чат, а журнал состояния

Я не связываю Claude Code и Codex через "общую память" в абстрактном смысле. Я связываю их через внешний state store. На моём стеке это обычно Postgres или Supabase Postgres, а n8n исполняет простую логику оркестрации: создать задачу, назначить агента, получить артефакты, прогнать проверки, при сбое передать следующему агенту уже не prompt, а карточку состояния.

Слой Что хранить Зачем это второму агенту
Task state task_id, branch, commit_sha, goal, owner_agent Понять, что именно продолжается
Execution log команды, stderr/stdout, коды возврата Не повторять уже провалившиеся шаги
Code artifacts diff summary, changed_files, test results Войти в задачу без сканирования всего репозитория
Risk gates semgrep, bandit, gitleaks, manual review flag Не протащить уязвимость при handoff

Минимальный контракт handoff

У каждого агента должен быть фиксированный выходной формат. Не "опиши, что ты сделал", а JSON с обязательными полями. Если агент не может вернуть этот контракт, задача не передаётся дальше автоматически.

from pydantic import BaseModel
from typing import List, Literal

class HandoffState(BaseModel):
    task_id: str
    agent: Literal["claude_code", "codex"]
    branch: str
    commit_sha: str
    changed_files: List[str]
    test_status: Literal["passed", "failed", "not_run"]
    security_status: Literal["passed", "failed", "not_run"]
    next_action: str
    blocker: str | None = None

Этот контракт кажется скучным, пока не случится первый аварийный переход между агентами в пятницу вечером. После этого скука становится достоинством.

Как убрать ручные restart через n8n и Postgres

Механика простая. Claude Code получает задачу на реализацию. Если он доходит до лимита, timeout или не проходит gate, n8n не шлёт человеку сообщение "перезапусти". Вместо этого workflow сохраняет handoff state в Postgres, переключает owner_agent на Codex и передаёт только task_id. Codex сначала читает состояние, а уже потом открывает репозиторий и продолжает с нужной точки.

version: "3"
steps:
  - name: run_claude_code
    on_error: persist_state
  - name: persist_state
    action: write_postgres
  - name: run_checks
    action: bash
  - name: route_next_agent
    when: "quota_hit || context_loss || timeout"
    action: assign_codex
  - name: require_review
    when: "security_failed"
    action: notify_human

Да, это упрощённое представление. Но принцип важнее деталей: handoff должен запускаться событием, а не человеком. И переключение не должно зависеть от того, сохранил ли кто-то "тот самый последний prompt" в заметках.

Какие события реально стоит ловить

Я обычно использую 5 триггеров: quota hit, context truncation, command timeout, failed tests и failed security scan. Первые 3 ведут к автоматическому handoff. Последние 2 чаще ведут либо к возврату задачи тому же агенту с узким remediation prompt, либо к human review, если код касается auth, SQL или работы с секретами.

Безопасность: не доверяйте второму агенту больше, чем первому

Одна частая ошибка — считать handoff просто операционной проблемой. На деле это ещё и security-проблема. Второй агент склонен "чинить" не понимая, почему первое решение было ограничено. Именно на handoff у меня чаще всего всплывают лишние расширения прав, сырые SQL-запросы или случайная запись секретов в лог.

OWASP в 2021 году в Top 10 закрепил injection как один из базовых классов риска: owasp.org/Top10. Поэтому я не пропускаю handoff без статических проверок. Для Python это может быть bandit, для общего паттерн-матчинга — semgrep, для секретов — gitleaks.

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

pytest -q
semgrep --config auto .
bandit -r app -q
gitleaks detect --no-banner --redact

echo "checks_passed=true"

На 3 недавних agent deployment я ловил один и тот же паттерн: первый агент аккуратно использовал параметризованные запросы, второй при срочном исправлении регрессии вставлял сырой SQL в helper-слой. Не потому что модель "плохая", а потому что handoff был бедным по контексту и богатым по давлению на скорость.

Практическая схема для regulated Europe

Для клиентов из логистики, fintech и industrial automation в DACH я стараюсь держать архитектуру скучной и проверяемой. Исходники в Git, состояние задач в Postgres, секреты в Doppler, оркестрация в n8n, артефакты проверок рядом с task_id. Это важно не только для удобства, но и для аудита: кто менял код, какой агент это делал, какие проверки были пройдены, где потребовался человек.

Если у вас есть Supabase, не превращайте его только в backend для приложения. Это хороший слой для журналирования agent runs, особенно если нужно быстро поднять таблицы состояния, webhooks и простые административные представления. Главное — не хранить "память" агента в одном текстовом blob. Храните нормализованные поля, по которым можно строить маршрутизацию и контроль.

FAQ

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

Да. Логику handoff можно собрать и на чистом Python с очередью задач. Но n8n удобен там, где нужны быстрые изменения маршрутов, уведомления и работа с webhooks без отдельного сервиса оркестрации.

Нужно ли давать Claude Code и Codex доступ к одной ветке?

Обычно да, но только при жёстком контракте состояния и фиксации commit SHA. Если риск высокий, лучше делать handoff через новую ветку от последнего подтверждённого коммита и автоматически собирать diff.

Что важнее: длинный prompt или внешний state store?

Внешний state store. Длинный prompt полезен как краткое резюме, но он не заменяет результаты тестов, историю команд и статусы проверок в структурированном виде.

Когда обязательно нужен human review?

Когда задача затрагивает auth, права доступа, SQL, секреты, платёжную логику или персональные данные. Чем ближе код к границе риска, тем меньше смысла надеяться на автоматический handoff без человека.

Как понять, что handoff у вас уже сломан?

Если агенты часто перечитывают весь репозиторий, повторяют одинаковые команды, спорят с уже принятыми решениями или производят конфликтующие изменения, значит состояние не передаётся явно. Это не проблема модели, это проблема операционного слоя.

Где в вашем LLM pipeline чаще всего рвётся работа в проде — на квотах, на потере контекста, на security gate или уже на человеческом ревью? Мне правда интересно сравнить это с тем, что я вижу в DACH-проектах.
I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.

Читать дальше
Всегда-on агенты уже здесь: как не превратить Claude Duet в источник утечек, ложных действий и хаоса в доступах
LiteLLM снова скомпрометировали: как не потерять SSH-ключи и API-секреты через AI gateway в проде
Если вашему AI-агенту нужен веб-доступ, MCP уже стал новым стандартом: что реально решает Firecrawl MCP в проде
MCP дошёл до Go: как не утонуть в интеграциях агентов и собрать production-ready сервер без самописного glue-кода
Все статьи →
Где это применяется
Услуги — что мы делаем
Поговорить с голосовым агентом
Кейсы
Готовы к следующему шагу?

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

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

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