Глава 16: GitHub Copilot
9 апреля 2026 г.
Принцип
Copilot генерирует код на основе контекста: текущего файла, открытых вкладок, комментариев. Качество подсказок зависит от качества контекста.
Inline Completion
Комментарии как спецификация
Подробный комментарий перед функцией направляет генерацию.
Пример 1: Простая функция
\# Функция проверки валидности ИНН
\# - 10 цифр: организация, проверка контрольной суммы
\# - 12 цифр: физлицо, две контрольные суммы
\# - Возвращает tuple (is\_valid: bool, inn\_type: str | None)
def validate\_inn(inn: str) -\> tuple$bool, str | None$:
\# Copilot сгенерирует реализацию
Пример 2: Класс с методами
\# Repository для работы с пользователями
\# Методы: get\_by\_id, get\_by\_email, create, update, delete
\# Использует SQLAlchemy AsyncSession
\# Все методы async
class UserRepository:
def \_\_init\_\_(self, session: AsyncSession):
self.\_session = session
\# Copilot предложит методы
Пример 3: Сложный алгоритм
\# Алгоритм: LRU Cache
\# - get(key): O(1), возвращает значение или None
\# - put(key, value): O(1), вытесняет старые при превышении capacity
\# - Использует OrderedDict для порядка доступа
class LRUCache:
def \_\_init\_\_(self, capacity: int):
\# Copilot сгенерирует реализацию
Type hints как контракт
Типы сужают пространство генерации.
Пример 1: Типизированная сигнатура
def parse\_config(
path: Path,
schema: type$BaseModel$,
encoding: str = 'utf-8'
) -\> BaseModel:
\# Copilot знает: читать файл, парсить, валидировать Pydantic
Пример 2: Protocol
from typing import Protocol
class Repository(Protocol$T$):
async def get(self, id: int) -\> T | None: ...
async def save(self, entity: T) -\> T: ...
async def delete(self, id: int) -\> bool: ...
class UserRepository: \# Copilot предложит реализацию Protocol
Пример 3: TypedDict
from typing import TypedDict
class OrderItem(TypedDict):
product\_id: int
quantity: int
price: Decimal
class Order(TypedDict):
id: int
user\_id: int
items: list$OrderItem$
total: Decimal
status: Literal$'pending', 'paid', 'shipped'$
def calculate\_order\_total(order: Order) -\> Decimal:
\# Copilot знает структуру order
Docstring первым
Написание docstring до кода улучшает генерацию.
Пример 1: Google style docstring
def retry\_with\_backoff(
func: Callable$..., T$,
max\_retries: int = 3,
base\_delay: float = 1.0
) -\> T:
"""
Выполняет функцию с экспоненциальным backoff при ошибках.
Args:
func: Функция для выполнения
max\_retries: Максимальное число попыток
base\_delay: Начальная задержка в секундах
Returns:
Результат выполнения функции
Raises:
Exception: Если все попытки исчерпаны
Example:
\>\>\> result = retry\_with\_backoff(lambda: api.call(), max\_retries=5)
"""
\# Copilot сгенерирует реализацию по docstring
Пример 2: С примерами
def merge\_sorted\_lists(lists: list$list\[int$\]) -\> list$int$:
"""
Сливает несколько отсортированных списков в один.
Examples:
\>\>\> merge\_sorted\_lists($\[1, 3, 5$, $2, 4, 6$\])
$1, 2, 3, 4, 5, 6$
\>\>\> merge\_sorted\_lists($\[1$, $2$, $3$\])
$1, 2, 3$
\>\>\> merge\_sorted\_lists($$)
$$
"""
Пример 3: С ограничениями
def validate\_password(password: str) -\> tuple$bool, list\[str$\]:
"""
Валидация пароля по правилам безопасности.
Правила:
- Минимум 8 символов
- Минимум 1 заглавная буква
- Минимум 1 строчная буква
- Минимум 1 цифра
- Минимум 1 спецсимвол (!@\#$%^&\*)
Returns:
(is\_valid, errors): Флаг валидности и список ошибок
"""
Copilot Chat
Slash commands
Пример 1: /explain
\# Выделить код, затем:
/explain
\# Дополнительно:
/explain focus on the error handling
Пример 2: /fix
\# При ошибке в коде:
/fix TypeError: 'NoneType' object is not subscriptable
Пример 3: /tests
/tests
\# Уточнение:
/tests using pytest, with parametrize for edge cases
Пример 4: /doc
/doc
\# Уточнение:
/doc Google style docstring with examples
Вопросы о коде
Пример 1: Понимание
"Что делает этот декоратор?"
$выделенный код$
Пример 2: Сравнение
"В чём разница между этими двумя реализациями?
Какая эффективнее для больших данных?"
Пример 3: Улучшение
"Как оптимизировать эту функцию для работы с 1M записей?"
Генерация кода
Пример 1: По описанию
"Напиши декоратор для кэширования с TTL.
- Ключ: аргументы функции
- Хранение: Redis
- TTL: параметр декоратора"
Пример 2: По примеру
"Создай класс ProductRepository по аналогии с UserRepository.
Методы те же, модель Product."
Пример 3: Рефакторинг
"Преобразуй этот callback hell в async/await:
$код с вложенными callbacks$"
Workspace Context
@workspace
Поиск по всему проекту.
Пример 1: Поиск использований
"@workspace где используется функция validate\_token?"
Пример 2: Паттерны проекта
"@workspace как в проекте обрабатываются исключения БД?"
Пример 3: Архитектура
"@workspace покажи data flow от API до базы данных"
Пример 4: Генерация по образцу
"@workspace создай OrderService по аналогии с UserService"
@file
Контекст конкретного файла.
Пример 1: Ссылка на модель
"@file:src/models/user.py
Создай Pydantic схемы для User"
Пример 2: Несколько файлов
"@file:src/services/auth.py @file:src/repositories/user.py
Как они взаимодействуют?"
Пример 3: Тесты по коду
"@file:src/utils/validators.py
Напиши тесты для всех функций"
@terminal
Контекст терминала.
Пример 1: Ошибка
"@terminal
Почему тест падает?"
Пример 2: Вывод команды
"@terminal
Объясни вывод pytest --cov"
Настройка поведения
Файл .github/copilot-instructions.md
\# Copilot Instructions
\#\# Язык
Код и комментарии на английском.
Ответы на русском.
\#\# Стиль кода
- Python 3.11+
- Type hints обязательны
- Docstrings: Google style
- Форматирование: black
- Линтер: ruff
\#\# Паттерны проекта
- Async по умолчанию
- Dependency injection через конструктор
- Repository pattern для БД
- Pydantic для валидации
\#\# Тестирование
- pytest
- Fixtures в conftest.py
- Mocker для внешних зависимостей
\#\# Не делать
- Глобальные переменные
- Mutable default arguments
- Bare except
- Print вместо logging
Эффективные практики
Структура файла
\# Хорошая структура помогает Copilot
\# === IMPORTS ===
from typing import Optional
from dataclasses import dataclass
\# === TYPES ===
UserId = int
Email = str
\# === MODELS ===
@dataclass
class User:
id: UserId
email: Email
\# === FUNCTIONS ===
def get\_user(user\_id: UserId) -\> Optional$User$:
"""Get user by ID."""
\# Copilot понимает контекст
Именование
\# Чёткие имена → лучшие подсказки
\# Плохо
def proc(d): \# Copilot не понимает контекст
pass
\# Хорошо
def process\_payment(payment\_data: PaymentRequest) -\> PaymentResult:
\# Copilot понимает: обработка платежа
pass
Контекст через открытые файлы
Для генерации связанного кода открой вкладки:
1. Модель (User)
2. Схема (UserCreate, UserResponse)
3. Существующий сервис (аналог)
4. Тесты (стиль)
Copilot использует открытые файлы как контекст.
Ограничения
| Ограничение | Решение |
|---|---|
| Не знает специфику проекта | Добавить copilot-instructions.md |
| Генерирует устаревший код | Указать версию в комментарии |
| Не видит весь проект | Использовать @workspace |
| Галлюцинирует API | Проверять документацию |
Keyboard shortcuts
| Действие | Mac | Windows/Linux |
|---|---|---|
| Принять подсказку | Tab | Tab |
| Отклонить | Esc | Esc |
| Следующая подсказка | Option+] | Alt+] |
| Предыдущая | Option+[ | Alt+[ |
| Открыть Copilot Chat | Cmd+I | Ctrl+I |