Claude Code

Сравнение возможностей Codex и Claude Code

В ходе обсуждения предыдущей заметки в чате телеграм-канала прозвучало заявление, что Codex — намного более качественный агент, чем плохо написанный Claude Code, качество которого (вместе с моделью LLM) постоянно деградирует.

Я последние несколько месяцев регулярно сравниваю разные агенты — и чтобы просто знать, и чтобы пробовать применять на практике, — и как раз относительно недавно такой анализ делал. По его результатам выходило, что Codex, конечно, неплохо стал развиваться, но многие возможности Claude Code в нем отсутствуют. Отступая в сторону, могу сказать, что действительно хорошо развит OpenCode, хотя у него есть некоторые ограничения, и есть еще Pi, который по определению можно настроить как угодно, поскольку его идея в том, что он сам себя дописывает.

Впрочем, проверить не мешает. Проверка получилась простой — я запустил codex cli прямо в его директории ~/.codex и дал ему проанализировать три источника — его собственные настройки, официальную документацию (у него есть встроенный скилл openai-docs плюс я дал сайт) и настройки Claude Code. Задача выглядела просто — проанализировать все настройки и предложить, как портировать настройки Claude Code в Codex.

У меня очень солидно навороченные настройки в Claude Code — специализированные агенты, скиллы, гибкая система разрешений, хуки, которые запускают проверки и линтеры, блокируют опасные команды, вставляют нужный контекст в особых случаях и сложная система промптов, которые подгружаются по необходимости. Так что задача не была простой, конечно, но она вполне реальна — я использую Codex для ревью проектов и в качестве “второго мнения”, поэтому логично держать его настроенным так же хорошо, как и основного агента.

К сожалению, совсем так же хорошо не получается. Вот краткий список того, что перенести не получается:

  • реализация hooks в Codex пока экспериментальная и минимальная. Фактически они срабатывают только на bash команды, поэтому получится только перехватить опасные команды, но запуск линтера или форматтера при редактировании кода не получится. Технически можно запустить отдельный процесс, который будет отслеживать изменения файлов, прогонять проверки и писать результат в отчет, а по событию Stop будет срабатывать хук, который допишет этот результат в контекст, но это обходной вариант. Отпадают и другие срабатывания, которые я использую.
  • аналога /rules в Codex нет. В Claude Code это отдельная папка с промптами, которые подгружаются в контекст автоматически, когда Claude работает с соответствующими файлами. Например, отдельный файл у меня содержит инструкции по написанию Python-скриптов и эти инструкции агент читает, только приступая к работе с Python кодом. Часть инструкций загружаются всегда, часть — только при обращении к определенному MCP и так далее. В Codex такое невозможно — общие рекомендации можно прописать в AGENTS.md, что-то специфическое для кода можно вынести в skill, допустимо создать профили, но переключать их придется вручную.
  • Skills просто так скопировать не выйдет. Скиллы в Codex фактически являются только инструкциями для использования основным агентом. В Claude Code можно задать скиллу параметр context:fork для запуска в отдельном контексте, назначить тип агента, модель для использования и даже глубину размышлений. Это позволяет не заморачиваться, если вам надо просто обработать специфический тип данных — основной агент использует скилл, который запускается как отдельный субагент, например, general-purpose, с быстрой моделью и возвращает только результат. В Codex так не выйдет — придется конфигурировать специального субагента и запускать именно его. Не очень критично, но все же дополнительные усилия.
  • Сильно отличается система разрешений. Claude фактически оперирует разрешениями для конкретных tools, что делает контроль очень точечным и понятным в разрезе именно команд. Кстати, сейчас появился режим auto, где модель сама решает, насколько безопасна команда и решает достаточно неплохо — правда, уж если она знает, что это мутирующая команда (git push, например), запустить ее получится только самому пользователю. У Codex совсем не так — там задается sandbox и внутри нее по умолчанию модель работает, спрашивая разрешение только на запуски что-то изменяющих скриптов. Явно понадобится разрешить также доступ в сеть, можно прописать режим запуска команд вне sandbox. Выглядит вроде бы жестче и системнее, но по удобству Claude выглядит лучше.

В общем, какой-то порядок с настройками Codex я навел, но дотянуть его до уровня Claude Code не получилось. Подождем доработок, кажется, разработчики там достаточно активны.

Чудо уговаривания LLM

Наткнулся в Facebook на характерную запись.

Скриншот записи в Facebook по использованию Claude

С одной стороны, меня очень радуют подобные вещи — они показывают, что количество людей, которым понадобятся мои объяснения, как именно надо использовать AI, уменьшаться в обозримой перспективе не будет. Кроме того, это подтверждает мое мнение о людях, которые считают программирование достаточным признаком инженера — у автора тоже написано в профиле software engineer, хотя второе слово явно не имеет к нему отношения.

С другой стороны, слегка утомителен тот факт, что до подобных откровений приходится буквально докапываться через бронебойную уверенность, что “AI это просто генератор случайных токенов”, “AI вам ничего не напишет”, “Вы еще придете просить, чтобы мы разобрались с вашим вайб-проектом”.

Проблема, описанная в записи, решается за минуту конфигом Claude Code — в settings.json надо указать явно:

{
  "permissions": {
    "ask": [
      "Bash(git commit *)",
      "Bash(git * main)",
    ],
    "deny": [
      "Bash(git push *)"
    ]
  }
}

После этого агент будет обязательно спрашивать всякий раз перед коммитом, даже если ему разрешены все правки, и не сможет сделать push, который часто запускает деплой. Если вы используете что-то свое для деплоя — укажите именно этот скрипт.

Более того, в Claude Code есть хуки, которые позволяют еще раз запретить запуск опасных команд.

    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qiE '(deploy.sh|git.*push)'; then echo 'BLOCK: Deployment commands require explicit user approval' >&2; exit 2; fi"
          },
   }
]

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

Перефразируя фразу про магию и физику — никогда не читайте документацию по настройке агентов и жизнь ваша наполнится чудом уговаривания LLM. Ах, да, ему же приключений хочется — ну, так они ему будут.

Skills как замена подтверждениям

Много раз убеждался, что некоторые вещи, которые кому-то кажутся очевидными, другим людям в голову не приходят. Так что очередное небольшое наблюдение из работы с Claude Code запишу сюда.

У большинства пользователей skills (скиллы или навыки) воспринимаются как специализированные инструкции для агента, которые описывают, как ему работать с какой-то частью задачи, API или типом данных. Как-то гораздо реже встречается другая сторона использования скиллов — возможность найти золотую середину в использовании агентов внешних инструментов без создания проблем в безопасности, и добавить этому использованию детерминированности.

Предположим, вы с агентом выполняете какую-то задачу, предусматривающую запуск команды в терминале или обращения к внешним ресурсам, через API, например. Если у вас разумно настроена безопасность, то агент на каждый такой запрос просит разрешения — потому что он либо запускает curl, либо пишет небольшой код на python, и хорошо бы убедиться, что он не дергает ничего потенциально опасного, а за запрос разрешений отвечают простые маски и там не пропишешь сложную логику. В итоге вы либо тупо соглашаетесь с каждым предложением, что небезопасно, либо разрешаете ему запускать curl в любом виде, что вообще опасно. Кроме того, всякий раз конструируя команду, агент регулярно ошибается — если бы это был человек, то это был бы аналог того, что каждую новую команду он набирает по символу. А это время и токены, между прочим.

Первый подход к скиллам обычно выглядит как “Давайте ему запишем все возможные команды в SKILL.md и он не будет ничего придумывать”. Но всё, что вы даёте агенту в формате .md — это инструкции и их выполнение недетерминированно — иначе говоря, агент может модифицировать команду, особенно, когда она будет шаблонной.

Поэтому более системный подход будет таким — “Напишем скрипт с обертками всех необходимых для этой задачи команд и разрешим агенту запускать только его”. Агенту не надо ничего придумывать — у него есть собственный tool со всеми необходимыми функциями, разрешение его использовать всегда и этот скрипт будет работать совершенно определенным образом, без фантазий LLM. Мне встречалось, правда, желание агента переписать этот скрипт, но это уже другая операция и её можно перехватить.

Еще более правильный подход — если задача объемная и довольно инструментальная, то создать соответствующего агента, который будет запускаться основным процессом, работать со своим контекстом, возможно, использовать более слабую модель (какой-нибудь поиск по тексту или проверка отчетов через API) и использовать только этот скрипт. В принципе, можно и скилл запускать с параметром context:fork, что даст похожий эффект, но использование отдельного агента позволит вам точнее его инструктировать — с context:fork Claude запустит general-purpose агента, инструкции которого довольно общие.

Так вот, если из всего потока операций при выполнении задачи выделить команды, требующие подтверждения, обернуть их скриптом (конечно же, пусть его сам Claude Code и напишет), где эти команды будут запускаться с ограниченным набором параметров, и разрешить только этот скрипт выполнять без подтверждений — ваша клавиша Enter будет вам благодарна, а вы сами сможете отойти от компьютера без ущерба для работы.

Как Claude Code экономит токены

Ночью пришло сообщение от Anthropic, которое быстро взбудоражило всё сообщество — компания официально объявила, что подписка на её сервисы больше не покрывает использование сторонних агентов, в том числе OpenClaw. Понятно, что тут же начались возмущенные твиты “Я отказываюсь от подписки”, “Anthropic ненавидит open source” и так далее, но это всё шум. Реальность такова, что компания наконец-то высказалась ясно на тему использования лимитов подписки в сторонних агентах — это, на мой взгляд, хорошо и давно пора было. При этом публичные лица компании — начиная с Бориса Черни, руководителя Claude Code, — довольно подробно начали объяснять, что подписка оптимизирована под взаимодействие с нативными агентами и в условиях дефицита мощностей компания вынуждена приоритезировать их поддержку. Разумеется, это не мешает критикам возмущаться и дальше.

Сообщение от Anthropic про запрет использования сторонних клиентов в рамках подписки Claude

Утечка workflow в скиллах Claude Code

Есть много занятий, которыми можно заниматься постоянно и у меня к таким в последний год добавился регулярный анализ конфигурации всей моей AI-инфраструктуры, включая агентов. Тут, конечно, главное — вовремя остановиться в совершенствовании инструмента и перейти к его применению, но процесс все равно интересный.

Я регулярно нахожу самые разные советы, собираю целые фреймворки для работы, например, Claude Code, стараюсь анализировать, что нахожу, комбинировать со своими наработками.

Вот очень необычный и интересный совет, который я вытащил из фреймворка superpowers.

Автор фреймворка обнаружил явление, которое можно назвать утечкой workflow. В Claude Code широко распространены скиллы, описывающие порядок действий в определенных случаях, которые подгружаются в контекст агента в случае срабатывания триггеров. Триггеры ориентируются на описание (description) скилла, поэтому принято там описывать назначение. Так вот, оказывается, если описание содержит не только случаи, в которых должен сработать скилл, но и описание того, что скилл делает, то Claude Code (точнее, LLM) может проигнорировать всё остальное содержание, посчитав описание достаточной инструкцией для работы.

В случае у автора Claude, прочтя в описании “code review between tasks”, провел одно ревью вместо процедуры из нескольких этапов.

Простое исправление — перечислять в description собственно условия срабатывания скилла и не допускать описания непосредственно процесса.

Например, вместо “Comprehensive testing workflow with parallel unit/integration tests and gated E2E” написать “Use for ‘run tests’, ’test this’, ‘check test coverage’” или вместо “Bug investigation and resolution workflow. Routes to investigate, diagnose, implement” прописать “Use for ‘fix this bug’, ‘debug this’, ’this is broken’”.

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

Как реорганизовать память в Claude Code

Одна из главных проблем работы с кодинг-агентами — это контекст. Во-первых, размер контекста не бесконечный, во-вторых, даже очень большой контекст (как, например, 1 млн токенов у Gemini) не гарантирует, что модель с ним хорошо работает. Как тут не вспомнить принцип Шерлока Холмса, который сравнивал человеческий мозг с чердаком, где всё должно быть аккуратно разложено, чтобы им можно было воспользоваться.

Есть много способов организовать работу того же Claude Code, чтобы не захламлять контекст лишними токенами. Но так или иначе, по мере развития проекта, над которым вы работаете с агентом, в нем накапливается большое количество информации, которое хорошо бы держать доступной для агента. А если проектов много, какая-то информация, конфигурации, субагенты и скиллы начинают выноситься на уровень пользователя (не говоря о том, что часто типичная установка MCP серверов или скиллов норовит вписать себя именно на уровень пользователя) и присутствовать в результате в контексте вообще всех проектов.

Недавно Anthropic выложили очень полезную статью, подробно описывающую то, как Claude Code работает с памятью. Плохая новость — это не приводит к автоматической перестройке всех проектов. Этим придется заняться самому пользователю.

Хорошая новость — для этого можно привлечь сам Claude Code. Попробуйте для начала на одном проекте. Запустите Claude Code в проекте и дайте ему следующую инструкцию:

Прочитай https://code.claude.com/docs/en/memory. Проанализируй текущую память проекта и дай предложения в соответствии с рекомендациями статьи.

Claude Code прекрасно воспринимает инструкции на любом языке, можно не заморачиваться обязательным английским — тем более, что память он в итоге перепишет на английском. Скорее всего, он предложит превратить память проекта (~/.claude/projects/projectID/memory/MEMORY.md) в некое оглавление, а текущее содержание разделить на специфические файлы по темам — в этом случае на старте загружаться будут только несколько десятков строк основного файла, а файлы по темам будут подгружаться по необходимости. Кроме того, он увидит дублирующие инструкции в этих файлах и CLAUDE.md проекта и в итоге дойдет до ваших основных файлов (~/.claude/CLAUDE.md) и предложит переделать и их.

Вот тут удержитесь от полной переделки — проверьте, как это пройдет с одним проектом. Если он не предложит сделать бэкап текущих файлов, напомните про это, дайте сделать все правки. Перезайдите в сессию — claude –resume, — и посмотрите на результат.

Мне на довольно развесистом проекте с десятками сессий и большому количеству данных в памяти удалось снизить начальную занятость контекста до 11% от общего окна — это очень неплохой результат, в среднем без подобной реорганизации легко обнаружить начальный контекст на уровне 25-30%. Учитывая, что после 140-150k токенов (при общем окне в 200k) модели становится тяжело помнить начало сессии, выигрыш сразу становится ощутим в практической работе.

Оставайтесь с нами, у меня еще много всяких соображений накопилось на эту тему и не только.