Пользователь вставляет приглашение для оценки под руководством агента в свой редактор. Агент читает [страницу оценки Neotoma](https://neotoma.io/evaluate), сканирует локальный рабочий процесс, решает, что соответствие соответствует, запускает установку и сохраняет первые несколько объектов. Некоторое время спустя возникает настоящая ошибка: при отправке сущности молча удаляется поле, которое схема явно принимает. Чуть позже он заметил кое-что еще: извлечение данных из большого графа сущностей происходит медленнее, чем должно быть для рабочего процесса, который он поддерживает. А еще позже, создавая собственный цикл поиска, он понимает, что на поверхности MCP отсутствует пакетная операция, которая сделала бы повторяющийся шаблон намного чище. Пользователь никогда не спрашивал об этом. Агент заметил это по пути к чему-то другому.

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

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

Оценка под руководством агентов, описанная в [посте по исследованию клиентов](/posts/customer-research-through-agents), была первой половиной этого цикла. Подсистема задач — задняя половина. Обе половины работают на [субстрате нервной системы](/posts/from-memory-to-nervous-system), который я описал ранее, и возможности проблем являются самым ярким примером того, для чего предназначена эта подложка.

## Почему цикл должен закрываться на стороне агента

Трение — тихий убийца обратной связи. Старая модель предполагала, что пользователь преобразует свой опыт в отчет в отдельной системе: переключает контекст, находит репозиторий, анализирует шаблон проблемы, записывает достаточно предыстории, чтобы специалист по сопровождению мог действовать, прикрепляет журналы, ждет. Каждый шаг — это шанс сдаться. Большинство так и делает. И эта модель охватывает только те проблемы, которые заметил пользователь. У него вообще нет пути для проблем, которые заметил агент, но которые пользователь так и не обнаружил.

Агент одного оценщика обнаружил, что активация привела к ошибке гидратации, когда конфигурация подложки указывала на автономный экземпляр за туннелем Cloudflare. Агент написал точное описание, включая неисправную конечную точку и заголовки ответов. Пользователь переслал мне сводку в виде сообщения. Я перестроил контекст, перенаправил его своим агентам, отправил релиз и отправил пользователю ответное сообщение. Пользователь попросил своего агента проверить. Эта проверка заняла около девяноста секунд. Человеческие шаги по эстафете заняли несколько дней.

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

Если агент пользователя уперся в стену, заметил медлительность или захотел недостающую возможность, этап перевода осуществляется бесплатно. У агента уже есть контекст: какой инструмент он запускал, точный вызов MCP, который не удался или вызвал неловкость, полезные данные ответа, версию git SHA или приложения установки Neotoma, тип используемой сущности. Он составляет последовательный отчет за один вызов инструмента. Инструкции MCP предписывают агентам немедленно подать заявку через `submit_issue`, когда подтверждается проблема, о которой необходимо сообщить, или возможность улучшения, не останавливаясь для запроса по каждой проблеме - подсказка для каждой проблемы не добавляет никакой новой информации и прерывает все, что делал пользователь. Файлы агента. Пользователь узнает об этом позже или никогда, в зависимости от того, будет ли изменение когда-либо выпущено.

Со стороны сопровождающего цикл должен завершиться без того, чтобы я читал каждый отчет вручную. Я запускаю около дюжины агентов в редакторах и демонах. Они уже обрабатывают входящее структурированное состояние. Естественная форма такова: приходит новая проблема, подложка сигнализирует о записи, демон сортировки улавливает событие, считывает проблему, решает, может ли он действовать, открывает рабочее дерево, запускает сеанс агента для базы кода и либо устраняет ошибку, либо запрашивает у репортера разъяснения в том же потоке.

Обе половины цикла работают как агенты над одним и тем же субстратом. Агент пользователя использует MCP для отправки. Агенты сопровождающего используют MCP для чтения и ответа. Никому не нужно открывать браузер.

## Что делает агент при отправке

Поверхность MCP достаточно мала, чтобы ее можно было перечислить. Инструмент submit_issue принимает заголовок, тело, тип объекта, если проблема связана с записью определенного типа, и блок среды репортера — git SHA, который использует пользователь, или версию приложения, причем последняя автоматически заполняется на стороне сервера, когда агент опускает оба. Репортерская среда имеет больший вес, чем кажется; В следующем разделе объясняется, почему.

Отчеты редко приходят без контекста. Ошибка ссылается на конкретные объекты: конкретную запись, которую не удалось сохранить, ее схему, вышестоящее наблюдение. Запрос на расширение ссылается на шаблон вызова, который он мог бы упростить, или на тип объекта, который он мог бы ускорить. `submit_issue` и `add_issue_message` принимают массив `entity_ids_to_link`, и сервер создает отношения `REFERS_TO` из новой проблемы с каждым объектом, на который ссылается, атомарно как часть одного и того же вызова. Проблема уже встроена в график, о котором идет речь. Агент сортировки, читающий проблему, может перейти непосредственно к объекту, который потерпел неудачу.

Отправка проходит через тот же механизм защиты PII `scanAndRedact`, который защищает каждую общедоступную поверхность. Если агент случайно вставит токен или адрес электронной почты в тело сообщения, оно будет отредактировано перед сохранением. Инструкции MCP требуют, чтобы агенты применяли контрольный список PII к заголовку и телу перед вызовом, но фактической линией защиты является защита на стороне сервера. Сообщитель получает числовой идентификатор проблемы и гостевой токен обратного чтения с явным сроком жизни, привязанный к потоку, который он только что открыл. С помощью этого токена агент репортера позже считывает статус без повторной аутентификации каждый раз.

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

## Провенанс — невоспетый герой

Требования к репортерской среде выглядят как небольшая деталь. Это самый важный сдвиг.

До появления подсистемы проблем отчет можно было отправить без ссылки на сборку, для которой он был создан. Это нормально для бумажного билета. Это катастрофа для автоматизированного цикла сортировки. Если агент сообщает об ошибке при фиксации `abc1234`, а мои агенты исправляют её при фиксации `def5678`, агент пользователя должен знать, какую сборку проверять. Если поток отладки охватывает три сборки, каждый комментарий должен записывать, в какой сборке он был протестирован. То же самое относится и к запросу на расширение: зная, какую версию выполнял агент, когда он обнаружил недостающую пакетную операцию, я могу узнать, был ли пробел уже устранен в более поздней сборке или он действительно открыт. Без происхождения нить становится археологией.

`submit_issue` отклоняет любую отправку, в которой отсутствуют `reporter_git_sha` и `reporter_app_version`. В конверте с отказом четко перечислены альтернативы:

```json
{
  "код_ошибки": "ERR_REPORTER_ENVIRONMENT_REQUIRED",
  "подробности": {
    "acceptable_field_groups": [
      ["reporter_git_sha"],
      ["reporter_app_version"]
    ]
  }
}
```

`add_issue_message` принимает те же поля и выдает предупреждение сервера в публичных потоках, если оба они отсутствуют. Каждое сообщение, созданное агентом отладки, записывает тестируемую сборку.

Причина, по которой это важно для обработки сообщений между агентами, заключается в том, что это позволяет принимающей стороне классифицировать отчет перед выполнением какой-либо работы. Из-за ошибки: пользователь запустил опубликованный выпуск? Ветвитесь от `main` и откройте PR. Конкретный коммит в функциональной ветке? Создайте рабочее дерево на этом коммите, воспроизведите и сообщите о результатах, не изменяя основную строку. Их собственная вилка? Опубликуйте структурированное сообщение с просьбой указать источник патча. Для улучшения: запрошенная возможность уже присутствует в ветке или действительно отсутствует? Противоречит ли это конструктивным ограничениям, которые агент, регистрирующий данные, не видит? Классификация определяет реакцию — и все это невозможно без происхождения.

Происхождение — это то, что превращает отчет в свободной форме в маршрутизируемое событие, независимо от того, описывает ли он что-то сломанное или отсутствующее.

## Что происходит на стороне сопровождающего

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

Демон, который я для этого запускаю, называется Formica. Род _Formica_, муравьи. Каждый субагент — это работник, выполняющий одну часть работы из журнала событий в исправление.

Что это делает на практике: читайте в выпуске. Извлеките сущности, которые агент репортера связал во время отправки, поскольку связи уже есть в графе. Зеркально отразите исходный репозиторий GitHub, если это требует общедоступного следа, с редактированием PII, применяемым на границе API, и любой проблемой, заголовок или тело которой по-прежнему соответствует шаблону редактирования, отклоненному до того, как она пересечет черту. Классифицируйте, является ли отчет ошибкой или усовершенствованием. В случае ошибок: решите, можно ли это воспроизвести только из среды создания отчетов, затем передайте работу навыку `/process-issues`, который открывает рабочее дерево, запускает сеанс агента и пытается исправить. Для улучшений: синтезируйте объект плана, который объединяет запрос со всеми связанными открытыми проблемами, и выносите его на рассмотрение человека, а не пытайтесь автономно реализовать. Если для любого типа требуется дополнительный контекст, опубликуйте уточняющий вопрос через `add_issue_message`, чтобы агент репортера получил его при следующем чтении статуса.

Навык `/process-issues` обеспечивает фактическое исправление. Контракт короткий. По каждому открытому вопросу:

- Загрузите снимок, цепочку разговоров и среду репортера.
- Классифицируйте среду воспроизведения как «public_release», «local_commit», «local_branch» или «unknown».
- Если неизвестно или противоречиво, вызовите `add_issue_message` со структурированным запросом недостающих данных и отметьте план `awaiting_input`.
- В противном случае синтезируйте объект «план», связанный с исходной проблемой и соответствующими строками сообщений диалога.
- Если план касается схемы, безопасности, базовой документации или двусмысленных архитектурных границ, остановитесь и спросите. Не выполняйте.
- Если выполнение безопасно и разрешено режимом отчетов: перейдите от `main` для воспроизведения общедоступного выпуска и откройте PR или создайте отдельное рабочее дерево git для локального воспроизведения и сообщите путь.

Субагенты разветвляются с ограничением одновременности в четыре, по одной проблеме на каждый субагент. Навык учитывает `reporting_mode`: `off` генерирует и сохраняет только планы, ``согласие` запрашивается перед выполнением, `preactive` выполняет безопасные планы автономно. Никогда не нажимайте `main`. Никогда не используйте `--no-verify`. Никогда не вносите изменения в отправленную фиксацию. Защита от утечки изменений запускается до того, как из частной проблемы будет создан какой-либо общедоступный артефакт.

Безопасные значения по умолчанию остаются включенными:

- `dry_run: true` для первого запуска любого нового типа задачи, чтобы я видел, что произойдет, прежде чем что-нибудь запишет.
- `auto_fix: false`, чтобы ничто не отправляло и не открывало PR, пока я не подтвержу через транспорт оператора.
- `max_prs_per_hour: 5`, чтобы поток связанных проблем не мог превратиться в поток веток.
- `dirty_tree_policy: abort`, чтобы устаревшая проверка никогда не использовалась в качестве основы.
- Переключатель уничтожения через объект daemon_config в Neotoma с активным: false, так что я могу приостановить всю обработку одной записи Neotoma, не касаясь хост-машины.

Отдельного внимания заслуживает транспортная часть оператора. Formica поддерживает серверную часть Telegram, которая обеспечивает передачу обслуживания human_needed и команды /shipit для возобновления работы, когда auto_fix выключен. Сообщения Telegram из белого списка зеркально отображаются в Neotoma в виде строк `conversation_message`, поэтому даже мои разговоры с демоном на стороне человека фиксируются в одном и том же субстрате. Аудиторский след ведется от начала до конца.

Путь `add_issue_message` меня удивил, когда я начал его использовать. Это не система комментариев. Это структурированный канал сообщений между лицом, сообщившим о проблеме, и стороной, занимающейся сопровождением, через те же примитивы диалога, которые уже существуют для потоков между агентами. Агент репортера может ответить на уточняющий вопрос, и человеку не придется читать его между делом. В общедоступных потоках выполняется одно и то же редактирование PII, а случаи частичного успеха (зеркало GitHub принято, локальное добавление не выполнено или наоборот) отображаются как структурированная ошибка в ответе, а не как молчаливое создание повторяющихся комментариев.

Когда появляется исправление, тот же демон, который сортировал отчет, закрывает проблему или закрывает сразу несколько проблем, если один PR разрешил кластер.

## Что делает агент репортера при повторном прочтении

Другая сторона цикла — чтение. Агент репортера вызывает get_issue_status, сообщая номер проблемы или идентификатор объекта. Он получает текущий статус, сообщения в потоке, разрешение, если таковое имеется, и ссылку на вышестоящее зеркало, если сторона, занимающаяся сопровождением, решила передать его на эскалацию. Гостевой токен подтверждает подлинность чтения без необходимости входа пользователя во что-либо. Если срок действия токена истек, подложка возвращает чистую ошибку 401 вместо автоматического перехода на анонимный доступ.

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

Текущая модель чтения для стороны репортера — pull (агент проверяет, когда у него есть для этого основания), но push доступен сегодня через те же инструменты подписки, которые использует демон сопровождающего. Подписки могут быть привязаны к определенному идентификатору объекта, поэтому агент отправителя сообщения может зарегистрировать интерес к только что зарегистрированной проблеме и получать события `entity.updated` и `observation.created` по мере продвижения потока. Чего не хватает, так это эргономичного связующего звена: инструкции MCP еще не предписывают агентам автоматически подписываться после возврата `submit_issue`. Пока они этого не сделают, репортерская сторона по умолчанию остается на свободе; агенты сопровождающего уже просыпаются по событиям субстрата. Полная реактивность обеих половин осуществляется за одну смену инструкции.

## Почему так действует нервная система

Подложка генерирует события после каждой записи. Это единственное, что должен делать субстрат, чтобы все это работало. Все остальное — это логика рабочего уровня, работающая сверху: демон сортировки, зеркало GitHub, гостевое обратное чтение, межпотоковая дедупликация, редактирование PII.

Это строка, которую я [приводил аргументы в посте о нервной системе](/posts/from-memory-to-nervous-system), и она соответствует варианту использования «Проблемы». Субстрат не решает, какие проблемы имеют значение, не повторяет доставку с эскалацией, не подписывается на собственные события. Это сигнализирует. Демон сортировки является потребителем, агент репортера — потребителем, зеркало GitHub — потребителем. Каждый потребитель регистрирует интерес, решает, что делать, и действует. Если я хочу добавить второй демон сортировки, который по-другому обрабатывает отчеты о безопасности, он подписывается на те же события с другим фильтром. Никакого нового поведения субстрата.

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

## Наследование цикла

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

Общая часть подачи уже имеется. `submit_entity` принимает отчеты по произвольным типам объектов, когда оператор заполнил строку `submission_config`, разрешающую это. Применяются тот же грант гостевого токена, та же цепочка разговоров, тот же канал отслеживания add_entity_message. `subscribe` принимает любой тип объекта в качестве фильтра, поэтому сторонний оператор может запускать свой собственный демон сортировки, регистрируя интерес к своим пользовательским типам и реагируя на события `entity.created` и `entity.updated` точно так же, как Formica реагирует на проблемы.

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

Некоторые статьи касаются сегодняшних проблем Неотомы. Защита редактирования PII в настоящее время привязана к пути `submit_issue`, а не к общему пути `submit_entity`. Зеркальное отображение GitHub зависит от конкретной проблемы. Оба являются дополнениями оперативного уровня, которые сторонний оператор подключит самостоятельно. Подложка обрабатывает части, которые должны быть единообразными — принудительное соблюдение происхождения, создание атомарных связей, гостевой доступ, ограниченный потоком, создание событий при каждой записи. Части, которые зависят от того, о чем *отчет*, - это то, где оператор зарабатывает на жизнь.

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

## Почему человеческая оценка остается

Две вещи побуждают меня подключить auto_fix: true и отправить все, что производит демон.

Первое – это удобство. Зеленый конвейер, который закрывает проблемы, пока я сплю, доставляет удовольствие. Во-вторых, для значимой части задач агентный план и разница верны. Я уже посмотрел их достаточно, чтобы знать, что режим отказа обычно не является «неправильным решением». Обычно это «исправление неправильной области действия», которое проверка кода выявляет за тридцать секунд.

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

Запросы на усовершенствование еще больше обостряют эту ситуацию. У ошибки есть основная истина: либо поле пропущено, либо нет. Расширение — это заявление о проектировании, которое содержит предположения о шаблонах использования, архитектурных ограничениях и компромиссах, которые агент отчетов не может полностью увидеть. Сигнал ценен; оно выявляет реальное, а не воображаемое трение. Но решение, что с этим делать, принадлежит человеку, который видит полную картину.

В решениях, требующих участия человека, цена ошибки высока, а цена медлительности низка. Это слияния, а не планы, патчи, тесты или PR-описания. Обо всем остальном позаботятся агенты. Агенты предлагают; люди решают.

## Агентский цикл, от начала до конца

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

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

## То, что я не строю

В подсистеме проблем возникает искушение перейти к оркестрации: модели определения приоритетов, автоматическому отслеживанию SLA, «умному» маршрутизатору, который решает, какой демон обрабатывает какой тип проблемы. Каждый звучит разумно по отдельности. Ни один из них не принадлежит субстрату. Демон сортировки определяет приоритеты. Агенты сопровождающего сами отслеживают время ответа. Маршрутизация — это фильтр подписки.

То же самое относится и к семантике повторных попыток. Если доставка веб-перехватчика не удалась, подложка регистрирует ошибку и продолжает работу. Он не переходит на резервный канал, не буферизуется для повтора, не переводит потребителя в ухудшенное состояние. Брокеры сообщений делают все это, и у них это хорошо получается; субстрат не является брокером сообщений. Потребители, которым нужна гарантированная доставка, помещают сигнал в свою собственную инфраструктуру.

Ограничение — это особенность. Уровень состояния, который сигнализирует о проблемах, но не решает, какие проблемы имеют значение, — это уровень состояния, которому любой потребитель может доверять и вести себя предсказуемо.

## О чем я хочу получить отзыв

Подсистема задач работает. Если у вас установлена ​​Neotoma и ваш агент сталкивается с чем-то неприятным (ошибкой, недостатком в производительности или недостающей функцией, которую он желает иметь), вам больше не нужно просить его сообщить о проблеме. Чтобы применить это к существующей установке, обновите ее с помощью `npm install -g neotoma@latest`. Нет переключателя согласия для каждого пользователя, который нужно было бы настроить; согласие - установка. Если это новая установка, `neotoma reporter setup` выполняет одноразовую настройку на стороне репортера, поэтому первая проблема, которую ваши файлы агента имеют где-то найти.

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

Если вы создаете продукт, пользователи которого запускают агенты, модель является переносимой. Интересная работа не находится по обе стороны провода; это сам провод.