Как нейросети помогают писать код на Python: GitHub Copilot, ChatGPT и альтернативы
Использование ИИ для написания Python кода: обзор инструментов и примеров
Современные системы искусственного интеллекта способны генерировать, дополнять и исправлять Python код, экономя время разработчика. Рассмотрим наиболее популярные решения и их применение на практике.
Основной инструмент: GitHub Copilot
Как сгенерировать функцию для обработки CSV файла с помощью ИИ?
GitHub Copilot на базе OpenAI Codex встраивается в IDE (Visual Studio Code, JetBrains) и предлагает автодополнения в реальном времени. Для получения кода достаточно написать комментарий на естественном языке.
Пример: пользователь пишет комментарий # функция для чтения CSV и возврата списка словарей, и Copilot предлагает реализацию.
import csv
def read_csv_to_dicts(filepath: str) -> list[dict]:
"""Читает CSV файл и возвращает список словарей."""
with open(filepath, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
return list(reader)ии для кода python (использование ии для написания python кода)
Возможные проблемы и их решения:
- Copilot может предложить код с неправильным режимом открытия файла (например, 'w' вместо 'r'). Решение: явно указывать режим в строке документации или проверять предложение перед использованием.
- Иногда генерируется бесконечный цикл при обработке строк. Решение: добавлять ограничение в комментарий (например, # не более 1000 строк).
- Импорт модуля может отсутствовать. Решение: использовать автодополнение для импорта или добавлять import pandas в начало файла, если нужна продвинутая обработка.
Вариант 1: ChatGPT как автономный генератор кода
Как переписать существующую функцию с использованием list comprehension через ChatGPT?
ChatGPT (или любой другой языковой модель, например, Claude) позволяет общаться в диалоговом режиме. Пользователь даёт задание: Перепиши функцию на Python, которая фильтрует список чисел, используя list comprehension.
# Исходная функция
def filter_even(numbers):
result = []
for n in numbers:
if n % 2 == 0:
result.append(n)
return result
# Предложенный ChatGPT вариант
def filter_even(numbers):
return [n for n in numbers if n % 2 == 0]Типичные ошибки:
- Модель может изменить логику (например, проверить на нечётные). Решение: уточнять задачу или проверять результат юнит-тестами.
- Сгенерированный код может не соответствовать версии Python (например, использование f-строк до Python 3.6). Решение: указывать версию в запросе (для Python 3.10).
- ChatGPT не видит окружение проекта, поэтому импорты могут быть ошибочными. Решение: дополнять запрос списком доступных библиотек.
Вариант 2: Tabnine (на базе Codex и собственных моделей)
Как с помощью Tabnine создать функцию для вычисления факториала с рекурсией?
Tabnine работает подобно Copilot, но поддерживает больше языков и может работать локально (без отправки кода в облако). Для рекурсивной функции достаточно написать def factorial(n): и Tabnine предложит тело функции.
def factorial(n: int) -> int:
if n <= 1:
return 1
else:
return n * factorial(n - 1)Проблемы:
- Tabnine может предложить слишком много вариантов, отвлекающих разработчика. Решение: настроить количество предлагаемых вариантов в настройках IDE.
- В режиме локальной модели качество может быть ниже, чем у облачной. Решение: выбрать гибридный режим (локальная модель + облачная).
- Иногда Tabnine копирует код с открытых репозиториев без учёта лицензии. Решение: проверять сгенерированный код на уникальность.
Вариант 3: Codeium (бесплатная альтернатива Copilot)
Как создать простой REST API с помощью Codeium?
Codeium поддерживает автодополнение в IDE и поиск по документации. Написав комментарий # Flask приложение с одним маршрутом /hello, получим заготовку.
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True)Возможные трудности:
- Codeium может не распознать контекст проекта, если используется нестандартная структура. Решение: добавить комментарий с именем фреймворка.
- Автодополнение иногда заменяет существующий код целиком, а не только нужную часть. Решение: использовать комбинацию Ctrl+Z для отмены.
- Бесплатная версия имеет ограничение по количеству запросов в день. Решение: обновить до платной версии или использовать в спокойном режиме.
Как локально развернуть модель Code Llama для генерации кода?
Локальные модели (например, Code Llama от Meta) позволяют работать без интернета и без отправки данных. Для запуска потребуется библиотека transformers и файл модели. Пример использования через Python:
from transformers import AutoTokenizer, AutoModelForCausalLM
model_name = "codellama/CodeLlama-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
prompt = "def quicksort(arr):"
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))Сложности:
- Локальные модели требуют больших вычислительных ресурсов (GPU с 8+ ГБ). Решение: использовать квантованные версии (например, с библиотекой bitsandbytes).
- Качество генерации уступает облачным аналогам. Решение: дообучать модель на собственном коде (fine-tuning).
- Установка зависимостей может быть нетривиальной. Решение: использовать предварительно настроенные Docker-образы.
Расширенные примеры использования ИИ для Python кода
Ниже приведены нестандартные сценарии, демонстрирующие возможности ИИ помощников.
Пример 1: Генерация модульных тестов с помощью GitHub Copilot
Задача: написать тесты для функции, проверяющей палиндром. Copilot предлагает полный набор тестов после написания документации.
Код функции:
def is_palindrome(s: str) -> bool:
"""Возвращает True, если строка является палиндромом (без учёта регистра и пробелов)."""
cleaned = ''.join(ch.lower() for ch in s if ch.isalnum())
return cleaned == cleaned[::-1]После этого пишем комментарий # тесты для is_palindrome и Copilot генерирует:
import unittest
class TestIsPalindrome(unittest.TestCase):
def test_palindrome_simple(self):
self.assertTrue(is_palindrome("racecar"))
def test_palindrome_with_spaces(self):
self.assertTrue(is_palindrome("A man a plan a canal Panama"))
def test_non_palindrome(self):
self.assertFalse(is_palindrome("hello"))
def test_empty_string(self):
self.assertTrue(is_palindrome(""))
def test_palindrome_with_mixed_case(self):
self.assertTrue(is_palindrome("RaCeCaR"))Результат выполнения тестов (при условии, что функция определена):
..... ---------------------------------------------------------------------- Ran 5 tests in 0.001s OK
Пример 2: Рефакторинг старого кода с помощью ChatGPT
Исходный код (неэффективный цикл):
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n**2)Запрос к ChatGPT: Преобразуй этот код в однострочный с map и lambda. Ответ:
squares = list(map(lambda x: x**2, numbers))Результат (при печати print(squares)):
[1, 4, 9, 16, 25]
Пример 3: Создание сложного FastAPI приложения с помощью Tabnine
После написания from fastapi import FastAPI Tabnine может предложить полный скелет приложения с маршрутами и документацией:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello World"}
@app.post("/items/")
async def create_item(item: dict):
return {"item": item, "id": 1}Результат запроса GET к / через curl:
{"message":"Hello World"}Пример 4: Исправление ошибки с помощью ChatGPT (debugging)
Пользователь предоставляет код с ошибкой:
def divide(a, b):
return a / b
print(divide(10, 0))Запрос: Почему возникает ошибка и как её избежать? Ответ ChatGPT:
def divide(a, b):
if b == 0:
return "Ошибка: деление на ноль"
return a / bРезультат после исправления:
Ошибка: деление на ноль
Пример 5: Локальная генерация кода с Code Llama (нестандартный случай)
Использование модели для генерации кода асинхронной выборки данных из базы данных:
Команда для запуска (в терминале после установки библиотек):
python -c "
from transformers import AutoTokenizer, AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained('codellama/CodeLlama-7b-hf', device_map='auto')
tokenizer = AutoTokenizer.from_pretrained('codellama/CodeLlama-7b-hf')
prompt = 'async def fetch_users(user_ids: list[int]) -> list[dict]:'
inputs = tokenizer(prompt, return_tensors='pt')
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
"Пример сгенерированного кода (сокращён):
async def fetch_users(user_ids: list[int]) -> list[dict]:
async with aiohttp.ClientSession() as session:
tasks = []
for uid in user_ids:
url = f'https://api.example.com/users/{uid}'
tasks.append(session.get(url))
responses = await asyncio.gather(*tasks)
return [await r.json() for r in responses]