Настройка рабочего окружения для отсечения баззового boilerplate-кода, генерируемого ИИ-агентами
TuBrief 편집팀
2026년 7월 24일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
Стоит подключить ИИ-агента к реальной среде разработки, как его ограничения тут же вылезают наружу. Не понимая контекста предметной области, он начинает механически штамповать шаблон «Фабрика» или бесконечно генерировать абсолютно бесполезные утилитарные функции. Согласно отчету GitClear за 2024 год, основанному на анализе 623 миллионов строк коммитов, после широкого распространения ИИ-инструментов дублирование кода выросло на 81%, а доля рефакторинга, направленного на упорядочение существующего кода, упала с 25% до менее чем 10%. Из-за смещения контекстного окна в сторону свежести (recency bias) агент, пытаясь избежать рисков, постоянно сбегает к наиболее распространенным стандартным паттернам из обучающих данных. Чтобы подавить сбои в работе агента, необходимо явно зафиксировать архитектурные правила и логику синхронизации команды в виде файлов контекста.
Чтобы контролировать инструкции, которые различаются от инструмента к инструменту, первым делом следует разместить в корне проекта файл AGENTS.md, выступающий в роли единого источника правды (Single Source of Truth). Такие инструменты, как Cursor и Claude Code, читают эти правила. Единый файл .cursorrules уже давно устарел. Разбейте правила на MDC-файлы в директории .cursor/rules/, а в окружении Claude Code подключайте @AGENTS.md внутри CLAUDE.md, чтобы предотвратить «утечку» и игнорирование правил.
apps/api/src/common/dto.services/shared/uow.`
Если общая длина контекста превышает 800 строк (приблизительно 2000 токенов), агент начинает игнорировать ограничения, записанные в самом начале. В AGENTS.md следует оставлять только действительно критические запреты, а подробные записи архитектурных решений (ADR) выносить в директорию docs/context/.
AGENTS.md в корне проекта и прописать в нем запрет на интерфейсы с единственной реализацией и защитные блоки try-catch..cursor/rules/backend-constraints.mdc настроить пути к целевым файлам (globs) и ограничения YAML Frontmatter.@AGENTS.md в CLAUDE.md для синхронизации окружения.За правдоподобным кодом агента часто скрывается ловушка. Согласно исследованию Veracode 2024 года, в 45% кода, предложенного ИИ, были обнаружены уязвимости безопасности уровня OWASP Top 10. Попытки скрыть ошибки, грубо обернув потенциально сбойную логику в try-catch и возвращая пустой объект или null, происходят на 47% чаще, чем при написании кода человеком. Также регулярно возникают проблемы с отсутствием оптимистичной блокировки в операциях Read-Modify-Write или проблемы N+1 из-за постоянных вызовов БД внутри циклов.
| Область проверки | Детализируемые пункты проверки | Опасные паттерны и ловушки агента | Критерий блокировки мёрджа |
|---|---|---|---|
| Уязвимости безопасности | Использование Parameterized Query, изоляция тенантов, проверка неавторизованных пакетов | SQL-инъекции на основе конкатенации строк, вызовы непроверенных пакетов из-за галлюцинаций | Блокировка при отсутствии валидации входных данных или добавлении сторонних зависимостей неизвестного происхождения |
| Узкие места производительности | Ленивая загрузка ORM, вложенные циклы в Hot path, индексы БД | Запросы с обходом отдельных сущностей внутри цикла, фильтрация всей таблицы в памяти | Блокировка при наличии вызовов БД или внешних API внутри циклов, а также при отсутствии пагинации |
| Типобезопасность | Строгая проверка типов (Strict Type), обработка исключений на границах, контроль конкурентности | Злоупотребление as any, сокрытие ошибок с помощью пустых блоков Catch |
Блокировка при наличии any и необдуманного приведения типов as, а также блоков Catch без логирования |
Тестовый код, который пишет агент, часто сводится к банальному дублированию и копированию кода реализации. Такие тесты абсолютно не способны выявить реальные бизнес-дефекты. Необходимо жестко применять правило: «Если уже существует готовая утилита, агент должен удалить созданную им новую утилиту и повторно использовать существующий код».
any.as any или await внутри циклов.Если попытаться затолкнуть сложную логику взаиморасчетов или обработку заказов на основе конечного автомата в один промпт, агент зациклится на вызове инструментов или выдаст пустую пустышку вместо кода. Это происходит потому, что порядок распределения токенов путается при попытке одновременно обработать проектирование схемы, API-интерфейсы, обработку исключений и бизнес-правила.
`
[Этап 1: Моделирование данных] -> Создание сущностей БД, схем Zod
│
▼ (передача результата в контекст)
[Этап 2: Определение интерфейсов] -> Определение API DTO, Custom Error, сигнатур сервисов
│
▼ (передача результатов этапов 1+2 в контекст)
[Этап 3: Реализация бизнес-логики] -> Завершение транзакций, переходов состояний, контроля конкурентности
`
Передавать всё это вручную довольно хлопотно. Намного эффективнее написать CLI-скрипт автоматизации (scripts/agent-decomposed-build.ts), который свяжет результат предыдущего шага с входным контекстом следующего.
`typescript
import { execSync } from 'child_process';
import * as fs from 'fs';
interface TaskPipeline {
featureName: string;
stage1Prompt: string;
stage2Prompt: string;
stage3Prompt: string;
}
async function runDecomposedAgentPipeline(pipeline: TaskPipeline) {
console.log([Stage 1] Executing Data Modeling for ${pipeline.featureName}...);
const stage1Output = execSync(claude --print "${pipeline.stage1Prompt}").toString();
fs.writeFileSync(./tmp/${pipeline.featureName}_stage1.ts, stage1Output);
console.log([Stage 2] Executing Interface Definition...);
const stage2InputPrompt = ${pipeline.stage2Prompt}\n\nContext Models:\n${stage1Output};
const stage2Output = execSync(claude --print "${stage2InputPrompt}").toString();
fs.writeFileSync(./tmp/${pipeline.featureName}_stage2.ts, stage2Output);
console.log([Stage 3] Executing Business Logic Implementation...);
const stage3InputPrompt = ${pipeline.stage3Prompt}\n\nContext Models:\n${stage1Output}\n\nContext Contracts:\n${stage2Output};
const stage3Output = execSync(claude --print "${stage3InputPrompt}").toString();
fs.writeFileSync(./src/services/${pipeline.featureName}.service.ts, stage3Output);
console.log([Pipeline Complete] Business logic generated cleanly without cognitive stagnation.);
}
`
scripts/agent-decomposed-build.ts, связывающий вывод предыдущего этапа с контекстом следующего промпта.Чем активнее используются ИИ-инструменты разработки, тем больше накапливается «кода только для записи» (write-only code), в котором отсутствуют причины принятия тех или иных решений. Код, в котором не зафиксированы компромиссы (trade-offs) архитектурного выбора, позже становится тяжелым обузой для разработчиков-людей. В AGENTS.md необходимо прописать требование, чтобы агент при генерации кода обязательно оставлял стандартные комментарии TSDoc прямо в исходном коде.
`typescript
/**
`
Чтобы предотвратить расхождение настроек агента у разных разработчиков, следует сделать AGENTS.md единым источником правды и перед коммитом запускать скрипт синхронизации (tools/sync-agent-rules.ts), который обновляет CLAUDE.md и .cursor/rules/global.mdc.
`typescript
import * as fs from 'fs';
import * as path from 'path';
const AGENTS_MD_PATH = path.join(__dirname, '../AGENTS.md');
const CLAUDE_MD_PATH = path.join(__dirname, '../CLAUDE.md');
const CURSOR_RULE_PATH = path.join(__dirname, '../.cursor/rules/global.mdc');
function syncRules() {
if (!fs.existsSync(AGENTS_MD_PATH)) {
console.error('Error: AGENTS.md does not exist.');
process.exit(1);
}
const baseRules = fs.readFileSync(AGENTS_MD_PATH, 'utf-8');
const claudeContent = # AUTOMATICALLY GENERATED FROM AGENTS.md - DO NOT EDIT DIRECTLY\n\n${baseRules};
fs.writeFileSync(CLAUDE_MD_PATH, claudeContent);
const mdcHeader = ---\ndescription: Global Agent Rule Sync\nglobs: **/*\nalwaysApply: true\n---\n\n;
fs.writeFileSync(CURSOR_RULE_PATH, ${mdcHeader}${baseRules});
console.log('Successfully synchronized AGENTS.md to CLAUDE.md and Cursor MDC rules.');
}
syncRules();
`