이벤트 모델

이벤트 모델 (The Event Model)

이벤트 봉투(envelope), 일반 필드, 식별자, 그리고 모든 이벤트의 지도 — 1.0 버전을 설명드릴게요.

출처: 문서

본문

기본 프로토콜(base protocol)은 사용하는 기능과 무관하게 모든 구현이 말하는 것입니다:

  • 이벤트 모델 — 이 페이지: 모든 이벤트가 공유하는 봉투, 일반 필드, 이벤트를 묶는 식별자.
  • Run input — 반대 방향으로 이동하는 유일한 메시지.
  • Metadata — 모든 것 위에 있는 개방 채널과 그 병합 방식.
  • Capabilities — 실행 전에 에이전트가 자신에 대해 선언하는 것과, 선언이 요구하는 바.
  • Event patterns — 이벤트가 스트림으로 구성되는 방식.
  • Transports — 스트림이 어떻게 프레이밍되고 전달되는지.
  • Processing model — 소비자가 인식하지 못하는 자료를 어떻게 처리하는지.
  • Versioning and compatibility — 더 오래되거나 더 새로운 상대와 대화하기.

모든 구현은 이벤트 모델과 이벤트 패턴을 반드시(MUST) 지원해야 해요. 실행 수명주기 너머의 이벤트 패밀리는 기능입니다: 프로듀서는 전할 것이 있는 것만 발행해요.

이벤트 (Events)

모든 이벤트는 하나의 봉투를 공유하는 JSON 객체이며, 스키마가 BaseEvent로 정의합니다:

  • type — 필수(REQUIRED). 판별자(discriminator)로, EventType의 31개 값 중 하나예요. 이 스펙의 모든 규칙은 이 필드를 통해 이벤트에 붙습니다.
  • timestamp — 선택(OPTIONAL). 이벤트가 생성된 시각. 정보용입니다: 소비자는 이를 사용해 이벤트를 정렬해선 안 되며(MUST NOT) — 도착 순서가 프로토콜의 순서예요. 관례상 단위는 Unix epoch 이후 밀리초입니다.
  • rawEvent — 선택(OPTIONAL). 이 이벤트가 변환된 공급자 네이티브 이벤트를 그대로 담아요. 소비자는 이로부터 프로토콜 동작을 유도해선 안 돼요(MUST NOT).
  • metadata — 선택(OPTIONAL). 일반 필드 참고.

서브에이전트의 작업에 속할 수 있는 이벤트는 추가로 선택(OPTIONAL) subagentRunId(스키마의 Attributable)를 담아요; 서브에이전트 규칙이 이를 규정합니다. 실행 스코프의 RUN_STARTED, RUN_FINISHED, RUN_ERROR, MESSAGES_SNAPSHOT 이벤트는 실행이나 대화 전체를 기술하며 귀속(attribution)을 담지 않아요.

일반 필드 (General fields)

metadata

모든 것 위에 있는 개방 채널: 키별로 개방되고, 키 아래에 어떤 JSON 값이든 허용되며, 항목을 구성하는 이벤트들에 걸쳐 축적됩니다 — 키별로, 마지막 쓰기가 이기고, 재귀는 없으며 — 패밀리별 병합 대상을 갖고 ag-ui 키는 예약되어 있어요. 이에 대한 전용 페이지가 있어요: Metadata.

부재는 부재다 (Absent means absent)

값이 없는 선택 필드는 null로 보내기보다 생략해야 해요(MUST).

이는 rawEvent, RUN_FINISHED.result, forwardedProps처럼 임의의 JSON을 담는 필드를 포함해 모든 선택 필드에 적용돼요. null로 설정된 선택 필드 전체는 생략되어야 해요. 필수 JSON payload는 null일 수 있어요. 예를 들어 CUSTOM.value나 STATE_SNAPSHOT.snapshot요.

이것은 스타일 선호가 아니에요. 두 철자를 모두 받아들여야 하는 소비자는 어디서든 같은 것으로 취급해야 하며, 그런 허용은 한 번 출시되면 영구적이에요. 프로토콜은 모든 구현이 표현할 수 있는 단일 철자를 담아요.

개방 키 객체 아래의 null 값 — metadata 값, state 안의 무언가 — 은 데이터이며 보존되어야 해요. 전체 부재 필드를 대신하는 null만 금지됩니다.

프로토콜이 이미 선택 위치에서 null에 대한 허용을 출시한 경우, 이 규칙이 아니라 호환성 심(shim)으로 처리해요. Versioning and compatibility 참고.

식별자 (Identifiers)

  • threadId는 대화를 식별해요. 애플리케이션이 만들며 실행 간에 안정적입니다.
  • runId는 한 번의 실행을 식별해요. 같은 스레드의 다른 실행에 재사용되선 안 돼요(MUST NOT).
  • messageId는 메시지를 식별해요. 실행 경계를 넘어요 — 이후 실행의 스냅샷이 메시지를 id로 다시 진술할 수 있으므로 — 따라서 스레드 내에서 고유해야 해요.
  • toolCallId는 한 번의 도구 호출을 식별하고, 그 결과와 그것에 관한 어떤 인터럽트를 다시 연결해요.
  • subagentRunId는 한 번의 서브에이전트 호출(invocation) 을 위한 불투명 핸들이며, 서브에이전트 정의를 위한 재사용 가능한 이름이 아니에요: 같은 서브에이전트의 두 호출은 서로 다른 두 값을 담아요.

모든 식별자는 불투명 문자열입니다: 소비자는 그들로부터 구조를 파싱해선 안 돼요(MUST NOT).

이벤트들 (The events)

여덟 패밀리에 걸친 서른한 가지 이벤트 유형:

Family Events Pattern
Runs and steps RUN_STARTED RUN_FINISHED RUN_ERROR STEP_STARTED STEP_FINISHED lifecycle
Text messages TEXT_MESSAGE_START TEXT_MESSAGE_CONTENT TEXT_MESSAGE_END TEXT_MESSAGE_CHUNK streaming
Tool calls TOOL_CALL_START TOOL_CALL_ARGS TOOL_CALL_END TOOL_CALL_CHUNK TOOL_CALL_RESULT streaming
Reasoning REASONING_START REASONING_END REASONING_MESSAGE_START REASONING_MESSAGE_CONTENT REASONING_MESSAGE_END REASONING_MESSAGE_CHUNK REASONING_ENCRYPTED_VALUE streaming
State STATE_SNAPSHOT STATE_DELTA MESSAGES_SNAPSHOT snapshot–delta
Activity ACTIVITY_SNAPSHOT ACTIVITY_DELTA snapshot–delta
Subagents SUBAGENT_STARTED SUBAGENT_FINISHED SUBAGENT_ERROR lifecycle
Passthrough RAW CUSTOM standalone

스키마 (Schema)

프로토콜의 전체 구조는 /spec/1.0/schema.json의 JSON Schema로 정의돼요. 이것이 진실의 원천(source of truth)입니다: TypeScript, Python, .NET 모델은 이로부터 생성되며, 이 문서가 필드를 언급할 때마다 그것은 스키마가 정의하는 무언가를 명명하는 것이지 그 형태를 다시 진술하는 게 아니에요.

스키마는 의도적으로 이 문서가 말하는 것을 말하지 않아요: 순서, 수명주기, 귀속, 오류 처리, 호환성은 행동적이며 스키마는 이를 표현할 수 없어요. 구조에 대해 둘이 어긋난다면 스키마가 이기고 이 문서에 버그가 있는 거예요.

더 알아보기 (Learn more)