1.0.1 ko public

스펙

RAWP-DPS

Data processing specification for RAWP integrations.

10. 서브에이전트 위임 규격 (Subagent Delegation)

에이전트가 하위 에이전트(서브에이전트)를 생성하여 작업을 위임하는 구조를 정의한다. 서브에이전트는 부모 에이전트와 동일한 Agent Session 내에서 실행되며, 서브에이전트 내부에서 발생하는 모든 DPS 프레임은 부모와 동일한 session_id를 공유한다.

10.1. 서브에이전트 호출

tool.invoke.request에서 서브에이전트를 생성하는 도구를 호출한다. payloadsubagent 필드가 존재하면 이 도구 호출이 서브에이전트를 생성함을 의미한다.

{
  "type": "tool.invoke.request",
  "payload": {
    "invocation_id": "String (필수, UUID v4. 이 값이 서브에이전트의 parent_invocation_id가 된다)",
    "tool_name": "String (필수, 예: 'Task', 'Agent')",
    "input": {
      "description": "String (필수, 서브에이전트 임무 설명)",
      "prompt": "String (필수, 서브에이전트에게 전달할 프롬프트)",
      "allowed_tools": ["String (선택, 서브에이전트 허용 도구 목록)"],
      "model": "String (선택, 사용할 모델)"
    },
    "subagent": {
      "agent_type": "String (선택, 서브에이전트 유형. 예: 'Explore', 'Plan', 'general-purpose')",
      "description": "String (선택, 서브에이전트 임무 요약)"
    }
  }
}

subagent 필드가 없으면 일반 도구 호출이다.

10.2. 서브에이전트 컨텍스트 (metadata.subagent_context)

서브에이전트 내부에서 발생하는 모든 DPS 프레임은 metadata.subagent_context 필드를 포함해야 한다 (MUST). 이를 통해 수신 측은 각 메시지의 출처 에이전트를 식별할 수 있다.

{
  "metadata": {
    "subagent_context": {
      "parent_invocation_id": "String (필수, 이 서브에이전트를 호출한 tool.invoke.request의 invocation_id)",
      "agent_type": "String (선택, 서브에이전트 유형)",
      "depth": "Number (필수, 중첩 깊이. 0 = 메인 에이전트, 1 = 서브에이전트, 2 = 서브의 서브에이전트)"
    }
  }
}

규칙:

  • subagent_context가 없거나 null인 프레임은 메인 에이전트(depth: 0)의 메시지로 취급해야 한다 (MUST).
  • 서브에이전트 내부의 agent.*, tool.*, session.* 모든 프레임에 포함해야 한다 (MUST).
  • depth는 발신 측(클라이언트)이 서브에이전트 생성 시점에 이미 알고 있는 값이다. 수신 측이 전체 프레임 히스토리 없이 단일 프레임만으로 중첩 깊이를 결정할 수 있도록 명시적으로 포함한다.
  • 중첩 서브에이전트의 경우 parent_invocation_id는 직계 부모의 invocation_id만 가리킨다. 전체 위임 체인이 필요한 경우 parent_invocation_id를 재귀 추적하여 복원한다.

10.3. 서브에이전트 생명주기 이벤트

10.3.1. agent.subagent.started (Client → Master)

서브에이전트가 시작되었음을 통보한다. tool.invoke.request(subagent 포함) 발송 직후에 발송해야 한다 (MUST).

{
  "type": "agent.subagent.started",
  "payload": {
    "parent_invocation_id": "String (필수, 대응하는 tool.invoke.request의 invocation_id)",
    "agent_type": "String (선택, 서브에이전트 유형)",
    "description": "String (선택, 서브에이전트 임무 설명)",
    "depth": "Number (필수, 중첩 깊이. 1 = 서브에이전트, 2 = 서브의 서브에이전트)"
  }
}

10.3.2. agent.subagent.ended (Client → Master)

서브에이전트가 종료되었음을 통보한다. tool.invoke.result(output_type: agent_result) 발송 직전에 발송해야 한다 (MUST).

{
  "type": "agent.subagent.ended",
  "payload": {
    "parent_invocation_id": "String (필수)",
    "status": "String (필수, 'completed' | 'failed' | 'cancelled')",
    "duration_ms": "Number (선택, 서브에이전트 실행 시간 밀리초)"
  }
}

이벤트 순서:

tool.invoke.request (subagent 포함)
  → agent.subagent.started
  → 서브에이전트 내부 메시지들 (subagent_context 포함)
  → agent.subagent.ended
  → tool.invoke.result (output_type: "agent_result")

10.4. 서브에이전트 출력

서브에이전트의 중간 출력은 tool.invoke.stream으로 중계되거나, subagent_context가 포함된 개별 DPS 프레임(agent.text.delta, tool.invoke.request 등)으로 마스터에 직접 노출될 수 있다.

완료 시 tool.invoke.result(output_type: agent_result)로 최종 결과가 보고된다.

10.5. 사용량 보고 규칙

서브에이전트 내에서 발생하는 session.usagesubagent_context를 포함하여 독립적으로 보고해야 한다 (MUST). 서브에이전트의 사용량을 메인 에이전트의 누적 사용량에 합산할지 여부는 마스터 또는 엣지 노드가 결정한다. 본 규격은 합산 정책을 규정하지 않는다.

10.6. 능력 협상

session.capabilities(§12.2.1)의 features 객체에 서브에이전트 관련 능력을 고지한다:

필드 설명
subagent 서브에이전트 도구 호출 지원 여부 (기존)
subagent_context metadata.subagent_context 필드 제공 여부. true이면 서브에이전트 메시지에 컨텍스트를 포함한다. false이거나 미고지이면 모든 메시지를 플랫하게 처리한다.

subagent_context: false인 클라이언트의 메시지에 대해 마스터 및 CRS는 그룹핑을 시도해서는 안 된다 (MUST NOT).

10.7. 서브에이전트 미지원 폴백

서브에이전트를 지원하지 않는 에이전트(프로세스 기반 어댑터 등)의 경우:

  • subagent_context를 생략하거나 null로 설정해야 한다 (MUST).
  • 모든 메시지는 메인 에이전트의 메시지로 취급된다.
  • output_type: "agent_result"tool.invoke.resultsubagent_context 없이도 서브에이전트 결과임을 암시하지만, 내부 메시지 그룹핑은 불가능하다.

참조