temporality
Изменить страницу↗
Инженерные документы

Техническое задание: Runtime Knowledge Activation в Temporality

Статус: проект задания на разработку
Компонент: Temporality Kernel + Observation
Цель: завершить исходную концепцию Temporality — реактивную активацию накопленных знаний во время исполнения агента, а не только предварительную выдачу знаний при старте run.


#1. Контекст и проблема

Изначальная идея Temporality состояла в том, чтобы предлагать агенту накопленный опыт в момент, когда он может повлиять на следующее решение:

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

При этом Observation уже содержит значительную часть необходимого механизма:

Следовательно, задача не предполагает создание второго механизма поиска знаний. Необходимо связать события исполнения Kernel с существующим retrieval-контуром Observation и обеспечить корректную доставку результатов в работающий контекст модели.

#2. Цель разработки

Реализовать Runtime Knowledge Activation — механизм повторного поиска и контекстной инъекции накопленных знаний во время исполнения агента.

Система должна:

  1. Реагировать на значимые события исполнения.
  2. Формировать контекстный запрос к существующему Observation API.
  3. Получать релевантные знания с учётом уже выданных знаний и активных Skills.
  4. Не допускать повторной выдачи одного знания в рамках run.
  5. Вставлять новые подсказки в историю модели в корректной точке протокола tool calls.
  6. Учитывать бюджет контекста, ограничения частоты и ошибки retrieval.
  7. Сохранять состояние активации при ContinueAsNew.
  8. Позволять проследить причинную цепочку от события исполнения до выдачи знания и последующего результата.

Главный принцип: Temporality предлагает опыт в подходящий момент, но не управляет действиями агента. Агент самостоятельно решает, использовать ли предложенное знание.

#3. Термины

Термин Значение
Run Один запуск агента, включая продолжения через ContinueAsNew
Activation Один запрос на поиск знаний, вызванный событием исполнения или начальным priming
Trigger Событие, инициирующее activation
Candidate Знание, найденное Observation
Offered Знание, выбранное Observation и записанное как предложение
Injected Знание, фактически добавленное Kernel в историю модели
Used Знание, которое агент фактически использовал по принятой эвристике
Outcome Оценка полезности или вреда знания по результатам run
MCP server key Стабильный идентификатор MCP-сервера в конфигурации инструмента, не имя отдельного tool

#4. Область работ

#4.1. Входит в задачу

#4.2. Не входит в задачу

#5. Триггеры активации

Реализовать триггеры как расширяемую политику Kernel. На первом этапе обязательны следующие типы.

#5.1. tool.failed

Назначение: найти известный опыт диагностики и устранения проблемы после неудачного вызова инструмента.

Условия:

В запрос передавать:

Не считать tool.blocked, отказ в approval и policy denial обычной ошибкой инструмента. Для них автоматический retrieval в рамках P0 не выполнять.

Не делать вывод о безопасности повтора операции. Подсказка не должна отменять существующие сведения об effect/side effects (none, uncertain и другие статусы).

#5.2. mcp.first_call

Назначение: предложить проверенные практики работы с MCP-сервером при первом обращении к нему в данном run.

Условия:

В запрос передавать:

Первичный вызов сервера, завершившийся ошибкой, обрабатывается триггером tool.failed. Он также должен пометить сервер как уже встречавшийся, чтобы последующий успешный вызов не запускал вторую первичную активацию. Если при первой ошибке идентификатор сервера не был доступен, последующий вызов может стать первым распознанным MCP-вызовом.

#5.3. Будущие триггеры

Архитектура должна допускать добавление новых trigger types без переработки основного цикла исполнения. В частности, потенциально могут появиться:

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

#6. Архитектура исполнения

#6.1. Общий цикл

Ожидаемый цикл:

  1. Модель возвращает один или несколько ToolCalls.
  2. Kernel выполняет все вызовы согласно существующему механизму.
  3. Kernel добавляет в историю все соответствующие tool replies.
  4. По результатам исполнения собираются activation candidates.
  5. Применяются trigger policy, дедупликация и ограничения частоты.
  6. Для оставшихся activation candidates выполняется retrieval через ActivityKnowledgeHints.
  7. Kernel проверяет бюджет и отбирает знания для фактической инъекции.
  8. Новые knowledge cues добавляются в историю модели отдельным сообщением после всех tool replies.
  9. Следующий вызов модели получает результаты инструментов и новые знания.

#6.2. Требование к протоколу tool calls

Нельзя вставлять сообщения с подсказками между assistant tool-call message и ответами на вызовы инструментов, относящиеся к этому сообщению.

Если модель вернула несколько ToolCalls, ответы на них должны остаться непрерывной последовательностью в соответствии с используемым API-протоколом.

Dynamic context injection выполняется только после того, как Kernel добавил ответы на все tool calls данного ответа модели.

Если в текущей реализации есть отдельные ветки для background operations, ожидания результата, HITL, plan/delegate или иных типов инструментов, необходимо проверить их совместимость с этим правилом. Нельзя добавлять подсказку в промежуточную точку, где модель ещё должна получить tool reply.

#6.3. Разделение ответственности

Не помещать HTTP-вызов Observation непосредственно внутрь ActivityRunTool. Не смешивать выполнение инструмента и поиск знаний.

#7. Контракт Kernel → Observation

#7.1. Расширение HintRequest

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

Поле Тип/смысл
Trigger Тип активации: task.priming, tool.failed, mcp.first_call
Tool Имя вызванного инструмента
MCPServer Стабильный ключ MCP-сервера, если применимо
ToolResult Ограниченный диагностический/результирующий текст
ErrorClass Класс ошибки, если доступен
IssuedKnowledgeIDs Knowledge IDs, уже фактически внедрённые в контекст этого run
ActivationSourceID Идентификатор события/операции, вызвавшей активацию

Сохранить совместимость с существующими полями:

Не дублировать данные, которые уже надёжно выводятся на стороне Observation из существующего контракта. Не вводить необязательные поля без конкретного потребителя.

#7.2. Observation HTTP API

Использовать существующий POST /v1/observations/hints.

Расширить observationHintRequest только теми полями, которых пока не хватает для трассировки или корректной семантики trigger. Сохранить текущую обработку:

FindHints остаётся единым механизмом поиска для начального и динамического priming.

hint.query должен содержать как минимум:

hint.offered должен содержать:

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

#7.3. Ограничение и очистка содержимого

Текст tool_result и ошибки может содержать секреты, персональные данные, большие документы и недоверенные инструкции.

Требования:

Kernel должен ограничивать данные до отправки, а Observation сохраняет собственную валидацию как второй рубеж.

#8. Состояние Workflow

Состояние динамической активации должно быть частью сериализуемого состояния run и корректно переноситься через ContinueAsNew.

Предлагаемые логические поля:

Поле Назначение
IssuedKnowledgeIDs Набор знаний, фактически внедрённых в контекст
ActivatedMCPServers Набор MCP server keys, для которых обработан первичный триггер
ActivationCount Количество выполненных динамических retrieval
DynamicActivationTokensUsed Учёт токен-бюджета динамических подсказок
ProcessedActivationKeys Ключи уже обработанных однотипных ситуаций для дедупликации

Требования:

  1. Состояние должно быть детерминированным и сериализуемым средствами используемого workflow engine.
  2. Порядок элементов в сериализуемых коллекциях должен быть детерминированным, если это важно для воспроизводимости.
  3. Нельзя хранить в состоянии полный tool output или полный ответ Observation, если достаточно ID и агрегированных счётчиков.
  4. Состояние должно переноситься в ContinueAsNew.
  5. Повторное выполнение workflow/activity не должно приводить к неконтролируемой повторной инъекции.
  6. Учесть семантику retry и replay используемого workflow engine.

IssuedKnowledgeIDs обновляется после фактической инъекции, а не сразу после получения ответа Observation.

#9. Дедупликация и throttling

#9.1. Дедупликация знаний

Observation уже поддерживает issued_knowledge_ids. Kernel обязан передавать туда только знания, которые действительно были внедрены.

Если знание было найдено, но отброшено из-за бюджета, оно не должно автоматически считаться внедрённым. При этом необходимо избегать повторных дорогостоящих запросов, которые каждый раз возвращают тот же неподходящий кандидат. Для этого допускается отдельное состояние suppression/deferred IDs, но оно не должно смешиваться с IssuedKnowledgeIDs.

#9.2. Дедупликация ситуаций

Повторные идентичные ошибки не должны порождать бесконечный retrieval.

Ключ ситуации формировать из нормализованных признаков, например:

Не включать в fingerprint случайные идентификаторы, timestamps и нестабильные части текста ошибки.

Новая ошибка другого класса или содержательно другая ситуация должна иметь возможность инициировать новую активацию.

Точный алгоритм fingerprint и нормализации покрыть тестами и документировать.

#9.3. Ограничение частоты

Начальные рекомендуемые ограничения (конфигурируемые константы; значения уточнить по benchmark):

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

#10. Контекстная инъекция

#10.1. Формат

Использовать существующий формат temporality.memory / RenderHintBlock, не создавать отдельный формат динамической памяти без необходимости.

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

Рекомендуемая семантика текста:

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

Не требуется дословно использовать этот текст, если существующий RenderHintBlock уже задаёт эквивалентную семантику.

#10.2. Положение в истории

#10.3. Учёт фактической инъекции

Разделить следующие состояния:

  1. retrieved — Observation вернул кандидат.
  2. offered — Observation записал hint.offered.
  3. selected — Kernel выбрал подсказку с учётом бюджета.
  4. injected — подсказка фактически добавлена в messages.
  5. used — существующая логика оценки определила использование.
  6. outcome — оценён полезный/вредный эффект.

Нельзя считать offered эквивалентом injected, а injected — эквивалентом used или helpful.

Если Kernel не смог внедрить подсказку после ответа Observation, это должно быть видно в telemetry. Необходимо выбрать совместимый с текущей моделью событий способ фиксации результата доставки, например отдельное событие hint.delivery либо расширение существующего события, если это допустимо схемой.

#11. Бюджетирование

Начальный priming и динамические подсказки должны иметь раздельные бюджеты.

Требования:

Начальные значения вынести в конфигурацию или централизованные константы. В качестве стартовой настройки для тестового профиля можно использовать небольшой бюджет: до 300–500 токенов на одну активацию и до 1500–2000 токенов динамического контекста на run. Эти значения являются исходными для эксперимента, а не окончательными продуктовыми нормативами.

Если кандидат не помещается в бюджет:

#12. Отказоустойчивость и производительность

Retrieval является best-effort подсистемой.

Для P0 допустим синхронный retrieval на границе model turn с небольшим таймаутом. Асинхронная доставка не входит в обязательный объём: она усложняет согласование с моментом следующего model call и должна рассматриваться отдельно, если измерения покажут необходимость.

#13. Telemetry и диагностика

Нужно обеспечить возможность восстановить полную цепочку:

trigger event → activation request → retrieved candidates → selected hints → injected hints → subsequent execution → usage/outcome

Для каждой активации должны быть доступны:

Не записывать в диагностические события полные секретоносные tool outputs.

Существующие hint.query, hint.offered, hint.used, hint.ignored, hint.outcome сохранить. Новые события должны быть совместимы с текущей проекцией Knowledge и не приводить к лишней инвалидации knowledge cache.

Отдельно проверить комментарии и allow-list knowledgeProjectionTypes / affectsKnowledgeProjection: события активации и доставки, не влияющие на Knowledge projection, не должны ошибочно инвалидировать её кеш.

#14. Изменения в Debugger / Observability

В рамках базовой реализации обеспечить доступность причин активации в существующем run timeline/inspector.

Минимально необходимо видеть:

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

#15. Требования к ContinueAsNew и восстановлению

Проверить все места, где формируется и восстанавливается RunState, включая:

Состояние динамической активации должно переноситься без потери:

Не переносить временные объекты или контексты activity. В состоянии должны оставаться только сериализуемые значения.

Повторный replay не должен приводить к дублированию сообщений или повторной выдаче знаний. Использовать принятые в проекте практики детерминизма workflow engine и идемпотентности activity.

#16. Тестирование

#16.1. Unit tests

Проверить:

#16.2. Workflow tests

Обязательные сценарии:

Сценарий Ожидаемый результат
Первый успешный вызов MCP Выполняется одна активация mcp.first_call
Второй вызов того же MCP Повторной первичной активации нет
Первый вызов MCP завершился ошибкой Выполняется tool.failed; сервер отмечается как встречавшийся
Обычная ошибка инструмента Выполняется динамический retrieval
Повтор идентичной ошибки Повторный retrieval подавляется
Другая ошибка того же инструмента Новая активация допускается
Несколько tool calls в одном ответе Все tool replies идут непрерывно; подсказки добавляются после них
Два разных MCP в одном ответе Обрабатываются оба первичных триггера, если позволяет per-turn budget
Знание уже внедрялось Повторная инъекция подавляется
Знание найдено, но не помещается в бюджет Оно не попадает в IssuedKnowledgeIDs
Observation недоступен Run продолжается штатно
ContinueAsNew Состояние активации сохраняется
Background operation Активация происходит после фактического результата, а не после выдачи operation ID
Tool blocked / approval denied Автоматическая активация не запускается
Неопределённый side effect Подсказка не разрешает безусловный повтор операции

#16.3. Integration test

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

Сценарий:

  1. Запустить агента с задачей, которая сама по себе не активирует это знание на старте.
  2. Выполнить инструмент, возвращающий известную ошибку.
  3. Убедиться, что Kernel инициировал tool.failed.
  4. Убедиться, что Observation нашёл подготовленное знание.
  5. Убедиться, что Kernel добавил его в историю после tool reply.
  6. Убедиться, что следующий запрос модели содержит подсказку.
  7. Убедиться, что telemetry связывает событие, activation и hint.

Отдельно выполнить аналогичный сценарий для первого успешного MCP-вызова.

#16.4. Behavioral test

Провести контролируемый эксперимент на одинаковом наборе задач:

Сравнить:

Не считать простое увеличение hint.used доказательством улучшения качества. Основной критерий — улучшение результата задачи при приемлемой стоимости и задержке.

#17. Этапы разработки

#P0. Замкнуть цикл на ошибках

  1. Изучить все ветки исполнения инструментов в kernel/agent/workflow.go.
  2. Расширить HintRequest и KnowledgeHints.
  3. Провести issued_knowledge_ids от Workflow до Observation.
  4. Добавить состояние фактически внедрённых знаний.
  5. Реализовать сбор trigger candidates после tool execution.
  6. Реализовать tool.failed.
  7. Добавить безопасную инъекцию после всех tool replies.
  8. Реализовать базовую дедупликацию и лимиты.
  9. Обеспечить ContinueAsNew.
  10. Добавить workflow и integration tests.
  11. Обеспечить telemetry offered/injected.

Критерий завершения P0: знание, которое не было найдено на старте run, может быть найдено после ошибки инструмента и попасть в следующий model request без нарушения протокола tool calls.

#P1. Контекстная активация по MCP

  1. Определить стабильный MCP server key в представлении инструмента.
  2. Добавить ActivatedMCPServers в RunState.
  3. Реализовать mcp.first_call.
  4. Обрабатывать несколько новых MCP-серверов в одном turn.
  5. Добавить bounded tool result для успешных вызовов.
  6. Добавить тесты на первый вызов, повторные вызовы и ContinueAsNew.
  7. Сравнить полезность MCP-triggered activation с failure-triggered activation.

Критерий завершения P1: первое успешное обращение к каждому MCP-серверу в run может активировать относящиеся к нему знания ровно один раз.

#P2. Измерение эффективности

  1. Добавить отображение trigger и activation chain в Debugger.
  2. Добавить группировку effectiveness по trigger type.
  3. Сравнить helpful/harmful outcomes для разных типов активации.
  4. Провести behavioral benchmark.
  5. По результатам определить необходимость новых триггеров и изменения бюджетов.

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

#18. Критерии приёмки всей задачи

Разработка считается завершённой, если выполняются все условия:

#19. Рекомендуемые точки изменения кода

Перед реализацией разработчик должен повторно проверить актуальное состояние ветки и найти фактические точки исполнения. Предварительные ориентиры:

Область Файл / компонент
Основной цикл и состояние run kernel/agent/workflow.go
Контракт HintRequest и activity kernel/agent/activities.go
Механизм выбора знаний observation/hints.go
HTTP endpoint активации observation/httpapi/server.go
Алгоритм priming и ограничения релевантности docs/plan-priming-relevance.md
Событийная модель и Knowledge projection observation/knowledge.go и связанные типы
ContinueAsNew kernel/agent/workflow.go и соответствующие тесты
Workflow tests kernel/agent/*_test.go
Benchmark priming observation/testdata/priming/ и связанные тесты

Список не является исчерпывающим. Необходимо найти все реализации tool execution, включая специальные пути background, delegation, plan и HITL.

#20. Архитектурные решения, которые нельзя нарушать

  1. Один retrieval engine. Начальный и динамический поиск используют существующий Observation FindHints.
  2. Kernel управляет моментом доставки. Observation не должен самостоятельно менять историю модели.
  3. Никаких подсказок между tool replies. Инъекция выполняется на безопасной границе model turn.
  4. Offered не равно injected. Событие предложения не доказывает, что агент получил знание.
  5. Injected не равно used/helpful. Оценка применения остаётся отдельной.
  6. Только best effort. Отказ подсистемы знаний не должен ломать выполнение задачи.
  7. Никакого автоматического исполнения рекомендаций. Знание — контекст для решения агента, а не команда Kernel.
  8. Детерминизм workflow. Все изменения состояния должны быть совместимы с replay и ContinueAsNew.
  9. Минимизация контекста. Передавать только данные, необходимые для поиска релевантного опыта.
  10. Измерять behavioral impact. Количество найденных подсказок само по себе не является метрикой успеха.

#21. Ожидаемый результат

После реализации Temporality должна работать не только как система предварительной подготовки контекста, но и как система runtime knowledge activation:

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