Качественно новое, что придумалось за 3 последних года во всем нашем GenAI, - это интерпретатор с любого языка (не только программирования) на любой другой язык. Мы его называем LLM. А раз так, то английский - теперь тоже интерпретируемый язык программирования (пусть и с вероятностной семантикой). Интерпретируемый в bash, python, java, json, xml - ровно как в английский, русский, немецкий, ровно как в user stories, хайку, эссе, письмо - в любой комбинации этих форматов. Можно попросить интерпретировать текст идеи в хайку на немецком, который выдаст текст на питоне, который напечатает текст на джаваскрипте, который будет вставлен внутрь сопроводительного письма в eml-формате. Изи (ну, почти).
Новый GenAI инженер - это во многом DevOps
А во многом из того, что мы делаем поверх этого, - очень много от DevOps-работы. Раньше DevOps-специалисты автоматизировали CI/CD на bash/batch, а сейчас любой может автоматизировать на английском любой SDLC. И новый тип инженера, о котором все говорят, - это во многом DevOps-мышление. По сути: прийти на проект, разобраться в SDLC pipeline и тулах, которые использует команда. Автоматизировать его. Показать команде, на какие кнопочки нажимать, чтобы все летело. И потом просто на 15% ассайнмента поглядывать за пайплайном, чтобы не свалился, и если появятся новые требования - оперативно их дореализовать. Коллеги DevOps - поправьте, если не прав.
Это подтверждается и на практике. Во время коучинга, который провожу каждый день, единственная аудитория, которая не удивляется так же, как все, - это DevOps. Все в "щенячьем восторге" от создания всяких DarkFactory, а вот DevOps - "да ладно, мы это всегда делали, просто не все можно было в bash/batch уложить оперативно". Раз так, то давайте переиспользовать многолетний опыт DevOps-специалистов.
Промпт - это исходный код
И второе - раз уж мы относимся к любому тексту как к исходному коду на языке (программирования). Не важно, это ваши данные, вытянутые скиллом из бинарника xls. Или тот же смысл, переданный текстом письма на русском. Или программа, написанная на питоне, делающая то же самое. И мы все программируем. Во многом программируем сейчас в процедурном стиле, создавая маркдаун-документы - читай, процедуры и функции. Так почему бы не переиспользовать все те накопленные знания и умения за последние лет 50 в области программирования? Те же базовые SRP, OCP, DRY, KISS и так далее - вплоть до более сложных, только применительно к новым интерпретируемым благодаря LLM языкам. Простой пример: одна и та же инструкция, повторяющаяся в пяти промптах, - это нарушение DRY, и лечится оно ровно так же, как в коде.
Отсюда следует ещё один важный момент. В мире, где все генерируется из ваших промптов, ваши промпты - и есть source code. Организуйте и храните его в кодовой базе - с версионированием, ревью и историей изменений. Например я использую
iterative prompt для общения с агентами. Теперь всегда можно посмотреть как любой участник пришел к тому результату, который мы наблюдаем. Теперь больше не будет вопроса у QA как и почему Dev сделал такой фикс. Теперь можно всегда спросить у агента, гдие и когда такое решение было принято.
Всё сводится к тексту, а текст - к Unix
Все, что можно свести к тексту сегодня, - будет сведено. Потому что текст - это программа. Бинарник (xls, mp4, zip, docx) сводится к тексту с помощью другого текста - программы на питоне с подключением определенной opensource-библиотеки, организованной в Skills. Если нужно достать данные откуда угодно - тот же Skills в помощь. Skill - это сейчас как Unix tools.
И тут стоит напомнить, откуда растут ноги. Принципы Unix были сформулированы Дугом МакИлроем (создатель pipe в Unix) и развиты в культуре Bell Labs. Классическая формулировка:
- Do one thing and do it well. Одна утилита - одна задача.
grep ищет, sort сортирует, wc считает. Не пытаться сделать швейцарский нож. - Write programs to work together. Утилиты должны быть комбинируемыми. Выход одной - вход другой. Отсюда пайпы:
cat file | grep error | sort | uniq -c. - Write programs to handle text streams, because that is a universal interface.
Текст - универсальный интерфейс. Не бинарные форматы, не проприетарные протоколы. Простой текст, который читается человеком и парсится другой программой.
Дополнительные принципы (из «The Art of Unix Programming» Эрика Реймонда):
- Rule of Modularity - пиши простые части, связанные чистыми интерфейсами.
- Rule of Composition - проектируй так, чтобы можно было соединять с другими программами.
- Rule of Separation - отделяй политику от механизма (что делать - от того, как).
- Rule of Simplicity - проектируй в сторону простоты, добавляй сложность только когда обязан.
- Rule of Silence - если программе нечего сказать, она должна молчать (никакого лишнего output).
- Rule of Least Surprise - интерфейс должен быть предсказуемым.
- Rule of Repair - если что-то сломалось, ломайся громко и сразу.
Skill - это package, а не откровение
Концепция Skills очень мне близка с другой, уже известной нам концепцией - package. Любой проект состоит из кирпичей, пакетов. Каждый пакет делает что-то полезное и стоит особняком. Пакет может зависеть от другого пакета. Пакет дает публичный интерфейс и прячет реализацию. Добавьте к пакету Skill.md (как документацию) и снабдите CLI-интерфейсом - и вот вам Skill. А что такое этот Skill.md - это индекс для модельки над внутренностями пакета, чтобы ей не приходилось загружать все файлы в контекст. Это документация, и она дублирует поведение, а значит устаревает. Были бы у нас бесконечные контексты, мы бы не писали эти индексы. Ну то есть в Skill-концепции не так уж и много нового по сути. А раз так, зачем изобретать колесо? Переиспользуем то, что мы уже знаем.
И может быть, MCP тогда не понадобится
Если принять эту оптику, может быть, и не появится таких штук, как MCP - напрочь искусственных и очень молодых, а значит, не продуманных интерфейсов. Ведь он первый появился в ответ на «нам надо USB между агентными упряжками и остальным миром как провайдерами контекста». Придумали целый протокол. SDK на сервере, SDK на клиенте. К нашему старому доброму REST надо добавить точно такой же сервис, дублирующий API, но через MCP. Потом кто-то подумал: а почему бы не переиспользовать REST? Пишем тонкого клиента - и все.
MCP уйдет. Не только по этой причине. А еще и потому, что тулу в Skill можно сделать такой, которая будет читать файл, класть результат выполнения в другой файл, и при этом моделька не будет вмешиваться (читать, интерпретировать) в эти данные. После этого вторая Skill прочитает файл, превратит его в другой. А моделька - как оркестратор. А вот если окажется, что и сам путь оркестрации уже устаканился - его можно упаковать в pipeline, используя любой доступный для этого конфигурируемый фреймворк.
Отсюда и градация по цене и детерминизму. Можно открыть чат с агентом, выбрать Claude Opus и попросить сделать работу - будет дорого, но сделает. Можно попросить написать скрипты в Skill, которые будут переиспользуемыми и передавать работу друг другу через файлы. Можно попросить сделать упряжку для всего пайплайна. Модельку оставить только там, где детерминированный код невозможно написать.
Вывод: мы не изобретаем - мы переоткрываем
Мы уже сгенерировали столько принципов за последние 60 лет. Я лишь хочу о них всех напомнить. Мы не делаем что-то новое. Мы получили «интерпретатор» с любого языка на любой и дотянулись до новых видов автоматизации. Моделька усиливает вашу мысль 10-кратно. Причем читает модель ее между строк вашего промпта. Потому я попытался напомнить нам про все концепции, которые уже были придуманы ранее. Держа их в голове, модель сгенерирует другой ответ.
Любые эксперименты - ок, ведь можно открыть что-то новое. Но база посыла в том, что на 90% мы пытаемся пересоздать в GenAI старые концепции, хотя надо их переиспользовать.