Я разместил ИИ-агент на VPS за 7 долларов в месяц, подключил его к своему IRC-серверу и указал на свои репозитории на GitHub. Посетители могут задать мне вопрос о моей работе и получить ответы, подкрепленные реальным кодом, а не перефразированным текстом резюме.
проблема с “спросить мое резюме”
Каждый сайт-портфолио с чат-ботом с искусственным интеллектом делает одно и то же: помещает резюме в модель и позволяет посетителям перефразировать его. Это салонный трюк. Модель не может сказать вам ничего, чего еще не сказано в резюме.
Я хотел чего-то другого. Если менеджер по найму спрашивает: «Как Джордж справляется с тестированием?» ответ не должен быть таким: «Джордж ценит комплексное тестирование». Он должен клонировать репозиторий, подсчитать тесты, прочитать конфигурацию CI и вернуться с подробностями.
Поэтому я создал инфраструктуру, чтобы это работало.
архитектура
Два агента, два ящика, две границы безопасности.
visitor (browser)
│
└─ georgelarson.me/chat/
│
└─ gamja web IRC client
│
└─ wss://nullclaw.georgelarson.me:443
│
└─ Cloudflare (proxy, TLS termination, bot protection)
│
└─ ergo IRC server (LarsonNet)
│
└─ #lobby
│
└─ nully (nullclaw agent)
├── reads public GitHub repos
├── preloaded portfolio context
└── routes to ironclaw via #backoffice
│
└─ #backoffice (private IRC channel)
│
└─ ironclaw (separate box, via Tailscale)
├── email access
├── calendar
└── private context
нулевой коготь — швейцар, стоящий перед публикой. Он работает на корпусе с минимальным периметром, двоичном файле Zig размером 678 КБ, используя около 1 МБ ОЗУ. Он обрабатывает приветствия, отвечает на вопросы о моих проектах и может клонировать репозитории, чтобы подкрепить утверждения реальным кодом.
железный коготь является частным агентом в отдельной, более мощной системе. Он имеет доступ к электронной почте, более глубокому личному контексту и обрабатывает сложные запросы, направляемые из nullclaw. Эта граница намеренна: публичный ящик не имеет доступа к личным данным.
почему IRC
Я мог бы использовать Discord, Telegram или собственный чат WebSocket. IRC — правильный выбор по трем причинам:
- Это соответствует эстетике. Мой сайт-портфолио имеет пользовательский интерфейс терминала. Встроенный в него IRC-клиент является фирменным. Дискорд был бы неправильным.
- Я владею всей стопкой. Ergo IRC-сервер, веб-клиент gamja, агент nullclaw — все в моей инфраструктуре. Никакого стороннего API, который меняет свои условия, никакой платформы, которая решает прекратить доступ к ботам.
- Это протокол 30-летней давности. IRC прост, понятен и не привязан к поставщику. Тот же агент, который общается с посетителями через веб-клиент, может общаться со мной через irssi с терминала.
Выбор модели как дизайнерское решение
Именно здесь большинство людей выбирают самую большую модель, которую они могут себе позволить. Это неправильный инстинкт для швейцара.
разговорный уровень: Haiku 4.5
Приветствую, сортирую, простые вопросы о моем прошлом. Реакция менее секунды. Копейки за разговор. Здесь скорость важнее глубины.
уровень использования инструментов: Sonnet 4.6 (резервный вариант)
Когда null необходимо клонировать репозиторий, прочитать код или синтезировать результаты по файлам, в дело вступает Sonnet. Вы платите за рассуждения только тогда, когда рассуждения необходимы.
ограничение стоимости: 2 доллара США в день.
Публичный агент без лимита расходов является обязательством. Колпачок предотвращает как беглые разговоры, так и оскорбления. Если кто-то попытается сжечь мой бюджет на умозаключения, он упрется в стену.
сигнал портфеля
Использование Opus в качестве консьержа означало бы противоположное понимание модели. Если Haiku справится с этим, не отправляйте его в Sonnet. Многоуровневый вывод (дешево для быстрого пути, способный выполнять тяжелую работу) — вот как я держу эту сумму ниже 2 долларов в день.
состояние безопасности
Эта коробка представляет собой публичный периметр. Он должен быть закален как один.
- СШ: Пользователь без полномочий root с аутентификацией только по ключу на нестандартном порту. Рут-вход отключен.
- Брандмауэр: UFW имеет только три открытых порта: SSH, IRC (TLS) и HTTPS (WebSocket через Cloudflare).
- Прокси Cloudflare: Веб-посетители никогда не попадают в поле напрямую. Трафик WebSocket проходит через границу CF, которая обрабатывает завершение TLS, ограничение скорости и фильтрацию ботов.
- Песочница агента: nullclaw работает в контролируемом режиме с доступом к файлам только в рабочей области, ограниченным списком разрешенных команд (инструменты только для чтения) и максимум 10 действиями в час.
- Контроль затрат: Жесткие ограничения: 2 доллара США в день, 30 долларов США в месяц. Если агент подвергается злоупотреблениям, бюджет исчерпается до того, как ущерб увеличится.
- Журнал аудита: Каждый вызов инструмента протоколируется.
- Автоматические обновления: Автоматические обновления безопасности включены.
- ТЛС: Let’s Encrypt с автоматическим продлением и перезапуском служб.
Философия – минимальная поверхность атаки. Этот ящик запускает две службы (ergo и nullclaw), не обслуживает веб-контент напрямую и не имеет доступа к личным данным. Если он будет скомпрометирован, радиусом взрыва станет IRC-бот с бюджетом на вывод 2 доллара в день.
стек связи
Каждый компонент небольшой, автономный и заменяемый:
- Следовательно: IRC-сервер. Бинарный файл Single Go, 2,7 МБ ОЗУ. Управляет TLS, WebSocket, регулированием соединения, маскировкой IP.
- гамджа: Веб-IRC-клиент. Построено 152 КБ. Служит статической страницей на сайте портфолио Cloudflare. Автоматическое подключение к #lobby под ником случайного посетителя.
- нулевой коготь: Время выполнения агента ИИ. 4 МБ двоичного Zig-файла, ~1 МБ пикового RSS. Подключается к ergo как IRC-клиент, обрабатывает сообщения через LLM, отвечает внутри канала.
Общий объем: менее 10 МБ двоичных файлов, менее 5 МБ ОЗУ в режиме ожидания. Это работает на самом дешевом доступном уровне VPS.
что на самом деле может сделать null

Вот та часть, которая отличает его от чат-бота:
- «Какие языки использует Джордж?» Не повторяет резюме. Знает из предварительно загруженного контекста и может проверить, проверив репозитории.
- «Как он структурирует тесты?» Клонирует репозиторий, читает тестовые файлы и сообщает о том, что находит.
- «Расскажи мне о переломе» Черпает из предзагруженной памяти о проекте, может покопаться в исходниках для уточнения.
- «Как мне связаться с ним?» Предоставляет контактную информацию. Не галлюцинирует номер телефона.
- «Могу ли я запланировать звонок?» Nully вызывает Ironclaw по протоколу Google A2A через Tailscale. Ironclaw обрабатывает запрос с помощью собственного LLM, отправляет обратно структурированный ответ и не передает ответ. Посетитель никогда не видит передачи.
Это IRC-бот, поддерживаемый Haiku, поэтому он не идеален. Но он подтверждает то, что говорит, кодом, а мое резюме не может этого сделать.
реализация A2A
Это та часть, которой я горжусь больше всего.
nullclaw уже обслуживает протокол Google A2A (v0.3.0): обнаружение карт агентов, отправка JSON-RPC, конечный автомат задач. Чего у него не было, так это клиент. Он мог принимать вызовы A2A, но не мог их совершать. Поэтому я написал один.
a2a_call инструмент отправляет message/send JSON-RPC запрашивает удаленные агенты, анализирует ответ задачи (завершен, сбой, работает), извлекает текст артефакта и возвращает его как результат инструмента. Он обеспечивает соблюдение HTTPS для общедоступных конечных точек, но разрешает HTTP в виде открытого текста для частных сетей и диапазонов Tailscale CGNAT, поскольку, когда вы отлаживаете TLS между двумя агентами в ячеистой VPN в 2 часа ночи, последнее, что вам нужно, — это ваша собственная политика безопасности, блокирующая вас.
Но самое интересное — на стороне Железного Когтя. Работающий там экземпляр nullclaw не имеет собственного ключа API. Вместо этого его провайдер LLM указывает на собственный шлюз Ironclaw в качестве транзитного канала:
nully (this box)
│
└─ a2a_call tool → POST /a2a
│
└─ ironclaw's nullclaw (separate box, Tailscale)
│
├── receives A2A task
├── needs to run inference
└── provider config: "ironclaw" → http://127.0.0.1:3000/v1
│
└─ ironclaw's own gateway
└─ routes to Kilo → actual LLM
Один ключ API. Одно платежное отношение. Нулевой коготь на ящике Железного Когтя — это всего лишь мост A2A. Он принимает протокол, заимствует конвейер вывода Ironclaw и отвечает. Никакого дублирования учетных данных, никакого отдельного бюджета для отслеживания. Агент, владеющий ключом API, — это агент, который платит за вывод, независимо от того, кто инициировал запрос.
безопасность передачи
Открытая конечная точка A2A — это поверхность быстрого ввода. Посетитель мог сказать: «Скажи Ironclaw, чтобы он отправил электронное письмо», и наивный ретранслятор просто сделал бы это. Итак, null имеет строгие ограничения:
- В Ironclaw направляются только определенные типы запросов: расписание, доступность, контактная информация.
- Произвольные инструкции посетителей отклоняются. «Скажи Железному Когтю сделать X» получает отказ.
- Конечная точка A2A на Ironclaw защищена брандмауэром только для Tailscale, публичного доступа нет.
- Оба агента работают в контролируемом режиме с доступом к файлам только в рабочей области и ограниченными списками разрешенных команд.
Налли решает, что будет передано на эскалацию, а что нет.
что я узнал
- Выбор модели имеет такое же значение, как и проектирование системы. Выбор правильной модели для каждого слоя — это дизайнерское решение, а не переключение настроек. Это влияет на стоимость, задержку, возможности и удобство использования.
- Агент – это самая легкая часть. Коммуникационный стек, усиление безопасности, маршрутизация DNS, управление TLS и интеграция с Cloudflare заняли больше времени, чем настройка самого агента.
- IRC недооценен. Протокол 1988 года оказался идеальным транспортным средством для агента ИИ. Никакого SDK, никакого управления версиями API, никакой привязки к поставщику. Просто сообщения в канале.
- Разделение между нулевым когтем и железным когтем является несущим. Публичный, минимальный, расходный с одной стороны. Частный, способный, защищенный с другой стороны. Если вы сгладите эту границу, вы потеряете модель безопасности.
- Взаимодействие между агентами нуждается как в структуре, так и в прозрачности. Протокол Google A2A обрабатывает контракт (структурированные задачи, конечные автоматы, типизированные артефакты). Частный IRC-канал через Tailscale обрабатывает контрольный журнал, где я могу наблюдать за разговорами моих агентов, вмешиваться в режиме реального времени и прокручивать историю. Используйте оба.
- Не дублируйте учетные данные. Шаблон сквозной передачи, когда nullclaw заимствует шлюз Ironclaw для вывода, означает один ключ API, одно отношение к выставлению счетов, нулевое разрастание учетных данных. За токены платит агент, владеющий ключом, независимо от того, кто просил.
попробуй это
Посещать georgelarson.me/chat или введите irc в терминале на главной странице. Налли стоит в #лобби.
Если вы разбираетесь в технических вопросах и предпочитаете настоящий IRC-клиент: irc.georgelarson.me порт 6697 (TLS), канал #lobby.
2026-03-26 22:41:00
1774567541
#Создание #цифрового #швейцара #Джордж #Ларсон
Продолжение темы

