🤖 Eric Buess
Продвинутая агентная инженерия: автогенерируемые карты проекта, agent-scoped hooks, session ID для кеширования токенов и полная observability агентов. Подход для тех кто хочет контролировать AI-агентов на уровне production-систем.
"Project Indexer Hook + Agent-Scoped Hooks = агенты которые знают проект." Агент не должен тратить токены на "понимание" структуры при каждом запуске — hook автоматически генерирует актуальную карту проекта, а agent-scoped hooks несут нужную логику прямо в себе.
index.md структурирован под задачи агента, а не просто перечисляет файлы. Включайте в него: ключевые точки входа, паттерны именования, расположение тестов, команды запуска и сборки. Агент который получает навигационную карту тратит в 3–5 раз меньше токенов на первичную ориентацию чем агент который читает структуру файлов вручную.
Одна из самых дорогих операций в начале агентной сессии — "разведка": Claude просматривает файловую структуру, читает ключевые файлы, строит ментальную карту проекта. Для больших проектов это занимает десятки итераций tool calls.
Buess решает это через PreToolUse hook который автоматически генерирует минифицированный index.md при старте каждой сессии:
{
"hooks": {
"PreToolUse": [{
"matcher": ".*",
"hooks": [{
"type": "command",
"command": "node ~/.claude/hooks/project-indexer.js"
}]
}]
}
}
Скрипт project-indexer.js рекурсивно обходит файлы проекта и создаёт минимальный манифест:
const fs = require('fs');
const path = require('path');
// Сканировать только важные директории
const SCAN_DIRS = ['app', 'src', 'tests', 'database'];
const SKIP_DIRS = ['vendor', 'node_modules', 'storage', '.git'];
function scanDirectory(dir, depth = 0) {
if (depth > 3) return ''; // Максимум 3 уровня вложенности
const entries = fs.readdirSync(dir, { withFileTypes: true });
let result = '';
for (const entry of entries) {
if (SKIP_DIRS.includes(entry.name)) continue;
const indent = ' '.repeat(depth);
if (entry.isDirectory()) {
result += `${indent}📁 ${entry.name}/\n`;
result += scanDirectory(path.join(dir, entry.name), depth + 1);
} else if (entry.name.endsWith('.php') || entry.name.endsWith('.ts')) {
result += `${indent}📄 ${entry.name}\n`;
}
}
return result;
}
const index = `# Project Index (auto-generated ${new Date().toISOString()})
## Structure
${scanDirectory(process.cwd())}
`;
fs.writeFileSync('.claude/index.md', index);
console.log('Project index updated');
Результат — файл .claude/index.md который Claude читает в начале каждой сессии и мгновенно понимает структуру без дополнительных tool calls.
📁 Http/
📁 Controllers/ → UserController, AuthController, PaymentController
📁 Middleware/
📁 Services/ → UserService, SubscriptionService, StripeService
📁 Models/ → User, Subscription, Payment
tests/
📁 Feature/ → AuthTest, SubscriptionTest
📁 Unit/ → UserServiceTest
Buess использует два механизма для задач требующих глубокого анализа. Первый — слово ultrathink в промпте как сигнал для максимального использования extended thinking:
// Для архитектурных решений:
"ultrathink: как нам реорганизовать систему платежей
чтобы поддержать 5 разных провайдеров без дублирования логики?"
// Для сложного дебаггинга:
"ultrathink: почему race condition в SubscriptionService
проявляется только под нагрузкой >100 rps?"
// Для code review:
"ultrathink: review этой реализации @app/Services/StripeService.php
с фокусом на edge cases и потенциальные проблемы безопасности"
Второй механизм — subagents для research-фазы. Вместо одного агента который делает и исследование и реализацию — разделить роли:
# Шаг 1: Запустить research sub-агента
# Узнать Session ID текущей сессии:
/status # показывает Session ID
# Шаг 2: Запустить headless sub-агента с контекстом основной сессии
claude --session-id $SESSION_ID \
--model claude-opus-4-8 \
-p "Проанализируй @app/Services/ и составь список
всех мест где мы должны добавить транзакции БД.
Только анализ, без изменений."
# Шаг 3: Основной агент использует результаты research
# Prompt cache переиспользуется → экономия токенов
Стандартные hooks в settings.json — глобальные, применяются ко всем агентам. Buess использует возможность CC 2.1+ для agent-scoped hooks: hooks прямо в frontmatter агента, который несёт их с собой.
Преимущество: каждый специализированный агент имеет только свои hooks. Агент-тестировщик запускает lint после каждого изменения. Агент-деплойщик проверяет безопасность перед Bash командами. Без взаимного влияния.
---
hooks:
PreToolUse:
- matcher: "Bash"
command: "node ./hooks/check-safety.js"
# Проверяет: нет rm -rf, нет git push --force, нет DROP TABLE
- matcher: "Write|Edit"
command: "node ./hooks/check-file-path.js"
# Проверяет: файл не в protected/ директории
PostToolUse:
- matcher: "Write|Edit"
command: "node ./hooks/run-linter.js"
# Запускает pint/eslint сразу после каждого изменения файла
- matcher: "Bash"
command: "node ./hooks/log-command.js"
# Логирует все выполненные команды в claude-audit.jsonl
---
# Агент: Feature Developer
Ты реализуешь фичу по spec в docs/superpowers/specs/.
## Порядок работы
1. Прочитать spec файл
2. Прочитать examples/ для понимания паттернов
3. Реализовать по шагам с тестами
4. Верифицировать каждый шаг перед переходом к следующему
Когда запускается этот агент — его hooks активны только в этой сессии. После завершения — удаляются автоматически. Никакого загрязнения глобальной конфигурации.
claude --agent-file ./agents/feature-developer.md \
-p "реализуй @docs/superpowers/specs/2026-05-10-subscriptions.md"
Каждая сессия CC имеет уникальный Session ID. При передаче этого ID headless sub-агенту — они разделяют prompt cache, что приводит к значительной экономии токенов.
Практически важно для:
- Длинных CLAUDE.md (1000+ строк) — кешируются один раз для всех sub-агентов
- Больших spec-файлов которые читают несколько агентов последовательно
- Параллельных агентов работающих над одним проектом
#!/bin/bash
# Запустить основную сессию и сохранить Session ID
SESSION_INFO=$(claude --json /status)
SESSION_ID=$(echo $SESSION_INFO | jq -r '.sessionId')
echo "Session ID: $SESSION_ID"
# Sub-агент 1: анализ безопасности (переиспользует кеш)
claude --session-id "$SESSION_ID" \
-p "ultrathink: проверь @app/ на SQL injection уязвимости" \
> security-report.md &
# Sub-агент 2: анализ производительности (переиспользует кеш)
claude --session-id "$SESSION_ID" \
-p "найди N+1 запросы в @app/Http/Controllers/" \
> performance-report.md &
# Ждём завершения обоих
wait
echo "Анализ завершён. Результаты в security-report.md и performance-report.md"
Без Session ID каждый sub-агент платит полную стоимость за чтение CLAUDE.md, spec-файлов и контекста. С Session ID они переиспользуют prompt cache — стоимость повторного чтения кешированного контента на 90% ниже стандартной. При 5+ sub-агентах экономия становится существенной.
Production-системы требуют полной видимости. Buess применяет тот же принцип к AI-агентам: каждое действие должно быть залогировано, проанализировано и измерено. Это не опционально — это необходимость для устойчивой агентной разработки.
| Что логировать | Зачем | Инструмент |
|---|---|---|
| Все tool calls | Аудит действий агента, отладка неожиданного поведения | PostToolUse hook → JSONL файл |
| Стоимость каждого вызова | Мониторинг расходов, обнаружение дорогих паттернов | Anthropic API метаданные → dashboard |
| Ошибки и повторные попытки | Анализ паттернов сбоев, улучшение инструкций | PostToolUse hook на ошибки |
| Изменённые файлы | Полный список что агент поменял за сессию | PostToolUse Write/Edit hook |
| Время выполнения задач | SLA для агентных операций, оптимизация | PreToolUse/PostToolUse timestamps |
Пример hook для полного аудита:
'use strict';
const fs = require('fs');
const path = require('path');
// Читаем данные от CC через stdin
let raw = '';
process.stdin.on('data', chunk => raw += chunk);
process.stdin.on('end', () => {
try {
const input = JSON.parse(raw);
const logPath = path.join(process.cwd(), '.claude', 'claude-audit.jsonl');
const logEntry = {
ts: new Date().toISOString(),
tool: input.tool_name,
// Для файловых операций — логируем путь
file: input.tool_input?.file_path || null,
// Для Bash — логируем команду (первые 200 символов)
command: input.tool_input?.command?.substring(0, 200) || null,
// Оценка стоимости (примерная)
estimated_tokens: JSON.stringify(input).length / 4,
};
fs.appendFileSync(logPath, JSON.stringify(logEntry) + '\n');
} catch (e) {
// Не прерываем работу агента если логирование упало
process.stderr.write(`Logging error: ${e.message}\n`);
}
process.exit(0);
});
Анализ логов:
# Самые частые tool calls за сессию
cat .claude/claude-audit.jsonl | jq -r '.tool' | sort | uniq -c | sort -rn
# Все изменённые файлы
cat .claude/claude-audit.jsonl | jq -r 'select(.file != null) | .file' | sort | uniq
# Bash команды которые запускал агент
cat .claude/claude-audit.jsonl | jq -r 'select(.command != null) | .command'
# Примерная оценка стоимости сессии
cat .claude/claude-audit.jsonl | jq '[.estimated_tokens] | add'
Когда агент работает часы над сложной задачей, без логов невозможно понять что именно пошло не так если результат плохой. Логи позволяют воспроизвести "путь мышления" агента, найти момент ошибки и исправить инструкции для следующего запуска. Это не безопасность — это инженерная дисциплина.
Полная архитектура workflow Buess
Все 5 практик работают вместе в едином workflow:
# Запуск сессии
↓ PreToolUse hook: project-indexer.js генерирует .claude/index.md
↓ Claude читает index.md — мгновенно знает структуру проекта
# Постановка сложной задачи
↓ "ultrathink: ..." — максимальный thinking budget
# Параллельный анализ через sub-агентов
↓ claude --session-id $SID -p "анализ безопасности..." &
↓ claude --session-id $SID -p "анализ производительности..." &
↓ Оба переиспользуют prompt cache → экономия токенов
# Реализация через специализированного агента
↓ claude --agent-file ./agents/feature-developer.md
↓ Agent-scoped hooks: check-safety.js, run-linter.js, log-command.js
# Каждое действие агента
↓ PostToolUse hook: log-tool-calls.js → claude-audit.jsonl
↓ Полный аудит для анализа после завершения
# Завершение задачи
↓ verification-before-completion: реальный вывод тестов
↓ Анализ .claude/claude-audit.jsonl на паттерны
Источник
Практики и подходы Eric Buess публикуются в Twitter/X @EricBuess. Он специализируется на агентной инженерии для production-систем — там где надёжность, наблюдаемость и предсказуемость критически важны. Его подход особенно актуален для команд которые хотят использовать CC не как экспериментальный инструмент, а как часть production workflow с полным контролем над каждым действием агента.