멀티 에이전트
멀티 에이전트 (Multi-agent)
개요
Multi-agent는 모델이 서브에이전트를 병렬로 띄우고 조정해, 그 작업을 종합해 최종 응답을 제공하게 해요. 코드베이스 탐색, 문서화, 구현처럼 병렬 작업 위임의 이점이 있는 복잡한 과업을 가진 앱에 특히 효과적이에요.
출처: 문서
본문
Multi-agent는 모든 GPT-5.6 모델에서 베타 기능으로 사용할 수 있어요. 앱에서 Multi-agent를 활성화하기 전에 모델 페이지를 확인하세요.
언제 Multi-agent를 쓰나요
과업은 단일 에이전트가 순차적으로 완료할 독립적인 작업 구간으로 나눌 수 있는 경우가 많아요. 여러 에이전트는 그걸 병렬로 처리할 수 있어요. Multi-agent는 루트 에이전트가 여러 서브에이전트에 위임해 동시에 작업을 완료하게 해요. 이점은 여러 가지예요.
- 병렬 실행. 독립적인 연구·분석·구현 과업이 동시에 진행돼 더 빠르게 실행될 수 있어요.
- 집중된 컨텍스트. 각 서브에이전트는 경계가 있는(bounded) 과업을 받고 자체 컨텍스트를 유지해서, 관련 없는 작업 라인 사이의 컨텍스트 간섭을 줄이고 성능을 높여요.
- 모델 주도 조정. 루트 에이전트가 서브에이전트를 만들고, 추가 정보를 보내고, 결과를 기다리고, 최종 답변을 종합해요. 앱이 오케스트레이션을 구현할 필요가 없어요.
Multi-agent 오케스트레이션은 과업을 구체적이고 독립적인 워크스트림으로 나눌 수 있을 때 가장 유용해요.
- 큰 코드베이스의 서로 다른 부분 탐색
- 여러 제안·문서·가설 비교
- 여러 출처를 병렬 연구
- 독립 컴포넌트 구현이나 독립 테스트 스위트 작성
- 실패의 여러 가능한 원인을 병렬 조사
- 문제에 대한 여러 접근 방식을 동시에 탐색
서브에이전트 추가는 토큰 사용을 늘릴 수 있고, 단일 정렬된 추론 체인에 의존하는 과업, 공유 변경 가능 상태에 자주 쓰는 과업, 이미 느린 외부 작업 하나가 지배하는 과업에서는 그리 유익하지 않을 수 있어요.
| Multi-agent를 쓸 때 | 단일 에이전트를 선호할 때 |
|---|---|
| 작업을 독립적이고 경계 있는 과업으로 나눌 수 있음 | 각 단계가 이전 단계에 직접 의존함 |
| 분리된 컨텍스트가 집중력을 높임 | 과업이 짧은 실행 하나로 끝날 만큼 작음 |
| 병렬 탐색이 벽시계 시간을 줄일 수 있음 | 에이전트가 같은 변경 가능 자원을 두고 경쟁함 |
| 독립적 발견 비교가 커버리지를 높임 | 고정된 결정적 실행 그래프가 필요함 |
Quickstart
Python·JavaScript 예시는 베타 Responses SDK를 사용해요. HTTP 요청에는 client.beta.responses를 쓰고 betas 인자에 responses_multi_agent=v1을 전달해요. 원시 HTTP·WebSocket 연결에는 요청·연결 헤더에 OpenAI-Beta: responses_multi_agent=v1을 전달해요. Multi-agent가 베타인 동안 항목 스키마는 바뀔 수 있어요.
Responses API 요청에서 multi_agent.enabled로 Multi-agent를 활성화해요. true면 루트 에이전트가 서브에이전트 트리를 생성할 자격을 얻어요. 서브에이전트는 요청의 모델과 사용 가능한 도구를 공유하고, 에이전트들은 스폰·메시징·대기 같은 협업 프리미티브로 조정해요. 루트 에이전트는 서브에이전트 응답을 종합해 최종 응답을 제공할 책임이 있어요.
from openai import OpenAI
client = OpenAI()
def review_pull_request(diff: str) -> str:
response = client.beta.responses.create(
model="gpt-5.6-sol",
input=(
"Review the pull-request diff below with three agents: one for "
"correctness, one for security, and one for missing tests. "
"Reconcile duplicate or conflicting findings, then return a "
"prioritized review with file and line references.\n\n"
f"<diff>\n{diff}\n</diff>"
),
multi_agent={
"enabled": True,
"max_concurrent_subagents": 3,
},
betas=["responses_multi_agent=v1"],
)
return "".join(
part.text
for item in response.output
if (
item.type == "message"
and item.agent is not None
and item.agent.agent_name == "/root"
and item.phase == "final_answer"
)
for part in item.content
if part.type == "output_text"
)
max_concurrent_subagents는 전체 에이전트 트리에서 동시에 활성화될 수 있는 서브에이전트의 최대 수를 설정해요. 자식·손자·더 깊은 서브에이전트를 포함한 모든 후손을 포함하지만 루트 에이전트는 제외해요. API는 이 설정에 고정 상한을 두지 않아요. 기본값은 3이고 대부분의 워크로드에 권장돼요. Multi-agent 실행에도 트리 깊이나 실행 중 생성되는 총 서브에이전트 수에 고정 제한이 없어요.
루트 모델이 언제 서브에이전트를 띄울지 조정하려면 developer 메시지를 추가하세요. 이 developer 메시지는 루트·서브에이전트에 주입되는 지시에 덧붙여져요. 예를 들어 "사용자가 서브에이전트·위임·병렬 에이전트 작업을 명시적으로 요청하지 않으면 서브에이전트를 띄우지 마세요" 또는 "Proactive Multi-agent delegation이 활성화되어 있습니다. 병렬 작업이 속도나 품질을 실질적으로 개선할 때 서브에이전트를 쓰세요" 같은 예시가 있어요.
Multi-agent 동작 방식
Responses API는 루트·서브에이전트 모델에 호스팅된 오케스트레이션 액션과 그 사용 지시를 제공해요. 루트 에이전트는 /root로 이름 지어요. 생성된 서브에이전트는 계층적 경로를 사용해요.
/root
├── /root/researcher
├── /root/reviewer
└── /root/reviewer/tester
Multi-agent는 총 서브에이전트 수나 트리 깊이에 고정 제한을 두지 않아요. 대부분의 과업에서는 기본 max_concurrent_subagents 값 3을 쓰세요. 이 설정은 자식과 더 깊은 후손을 포함해 전체 트리의 활성 서브에이전트 턴 수를 제한해요.
Multi-agent 모드가 활성화되면 Responses API가 여섯 가지 호스팅 협업 액션을 제공해요. 이것들은 multi_agent_call 항목으로 보일 수 있어요. 앱은 이것을 실행하거나 출력을 제출하면 안 돼요.
| Action | 용도 |
|---|---|
spawn_agent |
서브에이전트를 만들고 초기 과업을 부여해요. |
send_message |
새 턴을 시작하지 않고 기존 에이전트에 메시지를 큐에 넣어요. |
followup_task |
기존 비루트 에이전트에 더 많은 작업을 부여하고 턴을 시작·재개해요. |
wait_agent |
호출 에이전트의 사서함에서 업데이트를 기다려요. |
interrupt_agent |
컨텍스트를 삭제하지 않고 다른 에이전트의 활성 턴을 인터럽트해요. |
list_agents |
현재 에이전트 트리, 상태, 각 에이전트의 last_task_message를 반환해요. |
개발자 정의 도구 호출 처리는 Multi-agent가 없을 때와 같은 방식이에요. 트리의 어떤 에이전트든 function_call을 내보낼 수 있고, 앱이 호출을 실행해 일치하는 function_call_output을 제출해야 해요. 트리의 모든 에이전트는 API 요청의 모델 호출에 구성된 도구에 접근할 수 있어요.
Responses API에서 Multi-agent 사용하기
HTTP와 WebSocket 성능
HTTP와 WebSocket은 같은 Multi-agent 기능을 지원하지만, WebSocket은 도구 중심·장기 실행 워크플로에 권장돼요. 지속 연결 덕분에 앱이 함수 출력을 사용 가능할 때마다 반환할 수 있어, 연속 오버헤드를 줄이고 에이전트가 기다리는 시간을 줄여요.
HTTP에서는 모든 활성 에이전트가 완료되거나 클라이언트 실행 함수 호출을 기다리기 위해 일시 중지될 때 응답이 완료돼요. 앱은 모든 미결 함수 호출을 실행하고 그 출력을 새 Responses API 요청에 제출해서 일시 중지된 에이전트가 재개하게 해요. WebSocket에서는 앱이 각 함수 출력을 사용 가능해지는 즉시 활성 응답에 주입할 수 있어요. 대기 에이전트는 다른 에이전트가 계속 작업하는 동안 즉시 재개할 수 있어요. 이렇게 하면 조정 지연이 줄고, 에이전트가 다른 시점에 끝나거나 도구를 요청할 때 추가 요청 왕복을 피할 수 있어요. HTTP는 병렬 웹 검색 같은 여러 호스팅 도구 호출이나 함수 호출이 적은 단일 요청 워크플로에 충분할 수 있어요. 대부분의 Multi-agent 워크플로에서는 WebSocket이 더 낮은 지연과 더 나은 종단 간 성능을 제공할 가능성이 커요.
HTTP
도구 중심 예시에서는 베타 Responses API를 노출하는 베타 SDK 빌드가 필요해요. HTTP 스트리밍은 client.beta.responses.create를 호출하고 betas 인자에 responses_multi_agent=v1을 전달해요. 이렇게 하면 베타 타입과 자동완성이 활성화돼요. 에이전트 하나 이상이 개발자 정의 함수를 호출하면, 모든 미결 호출을 실행하고 그 출력을 담은 연속 요청(continuation request)을 만들어요. 루트·서브에이전트의 출력을 구분하려면 이벤트의 agent.agent_name으로 누가 무엇을 출력했는지 판단해 표준 출력과 표준 오류로 나눠 렌더링할 수 있어요. HTTP 루프에서는 각 function_call을 실행해 function_call_output으로 히스토리에 추가하고, 미결 호출이 없을 때까지 새 요청을 계속 만들어요.
WebSocket
WebSocket 모드에서는 에이전트가 개발자 정의 함수를 호출하면, 앱에서 그 함수를 실행해 response.inject 이벤트로 결과를 활성 응답에 보내요. 그러면 대기 에이전트가 전체 Multi-agent 응답이 완료될 때까지 기다리지 않고 재개할 수 있어요.
{
"type": "response.inject",
"response_id": "resp_123",
"input": [
{
"type": "function_call_output",
"call_id": "call_123",
"output": "{\"temperature\":72}"
}
]
}
유효한 response.inject 요청에 서버는 두 이벤트 중 하나로 응답해요. response.inject.created(입력이 검증·수락되어 주입됨) 또는 response.inject.failed(주입되지 않음, error.code 확인). 요청이 response.inject 스키마를 따르지 않으면 서버가 상태 400의 일반 오류를 보내고 WebSocket 연결을 닫아요. 요청을 고치고 새 WebSocket 연결을 연 뒤 다음 이벤트를 보내세요.
Python 베타 SDK는 client.beta.responses.connect로, TypeScript 베타 SDK는 ResponsesWS로 WebSocket 모드를 노출해요. 연결 헤더에 OpenAI-Beta: responses_multi_agent=v1을 전달해요. HTTP 스트리밍과 달리 WebSocket 커넥터는 아직 betas 인자를 받지 않아요. response.created 이벤트의 응답 ID를 저장하고, 그 응답에 보내는 모든 response.inject 이벤트에 포함하세요. 주입 항목을 보낸 뒤에는 응답이 완료되고 모든 주입이 response.inject.created 또는 response.inject.failed 이벤트를 만들 때까지 WebSocket을 계속 읽어요. response.inject.failed가 response_already_completed면 실패 이벤트가 반환한 input을 가져와 완료된 응답에서 이어지는 새 response.create 요청으로 보내요. response_not_found면 response.created에서 받은 ID를 쓰고 있는지 확인하세요.
단일 Multi-agent 실행은 여러 Responses API 요청에 걸쳐 있을 수 있어요. HTTP에서는 에이전트가 개발자 정의 함수를 호출하면 앱이 함수를 실행하고 그 출력을 새 response.create 호출로 제출해요. WebSocket에서는 앱이 함수 출력을 활성 응답에 주입해요.
새 Multi-agent 출력 항목
Multi-agent 응답에는 세 가지 추가 출력 항목 유형이 포함될 수 있어요.
multi_agent_call:spawn_agent같은 호스팅된 Multi-agent 액션을 기록해요.multi_agent_call_output: 호스팅 액션 실행의 결과를 담아요.agent_message: 한 에이전트에서 다른 에이전트로 암호화된 메시지를 전달해요.
call_id 필드는 각 multi_agent_call을 대응하는 multi_agent_call_output에 연결해요. 각 항목에는 agent 속성도 있어요. agent_message의 agent.agent_name은 수신 에이전트를 식별하고, author와 recipient로 메시지 방향을 추적해요. 앱이 multi_agent_call을 받으면 그것을 함수 호출로 실행하거나 결과를 보내지 마세요. Responses API가 호스팅 액션을 실행하고 대응하는 multi_agent_call_output을 반환해요. 리플레이·추적에 필요하면 두 항목을 보존하세요.
[
{
"type": "multi_agent_call",
"id": "mac_123",
"call_id": "call_spawn_a",
"action": "spawn_agent",
"arguments": "{\"task_name\":\"agent_a\",\"fork_turns\":\"all\",\"message\":\"enc_...\"}",
"agent": { "agent_name": "/root" }
},
{
"type": "multi_agent_call_output",
"id": "maco_123",
"call_id": "call_spawn_a",
"action": "spawn_agent",
"output": [
{
"type": "output_text",
"text": "{\"task_name\":\"/root/agent_a\"}",
"annotations": [],
"logprobs": []
}
],
"agent": { "agent_name": "/root" }
},
{
"type": "agent_message",
"id": "amsg_123",
"author": "/root/agent_a",
"recipient": "/root",
"content": [
{
"type": "encrypted_content",
"encrypted_content": "enc_..."
}
],
"agent": { "agent_name": "/root" }
}
]
에이전트에 귀속되는 SSE 이벤트는 최상위 agent 속성을 포함해요. agent_message 이벤트의 agent.agent_name은 수신 에이전트를 식별하고, response.created·response.completed 같은 응답 수명주기 이벤트는 개별 에이전트가 아니라 전체 응답을 설명하므로 agent 속성을 포함하지 않아요.
제약 사항
- Compaction:
- Multi-agent가 활성화되면
/responses/compact엔드포인트가 지원되지 않아요. multi_agent.enabled가true면, 요청이context_management를 구성하지 않아도 자동 서버 측 컴팩션이 암묵적으로 활성화돼요. 컴팩션은 루트 에이전트와 각 서브에이전트에 독립적으로 적용되어 각자의 컨텍스트를 보존해요. 요청에 명시적context_management.compact_threshold를 설정해compact_threshold를 덮어쓸 수 있어요.
- Multi-agent가 활성화되면
- Multi-agent가 활성화되면
reasoning.summary가 지원되지 않아요. - Multi-agent가 활성화되면
max_tool_calls가 지원되지 않아요. max_concurrent_subagents는 기본값3이 권장 설정이에요.
프롬프트 가이드
Multi-agent가 활성화되면 시스템이 루트·서브에이전트에 새 developer 메시지로 이 지시를 자동으로 추가해요. 이 지시는 편집·제거할 수 없으므로, 여러분의 developer 지시는 자동 주입 지시에 "덧붙여지는( additive)" 것으로 프레이밍해야 해요.
루트 에이전트에는 자신이 /root이며 팀의 주 에이전트이고, 서브에이전트를 띄울 수 있으며, 모든 에이전트가 동등하게 지능적이고 같은 도구에 접근한다는 지시가 주입돼요. spawn_agent로 새 에이전트를, followup_task로 기존 에이전트에 새 과업을 주고 턴을 트리거하고, send_message로 턴을 트리거하지 않고 실행 중 에이전트에 메시지를 전달할 수 있어요. fork_turns 파라미터로 서브에이전트에 전파할 컨텍스트 양을 결정할 수 있어요. 사용 가능한 동시성 슬롯은 max_concurrent_subagents + 1개로, 자신을 포함해 동시에 활성일 수 있는 에이전트 수를 나타내요.
서브에이전트에는 자신이 팀의 에이전트이고, 하위 서브에이전트를 띄울 수 있으며, final channel에서 응답을 제공하면 즉시 부모 에이전트로 전달된다는 지시가 주입돼요.