Продвинутый

DietrichGebert/ponytail: AI agent thinks like lazy senior...

Алексей Кузнецов
Алексей Кузнецов
Системный администратор12 ноября 2026 г.10 мин чтения

AI‑agent, inspired by the laziest senior developer, writes minimal code that just works, using clever shortcuts and automation to avoid unnecessary work.

DietrichGebert/ponytail: AI agent thinks like lazy senior dev

AI‑agent, inspired by the laziest senior developer, writes minimal code that just works, using clever shortcuts and automation to avoid unnecessary work.

Принцип «ленивого» senior dev в AI‑agent

### Оптимизация запросов через шаблоны

Для уменьшения количества токенов и ускорения взаимодействия с моделью удобно заранее готовить шаблоны запросов. Шаблон задаёт структуру диалога: системное сообщение описывает роль, пользователь — конкретную задачу, а при необходимости добавляются примеры few‑shot.

bash
# пример шаблона в файле prompt_template.txt
SYSTEM: You are a helpful assistant that optimizes infrastructure code.
USER: <task_description>
ASSISTANT: <generated_response>
yaml
# пример использования в скрипте на Python
import json

with open('prompt_template.txt') as f:
    template = f.read()

payload = {
    "messages": [
        {"role": "system", "content": template.split('USER:')[0].strip()},
        {"role": "user", "content": "<task_description>"}
    ]
}

# отправка запроса
resp = client.chat.completions.create(**payload)

Сохраняя шаблон в отдельный файл, вы избавляетесь от повторного ввода одинаковых системных инструкций и можете быстро менять их без перезапуска кода.

Локальные ИИ-агенты и инструменты описывают подходы к организации таких шаблонов в продакшене.

affaan-m/ECC: AI Agent Harness Performance Optimization показывает, как измерять влияние шаблонов на latency и throughput.

### Минимальный код — только необходимое

Ленивый senior dev пишет код, который делает ровно то, что требуется, и ничего лишнего. Пример — Dockerfile, где используется минимальный базовый образ и копируются только нужные файлы.

dockerfile
# Dockerfile
FROM alpine:3.18

# копируем только необходимый скрипт
COPY optimize.sh /usr/local/bin/optimize.sh
RUN chmod +x /usr/local/bin/optimize.sh

# задаём точку входа
ENTRYPOINT ["/usr/local/bin/optimize.sh"]
bash
# одноимённый скрипт, минимальный набор команд
#!/usr/bin/env bash

# проверяем, что контейнер запущен с нужными переменными
if [[ -z "$TARGET_HOST" || -z "$TARGET_PORT" ]]; then
    echo "Ошибка: переменные TARGET_HOST и TARGET_PORT не заданы" >&2
    exit 1
fi

# основная логика в 5 строках
curl -s "http://$TARGET_HOST:$TARGET_PORT/health" | grep -q ok && echo "OK" || echo "FAIL"

В примерах выше видно, что каждый файл содержит минимум строк, а всё, что не влияет на результат, удалено.

Claw-code: автономный музейный экспонат на Rust демонстрирует, как в Rust‑проектах поддерживать минимальный набор зависимостей, что уменьшает размер образа и ускоряет сборку.

Оптимизация ИИ-агентов с помощью системы ECC описывает методы профилирования кода и выявления избыточных участков, которые можно убрать в pursuit минимальности.

Автоматизация рутинных задач

Скрипты‑заготовки в Ponytail

В Ponytail удобно держать набор готовых скриптов, которые решают типовые задачи без лишних уточнений.
Во‑первых, удобно хранить их в отдельном репозитории, чтобы можно было быстро копировать и адаптировать под конкретный сервер.
С практической точки зрения скрипт‑заготовка выглядит так:

bash
#!/usr/bin/env bash
# backup_home.sh – создаёт резервную копию домашнего каталога на TrueNAS

set -euo pipefail

SRC="${HOME}"
DEST="backup@truenas:/mnt/backup/${HOSTNAME}/$(date +%Y%m%d)"
LOG="/var/log/ponytail/backup_home.log"

mkdir -p "$(dirname "$LOG")"

rsync -a --delete "$SRC/" "$DEST/" >>"$LOG" 2>&1
echo "$(date '+%F %T') – backup completed" >>"$LOG"
  • Что делает скрипт:
    • берёт переменную SRC – каталог, который нужно защитить;
    • формирует целевой путь DEST на TrueNAS, используя текущую дату;
    • логгирует действия в системный журнал.

Для автоматизации запуска удобно создать systemd‑таймер:

ini
# /etc/systemd/system/ponytail-backup.service
[Unit]
Description=Ponytail backup service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup_home.sh
ini
# /etc/systemd/system/ponytail-backup.timer
[Unit]
Description=Run Ponytail backup daily at 02:00

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

После systemctl enable --now ponytail-backup.timer скрипт будет запускаться автоматически, а systemd будет следить за его состоянием и писать в journalctl.

Ссылка на материал о локальных ИИ‑агентах и инструментах – Локальные ИИ‑агенты и инструменты
Ссылка на статью о Claw‑Code – Автономная разработка на Rust с помощью Claw-Code


CI/CD без лишних шагов

Минимальная CI/CD‑конфигурация позволяет быстро проверять код, собирать образы и публиковать их без лишних стадий.
Во‑первых, достаточно одного workflow‑файла в .github/workflows/.
С практической точки зрения такой файл выглядит так:

yaml
name: CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASS }}

      - name: Build and push image
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: myregistry.example.com/ponytail-app:${{ github.sha }}
  • Что делает workflow:
    • запускается при пуше в main или PR;
    • проверяет код, собирает Docker‑образ с помощью Buildx;
    • авторизуется в Docker‑реестре через секреты;
    • пушит образ с тегом, содержащим короткий SHA‑коммит.

Для упрощения проверки тестов можно добавить pre‑commit hook, который запускает pytest локально перед коммитом. Пример .pre-commit-config.yaml:

yaml
repos:
  - repo: local
    hooks:
      - id: run-tests
        name: Run pytest
        entry: pytest
        language: system
        pass_filenames: false

Ссылка на оптимизацию агентов с помощью системы ECC – Оптимизация ИИ‑агентов с помощью системы ECC
Ссылка на автономный музейный экспонат на Rust – Claw-code: автономный музейный экспонат на Rust


Итог:
Скрипты‑заготовки в Ponytail позволяют быстро решать рутинные задачи, а минимальная CI/CD‑конфигурация обеспечивает предсказуемость и надёжность сборки без лишних стадий. Оба подхода работают одинаково хорошо в домашней лаборатории и в продакшене.

Интеграция с Claude‑Code

Настройка prompt‑engineering

Во-первых, prompt‑engineering — это не просто «написать просьбу», а формировать запрос так, чтобы модель поняла точный формат и контекст результата. Минимальный, но информативный запрос выглядит так:

text
Generate a docker‑compose.yml file for a home lab containing:
- plex service using the latest plexinc/plex-media-server image
- nextcloud service using the nextcloud Docker image
- backup service using alpine with a cron job that rsync /home to /backup
Use environment variables for PLEX_CLAIM and NEXTCLOUD_ADMIN_USER.

Сокращённый вариант, который удобно копировать в интерфейс Claude‑Code:

bash
cat > prompt.txt <<'EOF'
Generate a docker‑compose.yml for plex, nextcloud and a backup container.
Specify the latest images, set required environment variables, and expose ports.
EOF

Локальные ИИ‑агенты и инструменты описывают подробно, как формировать такие запросы, включая примеры для разных сценариев.

С практической точки зрения, при работе с claude‑code полезно задавать ограничение на количество строк в результате. Например, добавить в конец запроса:

Result must not exceed 30 lines.

Это предотвращает «размывание» вывода и упрощает последующее копирование в файл.

Автоматический генератор конфигураций

С deuxième perspective, генерация конфигураций вручную быстро выходит из-под контроля. Автоматизировать её можно с помощью небольших скриптов, которые берут шаблон и подставляют переменные. Ниже пример Bash‑скрипта, создающего конфиги Nginx для нескольких доменов:

bash
#!/usr/bin/env bash
# generate_nginx_conf.sh
# Usage: ./generate_nginx_conf.sh example.com test.local

DOMAINS=("$@")
for DO in "${DOMAINS[@]}"; do
  cat <<EOF > nginx_${DO}.conf
server {
    listen 80;
    server_name ${DO};
    root /var/www/${DO};
    index index.html;
}
EOF
done

Запуск выглядит так:

bash
./generate_nginx_conf.sh example.com test.local

Полученные файлы можно сразу поместить в /etc/nginx/conf.d/ и выполнить nginx -s reload. Такой подход гарантирует, что каждый домен имеет одинаковую структуру, а изменения в шаблоне мгновенно отражаются во всех конфигах.

Для более сложных сценариев удобно использовать Python‑скрипт, который читает CSV‑файл со списком параметров и генерирует конфиги Docker‑Compose. Пример кода:

python
import csv

with open('services.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"  {row['service']}:")
        print(f"    image: {row['image']}")
        print(f"    ports: [{row['host_port']}:{row['container_port']}]")
        if row['env']:
            print(f"    environment: {row['env']}")

Файл services.csv может выглядеть так:

service,image,host_port,container_port,env
plex,plexinc/plex-media-server,32400,32400,PLEX_CLAIM=myclaim
nextcloud,nextcloud,8080,80,NEXTCLOUD_ADMIN_USER=admin
backup,alpine,9000,9000,CRON="0 2 * * * rsync -a /home/ /backup/"

affaan-m/ECC: AI Agent Harness Performance Optimization показывает, как такие скрипты могут быть интегрированы в CI/CD, обеспечивая проверку корректности сгенерированных файлов перед применением.

В итоге, чётко сформированный prompt и автоматизированный генератор конфигураций позволяют сократить время разработки и повысить предсказуемость серверных решений.

Практика в домашней лаборатории

Docker‑Compose для изоляции сервисов

Во-первых, Docker Compose позволяет описать весь стек приложения в одном файле и гарантировать, что каждый сервис работает в отдельном контейнере. Это избавляет от конфликтов зависимостей и упрощает масштабирование. С практической точки зрения я обычно выделяю сеть для каждого проекта, чтобы трафик не «переполз» в соседние сервисы.

yaml
version: "3.9"
services:
  plex:
    image: linuxserver/plex
    container_name: plex
    restart: unless-stopped
    network_mode: "bridge"
    ports:
      - "32400:32400/tcp"
    volumes:
      - "/mnt/tank/media:/config"
      - "/data/media:/data"

  nextcloud:
    image: linuxserver/nextcloud
    container_name: nextcloud
    restart: unless-stopped
    network_mode: "bridge"
    ports:
      - "8080:80"
    volumes:
      - "/mnt/tank/nextcloud:/config"
      - "/data/nextcloud:/var/www/html/data"

  backup-agent:
    image: ghcr.io/taikayes/taikachedule:latest
    container_name: backup-agent
    restart: unless-stopped
    network_mode: "bridge"
    environment:
      - TZ=UTC
    volumes:
      - "/etc/backup:/etc/backup"

Команда docker compose up -d поднимает все сервисы в фоне, а docker compose down безопасно останавливает их без потери данных. Если нужно изолировать сервис от внешнего мира, достаточно добавить networks: и задать внутреннюю сеть без публикации портов.

Для справки, подробный пример использования Docker Compose в домашней лаборатории можно посмотреть в статье Локальные ИИ-агенты и инструменты.


ZFS‑хранилище с авто‑бэкапами

ZFS — это файловая система, которая сама управляет снимками (snapshot) и проверкой целостности данных. Автобэкапы делаются простым скриптом, который создаёт снимок, отправляет его на резервный хост и очищает старые снимки.

bash
#!/usr/bin/env bash
# /usr/local/bin/zfs-snapshot.sh

set -euo pipefail

ZFS_POOL="tank"
DATASET="tank/data"
BACKUP_HOST="backup-host"
BACKUP_PATH="backup/tank/data"

# Текущая дата в формате YYYY-MM-DD
SNAP_NAME="${DATASET}@$(date +%Y-%m-%d)"

# Создаём снимок
zfs snapshot -r "${SNAP_NAME}"

# Отправляем снимок на резервный хост
zfs send -R "${SNAP_NAME}" | ssh "${BACKUP_HOST}" "zfs receive -F ${BACKUP_PATH}"

# Удаляем снимки старше 30 дней
zfs list -t snapshot -o name -s creation "${DATASET}" | \
  grep -E "@[0-9]{4}-[0-9]{2}-[0-9]{2}$" | \
  while read -r snap; do
    if [[ $(date -d "$(echo "${snap}" | cut -d'@' -f2)" +%s) -lt $(date -d '30 days ago' +%s) ]]; then
      zfs destroy "${snap}"
    fi
  done

Скрипт добавляем в cron, например:

0 2 * * * /usr/local/bin/zfs-snapshot.sh >> /var/log/zfs-snapshot.log 2>&1

Эта запись будет запускаться каждый день в 02:00 UTC, создавая новый снимок и отправляя его на резервный сервер. При необходимости можно добавить проверку доступности резервного хоста (ping или nc) перед запуском zfs send.

Для более глубокой настройки автобэкапов и мониторинга снимков полезна статья Оптимизация ИИ-агентов с помощью системы ECC, где рассматриваются аналогичные подходы в контексте автоматизации.


Если понадобится более детальная настройка сети Docker Compose или интеграция ZFS‑резервного хранилища с другими сервисами, дайте знать — я подготовлю дополнительные примеры.

Часто задаваемые вопросы

Как создать эффективный шаблон запроса для AI‑agent и сократить количество токенов?

Во‑первых, оформите системное сообщение в виде короткой роли, описывающей задачу (например, «оптимизировать Docker‑образ»).
Во‑вторых, оставьте описание задачи в USER‑сообщении максимально лаконичным, указывая только необходимые параметры.
В‑третьих, добавляйте примеры few‑shot лишь при сложных сценариях, иначе они увеличат токенов без пользы.

Что подразумевается под «минимальным кодом» в AI‑agent и как это выглядит на практике?

Во‑первых, минимальный код — это набор команд, которые делают ровно то, что требуется, без лишних слоёв и повторов.
Во‑вторых, в Dockerfile это значит выбрать самый лёгкий базовый образ, копировать только нужные файлы и объединять RUN‑инструкции там, где это возможно.
В‑третьих, такой подход уменьшает размер образа, ускоряет сборку и упрощает последующее обслуживание.

Насколько полезна оптимизация запросов через шаблоны с точки зрения производительности?

Справедливо, шаблоны позволяют фиксировать системные инструкции один раз и переиспользовать их, что снижает количество токенов в каждом запросе.
С другой стороны, излишне громоздкие шаблоны могут увеличить размер контекста и замедлить отклик модели.
Поэтому рекомендуется измерять latency и throughput, как показано в affaan‑mecc‑ECC, и корректировать шаблон в зависимости от результатов.

Какие подводные камни могут возникнуть при использовании «ленивого» подхода в AI‑agent?

Во‑первых, чрезмерная лаконичность может привести к упущению важных деталей, из‑за чего агент будет генерировать некорректный код.
Во‑вторых, отсутствие тестирования и проверки крайних случаев делает такие решения хрупкими в продакшене.
В‑третьих, без документирования шаблонов и минимального кода сложно поддерживать их в дальнейшем, что противоречит принципу предсказуемости.

Поделиться:TelegramX / TwitterVK

Читайте также