ECC: оптимизация агентов под Claude Code и Cursor
Система оптимизации производительности агентов ECC: навыки, инстинкты, память, безопасность и разработка с приоритетом исследований для Claude Code, Codex, Opencode, Cursor и других.
Что такое ECC и зачем он нужен
Архитектура агентного движка
Система оптимизации агентов ECC (Entity-Centric Cognitive) строится вокруг трёх слоёв, каждый из которых решает свою задачу и не зависит от реализации остальных.
Слой сущностей (Entity Layer) хранит состояние агента: какие навыки уже освоены, какие инстинкты активированы, какие цели достигнуты. Всё это — в виде небольших JSON-объектов, которые можно быстро сериализовать и передать в контекст модели. Пример структуры одной сущности:
json{
"id": "skill:filesystem",
"type": "skill",
"state": "active",
"confidence": 0.87,
"last_used": "2024-06-12T14:30:00Z",
"metadata": {
"tools": ["read", "write", "edit"],
"success_rate": 0.92
}
}
Слой когнитивного движка (Cognitive Engine Layer) отвечает за выбор следующего действия. Здесь работает приоритет исследований: сначала агент проверяет, есть ли в памяти подходящий навык, потом активирует инстинкт (например, «не запускать скрипты от root»), и только потом переходит к выполнению задачи. Алгоритм выглядит так:
pythondef select_action(context, entities):
# 1. Поиск по навыкам
skill = find_skill(context.task, entities)
if skill and skill.confidence > 0.8:
return skill.action
# 2. Проверка инстинктов
for instinct in get_instincts(entities):
if instinct.triggered(context):
return instinct.response
# 3. Обращение к исследованию
return research_new_approach(context)
Слой безопасности (Security Layer) встраивается на каждом этапе. С точки зрения безопасности, нельзя допускать, чтобы агент сам модифицировал свои инстинкты. Все изменения проходят через проверку подписи. Пример конфигурации для Wazuh, который мониторит попытки изменить сущности:
yamlrules:
- id: 10001
name: Unauthorized entity modification
description: Attempt to modify ECC entity without valid signature
condition: >
file.name == "/opt/ecc/entities/*.json" and
process.name not in ["ecc-agent", "ecc-updater"]
level: 12
group: ecc-security
Связанный материал: Автоматизация и ИИ-агенты на сервере описывает, как подобные слои можно развернуть на домашнем сервере без потери производительности.
Поддерживаемые платформы и модели
На практике я вижу, что ECC-агенты работают стабильно на следующих платформах:
| Платформа | Модель | Ограничения |
|---|---|---|
| Claude Code | Claude 3.5 Sonnet | Требует CLAUDE.md в корне проекта |
| Cursor | Встроенные модели + кастомные через API | Иногда теряет контекст при больших сессиях |
| OpenCode | GPT-4o, Claude 3 Opus | Медленнее на сложных задачах рефакторинга |
| Codex CLI | o1-preview, o3-mini | Не поддерживает параллельные вызовы инструментов |
Пример конфигурации .cursor/settings.json для подключения кастомной модели через OpenRouter:
json{
"languageModel": {
"provider": "openrouter",
"model": "anthropic/claude-3-5-sonnet-20240620",
"apiKey": "${OPENROUTER_API_KEY}"
}
}
Для Claude Code ключевым является файл CLAUDE.md. В нём описываются правила, инструкции и ограничения. Пример минимального файла:
markdown# Project Rules
## Security
- Never run scripts as root
- All network calls must go through approved proxy
- File writes outside /workspace are forbidden
## Style
- Use 2-space indentation
- Prefer functional over imperative style
Подробнее о настройке этого файла — в гайде по наблюдениям Андрея Карпатского.
Типовая ошибка новичков — пытаться запустить тяжёлую модель на слабом железе. На практике хватает Ponytail-подхода: использовать лёгкую модель для планирования, а тяжёлую — только для выполнения критических операций.
Для интеграции с агент-управляемым экспонатом на Rust рекомендуется использовать локальную модель через Ollama, чтобы не зависеть от внешних API:
bash# Запуск локальной модели
ollama run llama3.1:8b-instruct-q6_K
# Передача контекста в Rust-агент
curl -s http://localhost:11434/api/chat \
-d '{
"model": "llama3.1:8b-instruct-q6_K",
"messages": [{"role": "user", "content": "Plan next action based on ECC state"}]
}'
Не делайте так: не включайте теле-метрию в модели и не передавайте секреты в открытом виде. Навыки Matt Pocock показывают, как писать безопасные промпты, которые не раскрывают внутреннюю структуру агента.
Навыки и инстинкты агентов
Система оценки навыков
Каждый агент, будь то Claude Code или Cursor, работает с ограниченным набором инструментов. Проблема в том, что «умение» вызвать bash не означает «умение» понять, что именно нужно выполнить. Я ввожу оценку навыков по шкале от 0 до 5, где 0 — агент не знаком с командой вообще, а 5 — агент может объяснить, почему эта команда опасна в production.
Оценка привязывается к конкретному контексту. Например, grep в логах — навык уровня 3. Тот же grep, но в контексте поиска секретов в исходниках — уровень 5. Агенту важно не просто знать синтаксис, а понимать границы применения.
В CLAUDE.md я храню таблицу навыков в виде YAML-блока. Это позволяет агенту самоанализировать свои слабые места:
yaml# skills_assessment
bash:
level: 4
notes: "Уверенно в basic, знает pipe, но не хватает опыта в trap и signal handling"
python:
level: 3
notes: "Может писать скрипты для автоматизации, но не понимает context managers"
docker:
level: 2
notes: "Знает run и compose, но не разбирается в security options"
Система оценки работает по принципу «доверяй, но проверяй». Агент может заявить навык на 4-м уровне, но реальная проверка покажет, что он не умеет, например, использовать strace для диагностики проблем в контейнере. Это типичная ошибка — переоценка собственных способностей.
На практике я видел случай, когда агент уверенно писал docker run --privileged, не понимая, что это отключает все основы безопасности контейнеров. С точки зрения безопасности, --privileged в production — это катастрофа, которая ждёт своего момента.
Моделирование инстинктов поведения
Инстинкты — это не программные правила, а паттерны поведения, которые агент развивает через множество итераций. Я выделяю три ключевых инстинкта:
Инстинкт 1: «Спросить три раза, выполнить один». Агент не спешит выполнять команду. Сначала он задаёт уточняющие вопросы: «Что именно вы хотите?», «Какие есть ограничения?», «Что может пойти не так?». Только после этого он действует.
Этот инстинкт особенно важен при работе с файловой системой. Вместо того чтобы сразу писать rm -rf /var/log/*, агент должен спросить: «Вы уверены, что хотите удалить все логи?», «Нужно ли сделать бэкап?», «Какая версия rm используется в системе?».
Инстинкт 2: «Проверить, прежде чем полагаться». Агент не доверяет выводу команды с первого раза. Он проверяет результат дважды: сначала через echo $?, потом через анализ вывода.
bash# Плохо: агент выполняет и считает, что всё ок
apt install nginx
# Хорошо: агент проверяет статус после установки
apt install nginx && systemctl is-active nginx
Инстинкт 3: «Остановиться, если что-то не так». Когда агент сталкивается с неожиданным поведением, он не пытается «исправить на лету». Он останавливается, анализирует ситуацию и запрашивает подтверждение.
Эти инстинкты не кодятся в CLAUDE.md напрямую. Они формируются через систему обратной связи. Каждый раз, когда агент делает что-то небезопасно, система фиксирует это и корректирует веса в нейросетевой модели.
В статье о домашних серверах я уже касался тем, как важно не просто настраивать агентов, а обучать их принимать решения в условиях неопределённости. Инстинкты — это способ формализовать этот процесс.
Для хранения модели инстинктов я использую локальную SQLite-базу, а не облачные решения. С точки зрения безопасности, данные об инстинктах агентов не должны покидать локальную сеть.
Связанная методология описана в руководстве по CLAUDE.md, где Андрей Карпатский предлагает подходить к настройке агентов через наблюдение за их реальным поведением, а не через теоретические сценарии.
Память и контекст в долгих сессиях
Управление контекстным окном
Контекстное окно — это бюджет. Каждый токен стоит. В долгой сессии Claude Code и Cursor съедают его быстрее, чем вы думаете, особенно если агент «запоминает» весь вывод git diff, логи сборки и ваши внутренние споры в чате.
С точки зрения безопасности, проблема в том, что вы не контролируете, что попадает в контекст. Иногда агент запрашивает файлы, которые не нужны, просто потому что они лежат рядом. Иногда он «залипает» на одном и том же файле, перечитывая его десяток раз.
Типовая ошибка: позволить агенту свободно просматривать директорию. Результат — он засасывает в контекст node_modules, .git, логи и ваш личный конфиг.
Решение — жёстко ограничить область видимости. В CLAUDE.md или .cursorrules укажите, какие директории реально нужны:
markdown# CLAUDE.md
## Область видимости
Работай только с файлами в ./src и ./tests.
Никогда не читай .git, node_modules, dist, .env.
Перед выполнением команды проверяй, чтобы она не затрагивала production-базы.
Для Cursor аналогично через .cursorrules:
textOnly access files in ./src and ./tests. Ignore: .git, node_modules, dist, .env, *.log
Но это не всё. Агенты любят «залипать». Чтобы не дать ему зациклиться на одном файле, используйте инструкцию типа:
textIf you re-read the same file more than 3 times in a row, stop and summarize what you already know before continuing.
На практике я видел случай, когда агент 40 минут перечитывал один и тот же config.ts, пытаясь понять, почему тест падает. Ошибка была в tests/setup.ts, но он не добрался туда, потому что «логичнее» было копаться в конфиге.
Настоятельно рекомендуется: использовать context7 или аналогичные инструменты для отслеживания потребления токенов в реальном времени. Если сессия превышает 50 тысяч токенов на файл — значит, что-то идёт не так.
Персистентное хранилище сессий
Контекстное окно очищается. Но знание — нет. Если вы работаете над долгосрочным проектом, вам нужно сохранять состояние между сессиями.
Самый простой подход — использовать CLAUDE.md как живой документ. Но он растёт, и агент начинает его переполнять. Лучше выделить отдельный файл — .claude/memory.md или .cursor/memory.md:
text.claude/ ├── CLAUDE.md ├── memory.md └── scratch/ ├── notes.md └── decisions.md
В memory.md храните:
- Архитектурные решения
- Ограничения и предположения
- Список «что ещё не сделано»
- Ключевые детали из логов или ошибок
Пример:
markdown# Память проекта
## Решения
- Используем Zod вместо Joi — легче отлаживать типы.
- API-ключи вынесены в GitHub Secrets, а не в env-файлы.
## Ограничения
- Минимальная поддерживаемая версия Node.js — 18.17.0.
- База данных — PostgreSQL 14+.
## TODO
- [ ] Добавить rate limiting для /api/auth
- [ ] Проверить CORS-политику для внешних клиентов
Для более продвинутого подхода можно использовать локальный векторный поиск. Например, Apache Lucene или Typesense для индексации ваших решений и заметок. Это позволяет агенту искать релевантную информацию по смыслу, а не по ключевым словам.
Но с точки зрения безопасности, хранилище должно быть локальным. Никогда не выгружайте сессии или решения в облако. Автоматизация и ИИ-агенты на сервере должна опираться на локальные инструменты.
Категорически не рекомендуется: использовать облачные хранилища для памяти агента. Даже если провайдер гарантирует шифрование — вы теряете контроль над тем, что именно попадает в контекст.
Если вам нужно что-то более лёгкое, чем векторный поиск, используйте ripgrep для поиска по локальным файлам:
bashrg --type md --max-count 5 "TODO" .claude/memory.md
Это быстрее, чем агент будет листать файл вверх-вниз.
Чеклист дальнейших действий:
- Создайте
.claude/memory.mdили.cursor/memory.mdв проекте - Добавьте в
CLAUDE.mdили.cursorrulesограничения на область видимости - Настройте локальный поиск (
ripgrep,ag) для быстрого доступа к памяти - Ограничьте размер
memory.md— если больше 500 строк, разбейте на тематические файлы - Проверьте, чтобы ни один агент не имел доступа к
.env,.gitилиnode_modules - Регулярно очищайте
scratch/— это временная память, а не архив
Безопасность и исследования перед деплоем
Изоляция и sandbox-окружения
С точки зрения безопасности, любой ИИ-агент — это потенциальный вектор атаки. Он читает файлы, пишет код, запускает команды. Если агент получает доступ к production-среде или хранит кре
денциальные данные, вы рискуете. Я видел случаи, когда агент, пытаясь «оптимизировать» конфиг, перезаписывал production-базу. Не делайте так.
Изоляция начинается с контейнеров. Для локальной разработки использую Docker с жёсткими ограничениями. Вот мой стандартный профиль:
bashdocker run --rm \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--network none \
-v $(pwd)/workspace:/workspace:ro \
-v $(pwd)/output:/output:rw \
my-agent-image
Ключевые моменты:
--read-only— корневая файловая система только для чтения. Агент не может изменить ОС.--tmpfs /tmp— временная файловая система безexec, чтобы предотвратить запуск бинарников из/tmp.--cap-drop=ALL— отключение всех Linux-способностей. Агент не может, например, менять сетевые настройки.--network none— полное отключение сети. Если агенту нужен доступ к интернету (например, для скачивания пакетов), используйте прокси с ограниченным доступом.
Для более строгой изоляции — Firecracker или gVisor. Я лично использую Firecracker для CI-агентов. МикровМ не имеет прямого доступа к хосту, а все сетевые запросы проходят через sidecar-прокси.
Настройка Firecracker для агента:
json{
"boot-source": {
"kernel_image_path": "/path/to/vmlinux",
"boot_args": "console=ttyS0 reboot=k panic=1 i8042.noaux=1"
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": "/path/to/rootfs.img",
"is_root_device": true,
"is_read_only": false
}
],
"network_interfaces": [
{
"iface_id": "eth0",
"host_dev_name": "tap0"
}
],
"machine-config": {
"vcpu_count": 1,
"mem_size_mib": 256
}
}
Сеть в sandbox — отдельная тема. Никогда не давайте агенту прямой доступ к production-сети. Используйте Open vSwitch с ACL:
bashovs-vsctl add-br br-sandbox
ovs-vsctl add-port br-sandbox tap0
ovs-vsctl set interface tap0 external-ids:iface-id=sandbox-iface
# Разрешаем только DNS и HTTP/HTTPS к whitelisted-хостам
ovs-vsctl add-port br-sandbox tap0 \
-- set interface tap0 external-ids:iface-id=sandbox-iface
ovs-appctl qos/set-policy br-sandbox \
"priority=100,action=drop" \
"priority=200,ip,nw_dst=1.1.1.1,tp_dst=53,action=output:1" \
"priority=200,ip,nw_dst=8.8.8.8,tp_dst=53,action=output:1"
Для локальной разработки на macOS или Windows используйте OrbStack или Colima — они легче Docker Desktop и не требуют Hyper-V.
Совет от себя: всегда проверяйте, что агент не может выйти за пределы sandbox. Запустите тест:
bash# Внутри sandbox
curl http://169.254.169.254/latest/meta-data/ # AWS metadata
cat /proc/1/root/etc/shadow # Доступ к хосту
mount | grep overlay # Проверка на overlayfs
Если что-то работает — значит sandbox пробит. Исправляйте до деплоя.
Автоматизированный security-review
ИИ-агенты пишут много кода. И этот код нужно проверять. Вручную — невозможно. Автоматизируйте.
Мой pipeline выглядит так:
yaml# .github/workflows/security-review.yml
name: Security Review
on: [push, pull_request]
jobs:
security-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/ci-attack-surface
p/secrets
r/python.lang.security.audit
- name: Run Bandit (Python)
run: |
pip install bandit
bandit -r . -f json -o bandit-report.json
- name: Run npm audit (Node.js)
run: npm audit --audit-level=high
- name: Run Trivy (container scan)
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-agent-image:latest'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Run Checkov (IaC)
run: |
pip install checkov
checkov -d . --quiet
Semgrep — ваш лучший друг. Она находит паттерны уязвимостей в коде, который пишет агент. Примеры правил, которые я использую:
yaml# .semgrep/rules/custom.yaml
rules:
- id: hardcoded-secret
patterns:
- pattern-either:
- pattern: "API_KEY = '...'"
- pattern: "password = '...'"
- pattern: "token = '...'"
message: "Hardcoded secret detected. Use environment variables."
languages: [python, javascript, go]
severity: ERROR
- id: dangerous-subprocess
patterns:
- pattern-either:
- pattern: "subprocess.call(..., shell=True)"
- pattern: "os.system(...)"
message: "Dangerous subprocess call. Use subprocess.run with shell=False."
languages: [python]
severity: WARNING
Для Python-агентов используйте Bandit + pip-audit:
bash# Bandit
bandit -r ./agents/ -f json -o bandit-report.json
# pip-audit
pip-audit --requirement requirements.txt --format json > pip-audit-report.json
Для JavaScript/TypeScript — npm audit и Snyk:
bashnpm audit --audit-level=high --json > npm-audit-report.json
npx snyk test --json-file-output=snyk-report.json
Самый важный шаг — это не просто сканировать, а блокировать деплой при критических уязвимостях. Настройте CI так:
bash# В конце pipeline
if [ -s bandit-report.json ] && jq -e '.results[] | select(.issue_severity == "HIGH")' bandit-report.json; then
echo "Critical vulnerabilities found. Blocking deployment."
exit 1
fi
Не забывайте про dependency confusion. Агенты часто тянут пакеты с непроверенных источников. Используйте pip.conf и npmrc с указанием только доверенных реестров:
ini# pip.conf
[global]
index-url = https://pypi.org/simple/
trusted-host = pypi.org
pypi.python.org
files.pythonhosted.org
ini# .npmrc
registry=https://registry.npmjs.org/
@company:registry=https://npm.company.internal/
Проверено на практике: без этих ограничений агент может установить пакет с именем requests из чужого реестра, который содержит вредоносный код. Я видел, как это ломало CI-конвейеры.
Связанные материалы: Автоматизация и ИИ-агенты на сервере, Настройка CLAUDE.md для Claude Code по наблюдениям Андрея Карпатского.
Часто задаваемые вопросы
Как ECC влияет на скорость работы агента в Cursor
Система приоритета исследований в ECC сокращает количество «пробных» вызовов инструментов. Вместо трёх‑четырёх попыток найти нужный подход агент сначала проверяет свою память навыков, и если уверенность выше 0,8, сразу применяет проверенный метод. На практике я видел случаи, когда это уменьшало число шагов до выполнения задачи в среднем на 40–60 %.
Однако с точки зрения безопасности, ускорение достигается за счёт кэширования, а не за счёт упрощения проверок. Каждый вызов всё равно проходит через слой инстинктов: если агент пытается прочитать файл за пределами рабочей директории, инстинкт «sandbox_violation» блокирует операцию до того, как она будет выполнена.
Рекомендуется включать ECC только после того, как вы убедились, что базовые ограничения окружения (например, --workspace-root в Cursor) настроены корректно.
Можно ли отключить слой безопасности, если он мешает
Категорически не рекомендуется. Слой безопасности в ECC не просто «добавляет задержки» — он предотвращает типичные ошибки, которые я наблюдал на практике: агент читает .env, пытается записать в /etc, или передаёт секреты в лог. Отключение этого слоя превращает агента из помощника в потенциальный вектор утечки.
Если конкретный инстинкт срабатывает ложно, правильный путь — скорректировать его триггер, а не выключать весь слой. Например, если агент работает в контейнере с ограниченными правами, можно ослабить инстинкт «file_permission_check», но только после подписи изменения через Wazuh.
Настоятельно рекомендуется: перед любой модификацией безопасных параметров ECC проверяйте, что изменение не открывает путь к обходу остальных инстинктов.
Почему агент «застревает» на этапе исследования вместо выполнения
Это типовая ошибка конфигурации. Агент переходит к этапу исследования, когда не находит подходящий навык с уверенностью выше 0,8 или когда активируется инстинкт с приоритетом «block_and_research». Чаще всего проблема в том, что навыки не обновляются после успешных операций — success_rate остаётся ниже порога.
С точки зрения безопасности, «застревание» на исследовании лучше, чем спешное выполнение с низкой уверенностью. Но чтобы избежать зацикливания, рекомендуется настроить таймаут исследования: если агент тратит больше 30 секунд на поиск, он должен переключаться на fallback‑навык с базовой уверенностью 0,6.
Проверьте также, что JSON‑объекты сущностей не раздуты: если в памяти накапливается больше 50 навыков, поиск становится медленнее, и агент начинает «перебирать» варианты вместо того чтобы выбрать оптимальный.