Когда два ИИ смотрят на один файл
Открываешь утром репозиторий, а там - полный бардак. Cursor переписал половину функций, Windsurf добавил свои комментарии, а Git показывает конфликты в каждом втором файле. Знакомо? Это не ошибка инструментов. Это проблема организации.
AI-ассистенты вроде Cursor и Windsurf работают как очень старательные, но совершенно не координированные стажёры. Каждый хочет показать свою полезность. Каждый считает, что именно его изменения самые важные. И каждый оставляет после себя следы в виде конфигурационных файлов, временных данных и переписанного кода.
Проблема не в том, что инструменты плохие. Проблема в том, что они слишком хорошие. Когда два ИИ одновременно оптимизируют код - получается оптимизированный бардак.
Типичные конфликты, которые сводят с ума
Давайте разберемся, что именно ломается:
- .cursorrules против .windsurf - каждый инструмент создает свои конфигурационные файлы, которые часто противоречат друг другу
- Разные стили форматирования - один ИИ ставит фигурные скобки на новой строке, другой на той же
- Конфликтующие зависимости - Cursor предлагает использовать одну версию библиотеки, Windsurf другую
- Пересекающиеся временные файлы и кэши
- Разные подходы к рефакторингу - один переименовывает функции, другой продолжает использовать старые названия
Худший сценарий? Когда оба инструмента начинают "исправлять" код друг друга. Получается бесконечный цикл изменений, где каждый коммит отменяет предыдущий. Git превращается в поле битвы, а не в систему контроля версий.
1 Декларируйте зоны ответственности
Первый шаг - самый очевидный, но его почему-то все пропускают. Определите, кто за что отвечает. Не формально, а буквально запишите в README или в отдельном файле конвенций.
| Инструмент | Зона ответственности | Что игнорировать |
|---|---|---|
| Cursor | Рефакторинг, генерация тестов, работа с бизнес-логикой | Форматирование, конфигурационные файлы CI/CD |
| Windsurf | Автодополнение, поиск ошибок, работа с инфраструктурой | Крупные изменения архитектуры |
Это не жесткое правило, а скорее соглашение. Если Cursor начинает предлагать изменения в Dockerfile - вежливо напомните ему, что это не его зона. Как? Через контекст в промптах или через настройки самого инструмента.
2 Изолируйте конфигурационные файлы
Каждый AI-инструмент считает себя главным. И каждый хочет оставить свои конфиги в корне проекта. Решение? Используйте поддиректории или префиксы.
Вместо .cursorrules в корне создайте tools/cursor/.cursorrules. Для Windsurf - tools/windsurf/.windsurf. Да, придется немного покопаться в настройках, чтобы указать инструментам новые пути. Но это того стоит.
# Структура проекта после реорганизации
project/
├── .gitignore
├── src/
├── tools/
│ ├── cursor/
│ │ ├── .cursorrules
│ │ └── config.json
│ └── windsurf/
│ ├── .windsurf
│ └── cache/
└── README.md
Не забудьте добавить пути к временным файлам в .gitignore:
# Игнорируем временные файлы AI-инструментов
tools/cursor/.cache/
tools/windsurf/cache/
*.cursor-tmp.*
*.windsurf-tmp.*
ln -s tools/cursor/.cursorrules .cursorrules. На Windows через mklink. Только не коммитьте симлинки в репозиторий - создавайте их локально.3 Создайте веточную стратегию для ИИ
Git-ветки - это не только для людей. ИИ тоже должны работать в своих песочницах. Особенно если вы используете несколько AI-инструментов одновременно.
Предлагаю простую, но эффективную схему:
# Основные ветки
main # Только ручные мержи, только проверенный код
develop # Интеграционная ветка для людей
# Ветки для AI-инструментов
feature/ai-cursor-* # Все изменения от Cursor
feature/ai-windsurf-* # Все изменения от Windsurf
feature/ai-experiment-* # Экспериментальные изменения, можно удалять
Правило простое: каждый AI-инструмент работает только в своей ветке. Никогда не коммитите напрямую в develop или main из под AI. Сначала создайте feature-ветку, дайте ИИ поработать там, потом ревью и мерж.
Как автоматизировать? Git hooks. Простой pre-commit хук может проверять, не пытается ли ИИ закоммитить в защищенную ветку:
#!/bin/bash
# .git/hooks/pre-commit
protected_branches=("main" "develop")
current_branch=$(git symbolic-ref --short HEAD)
# Проверяем, не в защищенной ли ветке
for branch in "${protected_branches[@]}"; do
if [ "$current_branch" = "$branch" ]; then
echo "Ошибка: Нельзя коммитить в $branch напрямую из AI-инструмента"
echo "Создайте feature-ветку: git checkout -b feature/ai-yourname"
exit 1
fi
done
4 Используйте Docker для полной изоляции
Самый радикальный, но самый эффективный способ. Каждый AI-инструмент в своем контейнере. Ноль конфликтов, ноль проблем с зависимостями.
Создайте отдельные Docker-образы для каждого инструмента. В каждом образе - свои зависимости, свои настройки, свои версии библиотек. Проект монтируете как volume, а инструменты работают изолированно.
# Dockerfile.cursor
FROM python:3.11-slim
# Устанавливаем только то, что нужно Cursor
RUN pip install --no-cache-dir black isort mypy
# Копируем конфиги Cursor
COPY tools/cursor/.cursorrules /root/.cursorrules
WORKDIR /workspace
CMD ["bash"]
# Dockerfile.windsurf
FROM node:18-alpine
# Устанавливаем зависимости для Windsurf
RUN npm install -g prettier eslint
# Конфиги Windsurf
COPY tools/windsurf/.windsurf /root/.windsurf
WORKDIR /workspace
CMD ["bash"]
Запускаете Cursor в своем контейнере, Windsurf в своем. Они даже не знают о существовании друг друга. Как будто работают на разных компьютерах. Только код общий.
Минус подхода - нужно настраивать интеграцию IDE с Docker. Не все инструменты хорошо работают через удаленные контейнеры. Но если справитесь - получите идеальную изоляцию.
5 Настройте линтеры и форматеры один раз на всех
Больше половины конфликтов возникают из-за форматирования. Cursor любит двойные кавычки, Windsurf одинарные. Один ставит точку с запятой, другой нет.
Решение - единый .editorconfig и линтеры, которые работают одинаково для всех инструментов. Не надейтесь, что ИИ сами договорятся о стиле. Они не договорятся.
# .editorconfig - единый для всего проекта
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{js,ts,jsx,tsx}]
quote_type = single
semi = true
[*.py]
max_line_length = 88
Добавьте pre-commit хуки, которые запускают форматирование перед каждым коммитом. И настройте все AI-инструменты использовать эти же настройки. В Cursor можно указать путь к конфигу black/isort, в Windsurf - к .prettierrc.
Рабочий процесс, который не сломается
Давайте соберем все вместе. Как выглядит идеальный день разработки с двумя AI-инструментами?
- Утром создаете ветку
feature/ai-cursor-refactor-authдля Cursor - Даете Cursor задачу по рефакторингу, он работает в своей изолированной среде
- Параллельно в другой ветке
feature/ai-windsurf-optimize-queriesзапускаете Windsurf - Каждый инструмент коммитит только в свою ветку
- Вечером делаете code review обеих веток (или поручаете это другому ИИ, почему нет?)
- Мержите изменения в develop, предварительно решив конфликты вручную
- Профит
Звучит сложно? Первую неделю - да. Потом это становится рутиной. Как завязывать шнурки.
Чего делать категорически нельзя
- Не давайте обоим ИИ доступ к одним и тем же файлам одновременно. Это гарантированный конфликт. Разделяйте ответственность на уровне файлов или директорий.
- Не игнорируйте временные файлы. Каждый AI-инструмент генерирует тонны временных данных. Если не добавить их в .gitignore, репозиторий раздуется до неприличных размеров.
- Не надейтесь на авторазрешение конфликтов. ИИ плохо справляются с merge conflicts. Они либо создают еще больший бардак, либо просто откатывают все изменения.
- Не используйте AI-инструменты для работы с Git. Пусть коммитят, но пусть не мержат, не ребейзят и не делают сложные операции. Git - это пока слишком сложно для ИИ.
Помните статью про контекстную слепоту агентов? Там как раз объясняется, почему ИИ не видят всей картины. И почему они ломают то, что только что починили.
Когда все равно ничего не помогает
Бывает. Инструменты конфликтуют на уровне архитектуры. Cursor переписывает API на GraphQL, а Windsurf генерирует код для REST. Или один переходит на async/await, а второй продолжает использовать callbacks.
В этом случае нужно поднять уровень абстракции. Используйте оркестраторы вроде Beads, которые координируют работу нескольких агентов. Или создайте своего собственного диспетчера.
Самый простой вариант - использовать ACDD и атомарные коммиты. Каждое изменение - маленькое, самодостаточное, легко откатываемое. Даже если ИИ накосячит, ущерб будет минимальным.
Будущее, которое уже здесь
Скоро AI-инструменты научатся договариваться между собой. Появятся протоколы обмена контекстом, стандарты взаимодействия, maybe даже что-то вроде API для меж-ИИ коммуникации.
Но пока этого нет. Пока мы живем в диком западе, где каждый ИИ сам за себя. И наша задача - не дать им перестрелять друг друга в салуне нашего репозитория.
Начните с малого. Разделите зоны ответственности. Настройте изоляцию. Создайте веточную стратегию. И наблюдайте, как хаос превращается в порядок. Ну, или хотя бы в управляемый хаос.
А если совсем ничего не помогает - вспомните старую добрую истину: иногда один хороший разработчик с Notepad++ эффективнее десяти ИИ, которые дерутся за каждый файл.