---
title: "Контекстно-слепое именование"
type: "ai-smell"
slug: "context-blind-naming"
url: "http://localhost:3000/ru/ai-smells/context-blind-naming.md"
category: "Ясность"
description: "ИИ-ассистент даёт новому коду обобщённые заглушки-имена или новое соглашение, игнорируя существующие идентификаторы и доменный словарь репозитория, что подрывает читаемость и плодит дублирующиеся, неверно описанные понятия."
---
# Контекстно-слепое именование

> ИИ-ассистент даёт новому коду обобщённые заглушки-имена или новое соглашение, игнорируя существующие идентификаторы и доменный словарь репозитория, что подрывает читаемость и плодит дублирующиеся, неверно описанные понятия.

## Signs and Symptoms

Ревьюер замечает контекстно-слепое именование, когда имена в созданном ИИ диффе локально правдоподобны, но оторваны от окружающего репозитория. Характерные признаки:

* **Обобщённые заглушки в доменном коде:** `data`, `result`, `temp`, `item`, `obj`, `payload`, `response`, `value`, `handleStuff`, `processData` там, где модуль уже говорит на конкретном языке (`grossPremium`, `Customer`, `getCustomerById`).
* **Дрейф соглашений:** символ в `snake_case`, помещённый в файл на `camelCase`, отсутствующий булев префикс `is`/`has` или новый CRUD-глагол (`fetch*`) в кодовой базе, стандартизированной на `get*`. Каждый дифф "следует тому стилю, который встретил последним, вводя четвёртое соглашение. Затем пятое".
* **Разрастание синонимов / дублирующиеся понятия:** ИИ выдумывает `fetchUser`, когда `getCustomerById` уже существует, или смешивает `customer`/`client`/`user` для одной сущности — реализуя заново вместо переиспользования.
* **Имена, описывающие механизм, а не намерение — или лгущие о поведении:** `processData()`, который на деле вычисляет налог с продаж. Агенты (и следующий агент) "читают `processData()` и действуют так, будто это имя рассказывает всю историю", поэтому неверный смысл распространяется на каждое место вызова.

```ts
// Репозиторий уже экспортирует getCustomerById(id: CustomerId): Promise<Customer>
// ИИ добавляет почти-дубликат с контекстно-слепыми именами:
async function fetchData(id: string) {          // обобщённый глагол, размытый тип
  const result = await db.query("select * from customers where id = $1", [id]);
  const temp = result.rows[0];                  // 'temp' скрывает, что это Customer
  return temp;                                  // ничто здесь не говорит "Customer"
}

```

## Reasons for the Problem

**Почему модели это порождают**

* **Смещение к частотности следующего токена.** По всему обучающему корпусу `data`/`result`/`temp`/`foo` — идентификаторы с наивысшей вероятностью, особенно в учебном и шаблонном коде, который LLM усваивают в больших объёмах. Генерация _статистически среднего_ имени — это ровно то, на что оптимизирован предсказатель следующего токена, и это сглаживает доменный смысл ([Towards Data Science](https://towardsdatascience.com/the-missing-curriculum-essential-concepts-for-data-scientists-in-the-age-of-ai-coding-agents/)).
* **Отсутствие (или усечённый) контекст репозитория.** Модель редко видит глоссарий соседнего модуля или существующий `getCustomerById`. GitClear напрямую связывает с этим всплеск дублирования: ассистент "с меньшей вероятностью предложит переиспользовать похожую функцию из другого места... отчасти из-за ограниченного размера контекста" ([GitClear 2025](https://www.gitclear.com/ai%5Fassistant%5Fcode%5Fquality%5F2025%5Fresearch)).
* **Локальная оптимизация / слабый инстинкт рефакторинга.** Каждый ход оптимизирует непосредственный промпт, "не учитывая накопительное архитектурное влияние". OX Security обнаружила _Избегание рефакторингов_ в 80–90% ИИ-кода, поэтому модель добавляет свежеименованный символ, а не переименовывает или переиспользует существующий ([отчёт OX](https://www.prnewswire.com/news-releases/ox-report-ai-generated-code-violates-engineering-best-practices-undermining-software-security-at-scale-302592642.html)).
* **Устаревание из-за порога обучения.** Соглашения и имена API из более старых корпусов всплывают вновь даже после того, как проект ушёл вперёд.

**Почему это вредит**

* **Читаемость/сопровождаемость:** имена — это первичная документация кодовой базы; обобщённые имена вынуждают каждого читателя заново выводить намерение из тела.
* **Дублирование и дефекты:** переименование понятия порождает параллельную реализацию. GitClear измерил рост дублированных блоков примерно в 8 раз, а копипаста впервые обогнала перемещённые (отрефакторенные) строки в 2024 году; клоны несут, по оценкам, на 15–50% больше дефектов.
* **Петля обратной связи агента (специфичный для ИИ вред):** имена — это интерфейс, который _следующий_ агент воспринимает буквально. Вводящее в заблуждение или обобщённое имя "распространяет ошибки по всему сгенерированному агентом коду, который на нём строится" ([AI Pattern Book](https://aipatternbook.com/naming)).
* **Нагрузка на ревью и корректность:** ревьюерам приходится мысленно отображать `temp`/`data` обратно на доменные понятия, что прячет ошибки; вводящие в заблуждение имена приводят к неправильному использованию в местах вызова.
* **Слепые зоны безопасности/аудита:** секрет или токен, припаркованный в переменной с именем `data`/`tmp`, проскальзывает мимо grep-ов по именам и внимания ревью.

Примечание: исследования вроде arXiv [2509.20491](https://arxiv.org/abs/2509.20491) показывают, что статические инструменты хорошо ловят _локальные, явные_ запахи, но грань доменного смысла здесь зависит от значения/намерения и в значительной мере ускользает от автоматического обнаружения.

## Treatment

**Тактики ревью и промптинга**

* **Подайте соглашения и глоссарий в контекст.** Держите краткое руководство по именованию (регистр, булевы префиксы, CRUD-глаголы, доменные термины) в `CLAUDE.md`/документах по стилю и требуйте, чтобы модель ему следовала. Применяйте термины доменного глоссария последовательно, чтобы синонимы схлопнулись к одному слову.
* **Принуждайте к переиспользованию до создания.** Промпт: "Найди в репозитории существующую функцию/тип для этого, прежде чем добавлять новую; переиспользуй её". Это прямо противодействует ошибке дублирования понятий, на которую указывают GitClear и OX.
* **Называйте вещи в промпте.** "Назови обработчик `createRefund`" лучше, чем "добавь обработку возвратов". Указывайте доменные имена (`monthlyRevenue`, а не `float1`).
* **Требуйте запуска линтера + сканирования дублирования** на диффе (naming-convention + `id-denylist` \+ jscpd) и пусть модель исправляет нарушения, а не вы вручную.

**Рефакторинг** — примените _Rename Variable/Function_ (Переименование переменной/функции, у Фаулера "Change Function Declaration"), устраняя запах **Mysterious Name** (Загадочное имя), и _Consolidate Duplicate Code_ (Консолидация дублирующегося кода), переиспользуя существующий символ вместо нового.

До:

```ts
async function fetchData(id: string) {
  const result = await db.query("select * from customers where id = $1", [id]);
  const temp = result.rows[0];
  return temp;
}

```

После (переиспользуйте существующую функцию репозитория; раскрывающие намерение, соответствующие соглашениям имена и типы):

```ts
// Не делай повторный запрос — переиспользуй getCustomerById и сохрани доменный словарь.
async function getCustomerById(id: CustomerId): Promise<Customer | null> {
  const { rows } = await db.query<Customer>(
    "select * from customers where id = $1",
    [id],
  );
  return rows[0] ?? null;
}

```

Если вводящее в заблуждение имя уже попало в продакшен, переименуйте его в соответствие с поведением (`processData` → `calculateSalesTax`) до того, как строить на нём, чтобы последующие агенты и люди унаследовали верный сигнал.

## Detected by

- **ESLint (core)** `id-denylist` — Запрет указанных идентификаторов (https://eslint.org/docs/latest/rules/id-denylist)
- **ESLint (core)** `id-length` — Обеспечение минимальной/максимальной длины идентификатора (https://eslint.org/docs/latest/rules/id-length)
- **typescript-eslint** `@typescript-eslint/naming-convention` — Обеспечение соглашений об именовании (регистр/префиксы) (https://typescript-eslint.io/rules/naming-convention/)
- **eslint-plugin-unicorn** `unicorn/prevent-abbreviations` — Предотвращение сокращений / чрезмерно обобщённых имён (https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prevent-abbreviations.md)
- **SonarQube / SonarSource** `typescript:S117` — Имена локальных переменных и параметров должны соответствовать соглашению об именовании (https://rules.sonarsource.com/typescript/RSPEC-117/)
- **jscpd** `copy-paste-detection` — Обнаруживает дублированные блоки, возникающие, когда переименованное понятие дублирует существующее (https://github.com/kucherenko/jscpd)
