Skip to main content

Режим флота

Используйте режим флота, чтобы разделить работу между несколькими субагентами и объединить их результаты в одной родительской сессии.

Когда использовать режим флота

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

Хорошие варианты включают:

  • Многофайловые рефакторинги, при которых каждый рабочий владеет определённым файлом, пакетом или языковым SDK.
  • Пакетные обзоры, где каждый работник проверяет отдельный дифференциал, модуль или группу оповещений.
  • Параллельные исследования между независимыми репозиториями, сервисами или тематическими областями.
  • Документация обновляется, когда у каждого сотрудника есть страница или тема.
  • Задачи миграции, где каждый работник может проверить свой срез и отчётиться об этом.

Избегайте режима флота для:

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

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

Стартовый режим флота

SDK открывает режим флота через пространство имён сессии RPC на нескольких языках. Связывание экспериментальное на сгенерированной поверхности RPC; Закрепите и SDK, и CLI-среду Copilot, если от этого зависит ваша заявка.

Внутри сессии

Метод провода — session.fleet.start. Опциональное prompt сочетается с инструкциями по оркестрации флота во время выполнения.

TypeScript
const result = await session.rpc.fleet.start({
    prompt: "Refactor each SDK package independently, then summarize the changes.",
});

if (result.started) {
    console.log("Fleet mode started");
}
Python
from copilot.generated.rpc import FleetStartRequest

result = await session.rpc.fleet.start(
    FleetStartRequest(
        prompt="Review each service independently, then summarize the risks."
    )
)

if result.started:
    print("Fleet mode started")
Go
package main

import (
    "context"
    "fmt"

    copilot "github.com/github/copilot-sdk/go"
    "github.com/github/copilot-sdk/go/rpc"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    session, err := client.CreateSession(ctx, &copilot.SessionConfig{})
    if err != nil {
        return
    }

    prompt := "Update each package independently, then report validation results."
    result, err := session.RPC.Fleet.Start(ctx, &rpc.FleetStartRequest{
        Prompt: &prompt,
    })
    if err != nil {
        return
    }
    if result.Started {
        fmt.Println("Fleet mode started")
    }
}
prompt := "Update each package independently, then report validation results."
result, err := session.RPC.Fleet.Start(ctx, &rpc.FleetStartRequest{
    Prompt: &prompt,
})
if err != nil {
    return err
}
if result.Started {
    fmt.Println("Fleet mode started")
}
.NET
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig());

var result = await session.Rpc.Fleet.StartAsync(
    "Audit each project independently, then summarize the findings.");

if (result.Started)
{
    Console.WriteLine("Fleet mode started");
}
var result = await session.Rpc.Fleet.StartAsync(
    "Audit each project independently, then summarize the findings.");

if (result.Started)
{
    Console.WriteLine("Fleet mode started");
}
Rust
use github_copilot_sdk::generated::api_types::FleetStartRequest;

let result = session
    .rpc()
    .fleet()
    .start(FleetStartRequest {
        prompt: Some("Research each crate independently, then summarize the plan.".into()),
    })
    .await?;

if result.started {
    println!("Fleet mode started");
}

Нативные типизированные привязки для режима флота были проверены в Node.js/TypeScript, Python, Go, .NET и Rust. Связывание Java не было найдено в java/src/main/java на этой ветви, поэтому Java примеры опускаются до тех пор, пока поверхность не станет доступна.

Из режима плана

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

type PlanModeExitAction =
  | "exit_only"
  | "interactive"
  | "autopilot"
  /** Exit plan mode and continue with parallel autonomous workers. */
  | "autopilot_fleet";

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

Как подагенты координируются

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

Каноническая схема выглядит следующим образом:

CREATE TABLE todos (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT,
    status TEXT DEFAULT 'pending'
);

CREATE TABLE todo_deps (
    todo_id TEXT,
    depends_on TEXT,
    PRIMARY KEY (todo_id, depends_on)
);

Каждая задача движется через небольшой автомат состояний:

pending -> in_progress -> done
                       \-> blocked

Субагент должен:

  1. Определите только один готовый к делу, установив status = 'in_progress'.
  2. Работайте только над прицелом этого дела.
  3. Сохраняйте его результат в разговоре или в соответствующей задаче.
  4. Устанавливается status = 'done' после завершения.
  5. Устанавливайте status = 'blocked' , когда не может продолжаться, и указывайте причину.

Оркестратор может найти работу, зависимости которых удовлетворяются таким запросом, как:

SELECT t.*
FROM todos t
WHERE t.status = 'pending'
  AND NOT EXISTS (
      SELECT 1
      FROM todo_deps td
      JOIN todos dep ON td.depends_on = dep.id
      WHERE td.todo_id = t.id
        AND dep.status != 'done'
  );

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

Хуки жизненного цикла

Режим флота вызывает субагентов через механизм задач во время выполнения. Время выполнения создаёт активность hook для вызовов инструментов подагентов: журнал изменений 1.0.52 отмечает, что preToolUse, postToolUse, subagentStartи subagentStop запускается правильно для вызовов инструментов подагентов.

Выделенный SDK-callback для subagentStart или subagentStop не был найден в публичной поверхности SDK на этой ветке. Потребители SDK могут наблюдать активность субагентов через общий поток событий сессии, включающий такие события, как subagent.started, subagent.completed, subagent.selected``subagent.failed, и subagent.deselected.

TypeScript
session.on((event) => {
    if (event.type === "subagent.started") {
        console.log(`Started ${event.data.agentDisplayName}`);
    }

    if (event.type === "subagent.completed") {
        console.log(`Completed ${event.data.agentDisplayName}`);
    }
});
Python
import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler

async def main():
    client = CopilotClient()
    await client.start()
    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
    )

    def handle_event(event):
        if event.type == "subagent.started":
            print(f"Started {event.data.agent_display_name}")
        elif event.type == "subagent.completed":
            print(f"Completed {event.data.agent_display_name}")

    unsubscribe = session.on(handle_event)

asyncio.run(main())
def handle_event(event):
    if event.type == "subagent.started":
        print(f"Started {event.data.agent_display_name}")
    elif event.type == "subagent.completed":
        print(f"Completed {event.data.agent_display_name}")

unsubscribe = session.on(handle_event)

Для конфигурации крючка, которая уже открыта на слое SDK, см. Работа с крючками. Для полезной нагрузки событий субагентов см. AUTOTITLE.

Подагенты плагинов

Среда выполнения может загружать плагины с --plugin-dirпомощью . Плагины, загруженные таким образом, могут регистрировать своих агентов как доступные task(agent_type=...) субагенты в режиме prompt, что означает, что режим флота может отправлять данные к этим типам работников, предоставленных плагинами.

В настоящее время это шаблон конфигурации на уровне выполнения времени, а не задокументированный регистрационный API на уровне SDK. Настройте Copilot CLI runtime с помощью каталога плагинов, затем подключите SDK-клиент к этой среде выполнения. В будущем могут быть добавлены нативные помощники SDK для регистрации типов подагентов плагинов.

Концептуально, в автопарке можно запросить конкретный тип работника:

Use task(agent_type="security-review") for each independent package.
Run the workers in parallel and summarize only high-confidence findings.

Держите типы субагентов, предоставляемые плагинами, узкими и описательными, чтобы оркестратор мог их надёжно выбирать.

Лучшие практики

  • Разложите работу на отдельные единицы перед началом режима флота.
  • Минимизировать зависимости между задачами; Зависимости снижают параллелизм.
  • Дайте каждому todo надёжное удостоверение личности, чёткий титул и полное описание.
  • Сделайте так, чтобы каждый субагент владел ровно одной задачей за раз.
  • Используйте фоновые субагенты для действительно параллельной работы.
  • Используйте синхронные вызовы субагентов для сериализированных шагов или валидационных элементов.
  • Предоставить каждому субагенту полный контекст; Субагенты не имеют статуса во всех вызовах.
  • Включайте пути к файлам, команды, ожидаемые выходы и ограничения в каждой рабочей строке.
  • Не отправляйте ни одного субагента на заднем плане; Предпочитаю синхронный вызов или одновременно вырабатывать несколько рабочих подрядчиков.
  • Избегайте назначать перекрывающиеся файлы разным работникам, если только родительский агент явно не согласует конфликты.
  • Обязать каждого работника сообщать, что изменилось, как это подтвердилось и что ещё заблокировано.
  • Пусть родительский агент проверит совместный результат после завершения работы.

Ограничения и открытые вопросы

  • Режим флота доступен через сгенерированные сессионные RPC-привязки и отмечен как экспериментальный в нескольких SDK.
  • Шаблон SQL todos является канонической координационной моделью в руководстве по выполнению, но вопрос о том, является ли он стабильным контрактом на расширение для пользователей SDK, остаётся открытым.
  • subagentStart и subagentStop являются именами хуков во время выполнения; эта ветка открывает жизненный цикл субагента потребителям SDK через общий поток событий сессии, а не через выделенные обратные вызовы хуков.
  • Регистрация подагентов плагина настраивается на уровне выполнения через --plugin-dir; на этой ветке не был проверен помощник регистрации плагинов на уровне SDK.
  • Java нативных типизированных привязок для session.fleet.start не было найдено в исходном коде SDK Java этой ветви.
  • Режим флота не устраняет необходимость в родительском агентском обзоре. Параллельные работники могут создавать противоречивые предположения, которые оркестратор должен согласовать.

См. также