Акты Становления

014: Агент/Области видимости

Это способ дать программе доступ только к определённой части информации из её окружения. Свойство _scopes работает как «список разрешённых», показывая, какие именно данные может видеть Вызов, чтобы всё было безопасно и по делу.

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

Когда мы ограничиваем доступ к информации, мы делаем систему безопаснее, предотвращаем случайные ошибки и помогаем нейросети (LLM) лучше сосредоточиться. Это делает её работу более предсказуемой и дешёвой. Такой подход также позволяет создавать самостоятельные, «переиспользуемые» модули, такие как Идеи и Действия. Этот документ объясняет, как это работает.

Предоставление и запрос данных

Предоставленный контекст

Вызов инструмента

Родительский контекст

Ввод

Состояние

_scopes: ['ввод']

Выполнить инструмент

Одобрение человеком

Схема _scopes определяет, получает ли команда данные заранее (предоставление) или запрашивает их по ходу дела (запрос).

  • Статичные области (предоставление данных): Если в _scopes указано конкретное значение const, это значит, что данные предоставляются заранее. Разработчик жёстко прописал, какую именно информацию может видеть инструмент.

    {
      "_scopes": {
        "const": ["input"]
      }
    }
    
  • Динамические области (запрос данных): Схема _scopes может быть более гибкой, позволяя запрашивать данные. В этом случае нейросеть сама решает, какая информация из доступной ей нужна для выполнения Вызова.

    {
      "_scopes": {
        "type": "array",
        "items": {
          "enum": ["state", "input"]
        }
      }
    }
    

    Такой способ особенно полезен, когда нужно участие человека для подтверждения — это добавляет важный слой контроля и прозрачности.

Роль областей видимости в командах

Свойство _scopes — это главный механизм, который контролирует, какую информацию видит Вызов. Оно работает как фильтр, который отсекает всё лишнее из окружения и даёт команде только то, что ей нужно. Этот «ограниченный взгляд» очень важен для работы Вызова и меняется в зависимости от того, как он используется: для простой логики, работы с несколькими объектами или для модульности.

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

  • Явное исполнение (_activity): Когда Вызов связан с конкретным Действием, роль областей видимости становится более прямой. Данные из указанной области передаются Действию целиком, как дополнительный параметр. Это даёт Действию доступ ко всей нужной информации, даже если нейросеть не использовала её для создания основных параметров Вызова. Смотри пример «Передача контекста в Действие».

  • Экземплирование (_instance): Когда агент обрабатывает сразу несколько одинаковых объектов, области видимости начинают работать для каждого из них отдельно. Система следит, чтобы Вызов, нацеленный на один конкретный объект, получил данные только для этого объекта. Это очень важно, чтобы информация не «протекла» между параллельными задачами.

  • Изолированное делегирование (_delegate): Когда Вызов передаётся внешнему Делегату, области видимости выступают в роли охранников. Они определяют, какая информация из родительского окружения будет добавлена к собственным данным делегата. Ничто извне не попадёт к нему, если это не разрешено в _scopes, что обеспечивает полную изоляцию. Смотри примеры «Ограничение контекста для Делегата» и «Экземплирование с изолированными Делегатами».

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

Примеры

Пример: Уточнение с помощью областей видимости

Неоднозначный контекст

В этом примере ситуация неоднозначна. Есть два разных пользователя: currentUser (текущий пользователь) в state (состоянии) и mentionedUser (упомянутый пользователь) в input (входных данных). Агенту нужно отправить сообщение, но непонятно, кому именно.

[
  {
    "type": "state",
    "currentUser": { "id": "user_A", "name": "Алиса" }
  },
  {
    "type": "input",
    "mentionedUser": { "id": "user_B", "name": "Борис" },
    "instruction": "Отправь приветственное сообщение упомянутому выше пользователю."
  }
]

`Вызов` с областью видимости

Добавив _scopes: ["input"], мы даём нейросети важную подсказку. Это говорит ей сосредоточиться на данных из input, что решает неоднозначность и гарантирует, что сообщение будет отправлено правильному получателю — Борису.

{
  "_tool": "sendMessage",
  "_scopes": ["input"],
  "recipientId": "user_B",
  "message": "Добро пожаловать, Борис!"
}

Пример: Передача контекста в Действие

Здесь Действию нужна информация, которая не является прямым параметром инструмента. Инструмент logEvent принимает только eventName (название события), но для правильной работы действию также нужен userId.

`Вызов` с областью видимости

Вызов очень простой, он передаёт только eventName. Но свойство _scopes: ["state"] указывает, что нужно также передать объект state (состояние) в действие.

{
  "_tool": "logEvent",
  "_scopes": ["state"],
  "eventName": "user_login"
}

Реализация Действия (TypeScript)

Функция, реализующая Действие, получает свои параметры напрямую из вызова и из указанной области видимости. Это даёт чистый и прямой доступ и к eventName, и к userId.

// Параметры деструктурируются для прямого доступа к 'eventName'
// из вызова и к 'state' из контекста области видимости.
Activity.register('logEvent', async ({ eventName }, { state }) => {
  const userId = state.userId;
  await analytics.track(eventName, { userId });
});

Пример: Ограничение контекста для Делегата

При делегировании _scopes определяет, какая часть родительского контекста будет добавлена к собственному контексту делегата. Здесь главный «Оркестратор» передаёт задачу, включая весь объект state, специализированному делегату «Суммаризатору».

Родительский `Вызов` с областью видимости

У агента-оркестратора есть свой контекст. Он делает Вызов, в котором указывает, что state нужно добавить в контекст делегата.

// Контекст и вызов Оркестратора
[
  {
    "type": "state",
    "articleText": "Длинная и сложная статья..."
  },
  {
    "_tool": "summarizeArticle",
    "_delegate": "SummarizerAgent",
    "_scopes": ["state"]
  }
]

Контекст подзапроса для Делегата

Рабочее окружение «Суммаризатора» состоит из его собственного внутреннего контекста плюс данных, которые ему передал родитель. Это позволяет делать модули независимыми, но при этом снабжать их нужной информацией.

// Контекст, созданный для подзапроса Суммаризатора
[
  // Внутренний контекст Суммаризатора
  {
    "type": "system",
    "message": "Ты — эксперт по созданию кратких изложений."
  },
  // Добавляется контекст, переданный родителем
  {
    "type": "state",
    "articleText": "Длинная и сложная статья..."
  }
]

Пример: Экземплирование с изолированными Делегатами

Этот пример показывает, как _scopes и _instance работают вместе, позволяя одному агенту управлять несколькими независимыми вызовами делегатов параллельно.

Родительский контекст и решение

У родительского агента есть два разных экземпляра State. Он генерирует solution (решение) с двумя Вызовами к делегату-переводчику (translatorDelegate). Каждый вызов нацелен на свой экземпляр и правильно передаёт только state, относящийся к этому экземпляру.

// РОДИТЕЛЬСКИЙ КОНТЕКСТ
[
  { "type": "state", "_instance": "①", "text": "Hello" },
  { "type": "state", "_instance": "②", "text": "Bonjour" }
]

// РЕШЕНИЕ НЕЙРОСЕТИ
{
  "calls": [
    {
      "_tool": "translate",
      "_delegate": "translatorDelegate",
      "_instance": "①",
      "_scopes": ["state"]
    },
    {
      "_tool": "translate",
      "_delegate": "translatorDelegate",
      "_instance": "②",
      "_scopes": ["state"]
    }
  ]
}

Контексты подзапросов для Делегатов

Система создаёт два независимых подзапроса. Свойства _instance и _scopes работают вместе, чтобы каждый делегат получил только свой собственный, правильно ограниченный state.

// КОНТЕКСТ ДЛЯ ДЕЛЕГАТА ①
[
  { "type": "system", "message": "Ты — переводчик." },
  { "type": "state", "text": "Hello" }
]

// КОНТЕКСТ ДЛЯ ДЕЛЕГАТА ②
[
  { "type": "system", "message": "Ты — переводчик." },
  { "type": "state", "text": "Bonjour" }
]