Аккуратно даем LLM контекст проекта. Go.. Go. json.. Go. json. llm.. Go. json. llm. vibe coding.. Go. json. llm. vibe coding. vibecoding.. Go. json. llm. vibe coding. vibecoding. искусственный интеллект.. Go. json. llm. vibe coding. vibecoding. искусственный интеллект. Программирование.

Привет, на связи Лука.

Знаете, есть такая поговорка: “тише едешь – дальше будешь”. Работая с LLM, я пришёл к выводу, что аккуратность и точность в подаче контекста – это один из самых важных ключиков к хорошему результату. Иначе получится как в другой поговорке – про дурака и стеклянный орган.

Чего греха таить – все мы пользуемся LLM в различных ситуациях. От генерации бойлерплейта до неожиданного, но изящного решения сложной логики. Ничего такого – очередной инструмент, которым можно, как молотком, забить гвоздь, а можно и… ну, вы поняли.

Но когда речь заходит о системе, в которой контекст содержится не в одном, не в двух, и даже не в десятке файлов – вопрос становится ребром. Просто скормить модели весь проект? Ну, можно, конечно. Модель, захлебнувшись в потоке зачастую ненужной информации, вряд ли выдаст что-то вменяемое. Она потратит драгоценные вычислительные ресурсы на анализ совершенно нерелевантных частей. Неэкологичненько.

А если как-то по-другому? Может, вручную отбирать файлы? Это мучительно долго, особенно если структура проекта ветвистая. К тому же, легко что-то упустить. Может, архивировать нужное и прикреплять архив? Тоже вариант, но не все LLM-интерфейсы это гладко переваривают, да и предварительная подготовка всё равно нужна.

Когда ты фулстек и горишь идеей быстренько поправить и контроллер, и репозиторий, и сервисный слой, и пару DTO, да ещё и на фронте композиты подправить под новый эндпоинт – вот тут-то и понимаешь, что существующие подходы к подаче контекста LLM напоминают попытку просунуть верблюда в игольное ушко.

Тогда у меня и родилась идея сборщика файлов, которая со временем, как снежный ком, начала обрастать новым функционалом.

Представляю вам projectson – утилиту на Go, которая собирает выбранные файлы вашего проекта в один аккуратный JSON-файл.

Почему именно JSON?

Да всё просто:

  • Компактность: JSON – это текстовый формат, но при должной обработке (о чём ниже) он может быть весьма лаконичным.

  • Удобство для LLM: Большинство современных LLM отлично понимают JSON. Его можно скормить модели как единый файл, что гораздо удобнее, чем вставлять километровые листинги кода в текстфилд, в результате чего весь интерфейс пыхтит и кряхтит в процессе рендера сего действа.

  • Структурированность: JSON сам по себе структурирован, что помогает модели лучше разделять и понимать отдельные фрагменты кода или текста.

Политика максимального сохранения контекстного окна

Одна из главных фишек – это стремление максимально эффективно использовать ограниченное контекстное окно LLM. Для этого предусмотрены:

  • Опции для вырезки “мусора”: Можно настроить правила для удаления из файлов определённых участков кода или текста (например, комментарии, ненужные в контексте текущего вопроса блоки).

  • Удаление лишних пробелов и переносов строк (по умолчанию): Автоматически сжимаем содержимое файлов, удаляя множественные пробелы и лишние переносы строк, заменяя их на одиночные пробелы. Это сокращает объём текста без потери семантики (для большинства языков программирования – привет, python). В будущем планируется добавить возможность более тонкой настройки этого процесса.

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

Философия и формат конфигурации

Сборка JSON-файла конфигурируется простым YAML файлом, который описывает, что и как собирать.

  1. root (Корневой путь):

    • Тип: String

    • Обязательно: Да

    • Описание: Абсолютный путь к корневой директории вашего проекта.

    • Пример:

      root: "/path/to/your/project" 
      # На Windows:
      # root: "C:\Users\YourName\Projects\MyProject"
      
  2. include (Что включаем):

    • Тип: List of Strings

    • Обязательно: Нет (По умолчанию сканируется вся root директория, с учётом formats и exclude_patterns)

    • Описание: Список файлов или директорий для включения. Пути указываются относительно root. Каждый элемент может определять путь и режим сбора:

      • "path/to/item": Собирает и путь, и содержимое (режим по умолчанию both). Если item – директория, сканируется рекурсивно.

      • "path/to/item:path": Собирает только путь.

      • "path/to/item:content": Собирает только содержимое.

      • "path/to/directory/*": Собирает файлы непосредственно внутри path/to/directory (нерекурсивно), режим по умолчанию both.

      • "path/to/directory/*:mode": Аналогично предыдущему, но с указанным режимом (path или content).

    • Пример:

      include:
        - "src"                   # Включить всё из src/, рекурсивно, путь и контент
        - "README.md:content"     # Только контент из README.md
        - "assets/*:path"         # Только пути файлов из assets/ (нерекурсивно)
        - "docs/api.md"           # Путь и контент docs/api.md
      
  3. formats (Форматы файлов):

    • Тип: List of Strings

    • Обязательно: Да

    • Описание: Список расширений файлов (без точки), которые нужно включать.

    • Пример:

      formats:
        - "go"
        - "vue"
        - "ts"
        - "js"
        - "py"
        - "html"
      
  4. output (Выходной файл):

    • Тип: String

    • Обязательно: Да

    • Описание: Полный путь к выходному JSON-файлу.

    • Пример:

      output: "project_data_output.json"
      # output: "/tmp/my_project_collection.json"
      
  5. exclude_patterns (Паттерны исключения по имени):

    • Тип: List of Strings

    • Обязательно: Нет

    • Описание: Список паттернов для исключения файлов или директорий. Применяются после правил include и formats.

      • Glob-паттерны: Стандартные (например, node_modules, .log, dist/). Метчатся по имени файла/директории или по относительному пути.

      • Регулярные выражения: Go-совместимые, должны быть заключены в слеши (например, /.git/, /private_.*.key$/).

    • Пример:

      exclude_patterns:
        - "node_modules"
        - ".git"
        - "*.min.js"
        - "dist"
        - "/test_data/" # Regex для исключения папок с именем test_data
        - "/^\.(svn|hg|DS_Store)/" # Regex для служебных файлов
      
  6. content_exclusions (Исключения содержимого из файлов):

    • Тип: List of Objects

    • Обязательно: Нет

    • Описание: Список правил для удаления определённых секций внутри файлов перед их добавлением в JSON. Это главное отличие от exclude_patterns, которые работают с именами файлов/папок.

      • type (String, Обязательно): delimiters (по начальному и конечному тегам) или regexp (по регулярному выражению).

      • file_pattern (String, Обязательно): Glob-паттерн, на какие файлы (по расширению или имени файла, если оно уникально как расширение) применять правило. * – для всех файлов, подходящих под formats. Метчится с расширениями (vue) или расширениями с точкой (.vue).

      • start (String, Опционально): Для type: "delimiters". Начальный тег.

      • end (String, Опционально): Для type: "delimiters". Конечный тег.

      • pattern (String, Опционально): Для type: "regexp". Регулярное выражение.

    • Пример:

      content_exclusions:
        - type: "delimiters"
          file_pattern: "*.vue"  # или просто "vue"
          start: "<style>"
          end: "</style>"
        - type: "regexp"
          file_pattern: "*.js"  # или "js"
          pattern: "(//.*)|(/\*[\s\S]*?\*/)" # Удалить JS комментарии
        - type: "regexp"
          file_pattern: "*" # Для всех типов файлов
          pattern: "SECRET_API_KEY = '.*?'" # Удалить строку с секретным ключом
      

Пример конфигурационного файла projectson_config.yaml:

root: "/Users/username/goprojects/my-awesome-app"
include:
  - "cmd"
  - "internal/services"
  - "internal/models:content" # Только контент моделей
  - "pkg/*:path"              # Только пути из pkg
  - "README.md"
  - "go.mod"
  - "main.go"
formats:
  - "go"
  - "md"
  - "mod"
output: "./collected_project_context.json"
exclude_patterns:
  - "internal/services/legacy_service.go" # Исключить конкретный файл
  - "/.*_test\.go$/"                      # Исключить все тестовые файлы (regex)
  - "vendor"
  - "*.tmp"
content_exclusions:
  - type: "delimiters"
    file_pattern: "go" # Применить ко всем .go файлам
    start: "// @exclude-start"
    end: "// @exclude-end"
  - type: "regexp"
    file_pattern: "md" # Применить ко всем .md файлам
    pattern: "[\s\S]*?"

Не YAML единым: графический интерфейс

  • Config: Здесь вы можете указать основные параметры: root, formats, output, а также управлять списком include (добавлять, удалять, изменять пути и режимы) и exclude_patterns.

Аккуратно даем LLM контекст проекта - 1
  • Exclusions: Эта вкладка посвящена правилам content_exclusions. Вы можете добавлять новые правила, выбирать их тип (delimiters или regexp), указывать file_pattern и соответствующие параметры (start/end или pattern). Каждое правило наглядно представлено, и его легко отредактировать или удалить.

Аккуратно даем LLM контекст проекта - 2
  • Config Docs: Чтобы не держать всю структуру YAML в голове, на этой вкладке вы найдете подробную документацию по всем полям конфигурационного файла. Очень удобно, когда нужно быстро освежить назначение параметра.

Аккуратно даем LLM контекст проекта - 3
  • Preview: Прежде чем запускать полную сборку, вы можете посмотреть, какие именно файлы будут обработаны согласно текущей конфигурации. На этой вкладке отображается список файлов. Выбрав файл, можно увидеть его оригинальное содержимое и то, как оно будет выглядеть после применения правил content_exclusions. Это помогает отладить правила исключений и убедиться, что в итоговый JSON попадет только нужное.

Аккуратно даем LLM контекст проекта - 4
  • Run: Сборка JSON. Здесь вы видите краткую сводку текущей конфигурации и кнопку для запуска. После завершения можно сохранить результат.

Аккуратно даем LLM контекст проекта - 5
  • Stats: После каждого запуска (или успешного Preview) здесь собирается статистика: количество обработанных файлов, общий размер выходных данных, время выполнения. Также отображается распределение файлов по форматам, режимам сбора и размерам (на основе данных из последнего Preview), и активные правила content_exclusions.

Аккуратно даем LLM контекст проекта - 6

Что дальше?

Пилите YAML-конфиги и скармливайте результат нейросети. Сохраняйте и переиспользуйте свои конфиги.

Aistudio отлично читает такие JSON’ы. Копировать код пока приходится ручками – но есть задумки на получение от LLM ответа в виде JSON-патча.

Приглашаю вас на GitHub проекта. Предложения приветствуются.

Автор: looqey

Источник

Rambler's Top100