---
title: "Multi-agent"
description: "Build a manager agent that routes GitHub work to a reviewer, a triager and a releaser, each a subagent with its own preset and approval policy."
canonical_url: "https://github-tools.com/guides/multi-agent"
---
# Multi-agent

> Build a manager agent that routes GitHub work to a reviewer, a triager and a releaser, each a subagent with its own preset and approval policy.

To split GitHub work across several AI agents, give a manager agent no GitHub tools and one subagent per job, each mounting the preset for that job: the manager reads the request, delegates to the right specialist, and combines the answers. This guide builds a manager with three subagents on [eve](https://github-tools.com/integrations/eve), then shows the same shape with the AI SDK.

## What you'll build

Ask "review #42 and check whether the changelog needs updating" and the manager calls `reviewer` for the pull request and `releaser` for the changelog, then answers with both results. Each specialist lists only its preset's tools and has its own approval policy, so no single context carries all 97 tools.

<subagent-router>



</subagent-router>

## Before you start

- Familiarity with the [eve extension](https://github-tools.com/integrations/eve) and [presets](https://github-tools.com/presets).
- A GitHub connector named `github/my-connector` in [Vercel Connect](https://github-tools.com/auth#create-a-github-connector), with its token pulled locally.

## 1. Install the packages

<code-group>

```bash [pnpm]
pnpm add @github-tools/eve-extension @vercel/connect eve ai zod
```

```bash [npm]
npm install @github-tools/eve-extension @vercel/connect eve ai zod
```

```bash [yarn]
yarn add @github-tools/eve-extension @vercel/connect eve ai zod
```

```bash [bun]
bun add @github-tools/eve-extension @vercel/connect eve ai zod
```

</code-group>

The project has a manager and three subagent directories:

```text
agent/
├── agent.ts                     # defineAgent({ model }), no GitHub extension
├── instructions.md              # routing rules
└── subagents/
    ├── reviewer/
    │   ├── agent.ts             # description + model
    │   ├── instructions.md
    │   └── extensions/github.ts # preset: 'code-review'
    ├── triager/
    │   ├── agent.ts
    │   ├── instructions.md
    │   └── extensions/github.ts # preset: 'issue-triage'
    └── releaser/
        ├── agent.ts
        ├── instructions.md
        └── extensions/github.ts # preset: 'release-manager'
```

eve turns each directory under `agent/subagents/` into a tool named after it. The manager's model calls `reviewer` with `{ message }`, and the subagent's final reply comes back as the result. A [declared subagent](https://eve.dev/docs/subagents#the-isolation-boundary) inherits nothing from the root, so each one mounts its own copy of the extension.

## 2. Write the manager's routing rules

The manager has no extension. Its instructions say which specialist handles what:

```md [agent/instructions.md]
You are the GitHub manager for this repository. You never call GitHub tools yourself.
You have three specialists: reviewer, triager, and releaser.

- Pull request reviews, diffs, or code quality: call reviewer.
- Issue classification, labels, or backlog questions: call triager.
- Changelogs, release notes, or what changed since the last release: call releaser.
- When a request spans several specialists, call each and combine their answers.
- Put everything a specialist needs in its message. It never sees this conversation.
```

## 3. Add a specialist

The reviewer is three files. `description` is required: the manager's model reads it to decide when to delegate.

```ts [agent/subagents/reviewer/agent.ts]
import { defineAgent } from 'eve'

export default defineAgent({
  description: 'Reviews pull requests: reads diffs and CI status, and drafts review comments.',
  model: 'anthropic/claude-opus-5.5',
})
```

```ts [agent/subagents/reviewer/extensions/github.ts]
import githubExtension from '@github-tools/eve-extension'

export default githubExtension({
  connector: 'github/my-connector',
  preset: 'code-review',
})
```

```md [agent/subagents/reviewer/instructions.md]
You review pull requests. Read the description and the changed files, check for bugs
and missing edge cases, and reply with a short, actionable summary.
```

The other two follow the same shape:

<table>
<thead>
  <tr>
    <th>
      Subagent
    </th>
    
    <th>
      <code>
        preset
      </code>
    </th>
    
    <th>
      <code>
        description
      </code>
    </th>
    
    <th>
      <code>
        requireApproval
      </code>
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        triager
      </code>
    </td>
    
    <td>
      <code>
        issue-triage
      </code>
    </td>
    
    <td>
      Triages issues: classifies, labels, and comments with a next step
    </td>
    
    <td>
      <code>
        { addLabels: false, addIssueComment: false }
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        releaser
      </code>
    </td>
    
    <td>
      <code>
        release-manager
      </code>
    </td>
    
    <td>
      Summarizes changes since the last release and drafts release notes
    </td>
    
    <td>
      default: every write asks
    </td>
  </tr>
</tbody>
</table>

All three share one connector here. Give each its own connector, or `connect: { repositories: [...] }`, when they should reach different repositories.

## 4. Decide who approves

Approvals from a subagent appear on the manager's session, so the person talking to the manager answers them.

`requireApproval: 'auto'` doesn't help inside a subagent. The decision model checks whether the latest message asked for the write, and in a subagent session that message comes from the manager, not a person, so every write keeps asking.

## Run it

```bash [Terminal]
npx eve dev
```

Ask "review vercel-labs/github-tools#42 and check whether the changelog needs updating for the next release". The manager calls `reviewer` and `releaser`, then answers with both results.

## Build it with the AI SDK

Without eve, wrap each `createGithubAgent` in a tool and give the tools to a manager `ToolLoopAgent`:

```ts [manager.ts]
import { createGithubAgent, type GithubToolPreset } from '@github-tools/sdk'
import { connectGithubToken } from '@github-tools/sdk/connect'
import { ToolLoopAgent, tool } from 'ai'
import { z } from 'zod'

function specialist(preset: GithubToolPreset, description: string) {
  const agent = createGithubAgent({
    model: 'anthropic/claude-opus-5.5',
    token: connectGithubToken('github/my-connector', { preset }),
    preset,
  })
  return tool({
    description,
    inputSchema: z.object({ message: z.string().describe('Everything the specialist needs to do the task') }),
    execute: async ({ message }) => (await agent.generate({ prompt: message })).text,
  })
}

export const manager = new ToolLoopAgent({
  model: 'anthropic/claude-opus-5.5',
  instructions: 'Route GitHub requests to the right specialist: reviewer, triager, or releaser.',
  tools: {
    reviewer: specialist('code-review', 'Reviews pull requests and drafts review comments.'),
    triager: specialist('issue-triage', 'Classifies and labels GitHub issues.'),
    releaser: specialist('release-manager', 'Drafts release notes from merged pull requests.'),
  },
})
```

Here a write that needs approval ends the specialist's turn, and its request stays inside that agent instead of reaching the manager's caller. Keep the specialists to reads, or set `requireApproval: false` only where a person reviews the result anyway.

## FAQ

<accordion>
<accordion-item label="When should I use subagents instead of combining presets?">

Combine presets, as in `preset: ['code-review', 'issue-triage']`, when one agent does both jobs in the same conversation and the merged tool list stays small. Use subagents when the jobs are separate, need different approval policies or repositories, or together would put most of the 97 tools in one context.

</accordion-item>

<accordion-item label="Does each subagent need its own token?">

No. Here all three use one connector, and each mints a token scoped to its own preset. Use separate connectors when the subagents should reach different repositories or accounts.

</accordion-item>

<accordion-item label="Can I add more specialists?">

Yes. Add a directory under `agent/subagents/`, such as a `security-audit` subagent for vulnerability reports. With many specialists, set `tool: 'deferred'` in a subagent's `agent.ts`, so the manager finds it with `eve__search` instead of listing it on every call.

</accordion-item>
</accordion>


## Sitemap

See the full [sitemap](https://github-tools.com/sitemap.md) for all pages.
