/ARTICLE

AI-Native Web Development: как собрать продакшен-стек на Django, Vue и Docker с AI-агентами внутри

Агенты

18 Мая 202610 мин чтения Pavel Katskov, Founder of Katskov Tech

«AI-Native» — это не просто Copilot в редакторе и чат-бот на сайте. Это архитектурный подход, при котором AI-агенты встроены в ядро продукта: от генерации UI-компонентов во Vue до автономных фоновых воркеров на Django. OpenCode и DeepSeek делают этот стек доступным без многомиллионного бюджета.

В этой статье — практическое руководство по сборке AI-Native веб-приложения на реальном стеке: Vue + Tailwind на фронте, Django на бэке, всё в Docker-контейнерах, с AI-агентами как полноценными участниками бизнес-процессов. Без маркетинга, только инженерия.

Что такое AI-Native и чем это отличается от «AI-фичи»

Большинство компаний добавляют AI как фичу: кнопка «Написать за меня», виджет чата, автогенерация описаний. Это AI-Assisted разработка — AI помогает пользователю или разработчику.

AI-Native — это другой уровень. Здесь AI-агенты:
Встроены в архитектуру как первоклассные компоненты системы.
Принимают решения в рамках заданных бизнес-правил автономно.
Общаются с другими сервисами через инструменты (tool calling).
Наблюдаемы — их действия логируются, трейсятся и аудитируются.

Ключевой вопрос: не «куда прикрутить чат-бот?», а «какие процессы в системе выиграют от автономного AI-агента и как это спроектировать надёжно?»

  1. Архитектура стека: Frontend — Vue + Tailwind, Backend — Django, Инфра — Docker

Перед тем как добавлять AI-агентов, нужен надёжный фундамент. Разберём выбор стека и его компоновку.

Почему Vue + Tailwind на фронте?
Vue 3 Composition API даёт реактивность и читаемость без overhead'а React.
Tailwind CSS устраняет споры о CSS-архитектуре и ускоряет верстку AI-сгенерированных компонентов: модель знает классы Tailwind на отлично.
Отличная совместимость: AI-агент может генерировать валидные Vue SFC-компоненты с Tailwind-разметкой прямо на лету.

Почему Django на бэке?
Batteries included: ORM, admin, миграции, auth — Django отдаёт всё из коробки.
Django REST Framework (DRF) — зрелый стандарт для API.
Celery + Django — проверенная связка для фоновых задач, в которые идеально вписываются AI-агенты.
Python — родной язык AI-экосистемы: LangChain, LlamaIndex, openai SDK, все модели — всё здесь.

bash
# Структура Django-проекта для AI-Native приложения
project/
├── docker-compose.yml
├── Dockerfile
├── backend/
│   ├── apps/
│   │   ├── core/          # Базовые модели и утилиты
│   │   ├── agents/        # AI-агенты как Django-приложение
│   │   │   ├── models.py  # AgentRun, AgentLog, ToolCall
│   │   │   ├── tasks.py   # Celery-таски для агентов
│   │   │   └── tools.py   # Инструменты агентов
│   │   └── api/           # DRF ViewSets
│   └── settings/
│       ├── base.py
│       └── production.py
└── frontend/
    ├── src/
    │   ├── components/
    │   │   └── AgentDashboard.vue
    │   └── composables/
    │       └── useAgentStream.ts
    └── vite.config.ts

  1. Docker-окружение: изоляция, которая не мешает AI-агентам работать

AI-Native приложение требует нескольких сервисов, работающих согласованно: веб-сервер, воркеры, модели, хранилища. Docker Compose — единственный разумный способ управлять этим локально и в продакшене.

Принципы компоновки:
• Один сервис — одна ответственность.
• AI-агенты запускаются в изолированных Celery-воркерах, не в веб-процессе.
• Модели (если self-hosted) — в отдельном сервисе с GPU-доступом.
• Переменные окружения для API-ключей — только через .env, никогда в образе.

yaml
# docker-compose.yml
version: '3.9'

services:
  db:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    env_file: .env

  redis:
    image: redis:7-alpine

  backend:
    build: ./backend
    command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - ./backend:/app
    depends_on:
      - db
      - redis
    env_file: .env

  # Celery-воркер для AI-агентов — изолированный процесс
  agent_worker:
    build: ./backend
    command: celery -A config worker -Q agents -c 2 --loglevel=info
    volumes:
      - ./backend:/app
    depends_on:
      - redis
      - db
    env_file: .env

  frontend:
    build: ./frontend
    ports:
      - "5173:5173"
    volumes:
      - ./frontend:/app

volumes:
  postgres_data:

Почему агенты в отдельной очереди agents? Запросы к LLM могут занимать 10–60 секунд. Если смешать их с обычными задачами, агенты заблокируют обработку обычных задач (отправку email, обновление кеша). Изоляция по очередям — обязательна.

  1. AI-агенты в Django: не чат-бот, а бизнес-компонент

Правильный AI-агент в веб-приложении — это управляемый, наблюдаемый, перезапускаемый процесс. Не просто вызов API с промптом.

Три принципа проектирования агентов:

  1. Каждый запуск агента — запись в БД. Статус, входные данные, вывод, использованные инструменты, токены.
  2. Инструменты — явные функции с валидацией. Агент не должен иметь доступ ко всей БД — только к задекларированным инструментам.
  3. Провалы — не исключения, а статусы. Агент может вернуть FAILED, это нормально. Система должна это обработать.
python
# backend/apps/agents/models.py
from django.db import models

class AgentRun(models.Model):
    class Status(models.TextChoices):
        PENDING = 'pending', 'Ожидает'
        RUNNING = 'running', 'Выполняется'
        SUCCESS = 'success', 'Успешно'
        FAILED  = 'failed',  'Ошибка'

    task_type   = models.CharField(max_length=100)
    input_data  = models.JSONField()
    output_data = models.JSONField(null=True, blank=True)
    status      = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.PENDING
    )
    tokens_used  = models.IntegerField(default=0)
    created_at   = models.DateTimeField(auto_now_add=True)
    completed_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        indexes = [models.Index(fields=['status', 'task_type'])]

  1. DeepSeek и OpenCode: self-hosted LLM без компромиссов по качеству

DeepSeek изменил экономику AI-Native разработки. Модели DeepSeek-V3 и DeepSeek-R1 показывают результаты уровня GPT-4o при стоимости в 10–30 раз ниже через API. Для кодогенерации — это смена парадигмы.

Два варианта использования DeepSeek в стеке:

A) Через API (облако):

Base URL: https://api.deepseek.com
Модели: deepseek-chat (V3), deepseek-reasoner (R1)
Совместимость: полная совместимость с OpenAI SDK

B) Self-hosted через OpenCode / Ollama:
OpenCode — это open-source CLI для AI-assisted разработки, который позволяет использовать любую совместимую модель, включая локально запущенный DeepSeek, как бэкенд для агентов разработчика.

Когда self-hosted критичен?
• Данные клиентов не могут покидать инфраструктуру (GDPR, финансы, медицина).
• Нужен предсказуемый latency без зависимости от внешнего API.
• Проект масштабируется до миллионов запросов в месяц.

python
# backend/apps/agents/client.py
# Единый клиент с поддержкой DeepSeek и self-hosted через OpenAI-совместимый API
from openai import AsyncOpenAI
from django.conf import settings

def get_llm_client() -> AsyncOpenAI:
    """Возвращает клиент в зависимости от настроек окружения."""
    return AsyncOpenAI(
        api_key=settings.LLM_API_KEY,
        base_url=settings.LLM_BASE_URL,  # https://api.deepseek.com или localhost
    )

async def run_agent_completion(
    system_prompt: str,
    user_message: str,
    tools: list | None = None,
) -> dict:
    client = get_llm_client()
    kwargs = {
        "model": settings.LLM_MODEL,  # deepseek-chat или deepseek-r1
        "messages": [
            {"role": "system", "content": system_prompt},
            {"role": "user",   "content": user_message},
        ],
        "max_tokens": 2048,
    }
    if tools:
        kwargs["tools"] = tools
        kwargs["tool_choice"] = "auto"

    response = await client.chat.completions.create(**kwargs)
    return response

  1. Frontend: Vue-компонент для стриминга агента в реальном времени

AI-агент работает долго. Показывать пустой спиннер на 30 секунд — плохой UX. Правильное решение — Server-Sent Events (SSE) или WebSocket для стриминга прогресса агента прямо в Vue-компонент.

Архитектура потока данных:
Celery Task → Django Channels / SSE endpoint → Vue composable → UI

vue
<!-- frontend/src/components/AgentDashboard.vue -->
<script setup lang="ts">
import { useAgentStream } from '@/composables/useAgentStream'

const { status, output, tokens, startAgent, isRunning } = useAgentStream()

async function handleRun() {
  await startAgent({
    task_type: 'content_review',
    input_data: { article_id: 42 }
  })
}
</script>

<template>
  <div class="p-6 bg-white rounded-2xl shadow-sm border border-slate-100">
    <div class="flex items-center justify-between mb-4">
      <h2 class="text-lg font-semibold text-slate-800">AI-агент: ревью контента</h2>
      <span
        :class="{
          'bg-amber-100 text-amber-700': status === 'running',
          'bg-emerald-100 text-emerald-700': status === 'success',
          'bg-red-100 text-red-700': status === 'failed',
        }"
        class="px-3 py-1 rounded-full text-sm font-medium"
      >
        {{ status }}
      </span>
    </div>

    <!-- Стримингový вывод агента -->
    <div
      v-if="output"
      class="bg-slate-50 rounded-xl p-4 font-mono text-sm text-slate-700
             whitespace-pre-wrap max-h-64 overflow-y-auto"
    >
      {{ output }}
    </div>

    <div class="mt-4 flex items-center justify-between">
      <span class="text-xs text-slate-400">Токенов использовано: {{ tokens }}</span>
      <button
        @click="handleRun"
        :disabled="isRunning"
        class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium
               hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed
               transition-colors"
      >
        {{ isRunning ? 'Выполняется...' : 'Запустить агента' }}
      </button>
    </div>
  </div>
</template>

Выводы: AI-Native — это архитектурное решение, а не набор фич

Собрать AI-Native приложение на Vue + Django + Docker с DeepSeek под капотом сегодня реально за 1–2 недели. Сложность не в технологиях — они зрелые и хорошо задокументированы. Сложность в инженерной дисциплине.

Ключевые тезисы:

  1. Агенты — это сервисы. Проектируйте их с моделью данных, статусами и логированием с первого дня.
  2. Изоляция воркеров — обязательна. Celery-очередь для AI отдельно от бизнес-задач.
  3. DeepSeek снижает стоимость входа. OpenAI-совместимое API позволяет переключаться между провайдерами без рефакторинга.
  4. Vue + Tailwind = идеальный UI для AI-контента. Модели генерируют валидные компоненты, Tailwind-классы модели знают отлично.
  5. OpenCode — ваш агент разработки. Используйте его для генерации boilerplate, но сохраняйте архитектурный контроль за командой.

Готовы перейти от экспериментов к продакшен-архитектуре? Начните с этих шагов сегодня:

  • Аудит существующих процессов: Определите 2–3 бизнес-процесса, которые выиграют от автономного AI-агента (не от чат-бота).

  • Стартовый стек: Разверните docker-compose с Django + Celery + Redis за один день — это ваш фундамент для агентов.

  • Попробуйте DeepSeek: Замените ваш текущий LLM-провайдер на DeepSeek API и измерьте разницу в стоимости и качестве для вашего use case.

Обсудить AI-Native архитектуру для вашего проекта

FAQ: Частые вопросы об AI-Native стеке

Чем AI-агент в Celery лучше, чем просто вызов OpenAI API в Django view?

View — синхронный, блокирующий, без состояния. Запрос к LLM на 20 секунд убьёт ваш веб-сервер при нагрузке. Celery-таска асинхронна, имеет retry-логику, сохраняет состояние в БД и не мешает обработке HTTP-запросов. Это разница между прототипом и продакшеном.

Почему DeepSeek, а не GPT-4o или Claude?

Для большинства задач в веб-приложениях (анализ данных, генерация контента, code review, классификация) DeepSeek-V3 даёт сопоставимое качество при стоимости в 10–30 раз ниже. GPT-4o и Claude Opus оправданы для задач, где разница в качестве критична. Правильный подход — маршрутизация по задачам, а не один провайдер для всего.

Нужен ли отдельный DevOps-специалист для такого стека?

Для старта — нет. Docker Compose на одном VPS справляется с нагрузкой до нескольких тысяч пользователей. DevOps нужен, когда вы переходите к Kubernetes и горизонтальному масштабированию воркеров под пиковую нагрузку агентов. До этого момента — сфокусируйтесь на продукте.