В индустрии программной инженерии 2026 года дисциплина управления языковыми моделями претерпела фундаментальную трансформацию: примитивный Prompt Engineering (подбор формулировок методом проб и ошибок) уступил место Context Engineering — строгой инженерной дисциплине компиляции, ранжирования и структурирования информационных потоков между локальной средой разработки и инференс-конвейером Large Language Models (LLM).
Физическая основа Context Engineering базируется на математических свойствах архитектуры Transformer и механизма Self-Attention. Несмотря на экспоненциальный рост контекстных окон современных моделей (от 128k до 1–2M токенов), пропускная способность внимания модели не является однородной:
В корпоративной разработке файлы конфигурации контекста (AGENTS.md, .cursorrules, .github/copilot-instructions.md, .windsurfrules) представляют собой декларативный контракт первого уровня (L1 Global Contract). Этот контракт определяет границы допустимого поведения автономного агента, форматы типов, архитектурные ограничения и политики безопасности до того, как агент получит доступ к исполнению инструментов или модификации дисковой подсистемы.
+----------------------------------------------------------------------------------------------------+
| ИЕРАРХИЯ КАДРОВ КОНТЕКСТНОГО ОКНА |
+----------------------------------------------------------------------------------------------------+
| [STATIC SYSTEM PREFIX: KV-CACHE HIT] |
| 1. Base Runtime Directives: Роль, протокол вызова инструментов, формат сериализации ошибок |
| 2. Monorepo Global Invariants (AGENTS.md): Языковые стандарты, строгие запреты, стек |
+----------------------------------------------------------------------------------------------------+
| [DYNAMIC CASCADING RULES: CACHED PER PACKAGE] |
| 3. Domain Policies (apps/billing/.cursorrules): Специфика домена, Zod-контракты, PCI-DSS |
+----------------------------------------------------------------------------------------------------+
| [RETRIEVED EPHEMERAL CONTEXT: DYNAMIC / UNCACHED] |
| 4. Tool Output / AST Skeletons: Сигнатуры типов, зависимости, результаты компиляции |
| 5. User Turn: Непосредственная задача разработчика (Recency Bias Zone) |
+----------------------------------------------------------------------------------------------------+Контракт AGENTS.md является кросс-платформенным спецификатором. В отличие от вендор-зависимых файлов вроде .cursorrules, спецификация AGENTS.md считывается headless-агентами в CI/CD (GitHub Actions), терминальными утилитами (Claude Code, Aider) и внутренними оркестраторами enterprise-платформ.
Ментальная модель Context Engineering эквивалентна компилятору с многоуровневым каскадным связыванием (Cascading Context Resolution). По аналогии с каскадом стилей CSS или резолвером модулей Node.js, движок контекста разрешает конфликты между глобальными стандартами предприятия и локальными соглашениями сервиса.
+-----------------------------+
| Enterprise Root |
| AGENTS.md |
| (Global Core Constraints) |
+--------------+--------------+
|
v
+---------------------------------------------+
| Context Compiler / Preprocessing Pipeline |
| - Path Specificity Weight Calculation |
| - Negative Few-Shot Injection |
| - KV-Cache Ephemeral Boundary Marker |
+----------------------+----------------------+
|
+-------------------------+-------------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| apps/web/.cursorrules | | services/api/.cursorrules |
| (Next.js 15, React 19 RSC) | | (Node.js, Fastify, Drizzle)|
+--------------+--------------+ +--------------+--------------+
| |
+-------------------------+-------------------------+
|
v
+-----------------------------+
| Target System Prompt Frame |
| [KV Anchor | Cascade Rules |
| Tool Specs | User Intent] |
+-----------------------------+Компилятор контекста находит корень репозитория, считывает AGENTS.md и определяет дерево каталогов для вычисления путей активных подмодулей.
Вычисляется специфичность путей (Path Specificity). Локальные файлы .cursorrules переопределяют или дополняют правила родительских модулей по модели CSS Cascade.
С помощью локального токенизатора (tiktoken) вычисляется размер системного блока. При превышении квоты отсекаются вторичные стилистические комментарии.
Статический блок отделяется служебным маркером кэширования (Anthropic Cache Control / OpenAI Prefix Alignment), гарантируя 100% Cache Hit в последующих запросах.
В конец промпта подмешиваются актуальные AST-сигнатуры затрагиваемых файлов и текст запроса разработчика в зону максимального внимания (Recency Bias).
Senior разработчик добавил в начало глобального AGENTS.md строку: 'Current Session Time: ISO_TIMESTAMP; Active Git Commit: COMMIT_HASH'. К каким системным последствиям это приведет при работе агентов в команде из 50 инженеров?
В монорепозиториях с десятками команд (Core Platform, Billing, UI-Kit, Analytics) единый промпт не способен отразить требования всех подсистем. Корневой AGENTS.md фиксирует общие принципы: запрет на прямые циклические зависимости, единая версия TypeScript, требование неизменяемости DTO. Внутри директории packages/ui размещается локальный .cursorrules, требующий использования исключительно Tailwind v4 и запрещающий прямой импорт клиентских хуков в RSC-компоненты. При редактировании файлов в apps/billing контекстный компилятор активирует строгие правила валидации входных параметров через z.string().uuid() и шифрования персональных данных (PII).
При переводе устаревшей кодовой базы с Pages Router на Next.js App Router или с Redux на Server Actions разработчики сталкиваются с тем, что AI по умолчанию предлагает устаревшие паттерны из обучающей выборки. Настройка файла AGENTS.md со списком строгих негативных ограничений (Negative Constraints) полностью блокирует появление устаревших методов вроде getServerSideProps или getInitialProps, форсируя использование React Server Components и fetch с тэгами ревалидации кэша.
AI-агенты, исполняемые в CI-конвейерах для проверки Pull Request'ов, получают скомпилированный контекст, включающий требования PCI-DSS и OWASP Top 10. Если PR вносит изменения в маршруты авторизации, агент сверяет AST измененных файлов со списком обязательных middleware-декораторов, описанных в AGENTS.md, отклоняя слияние при отсутствии валидации ролей доступа.
В системах, где над кодовой базой параллельно трудятся специализированные агенты (Planner, Implementer, Tester, Reviewer), Context Engineering распределяет разные контракты каждому агенту. Тестовый агент получает контракт, запрещающий мокать реальные вызовы базы данных и форсирующий использование Testcontainers, в то время как агент-имплементер ограничен контрактом на неизменяемость публичных API интерфейсов.
Эталонный документ AGENTS.md не должен содержать разговорных фраз. Каждая инструкция формулируется в терминах модальных глаголов спецификации RFC 2119 (MUST, MUST NOT, REQUIRED, SHALL, SHOULD NOT).
# Enterprise Architectural Contract for Autonomous Agents
Version: 3.2.0
RFC-2119-Compliance: STRICT
## 1. Runtime & Language Specification
- Target Runtime: Node.js 22.x LTS (strict ESM, "type": "module").
- Language: TypeScript 5.8+ configured with strictNullChecks and noImplicitAny.
- Framework: Next.js 15+ (App Router). All components are Server Components by default.
## 2. Invariant Rules (MUST COMPLY)
1. DIRECTIVE_NO_ANY: Any usage of the `any` type is STRICTLY PROHIBITED. Use `unknown` with Zod guards.
2. DIRECTIVE_NAMED_EXPORTS: MUST use named exports for all modules and components. Default exports are ONLY permitted in Next.js routing conventions (`page.tsx`, `layout.tsx`, `route.ts`).
3. DIRECTIVE_ERROR_HANDLING: Async operations returning errors MUST use the Result Pattern `{ ok: true, data: T } | { ok: false, error: DomainError }`. Throwing raw exceptions across module boundaries is FORBIDDEN.
4. DIRECTIVE_SERVER_ACTIONS: Server Actions MUST be placed in dedicated `actions/` files and validate arguments using Zod schemas before executing business logic.
## 3. Negative Constraints (PROHIBITED PATTERNS)
- FORBIDDEN: `useEffect` for data fetching. Use React Server Components or TanStack Query.
- FORBIDDEN: Direct SQL string interpolation. MUST use prepared statements or Drizzle ORM query builders.
- FORBIDDEN: Mutating function arguments or module-level singletons.
- FORBIDDEN: Hardcoded secrets, API endpoints, or environment fallbacks in application code.
## 4. Verification Protocol
Before marking any code task as complete:
1. Execute `pnpm typecheck` and ensure 0 errors.
2. Execute `pnpm lint` and ensure 0 warnings.
3. Validate that generated tests cover both happy-path and edge-case error branches.В реальных инструментах агентной разработки контекст компилируется специальным модулем. Приведенный ниже сервис выполняет поиск по дереву каталогов, каскадное объединение правил с разрешением специфичности и подсчет токен-бюджета с использованием BPE-токенизатора.
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { get_encoding } from 'tiktoken';
export interface ContextRuleSource {
filePath: string;
depth: number;
content: string;
tokenCount: number;
}
export interface CompiledContext {
staticPrefix: string;
dynamicRules: string;
totalTokens: number;
cacheControlAnchor: string;
}
export class ContextCompiler {
private readonly tokenizer = get_encoding('cl100k_base');
private readonly MAX_SYSTEM_TOKENS = 4096;
/**
* Сканирует директорию от корня до текущего рабочего пути,
* собирая и каскадируя контракты AGENTS.md и .cursorrules.
*/
public async compileForPath(workspaceRoot: string, targetFilePath: string): Promise<CompiledContext> {
const relativeTarget = path.relative(workspaceRoot, targetFilePath);
const pathSegments = relativeTarget.split(path.sep);
const ruleSources: ContextRuleSource[] = [];
// 1. Поиск корневого глобального контракта AGENTS.md
const rootContractPath = path.join(workspaceRoot, 'AGENTS.md');
try {
const content = await fs.readFile(rootContractPath, 'utf-8');
ruleSources.push({
filePath: rootContractPath,
depth: 0,
content: this.cleanRuleContent(content),
tokenCount: this.tokenizer.encode(content).length,
});
} catch {
console.warn(`[ContextCompiler] Root AGENTS.md not found at ${workspaceRoot}`);
}
// 2. Поиск каскадных .cursorrules вниз по иерархии папок
let currentDir = workspaceRoot;
let currentDepth = 1;
for (const segment of pathSegments.slice(0, -1)) {
currentDir = path.join(currentDir, segment);
const localRulesPath = path.join(currentDir, '.cursorrules');
try {
const localContent = await fs.readFile(localRulesPath, 'utf-8');
ruleSources.push({
filePath: localRulesPath,
depth: currentDepth,
content: this.cleanRuleContent(localContent),
tokenCount: this.tokenizer.encode(localContent).length,
});
} catch {
// Локальные правила отсутствуют на данном уровне вложенности — штатное поведение
}
currentDepth++;
}
// 3. Разрешение каскада: правила сортируются по глубине (глубокие имеют приоритет)
ruleSources.sort((a, b) => a.depth - b.depth);
// 4. Формирование неизменяемого префикса для фиксации KV-Cache
const staticPrefix = [
'# SYSTEM ENVIRONMENT: ENTERPRISE AI AGENT RUNTIME',
'# COMPLIANCE: RFC-2119 STRICT ENFORCEMENT',
'You are a Staff AI Software Architect. Adhere strictly to the architectural constraints below.',
].join('\n');
let dynamicRulesBuilder = '';
let accumulatedTokens = this.tokenizer.encode(staticPrefix).length;
for (const source of ruleSources) {
if (accumulatedTokens + source.tokenCount > this.MAX_SYSTEM_TOKENS) {
console.warn(`[ContextCompiler] Token budget exceeded. Skipping rules from ${source.filePath}`);
break;
}
dynamicRulesBuilder += `\n\n<!-- SOURCE: ${path.relative(workspaceRoot, source.filePath)} (Depth ${source.depth}) -->\n`;
dynamicRulesBuilder += source.content;
accumulatedTokens += source.tokenCount;
}
// 5. Разметка границы для Anthropic Prompt Caching или OpenAI Prefix Cache
const cacheControlAnchor = '<!-- KV_CACHE_ANCHOR_BOUNDARY -->';
return {
staticPrefix,
dynamicRules: dynamicRulesBuilder,
totalTokens: accumulatedTokens,
cacheControlAnchor,
};
}
/**
* Удаляет избыточные пустые строки и комментарии для оптимизации токенов.
*/
private cleanRuleContent(raw: string): string {
return raw
.replace(/\r\n/g, '\n')
.replace(/\n{3,}/g, '\n\n')
.trim();
}
public dispose(): void {
this.tokenizer.free();
}
}Чтение корневого AGENTS.md и каскада вложенных .cursorrules файлов по пути к целевому модулю.
Исключает директории .git, node_modules и build-артефакты.
Извлечение экспортируемых типов и сигнатур смежных файлов проекта без чтения их тел.
Сокращает объем контекста на 85% по сравнению с чтением полных файлов.
Расчет токенов через tiktoken. Проверка лимита системной квоты (не более 15% окна контекста).
Гарантирует отсутствие переполнения контекстного окна.
Выравнивание статического префикса под границы блоков памяти инференс-сервера (Prompt Caching).
Уменьшает задержку TTFT до минимальных значений.
Отправка результирующего контекстного кадра в API модели с метаданными и инструментами.
Модель генерирует строго типизированный AST-валидный код.
В корневом AGENTS.md задано: 'DIRECTIVE_STRICT_RSC: All components MUST be Server Components'. В директории `packages/charts/.cursorrules` задано: 'DIRECTIVE_CLIENT_MODULE: All Canvas renderers MUST declare use client at the top'. Как агент должен скомпилировать компонент `packages/charts/src/BarChart.tsx`?
Размещение в первых строках AGENTS.md переменных с текущим временем, Git commit SHA или ID сессии.
<!-- АНТИПАТТЕРН: Разрушает префиксный кэш для каждого запроса -->
Session ID: 9f8a3d-2341
Timestamp: 2026-03-31T12:00:00Z
Project Rules: ...Архитектурное последствие: Каждый HTTP-запрос к модели воспринимается инференс-сервером как абсолютно новый промпт. GPU вынужден заново вычислять матрицы внимания для сотен строк неизменных правил. Латентность TTFT вырастает на порядок, а затраты на токены подсказки оплачиваются по полному (некэшированному) тарифу. Решение: Разделять контекст на строго неизменяемый заголовок (Immutable Header) и динамический подвал (Dynamic Ephemeral Context).
Написание инструкций в виде вежливых просьб: «Пожалуйста, постарайся не использовать any, если это возможно, и пиши чистый код».
Архитектурное последствие: Языковые модели обучены на вероятностных распределениях текстов. Формулировка «постарайся» интерпретируется моделью как мягкое пожелание (Soft Preference), которое немедленно нарушается при первой же сложности типизации сложного generic-интерфейса.
Решение: Использование модальных глаголов стандарта RFC 2119: MUST, MUST NOT, STRICTLY PROHIBITED. Ограничение формулируется как бинарный критерий верификации: «DIRECTIVE_NO_ANY: Any usage of 'any' leads to immediate verification failure. Use 'unknown' with type narrowing».
Копирование сотен страниц документации библиотек или сторонних API в .cursorrules в надежде, что модель «будет лучше знать библиотеку».
Архитектурное последствие: Возникает эффект «Lost in the Middle». Токены системных инструкций вытесняют реальный код проекта. Механизм внимания модели рассеивается, а вероятность галлюцинаций возрастает из-за обилия нерелевантной информации, не относящейся к текущему тикету.
Решение: Использовать RAG (Retrieval-Augmented Generation) и динамическую подгрузку контекста через Model Context Protocol (MCP). В AGENTS.md должны храниться исключительно архитектурные инварианты и соглашения команды, а справочная документация должна извлекаться «on demand» по вызову инструмента.
Описание только того, что нужно делать, без явного запрета типичных антипаттернов, присутствующих в публичных обучающих датасетах.
Архитектурное последствие: Модель обучена на миллионах устаревших репозиториев GitHub и StackOverflow. При генерации кода на Next.js она по инерции предложит старый pages/_app.tsx, React Router v5 или вызов axios внутри useEffect.
Решение: Каждая архитектурная секция должна содержать обязательный блок PROHIBITED_PATTERNS с явным перечислением устаревших API и негативными примерами (Negative Few-Shot Examples).