멀티 에이전트를 사용하면 에이전트가 하위 에이전트에 작업을 위임할 수 있습니다. 각 하위 에이전트는 자체 컨텍스트에서 다른 하위 에이전트와 병렬로 작업할 수 있습니다. 주 에이전트는 이들의 작업을 조율하고 결과를 종합합니다.
서로 다른 문서를 검토하거나 장애의 원인 후보를 각각 조사하는 등 독립적으로 수행할 수 있는 작업에는 하위 에이전트를 사용하세요. 각 작업에서 답해야 할 질문과 기대하는 결과를 명확히 제시하세요.
짧은 작업이나 앞 단계의 결과가 필요한 단계는 주 에이전트가 직접 처리하도록 하세요. 여러 에이전트가 같은 파일을 편집할 때는 변경 사항을 서로 조율해야 합니다.
세션을 생성할 때 agent.multi_agent.enabled를 true로 설정하세요. 하네스는 하위 에이전트를 생성하고, 메시지를 보내고, 응답을 기다리고, 실행을 중단하는 도구를 제공합니다. 이 도구들을 직접 선언할 필요는 없습니다.
다음 예제에서는 사용자 입력에서 하위 에이전트 두 개를 명시적으로 요청합니다. 각 하위 에이전트가 릴리스 노트를 한 묶음씩 검토하고 주 에이전트가 검토 결과를 종합합니다. 이 예제에는 환경이나 별도로 설정한 도구가 필요하지 않습니다.
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
}'
environment.type: "none"을 사용할 때는 세션 생성 요청에 최초 input을 포함하세요. stream: true를 설정하면 첫 번째 턴도 스트리밍됩니다. 스트림 처리 및 복구 방법은 세션 이벤트 및 항목을 참고하세요.
max_concurrent_subagents는 동시에 실행할 수 있는 하위 에이전트 수를 제한합니다. 기본값은 6이며, 작업을 조율하는 주 에이전트는 이 수에 포함되지 않습니다. 위임을 활성화할 때는 양의 정수를 지정하세요.
위임을 비활성화하려면 multi_agent를 생략하거나, enabled를 false로 설정하고 동시 실행 제한을 생략하세요. 이 설정은 세션 생성 시 적용됩니다. 저장된 에이전트의 설정을 변경하면 새로 생성하는 세션에 적용됩니다.
에이전트가 파일을 사용하거나 명령어를 실행해야 한다면 환경을 추가하세요. 주 에이전트와 하위 에이전트는 해당 환경의 파일 시스템을 공유합니다. 하위 에이전트를 생성해도 별도의 환경이 생성되지는 않습니다.
다음 예제는 자체 환경에서 작업할 세션을 생성합니다.
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"
}
}'
반환된 세션 ID와 환경 ID를 애플리케이션에 저장하세요. 환경을 연결한 다음 입력을 보내 작업을 시작하세요.
하위 에이전트는 설정된 MCP 도구와 해당 도구의 인증 정보 및 허용된 도구 목록, 웹 검색 설정을 상속합니다. 환경에 있는 파일과 명령줄 도구도 사용할 수 있습니다. 하위 에이전트는 함수 도구를 지원하지 않습니다.
세션 이벤트 스트림에서 하위 에이전트의 활동을 확인할 수 있습니다.
agent.session.subagent.created는 새 하위 에이전트의 ID를 제공합니다.
agent.session.turn.item.added와 agent.session.turn.item.done은 에이전트 간 작업 조율에 사용된 동작을 알려 줍니다. 관련 항목 유형에는 create_subagent_call, send_subagent_input_call, wait_for_subagents_call, interrupt_subagent_call이 있습니다.
이 동작들은 하네스가 실행합니다. 생성 또는 대기 동작이 완료되어도 하위 에이전트의 작업까지 끝났다는 뜻은 아닙니다. 생성 항목의 agent_id는 하위 에이전트 생성을 요청한 에이전트를 식별합니다.
작업 조율 항목에는 메시지 내용이 생략될 수 있습니다. 에이전트 간에 주고받은 텍스트가 제공되는 경우 agent_message 항목에서 확인할 수 있지만, 스트림은 전체 대화 기록을 제공하지 않습니다.
종합 결과는 주 에이전트의 응답에서 확인하세요. 각 하위 에이전트의 기록을 포함해 이전 작업을 살펴보려면 저장된 항목과 턴을 조회하세요.
명령어 항목과 해당 세션 ID를 사용해 명령어가 실행된 턴을 조회하면 어떤 에이전트가 실행했는지 확인할 수 있습니다. 주 에이전트가 실행한 경우 해당 턴의 subagent_id 값은 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