

# 양방향 API를 사용하여 입력 이벤트 처리
<a name="sonic-input-events"></a>

양방향 스트림 API는 구조화된 입력 및 출력 이벤트를 갖춘 이벤트 기반 아키텍처를 사용합니다. 성공적인 대화형 애플리케이션을 구현하고 상호 작용 전반에 걸쳐 적절한 대화 상태를 유지하려면 올바른 이벤트 순서를 이해하는 것이 중요합니다.

## 개요
<a name="sonic-input-overview"></a>

Nova Sonic 대화는 구조화된 이벤트 시퀀스를 따릅니다. 먼저 온도 및 토큰 제한과 같은 추론 구성 파라미터가 포함된 `sessionStart` 이벤트를 전송합니다. 다음으로 `promptStart`를 전송하여 오디오 출력 형식 및 도구 구성을 정의하고, 모든 후속 이벤트에 포함되어야 하는 고유한 `promptName` 식별자를 할당합니다.

각 상호 작용 유형(시스템 프롬프트, 오디오 등)에 대해 세 부분으로 된 패턴을 따릅니다. `contentStart`를 사용하여 콘텐츠 유형과 콘텐츠 역할(`SYSTEM`, `USER`, `ASSISTANT`, `TOOL`, `SYSTEM_SPEECH`)을 정의한 다음, 실제 콘텐츠 이벤트를 제공하고, `contentEnd`로 마무리하여 해당 세그먼트를 닫습니다. `contentStart` 이벤트는 도구 결과, 스트리밍 오디오 또는 시스템 프롬프트 중 무엇을 전송할지 지정합니다. `contentStart` 이벤트에는 고유한 `contentName` 식별자가 포함됩니다.

## 대화 기록
<a name="sonic-conversation-history"></a>

시스템 프롬프트 후 오디오 스트리밍이 시작되기 전에 한 번만 대화 기록을 포함할 수 있습니다. 대화 기록은 동일한 `contentStart`/`textInput`/`contentEnd` 패턴을 따릅니다. 각 기록 메시지의 `contentStart` 이벤트에 `USER` 및 `ASSISTANT` 역할을 정의해야 합니다. 이는 현재 대화에 대한 필수적인 컨텍스트를 제공하지만, 새로운 사용자 입력이 시작되기 전에 완료되어야 합니다.

## 오디오 스트리밍
<a name="sonic-audio-streaming"></a>

오디오 스트리밍은 연속 마이크 샘플링으로 작동합니다. 초기 `contentStart`를 전송한 후, 오디오 프레임(각각 약 32ms)이 마이크에서 직접 캡처되어 동일한 `contentName`을 사용하여 즉시 `audioInput` 이벤트로 전송됩니다. 이러한 오디오 샘플은 캡처되는 대로 실시간으로 스트리밍되어 대화 전체에서 자연스러운 마이크 샘플링 케이던스를 유지해야 합니다. 모든 오디오 프레임은 대화가 끝나고 명시적으로 닫힐 때까지 하나의 콘텐츠 컨테이너를 공유합니다.

## 세션 닫기
<a name="sonic-closing-session"></a>

대화가 끝나거나 종료되어야 하는 경우 열려 있는 모든 스트림을 올바르게 닫고 올바른 순서로 세션을 끝내는 것이 중요합니다. 세션을 올바르게 끝내고 리소스 누수를 방지하려면 다음과 같은 특정 닫기 순서를 따라야 합니다.
+ `contentEnd` 이벤트를 사용하여 열려 있는 모든 오디오 스트림을 닫습니다.
+ 원래 `promptName`을 참조하는 `promptEnd` 이벤트를 전송합니다.
+ `sessionEnd` 이벤트를 전송합니다.

이러한 닫기 이벤트를 건너뛰면 대화가 불완전하거나 리소스가 분리될 수 있습니다.

이러한 식별자는 계층 구조를 생성합니다. `promptName`은 모든 대화 이벤트를 연결하고, 각 `contentName`은 특정 콘텐츠 블록의 경계를 표시합니다. 이 계층 구조는 모델이 상호 작용 전반에 걸쳐 적절한 컨텍스트를 유지하도록 합니다.

![](http://docs.aws.amazon.com/ko_kr/nova/latest/nova2-userguide/images/Closing-the-session_2.png)


## 입력 이벤트 흐름
<a name="sonic-input-event-flow"></a>

이 섹션에서는 입력 이벤트 흐름의 구조를 설명합니다.

### 1. RequestStartEvent(세션 시작)
<a name="sonic-session-start-event"></a>

세션 시작 이벤트는 추론 구성으로 대화를 초기화하고 탐지 설정을 켭니다.

**추론 구성:**
+ `maxTokens`: 응답에서 생성할 최대 토큰 수
+ `topP`: 무작위성 제어를 위한 Nucleus 샘플링 파라미터(0.0\~1.0)
+ `temperature`: 생성 시 무작위성 제어(0.0\~1.0)

**턴 탐지 구성:** `endpointingSensitivity` 파라미터는 사용자가 발언을 마쳤을 때 Nova Sonic에서 이를 탐지하는 속도를 제어합니다.
+ `HIGH`: 일시 중지를 빠르게 탐지하여 응답 속도를 높이지만 느린 화자를 중단시킬 수 있음
+ `MEDIUM`: 대부분의 대화형 시나리오에 대한 균형 잡힌 민감도(기본값 권장)
+ `LOW`: 음성 끝을 탐지하기 전에 더 오래 기다림, 사려 깊거나 주저하는 화자에게 적합함

```
{
    "event": {
        "sessionStart": {
            "inferenceConfiguration": {
                "maxTokens": "int",
                "topP": "float",
                "temperature": "float"
            },
            "turnDetectionConfiguration": {
                "endpointingSensitivity": "HIGH" | "MEDIUM" | "LOW"
            }
        }
    }
}
```

**예시:**

```
{
    "event": {
        "sessionStart": {
            "inferenceConfiguration": {
                "maxTokens": 2048,
                "topP": 0.9,
                "temperature": 0.7
            },
            "turnDetectionConfiguration": {
                "endpointingSensitivity": "MEDIUM"
            }
        }
    }
}
```

### 2. PromptStartEvent
<a name="sonic-prompt-start-event"></a>

프롬프트 시작 이벤트는 출력 형식, 음성 선택 및 사용 가능한 도구를 포함한 대화 구성을 정의합니다.

사용 가능한 음성 ID 목록은 [언어 지원 및 다국어 기능](https://docs.aws.amazon.com/nova/latest/nova2-userguide/sonic-language-support.html)을 참조하세요.

```
{
    "event": {
        "promptStart": {
            "promptName": "string", // unique identifier same across all events i.e. UUID
            "textOutputConfiguration": {
                "mediaType": "text/plain"
            },
            "audioOutputConfiguration": {
                "mediaType": "audio/lpcm",
                "sampleRateHertz": 8000 | 16000 | 24000,
                "sampleSizeBits": 16,
                "channelCount": 1,
                "voiceId": "matthew" | "tiffany" | "amy" | "olivia" | "lupe" | "carlos" | "ambre" | "florian" | "lennart" | "beatrice" | "lorenzo" |
                        "tina" | "carolina" | "leo" | "kiara" | "arjun",
                "encoding": "base64",
                "audioType": "SPEECH"
            },
            "toolUseOutputConfiguration": {
                "mediaType": "application/json"
            },
            "toolConfiguration": {
                "tools": [
                    {
                        "toolSpec": {
                            "name": "string",
                            "description": "string",
                            "inputSchema": {
                                "json": "{}"
                            }
                        }
                    }
                ]
            }
        }
    }
}
```

### 3. InputContentStartEvent
<a name="sonic-content-start-event"></a>

#### 텍스트
<a name="sonic-content-start-text"></a>

텍스트 콘텐츠 시작 이벤트는 시스템 프롬프트, 대화 기록 및 교차 모달 텍스트 입력에 대해 사용됩니다.

**대화형 파라미터:**
+ `true`: 활성 음성 세션 중에 텍스트 메시지를 허용하는 교차 모달 입력 활성화
+ `false`: 시스템 프롬프트 및 대화 기록에 대한 표준 텍스트 입력

**역할 유형:**
+ `SYSTEM`: 시스템 지침 및 프롬프트
+ `USER`: 대화 기록 또는 교차 모달 입력에서 사용자 메시지
+ `ASSISTANT`: 대화 기록에서 어시스턴트 응답
+ `SYSTEM_SPEECH`: 힌디어 코드 스위칭(라틴 문자/데바나가리 문자/혼합 스크립트)을 위한 트랜스크립션 형식 지정 제어

```
{
    "event": {
        "contentStart": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // unique identifier for the content block
            "type": "TEXT",
            "interactive": "boolean", // true for cross-modal input
            "role": "SYSTEM" | "USER" | "ASSISTANT" | "TOOL" | "SYSTEM_SPEECH",
            "textInputConfiguration": {
                "mediaType": "text/plain"
            }
        }
    }
}
```

**예제 - 시스템 프롬프트:**

```
{
    "event": {
        "contentStart": {
            "promptName": "conv-12345",
            "contentName": "system-prompt-1",
            "type": "TEXT",
            "interactive": false,
            "role": "SYSTEM",
            "textInputConfiguration": {
                "mediaType": "text/plain"
            }
        }
    }
}
```

**예제 - 교차 모달 입력:**

```
{
    "event": {
        "contentStart": {
            "promptName": "conv-12345",
            "contentName": "user-text-1",
            "type": "TEXT",
            "interactive": true,
            "role": "USER",
            "textInputConfiguration": {
                "mediaType": "text/plain"
            }
        }
    }
}
```

#### 오디오
<a name="sonic-content-start-audio"></a>

```
{
    "event": {
        "contentStart": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // unique identifier for the content block
            "type": "AUDIO",
            "interactive": true,
            "role": "USER",
            "audioInputConfiguration": {
                "mediaType": "audio/lpcm",
                "sampleRateHertz": 8000 | 16000 | 24000,
                "sampleSizeBits": 16,
                "channelCount": 1,
                "audioType": "SPEECH",
                "encoding": "base64"
            }
        }
    }
}
```

#### 도구
<a name="sonic-content-start-tool"></a>

```
{
    "event": {
        "contentStart": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // unique identifier for the content block
            "interactive": false,
            "type": "TOOL",
            "role": "TOOL",
            "toolResultInputConfiguration": {
                "toolUseId": "string", // existing tool use id
                "type": "TEXT",
                "textInputConfiguration": {
                    "mediaType": "text/plain"
                }
            }
        }
    }
}
```

### 4. TextInputContent
<a name="sonic-text-input-event"></a>

```
{
    "event": {
        "textInput": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // unique identifier for the content block
            "content": "string"
        }
    }
}
```

### 5. AudioInputContent
<a name="sonic-audio-input-event"></a>

```
{
    "event": {
        "audioInput": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string", // same unique identifier from its contentStart
            "content": "base64EncodedAudioData"
        }
    }
}
```

### 6. ToolResultContentEvent
<a name="sonic-tool-result-event"></a>

```
"event": {
    "toolResult": {
        "promptName": "string", // same unique identifier from promptStart event
        "contentName": "string", // same unique identifier from its contentStart
        "content": "{\"key\": \"value\"}" // stringified JSON object as a tool result 
    }
}
```

### 7. InputContentEndEvent
<a name="sonic-content-end-event"></a>

```
{
    "event": {
        "contentEnd": {
            "promptName": "string", // same unique identifier from promptStart event
            "contentName": "string" // same unique identifier from its contentStart
        }
    }
}
```

### 8. PromptEndEvent
<a name="sonic-prompt-end-event"></a>

```
{
    "event": {
        "promptEnd": {
            "promptName": "string" // same unique identifier from promptStart event
        }
    }
}
```

### 9. RequestEndEvent
<a name="sonic-session-end-event"></a>

```
{
    "event": {
        "sessionEnd": {}
    }
}
```