Почему это важно для AI-проектов
В AI-разработке проблема зависимостей острее, чем в обычном веб-проекте:
Тяжёлые пакеты
torch, transformers, langchain — гигабайты. Медленная установка без кэша убивает CI/CD
Конфликты версий
langchain требует одну версию pydantic, а твой код — другую. Это реальная проблема
Воспроизводимость
Агент работал вчера — сегодня нет. Причина: обновилась зависимость третьего уровня
Разные окружения
Ноутбук разработчика, сервер prod, Docker-контейнер — должны быть идентичны
Типичная структура зависимостей AI-агента: agent.py ├── openai → httpx → certifi → h2 → ... ├── anthropic → httpx → anyio → sniffio → ... ├── langgraph → langchain-core → pydantic → ... ├── pydantic-settings → pydantic → ... ├── chromadb → onnxruntime → numpy → ... └── tavily-python → requests → urllib3 → ... ~150+ транзитивных зависимостей в реальном проекте
Виртуальные окружения: обязательная база
Прежде чем разбирать инструменты — нужно понять зачем нужны виртуальные окружения. Без них все пакеты устанавливаются глобально в системный Python — это хаос:
# ❌ БЕЗ venv — всё глобально, конфликты неизбежны
pip install langchain # устанавливает pydantic 2.5
pip install old-project # требует pydantic 1.10 — КОНФЛИКТ!
# ✅ С venv — каждый проект изолирован
# Создать окружение
python -m venv .venv
# Активировать (Linux/macOS)
source .venv/bin/activate
# Активировать (Windows)
.venv\Scripts\activate
# Теперь pip устанавливает только в .venv
pip install langchain # изолировано от других проектов
# Деактивировать
deactivate
# Проверить какой Python активен
which python # должен указывать на .venv/bin/python
Называй виртуальное окружение .venv (с точкой). Это стандарт, который понимают VS Code, PyCharm, GitHub Actions и большинство инструментов. Добавь .venv/ в .gitignore.
pip + requirements.txt: классика
Стандартный инструмент Python. Прост, везде установлен, но имеет ограничения для больших проектов:
Базовые команды
# Установка пакета
pip install httpx
pip install "httpx>=0.27" # Минимальная версия
pip install "httpx>=0.27,<1.0" # Диапазон версий
pip install "httpx[http2]" # С опциональными зависимостями
# Установка конкретной версии (для воспроизводимости)
pip install httpx==0.27.0
# Установка из файла
pip install -r requirements.txt
# Удаление
pip uninstall httpx
# Список установленных пакетов
pip list
pip show httpx # Подробная информация о пакете
# Что зависит от пакета
pip show httpx | grep Requires-Dist
requirements.txt — два файла, не один
Хорошая практика — разделить прямые зависимости и заморозку версий:
# requirements.in — только ПРЯМЫЕ зависимости (коммитим в Git)
# Пишем сами, указываем ограничения если нужно
openai>=1.0
anthropic>=0.30
langchain>=0.3
pydantic>=2.0
httpx>=0.27
pydantic-settings
python-dotenv
tenacity
# requirements.txt — ГЕНЕРИРУЕМ командой (коммитим в Git)
pip freeze > requirements.txt
# Содержимое:
# annotated-types==0.7.0
# anyio==4.4.0
# certifi==2024.8.30
# h11==0.14.0
# httpcore==1.0.5
# httpx==0.27.0
# ...
# (все 150+ пакетов с точными версиями)
# Воспроизведение среды на другой машине
pip install -r requirements.txt
Нет встроенного разрешения конфликтов при установке: pip может установить несовместимые версии и не предупредить. Также нет разделения dev/prod зависимостей без ручных ухищрений (requirements-dev.txt и т.п.).
uv — современный стандарт (рекомендован)
uv — инструмент от Astral (авторы ruff), написанный на Rust. В 2024–2025 годах стал новым стандартом для Python-проектов. Заменяет pip, venv, pip-tools и отчасти pyenv — один инструмент вместо пяти.
uv заменяет целый стек: Раньше: pyenv + python-build + venv + pip + pip-tools Теперь: uv ← всё в одном, в 10–100x быстрее
Установка uv
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Через pip (если уже есть)
pip install uv
# Проверка
uv --version # uv 0.5.x
Создание нового AI-проекта
# Создать новый проект
uv init my-agent
cd my-agent
# Структура после init:
# my-agent/
# ├── .python-version ← версия Python для проекта
# ├── pyproject.toml ← конфигурация проекта и зависимости
# ├── README.md
# └── src/
# └── my_agent/
# └── __init__.py
# Добавить Python нужной версии (uv скачает сам если нет!)
uv python install 3.12
uv python pin 3.12 # Записывает в .python-version
# Создать venv и установить зависимости
uv sync # Читает pyproject.toml, создаёт .venv
Управление зависимостями
# Добавить зависимость (обновляет pyproject.toml и uv.lock)
uv add openai
uv add "anthropic>=0.30"
uv add "httpx[http2]"
# Добавить dev-зависимость (только для разработки)
uv add --dev pytest pytest-asyncio ruff mypy
# Добавить зависимость для конкретной группы
uv add --group notebooks jupyter ipykernel
# Удалить пакет
uv remove langchain
# Обновить пакет до последней версии
uv add openai --upgrade
# Обновить все пакеты
uv lock --upgrade
# Установить зависимости из pyproject.toml (после git clone)
uv sync
# Только prod зависимости (без dev, для Docker)
uv sync --no-dev
Запуск кода и скриптов
# Запустить скрипт в venv проекта (не нужно активировать!)
uv run python agent.py
uv run python -m pytest
uv run ruff check .
# Запустить инструмент без установки в проект (как npx)
uvx ruff check . # Запускает ruff во временном окружении
uvx mypy src/
# Запустить скрипт с inline зависимостями (uv script)
# В начале скрипта:
# /// script
# requires-python = ">=3.11"
# dependencies = ["httpx", "pydantic"]
# ///
uv run my_script.py # uv сам установит зависимости!
pyproject.toml — конфиг AI-проекта
[project]
name = "my-agent"
version = "0.1.0"
description = "AI Agent with LangGraph and RAG"
requires-python = ">=3.11"
dependencies = [
# LLM провайдеры
"openai>=1.50",
"anthropic>=0.40",
# Фреймворки агентов
"langgraph>=0.2",
"langchain-core>=0.3",
# Данные и валидация
"pydantic>=2.9",
"pydantic-settings>=2.5",
# HTTP и утилиты
"httpx>=0.27",
"python-dotenv>=1.0",
"tenacity>=9.0",
# Vector DB
"chromadb>=0.5",
]
[dependency-groups]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.24",
"pytest-cov>=5.0",
"ruff>=0.7",
"mypy>=1.11",
"ipykernel",
]
[tool.uv]
# Пакеты которые не хотим случайно обновить
constraint-dependencies = [
"pydantic>=2.0,<3.0",
]
# Настройки линтера ruff (бонус — раз уж мы в pyproject.toml)
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "UP"] # pycodestyle, pyflakes, isort, pyupgrade
# Настройки pytest
[tool.pytest.ini_options]
asyncio_mode = "auto" # pytest-asyncio: автоматический режим
testpaths = ["tests"]
# Настройки mypy
[tool.mypy]
python_version = "3.11"
strict = true
ignore_missing_imports = true
uv.lock — воспроизводимые сборки
# uv.lock создаётся автоматически при uv add / uv sync
# Содержит точные версии ВСЕХ зависимостей (включая транзитивные)
# Кроссплатформенный — один файл для Linux/macOS/Windows
# ✅ КОММИТИМ в Git (в отличие от requirements.txt с pip freeze)
git add uv.lock
# Установить точно те же версии что в lock-файле
uv sync --frozen # Не обновляет lock, использует как есть
# Проверить что lock актуален (в CI)
uv lock --check # Выходит с ошибкой если pyproject.toml изменился
uv.lock — кроссплатформенный, машиночитаемый, понимает разные ОС и архитектуры. pip freeze — платформоспецифичный снэпшот текущей среды. Для нового проекта всегда предпочитай uv.lock.
poetry — альтернатива с богатой экосистемой
poetry появился раньше uv и до сих пор широко используется. Если видишь в проекте pyproject.toml с секцией [tool.poetry] — это poetry-проект.
Установка и создание проекта
# Установка
curl -sSL https://install.python-poetry.org | python3 -
# Создание нового проекта
poetry new my-agent
cd my-agent
# Или инициализация в существующей директории
poetry init
# Добавить зависимость
poetry add openai
poetry add anthropic langchain pydantic-settings
poetry add --group dev pytest ruff mypy
# Установить все зависимости (создаёт venv автоматически)
poetry install
# Запустить в окружении проекта
poetry run python agent.py
poetry run pytest
# Активировать shell окружения
poetry shell
# Показать дерево зависимостей
poetry show --tree
# Обновить пакет
poetry update openai
pyproject.toml в стиле poetry
[tool.poetry]
name = "my-agent"
version = "0.1.0"
description = "AI Agent"
authors = ["Your Name "]
[tool.poetry.dependencies]
python = "^3.11"
openai = "^1.50"
anthropic = "^0.40"
langgraph = "^0.2"
pydantic = "^2.9"
pydantic-settings = "^2.5"
httpx = "^0.27"
python-dotenv = "^1.0"
tenacity = "^9.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
pytest-asyncio = "^0.24"
ruff = "^0.7"
mypy = "^1.11"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
| Критерий | uv | poetry | pip + venv |
|---|---|---|---|
| Скорость установки | ⚡ 10–100x быстрее | 🐢 Медленнее pip | Базовая |
| Lock-файл | ✅ uv.lock (кроссплатформ.) | ✅ poetry.lock | ⚠️ pip freeze вручную |
| Dev/prod группы | ✅ | ✅ | ❌ вручную |
| Управление версиями Python | ✅ встроено | ⚠️ нужен pyenv | ❌ нужен pyenv |
| Совместимость с pip | ✅ полная | ✅ полная | ✅ нативно |
| Publish в PyPI | ✅ | ✅ встроено | ⚠️ twine отдельно |
| Рекомендован для новых проектов | ✅ 2025 | Существующие проекты | Простые скрипты |
Структура AI-проекта: полный шаблон
my-agent/ ├── .python-version ← "3.12" (для uv) ├── pyproject.toml ← конфиг, зависимости, инструменты ├── uv.lock ← заморозка (коммитим!) ├── .env.example ← шаблон конфига (коммитим) ├── .gitignore ← .venv, .env, __pycache__, ... │ ├── src/ │ └── agent/ │ ├── __init__.py │ ├── main.py ← точка входа │ ├── config.py ← Settings(BaseSettings) │ ├── tools.py ← инструменты агента │ └── http_client.py ← AgentHttpClient │ ├── tests/ │ ├── conftest.py │ └── test_tools.py │ └── Makefile ← shortcuts: make install, make test, make lint
Makefile — удобные команды
.PHONY: install sync run test lint fmt typecheck clean
# Установить всё (первый запуск)
install:
uv sync --all-groups
# Синхронизировать зависимости (после git pull)
sync:
uv sync
# Запустить агента
run:
uv run python src/agent/main.py
# Запустить тесты
test:
uv run pytest tests/ -v
# Запустить тесты с покрытием
test-cov:
uv run pytest tests/ --cov=src --cov-report=html
# Проверить стиль кода
lint:
uv run ruff check src/ tests/
# Автоисправить стиль
fmt:
uv run ruff format src/ tests/
uv run ruff check --fix src/ tests/
# Проверить типы
typecheck:
uv run mypy src/
# Очистить кэш
clean:
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null; true
find . -type d -name .pytest_cache -exec rm -rf {} + 2>/dev/null; true
Docker и зависимости
При деплое агента в Docker важно правильно кэшировать слои — установка зависимостей не должна повторяться при каждом изменении кода:
FROM python:3.12-slim
# Устанавливаем uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
# Копируем ТОЛЬКО файлы зависимостей — слой кэшируется
# пока pyproject.toml и uv.lock не изменились
COPY pyproject.toml uv.lock ./
# Устанавливаем зависимости (без dev-группы для prod)
RUN uv sync --frozen --no-dev
# Копируем исходный код — этот слой инвалидируется при каждом изменении
COPY src/ ./src/
# Запускаем через uv run (не нужно активировать venv)
CMD ["uv", "run", "python", "src/agent/main.py"]
Docker кэширует слои последовательно. Если сначала скопировать весь код, а потом установить зависимости — при каждом изменении кода Docker будет переустанавливать все пакеты. Правильный порядок: сначала файлы зависимостей → установка → потом исходный код.
CI/CD: GitHub Actions
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Устанавливаем uv (быстро, ~2 секунды)
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
enable-cache: true # Кэшировать .venv между запусками
# Python версия из .python-version
- name: Set up Python
run: uv python install
# Установить зависимости (используется uv.lock)
- name: Install dependencies
run: uv sync --frozen --all-groups
# Линтер
- name: Lint
run: uv run ruff check src/ tests/
# Типы
- name: Type check
run: uv run mypy src/
# Тесты
- name: Run tests
run: uv run pytest tests/ -v --cov=src
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Полный .gitignore для AI-проекта
# Виртуальные окружения
.venv/
venv/
env/
.env/
# Секреты — НИКОГДА не коммитим!
.env
.env.local
.env.*.local
# Python кэш
__pycache__/
*.py[cod]
*.pyo
.pytest_cache/
.mypy_cache/
.ruff_cache/
# Данные и состояние агента (обычно не нужны в Git)
data/
*.json
!.env.example # Исключение: шаблон конфига коммитим
# Jupyter
.ipynb_checkpoints/
*.ipynb # Решай сам — бывает нужно коммитить ноутбуки
# Coverage
htmlcov/
.coverage
coverage.xml
# IDE
.idea/
.vscode/ # Или добавь только .vscode/settings.json
*.swp
# OS
.DS_Store
Thumbs.db
# Сборка
dist/
build/
*.egg-info/
Шпаргалка
# ── uv (рекомендован для новых проектов) ─────────────
uv init my-agent # Новый проект
uv python install 3.12 # Установить Python
uv python pin 3.12 # Зафиксировать версию
uv add openai # Добавить зависимость
uv add --dev pytest ruff # Dev-зависимость
uv remove langchain # Удалить
uv sync # Установить все зависимости
uv sync --frozen # Строго по lock-файлу (CI)
uv sync --no-dev # Без dev (Docker prod)
uv run python agent.py # Запустить (без активации venv)
uv run pytest # Запустить тесты
uvx ruff check . # Запустить инструмент без установки
uv lock --upgrade # Обновить все пакеты
uv lock --check # Проверить что lock актуален
# ── poetry (существующие проекты) ─────────────────────
poetry add openai # Добавить
poetry add --group dev ruff
poetry install # Установить всё
poetry run python agent.py # Запустить
poetry shell # Активировать venv
poetry show --tree # Дерево зависимостей
# ── pip + venv (скрипты и legacy) ─────────────────────
python -m venv .venv # Создать venv
source .venv/bin/activate # Активировать (Linux/macOS)
.venv\Scripts\activate # Активировать (Windows)
pip install httpx # Установить
pip install -r requirements.txt
pip freeze > requirements.txt
# ── .gitignore must-have ──────────────────────────────
# .venv/ .env __pycache__/ .pytest_cache/
Практическое задание
Задание: настрой AI-проект с нуля
- Установи
uvи создай новый проект командойuv init my-agent. Зафиксируй Python 3.12 - Добавь зависимости из этого модуля:
openai,anthropic,pydantic-settings,httpx,python-dotenv,tenacity - Добавь dev-зависимости:
pytest,pytest-asyncio,ruff,mypy - Создай
.env.exampleс шаблоном переменных и правильный.gitignore - Напиши
Makefileс командамиinstall,run,test,lint,fmt - Напиши простой
Dockerfileс правильным порядком слоёв для кэширования зависимостей
Модуль 01 завершён!
Ты изучил все инструменты Python-фундамента: асинхронность (asyncio), типизацию и валидацию (Pydantic), конфигурацию (JSON/ENV/.env), HTTP-запросы (httpx) и организацию проекта (uv). Теперь — к ядру AI-агентов.