L’orchestration multi-agent permet à un agent de déléguer des tâches à des sous-agents. Chaque sous-agent dispose de son propre contexte et peut travailler en parallèle avec les autres. L’agent principal coordonne leur travail et rassemble leurs résultats.
Utilisez des sous-agents pour des tâches indépendantes, par exemple pour examiner des documents distincts ou explorer différentes causes possibles d’une défaillance. Pour chaque tâche, formulez une question précise et indiquez le résultat attendu.
Confiez à l’agent principal les tâches courtes et les étapes qui dépendent les unes des autres. Les agents qui modifient les mêmes fichiers doivent coordonner leurs modifications.
Définissez agent.multi_agent.enabled sur true à la création de la session. Le harnais fournit les outils nécessaires pour créer des sous-agents, leur envoyer des messages, les attendre et les interrompre. Vous n’avez pas à déclarer ces outils vous-même.
Dans cet exemple, le message de l’utilisateur demande explicitement deux sous-agents. Chacun examine un ensemble de notes de version, puis l’agent principal fait la synthèse de leurs observations. Cet exemple ne nécessite aucun environnement ni outil configuré.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import OpenAI from "openai";
const client = new OpenAI();
const events = await client.beta.agents.sessions.create({
agent: {
model: "gpt-6-astra",
instructions:
"Delegate each release to a separate subagent. Ask each to extract customer-visible changes and required migration steps using only its release notes. Wait for both results, then combine them into one release summary with release labels. Do not invent missing details.",
multi_agent: { enabled: true, max_concurrent_subagents: 2 },
},
environment: { type: "none" },
input:
"Use two subagents, one for each release, and combine their findings into a labeled summary. Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",
stream: true,
});
events.withResultCollection();
try {
for await (const event of events) {
console.log(JSON.stringify(event));
}
console.log((await events.finalResult()).output_text);
} finally {
events.controller.abort();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from openai import OpenAI
client = OpenAI()
with client.beta.agents.sessions.create(
agent={
"model": "gpt-6-astra",
"instructions": "Delegate each release to a separate subagent. Ask each to extract customer-visible changes and required migration steps using only its release notes. Wait for both results, then combine them into one release summary with release labels. Do not invent missing details.",
"multi_agent": {"enabled": True, "max_concurrent_subagents": 2},
},
environment={"type": "none"},
input="Use two subagents, one for each release, and combine their findings into a labeled summary. Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",
stream=True,
).with_result_collection() as stream:
for event in stream:
print(event.model_dump_json())
result = stream.get_final_result()
print(result.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
ctx := context.Background()
client := openai.NewClient()
events := client.Beta.Agents.Sessions.NewStreaming(ctx, openai.BetaAgentSessionNewParams{Agent: openai.BetaAgentSessionNewParamsAgent{Model: openai.String("gpt-6-astra"),
Instructions: openai.String("Delegate each release to a separate subagent. Ask each to extract customer-visible changes and required migration steps using only its release notes. Wait for both results, then combine them into one release summary with release labels. Do not invent missing details."),
MultiAgent: openai.MultiAgentConfigParam{Enabled: true,
MaxConcurrentSubagents: openai.Int(2)}},
Environment: openai.EnvironmentParamUnion{OfParamNone: &openai.EnvironmentParamNone{}},
Input: openai.BetaAgentSessionNewParamsInputUnion{OfString: openai.String("Use two subagents, one for each release, and combine their findings into a labeled summary. Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.")}})
defer events.Close()
openai.BetaAgentSessionWithResultCollection(events)
for events.Next() {
fmt.Println(events.Current().RawJSON())
}
result, err := openai.BetaAgentSessionFinalResult(events)
if err != nil {
panic(err)
}
fmt.Println(result.OutputText())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.beta.agents.MultiAgentConfigParam;
import com.openai.models.beta.agents.sessions.SessionCreateParams;
import com.openai.services.beta.agents.AgentTurnResults;
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
try (var events =
client
.beta()
.agents()
.sessions()
.createStreaming(
SessionCreateParams.builder()
.agent(
SessionCreateParams.Agent.builder()
.model("gpt-6-astra")
.instructions(
"Delegate each release to a separate subagent. Ask each to extract"
+ " customer-visible changes and required migration steps using"
+ " only its release notes. Wait for both results, then combine"
+ " them into one release summary with release labels. Do not"
+ " invent missing details.")
.multiAgent(
MultiAgentConfigParam.builder()
.enabled(true)
.maxConcurrentSubagents(2L)
.build())
.build())
.environmentNone()
.input(
"Use two subagents, one for each release, and combine their findings into"
+ " a labeled summary. Release A: Search now supports filtering by date."
+ " Existing queries"
+ " continue to work. Release B: The export endpoint now returns a"
+ " download URL instead of file bytes. Update clients to fetch that"
+ " URL.")
.build())) {
AgentTurnResults.withResultCollection(events);
events.stream().forEach(System.out::println);
System.out.println(AgentTurnResults.getFinalResult(events).outputText());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25require "openai"
require "json"
client = OpenAI::Client.new
events = client.beta.agents.sessions.create_streaming(
agent: {
model: "gpt-6-astra",
instructions: "Delegate each release to a separate subagent. Ask each to extract customer-visible changes and required migration steps using only its release notes. Wait for both results, then combine them into one release summary with release labels. Do not invent missing details.",
multi_agent: {
enabled: true,
max_concurrent_subagents: 2
}
},
environment: { type: "none" },
input: "Use two subagents, one for each release, and combine their findings into a labeled summary. Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL."
)
begin
events.with_result_collection
events.each { |event| puts JSON.generate(event.to_h) }
result = events.get_final_result
puts result.output_text
ensure
events.close
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14curl --no-buffer --fail-with-body https://api.openai.com/v1/agents/sessions \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": {
"model": "gpt-6-astra",
"instructions": "Delegate each release to a separate subagent. Ask each to extract customer-visible changes and required migration steps using only its release notes. Wait for both results, then combine them into one release summary with release labels. Do not invent missing details.",
"multi_agent": { "enabled": true, "max_concurrent_subagents": 2 }
},
"environment": { "type": "none" },
"input": "Use two subagents, one for each release, and combine their findings into a labeled summary. Release A: Search now supports filtering by date. Existing queries continue to work. Release B: The export endpoint now returns a download URL instead of file bytes. Update clients to fetch that URL.",
"stream": true
}'
Avec environment.type: "none", incluez le champ input initial dans la requête de création. Avec stream: true, vous recevez également le premier tour en continu. Consultez la page Événements et éléments de session pour savoir comment traiter le flux et le reprendre après une interruption.
max_concurrent_subagents limite le nombre de sous-agents pouvant s’exécuter simultanément. La valeur par défaut est 6, sans compter l’agent coordinateur. Indiquez un entier strictement positif lorsque la délégation est activée.
Pour désactiver la délégation, omettez multi_agent ou définissez enabled sur false sans préciser de limite. Ces paramètres s’appliquent à la création de la session. Les modifications apportées à un agent enregistré s’appliquent aux nouvelles sessions.
Lorsque les agents doivent accéder à des fichiers ou exécuter des commandes, ajoutez un environnement. L’agent coordinateur et les sous-agents partagent son système de fichiers. La création d’un sous-agent ne crée pas d’environnement supplémentaire.
Cet exemple crée une session pour travailler dans votre propre environnement.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const result = await client.beta.agents.sessions.create({
agent: {
model: "gpt-6-astra",
instructions:
"Prepare release notes from the repository. Have one subagent identify customer-visible changes and another check migration guides and examples, then combine their findings.",
multi_agent: {
enabled: true,
max_concurrent_subagents: 3,
},
},
environment: {
type: "self_hosted",
workspace_directory: "/workspace",
},
});
1
2
3
4
5
6
7
8result = client.beta.agents.sessions.create(
agent={
"model": "gpt-6-astra",
"instructions": "Prepare release notes from the repository. Have one subagent identify customer-visible changes and another check migration guides and examples, then combine their findings.",
"multi_agent": {"enabled": True, "max_concurrent_subagents": 3},
},
environment={"type": "self_hosted", "workspace_directory": "/workspace"},
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17result, err := client.Beta.Agents.Sessions.New(ctx,
openai.BetaAgentSessionNewParams{
Agent: openai.BetaAgentSessionNewParamsAgent{
Model: openai.String("gpt-6-astra"),
Instructions: openai.String("Prepare release notes from the repository. Have one subagent identify customer-visible changes and another check migration guides and examples, then combine their findings."),
MultiAgent: openai.MultiAgentConfigParam{
Enabled: true,
MaxConcurrentSubagents: openai.Int(3),
},
},
Environment: openai.EnvironmentParamUnion{
OfParamSelfHosted: &openai.EnvironmentParamSelfHosted{WorkspaceDirectory: "/workspace"},
},
})
if err != nil {
panic(err)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26var result =
client
.beta()
.agents()
.sessions()
.create(
SessionCreateParams.builder()
.agent(
SessionCreateParams.Agent.builder()
.model("gpt-6-astra")
.instructions(
"Prepare release notes from the repository. Have one subagent"
+ " identify customer-visible changes and another check"
+ " migration guides and examples, then combine their"
+ " findings.")
.multiAgent(
MultiAgentConfigParam.builder()
.enabled(true)
.maxConcurrentSubagents(3L)
.build())
.build())
.environment(
EnvironmentParam.SelfHosted.builder()
.workspaceDirectory("/workspace")
.build())
.build());
1
2
3
4
5
6
7
8
9
10
11
12
13
14result = client.beta.agents.sessions.create(
agent: {
model: "gpt-6-astra",
instructions: "Prepare release notes from the repository. Have one subagent identify customer-visible changes and another check migration guides and examples, then combine their findings.",
multi_agent: {
enabled: true,
max_concurrent_subagents: 3
}
},
environment: {
type: "self_hosted",
workspace_directory: "/workspace"
}
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18curl https://api.openai.com/v1/agents/sessions \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": {
"model": "gpt-6-astra",
"instructions": "Prepare release notes from the repository. Have one subagent identify customer-visible changes and another check migration guides and examples, then combine their findings.",
"multi_agent": {
"enabled": true,
"max_concurrent_subagents": 3
}
},
"environment": {
"type": "self_hosted",
"workspace_directory": "/workspace"
}
}'
Enregistrez dans votre application les identifiants de session et d’environnement renvoyés. Connectez l’environnement, puis envoyez les données d’entrée pour lancer le travail.
Les sous-agents héritent des outils MCP configurés, des identifiants d’accès et de la liste des outils autorisés, ainsi que des paramètres de recherche web. Ils peuvent également utiliser les fichiers et les outils en ligne de commande de l’environnement. Les sous-agents ne prennent pas en charge les outils de type fonction.
Le flux d’événements de la session rend compte de l’activité des sous-agents.
agent.session.subagent.created fournit l’identifiant du nouveau sous-agent.
agent.session.turn.item.added et agent.session.turn.item.done signalent les actions de coordination. Les éléments associés peuvent notamment être de type create_subagent_call, send_subagent_input_call, wait_for_subagents_call ou interrupt_subagent_call.
Le harnais exécute ces actions. Une action de création ou d’attente peut se terminer avant que le sous-agent ait achevé sa tâche. Dans un élément de création, agent_id identifie l’agent qui a demandé la création du sous-agent.
Les éléments de coordination ne contiennent pas toujours le contenu des messages. Un élément agent_message contient le texte échangé entre les agents lorsqu’il est disponible, mais le flux ne fournit pas de transcription complète de la conversation.
Lisez la réponse de l’agent principal pour obtenir la synthèse des résultats. Consultez les éléments et les tours enregistrés pour examiner le travail déjà effectué, y compris l’historique de chaque sous-agent.
À partir de l’élément correspondant à une commande et de son identifiant de session, récupérez le tour auquel appartient la commande pour identifier l’agent qui l’a exécutée. Pour l’agent principal, le champ subagent_id du tour vaut null.
1
2
3
4
5
6// Use the saved session ID and command execution item from your application.
const turn = await client.beta.agents.sessions.turns.retrieve(
command.turn_id,
{ session_id: sessionId }
);
console.log(turn.subagent_id);
1
2
3
4
5# Use the saved session ID and command execution item from your application.
turn = client.beta.agents.sessions.turns.retrieve(
command.turn_id, session_id=session_id
)
print(turn.subagent_id)
1
2
3
4
5
6// Use the saved session ID and command execution item from your application.
turn, err := client.Beta.Agents.Sessions.Turns.Get(ctx, sessionID, item.TurnID)
if err != nil {
panic(err)
}
fmt.Println(turn.SubagentID)
1
2
3
4
5
6
7
8
9
10
11
12
13// Use the saved session ID and command execution item from your application.
var turn =
client
.beta()
.agents()
.sessions()
.turns()
.retrieve(
TurnRetrieveParams.builder()
.sessionId(sessionId)
.turnId(command.turnId())
.build());
System.out.println(turn.subagentId());
1
2
3# Use the saved session ID and command execution item from your application.
turn = client.beta.agents.sessions.turns.retrieve(item.turn_id, session_id: session_id)
puts turn.subagent_id