- 5.1 Operate and manage multi-agent workflows — orchestration patterns, isolation for parallel execution, detecting and resolving conflicts
- 5.2 Configure observability for multi-agent behaviour — reviewable artifacts, decisions and handoffs, post-hoc analysis
- 5.3 Detect and respond to failures and degraded behaviour — failed, partial and stalled runs; recovery with rollback and human-in-the-loop
- 5.4 Manage the lifecycle of agents — add, update, replace and retire agents without disrupting workflows
5.1 Operate and manage multi-agent workflows
Start with responsibilities
Multi-agent failures are predictable: overlapping responsibilities produce duplicated work, conflicting pull requests and unclear ownership. Assign each agent a narrow role, limit it by path and artifact type, and give it a completion signal GitHub can verify. The boundary stays the same as for one agent: agents propose; humans and policy accept.
| Agent | May change | Must not change | Done when |
|---|---|---|---|
| Dependency agent | Manifests and lockfiles | Application behaviour, workflows | PR open, checks green, alert closed |
| Refactoring agent | src/ | Manifests, lockfiles, workflows | PR open, behaviour unchanged (tests green) |
| Security agent | Nothing, or security fixes when explicitly asked | Unrelated refactoring | Report referencing checks and scan results |
| Documentation agent | docs/, *.md | Code | PR open, link check green |
Apply an orchestration pattern
Orchestration decides when agents run, in what order, and how outputs move between them. In GitHub it works best expressed through workflow events and shared artifacts, because then coordination is visible in runs, checks and pull requests. Hidden coordination makes failures impossible to diagnose.
| Pattern | Use when | GitHub mechanism |
|---|---|---|
| Sequential | One step's output must be validated before the next | workflow_run triggers, needs chains |
| Parallel fan-out / fan-in | Independent analyses that merge into one result | Parallel jobs joined by needs: [a, b] |
| Orchestrator–worker (subagents) | A main agent decomposes a task and delegates parts | Custom agents invoked through the agent tool; CLI built-in agents; /fleet |
| Artifact-based coordination | You want a hard line between reasoning and writing | Agent writes a plan or report artifact; a separate, controlled step applies only allowed operations |
| Event-driven | Recurring or reactive work | Schedules, issues and pull_request events, Copilot automations, Agentic Workflows |
flowchart LR DEP["Dependency agent<br/>opens PR"] --> CI["CI validation<br/>workflow"] CI -->|"workflow_run: completed"| SEC["Security validation<br/>workflow"] SEC --> HUMAN["Human review"] HUMAN --> MERGE["Merge when<br/>all gates pass"]
# .github/workflows/security-validate.yml — runs after CI finishes
name: Security validation
on:
workflow_run:
workflows: ["CI validation"]
types: [completed]
jobs:
validate:
if: github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- run: echo "Run security validation for ${{ github.event.workflow_run.head_sha }}" flowchart LR START["workflow_dispatch"] --> SPEC["spec_analyzer"] START --> RISK["risk_reviewer"] SPEC --> MERGER["plan_merger<br/>needs: both"] RISK --> MERGER MERGER --> PLAN["Merged plan<br/>artifact"]
name: multi-agent-orchestration
on:
workflow_dispatch:
permissions:
contents: read
jobs:
spec_analyzer:
runs-on: ubuntu-latest
steps:
- run: ./executors/spec_analyzer.sh
risk_reviewer:
runs-on: ubuntu-latest
steps:
- run: ./executors/risk_reviewer.sh
plan_merger:
needs: [spec_analyzer, risk_reviewer] # fan-in: waits for both
runs-on: ubuntu-latest
concurrency:
group: multiagent-${{ github.ref }} # never two merges on one branch
steps:
- run: ./executors/plan_merger.sh Fan-in means needs
The Learn module calls out fan-out / fan-in with needs as an exam topic. A job listing
needs: [spec_analyzer, risk_reviewer] waits for both; combined with a concurrency group it
also cannot overlap with another merge on the same branch. Parallelism is only safe when the agents' scopes do not
overlap — otherwise it increases instability, not throughput.
Subagents, built-in agents and fleet mode
Within one session, a main agent can run other agents as subagents, each in its own context window, and in parallel where subtasks are independent.
flowchart TB
TASK["Task from the user"] --> MAINA
subgraph SESSION["One session — separate context windows"]
direction TB
MAINA["Main agent<br/>orchestrator · owns the plan and the final answer"]
MAINA --> EXPLORE["explore<br/>read-only research"]
MAINA --> IMPL["implementer<br/>custom agent · edit tools"]
MAINA --> REVIEW["code-review<br/>read-only"]
end - Custom agents as subagents — give the orchestrator the
agenttool; the runtime matches subtasks to agents bynameanddescription, so specific descriptions delegate better. - Copilot CLI built-in agents —
explore(fast, read-only, safe to run in parallel),task(runs builds and tests, returns a short summary),general-purpose,code-review(high signal, never edits),research(only via/research),rubber-duck(a second opinion from a different model) andsecurity-review. /fleet(or--fleet) — the main agent splits a plan into independent subtasks and runs subagents in parallel, choosing custom agents where they fit (@test-writernames one explicitly). More subagents means more model calls and more AI credits, and it gives no benefit for inherently sequential work.- Copilot SDK —
customAgentson the session;infer: falsestops automatic selection;defaultAgent.excludedToolshides heavy tools from the main agent so it must delegate.
---
name: orchestrator
description: Breaks a feature into tasks and delegates to planner, implementer and reviewer agents
tools: ["read", "search", "agent"]
---
1. Ask @planner for a numbered plan and wait for it.
2. Delegate each implementation step to @implementer, one step at a time.
3. Ask @code-review to review the combined diff.
4. Record each handoff and decision in docs/handoffs.md. Handoffs are an IDE feature
VS Code custom agents support a handoffs property that offers a button to switch to the next agent
with a prepared prompt. The GitHub docs state that handoffs and argument-hint are
ignored by Copilot cloud agent on GitHub.com. On GitHub, express handoffs through the
agent tool, separate sessions, or artifacts and PR comments.
Configure agent isolation for parallel execution
Isolation means each agent operates in its own controlled scope so agents cannot interfere, share an execution context or thrash through repeated runs. It is what makes concurrency safe and attribution clear.
flowchart TB
subgraph REPO["One repository — isolated agents"]
direction LR
A1["agent/dependency/482<br/>lockfiles only · contents: write"]
A2["agent/refactor/511<br/>src/ only · contents: write"]
A3["agent/security/482<br/>reports only · contents: read"]
end
A1 --> PR1["PR · required checks · CODEOWNERS"]
A2 --> PR2["PR · required checks · CODEOWNERS"]
A3 --> RPT["Report artifact"] | Isolation layer | How |
|---|---|
| Branch | One branch per agent and task (agent/dependency/482); Copilot cloud agent works on exactly one branch and opens one PR per task |
| Workflow | A dedicated workflow, or job, per agent so triggers, permissions and outputs are easy to reason about |
| Permissions | Least privilege per workflow or job — the security agent needs contents: read, not write |
| Concurrency | A workflow-level group keyed on workflow and ref, with cancel-in-progress |
| Context | Subagents each get their own context window |
| Working tree | Copilot CLI --worktree / /new worktree runs a session in its own Git worktree |
# Workflow-level: one run per workflow per branch; a newer push cancels the older run
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true - Keying on
${{ github.ref }}alone makes the group global to the branch and can block unrelated workflows. - Job-level
concurrencyonly coordinates within a run, and astrategy.matrixcontrols intra-run parallelism — neither prevents two runs triggered by separate pushes from colliding. - For production deploys, use a fixed group such as
productionto serialize them.
| Agent mode | Parallel sessions across tasks? |
|---|---|
| Copilot cloud agent | Yes — many sessions, each on its own branch |
| Copilot CLI | Yes — multiple sessions, subagents and /fleet |
| Local IDE agent session | No — one at a time in a workspace |
Detect and resolve agent conflicts
| Conflict | Example | Detection and resolution |
|---|---|---|
| Textual (merge) conflict | Two agents edit the same lines | Merge-validation check; ask Copilot to resolve the conflict on its PR; escalate if it recurs |
| Semantic conflict | Both PRs merge cleanly but break together | Require branches to be up to date before merging; a merge queue that tests the combined result |
| Overlapping code changes | Refactoring agent edits a lockfile the dependency agent owns | Scope boundaries per agent; CODEOWNERS; a scope-check workflow |
| Duplicated effort | Two PRs fix the same alert differently | One owner per issue (assignment); labels; close the duplicate and keep the evidence |
| Contradictory outputs | One agent recommends 2.x, another pins 1.x | Arbitration by code owners; decision recorded in the PR; escalate to a human |
| Policy conflict | A path needs a different approval than the rest of the PR | Rulesets and CODEOWNERS decide, not timing |
- name: Validate the branch still merges cleanly with main
run: |
git fetch origin main
git merge --no-commit --no-ff origin/main || {
echo "::error::Conflicts with main — rebase or escalate"
exit 1
} Escalate instead of retrying when:
- a PR still conflicts after two rebase attempts,
- a required check fails twice with the same failure signature, or
- two agents propose incompatible fixes for the same alert.
Timing must not pick the winner
Without arbitration rules, whichever PR merges first "wins" and reviewers untangle the mess afterwards. Reliable systems detect conflicts early with required checks and resolve them intentionally through ownership (CODEOWNERS) and explicit escalation.
5.2 Configure observability for multi-agent behaviour
Produce artifacts suitable for review and audit
As the number of agents grows, traceability becomes the primary requirement: which agent produced a change, what it decided, what evidence supports it, and what happened next. Every meaningful step should leave a durable trace in GitHub.
- Attribution conventions — PR titles such as
[agent: dependency] Update axios to 1.8.2; labelsagent: dependency,agent: security; Copilot notes the custom agent it used in the PR description. - A standard PR body — Objective, Plan, Evidence, Decisions and handoffs, Risks and rollback.
- Machine-readable evidence —
report.json,plan.jsonand test results uploaded withactions/upload-artifact. - Workflow outputs — step and job outputs as explicit contracts between jobs, not values scraped from logs.
Document decisions, handoffs and outcomes
## Objective
Update axios to 1.8.2 (Dependabot alert #57).
## Plan
1. Bump axios in package.json 2. Regenerate the lockfile 3. Run tests
## Evidence
- CI run: https://github.com/org/repo/actions/runs/123456
- Dependency review: clean
## Decisions and handoffs
- Decision: pinned to 1.8.x, not 2.x — 2.x drops Node 18 support
- Handoff: @security-agent to confirm alert closure; next owner if blocked: @platform-team
## Risks and rollback
- Low risk; revert the merge commit
For multi-step orchestrations, keep a running handoff log (for example docs/handoffs.md) committed on the
branch, so the next agent — or person — can see who did what and why.
Perform post-hoc analysis
| Question | Source |
|---|---|
| What did each agent do and why? | Session logs (Agents page, linked from every commit) |
| What did the run produce? | Download the run's artifacts from the Artifacts section — the primary evidence even when live logs are gone |
| An artifact is missing — who deleted it? | Organization audit log, action:artifact.destroy |
| Which agent actions happened across the org? | Audit log filtered by actor:Copilot (180 days), grouped by agent_session_id; stream to a SIEM for longer retention |
| When did each subagent start, finish or fail? | SDK subagent.started / completed / failed events; subagentStart / subagentStop hooks; OpenTelemetry traces |
| What did I run last week? | Ask Copilot Chat to search your synced sessions |
5.3 Detect and respond to multi-agent failures and degraded behaviour
Identify failed, partial or stalled executions
Multi-agent failures are usually coordination failures, even when each agent is individually capable.
| Failure mode | What you see | Signal |
|---|---|---|
| Failed | The session or job errored | Failed run; subagent.failed; errorOccurred hook |
| Partial | A PR exists but evidence or validation is missing | Missing required check; empty Evidence section |
| Stalled | Checks fail repeatedly or approvals never arrive | PR age; pending environment approvals; a session that is still running near its 59-minute limit |
| Conflicting | PRs compete and block each other | Merge conflicts; duplicate PRs on one issue |
| Flapping | Workflows rerun with no convergence | Many cancelled or failed runs on the same branch |
# List recent agent tasks, then stream one session's log live
gh agent-task list
gh agent-task view 214 --log --follow session.on((event) => {
if (event.type === "subagent.failed") {
logger.error(`${event.data.agentName} failed: ${event.data.error}`);
// retry, fall back to the parent agent, or escalate
}
}); Respond to degraded behaviour or coordination
- Steer a session that is heading the wrong way; stop it if the task is no longer needed — pushed commits are preserved.
- Pause the automation or workflow that keeps re-triggering (disable the workflow, or the automation's trigger).
- If an orchestrator cannot call a specialist, check whether that profile sets
disable-model-invocation: true— such an agent cannot be invoked as a subagent. - If cloud agent is blocked by a ruleset (for example, restricted commit authors), add Copilot as a bypass actor on that ruleset.
- A policy block from a
preToolUsehook ("destructive operation detected") is a designed handoff to a human, not an error to retry.
Implement multi-agent recovery patterns
| Pattern | How |
|---|---|
| Bounded retry | An agent may revise its own PR branch to fix failures, within a limit |
| Escalation threshold | Same required check fails twice → stop and hand to a human with links and a summary |
| Rollback | Small, scoped PRs; close or revert; deploy explicit refs so a previous version is one redeploy away |
| Human-in-the-loop | Environments with required reviewers for high-risk steps; a human decides between competing PRs |
| Graceful degradation | On subagent.failed, fall back to the parent agent or skip the optional step and report it |
5.4 Manage the lifecycle of agents within multi-agent workflows
Add agents to existing workflows
- Define the new agent's responsibility and scope so it does not overlap existing agents.
- Create the profile —
.github/agents/NAME.agent.mdfor one repository, or theagents/folder of the organization's.github/.github-privaterepository for everyone. - For organization or enterprise agents, test privately first in
.github/agentsof the.github-privaterepository (only usable from that repository), then release by moving it to the rootagentsfolder. - Wire it in: add it to the orchestrator's prompt, a workflow job, or an automation — and give it its own branch prefix, label and concurrency group.
- Protect
.github/agents/,.github/hooks/and MCP configuration with CODEOWNERS and required code-owner review.
Update, reconfigure or replace without disruption
- Versioning is by commit SHA. A new task uses the latest profile on the repository and branch; once the agent opens a PR, interactions on that PR keep using the same version. Active work is not disrupted by a profile change.
- Try a change on a branch — you can create a profile on a chosen branch — before merging it to the default branch.
- Replace by introducing the new agent alongside the old one, moving callers over, then retiring the old one.
- Use the invocation controls to stage changes:
user-invocable: falsehides an agent from manual selection while keeping it callable programmatically;disable-model-invocation: truestops automatic selection (and subagent calls) while leaving it selectable by users. - Watch name precedence: a repository profile with the same name overrides the organization's, which overrides the enterprise's.
Retire agents while preserving auditability
- Remove or rename the profile through a pull request — Git history keeps the exact configuration every past PR used.
- Update every orchestrator prompt, workflow and automation that referenced it first, so nothing fails at call time.
- Keep the evidence: cloud agent sessions can be archived but not deleted, audit log events remain, and artifacts should be retained long enough for your audit needs.
- Consider a deprecation window —
disable-model-invocation: trueand a note in the description — before deletion.
Lifecycle is governance
Agents and their guardrails evolve together: each needs an owner, a runbook and a review cadence. The broader governance loop — weekly failure reviews, monthly permission reviews, quarterly ruleset audits — is on the guardrails page.