적용 대상: SDK v4
미들웨어는 어댑터와 봇 논리 사이에 있는 클래스일 뿐이며 초기화 중에 어댑터의 미들웨어 컬렉션에 추가됩니다. SDK를 사용하면 사용자 고유의 미들웨어를 작성하거나 다른 사람이 만든 미들웨어를 추가할 수 있습니다. 봇으로 들어오거나 봇에서 나가는 모든 작업은 미들웨어를 통과합니다.
어댑터는 봇 미들웨어 파이프라인을 통해 들어오는 작업을 처리하고 봇의 논리로 전달한 다음 다시 내보낼 수 있습니다. 각 작업이 봇으로 들어가고 나올 때 미들웨어의 각 부분은 봇 논리가 실행되기 전과 후에 작업을 검사하거나 작업에 따라 작동합니다.
미들웨어로 전환하기 전에 일반적으로 봇을 이해하고 활동을 처리하는 방법을 이해하는 것이 중요합니다.
미들웨어에 사용
"이 질문은 종종 제기됩니다: '일반적인 봇 논리를 사용하는 것과 미들웨어로 동작을 구현해야 하는 때는 언제인가요?' 미들웨어는 대화의 각 턴이 처리되기 전후에 사용자의 대화 흐름과 상호작용할 수 있는 추가 기회를 제공합니다." 미들웨어를 사용하면 대화와 관련된 정보를 저장 및 검색하고 필요한 경우 추가 처리 논리를 호출할 수 있습니다. 다음은 미들웨어가 유용할 수 있는 위치를 보여 주는 몇 가지 일반적인 시나리오입니다.
모든 활동을 관찰하거나 행동으로 옮기기
봇이 모든 활동 또는 특정 유형의 모든 활동에 대해 작업을 수행해야 하는 많은 상황이 있습니다. 예를 들어 봇이 수신하는 모든 메시지 활동을 기록하거나 봇이 이 턴에 응답을 생성하지 않은 경우 대체 응답을 제공할 수 있습니다. 미들웨어는 봇 논리의 나머지 부분을 실행하기 전과 후에 작동할 수 있는 기능을 갖춘 이러한 프로세스에 적합한 장소입니다.
턴 컨텍스트 수정 또는 향상
봇에 활동에 제공된 것보다 더 많은 정보가 있는 경우 특정 대화가 훨씬 더 유익할 수 있습니다. 이 경우 미들웨어는 지금까지 가지고 있는 대화 상태 정보를 확인하고, 외부 데이터 원본을 쿼리하고, 봇 논리에 실행을 전달하기 전에 컨텍스트 개체 를 턴 에 추가할 수 있습니다.
SDK는 들어오고 나가는 활동을 기록할 수 있는 로깅 미들웨어를 정의하지만 사용자 고유의 미들웨어를 정의할 수도 있습니다.
봇 미들웨어 파이프라인
각 작업에 대해 어댑터는 추가한 순서대로 미들웨어를 호출합니다. 어댑터는 순서 및 다음 대리자의 컨텍스트 개체를 전달하고 미들웨어는 대리자를 호출하여 파이프라인의 다음 미들웨어에 제어를 전달합니다. 미들웨어는 메서드를 완료하기 전에 다음 대리자가 반환된 후 작업을 수행할 수도 있습니다. 각 미들웨어 객체는 파이프라인에서 다음에 올 미들웨어 객체들에 대해 처음과 마지막으로 작동할 기회를 갖는다고 생각할 수 있습니다.
다음은 그 예입니다.
- 첫 번째 미들웨어 개체의 순서 처리기는 다음을 호출하기 전에 코드를 실행합니다.
- 두 번째 미들웨어 개체의 순서 처리기는 다음을 호출하기 전에 코드를 실행합니다.
- 봇의 턴 처리기가 실행되고 결과를 반환합니다.
- 두 번째 미들웨어 개체의 턴 처리기는 반환하기 전에 나머지 코드를 실행합니다.
- 두 번째 미들웨어 개체의 순서 처리기는 다음을 호출하기 전에 코드를 실행합니다.
- 첫 번째 미들웨어 개체의 턴 처리기는 반환하기 전에 나머지 코드를 실행합니다.
미들웨어가 다음 대리자를 호출하지 않는 경우 어댑터는 후속 미들웨어 또는 봇 턴 처리기 및 파이프라인 단락을 호출하지 않습니다.
봇 미들웨어 파이프라인이 완료되면 턴이 끝나고 턴 컨텍스트가 범위를 벗어나게 됩니다.
미들웨어 또는 봇은 응답을 생성하고 응답 이벤트 처리기를 등록할 수 있지만 응답은 별도의 프로세스에서 처리됩니다.
미들웨어 순서
미들웨어가 추가되는 순서는 미들웨어가 작업을 처리하는 순서를 결정하므로 미들웨어를 추가해야 하는 시퀀스를 결정하는 것이 중요합니다.
비고
이는 대부분의 봇에서 작동하는 일반적인 패턴을 제공하기 위한 것이지만, 미들웨어의 각 부분이 상황에 맞게 다른 부분과 상호 작용하는 방식을 고려해야 합니다.
미들웨어는 모든 봇에 대해 먼저 미들웨어 파이프라인에 추가되어야 하는 가장 낮은 수준의 작업을 처리합니다. 예를 들어 로깅, 예외 처리 및 변환이 있습니다. 들어오는 메시지를 먼저 번역할지, 메시지를 저장하기 전에 변환할지, 메시지 스토리지가 먼저 발생해야 하는지 여부 등 필요에 따라 순서를 지정합니다. 즉, 저장된 메시지가 번역되지 않을 수 있습니다.
봇 관련 미들웨어는 마지막으로 미들웨어 파이프라인에 추가되어야 하며, 봇으로 전송된 모든 메시지에서 일부 처리를 수행하도록 구현하는 미들웨어입니다. 미들웨어가 봇 컨텍스트에서 설정된 상태 정보 또는 기타 정보를 사용하는 경우 상태 또는 컨텍스트를 수정하는 미들웨어 뒤의 미들웨어 파이프라인에 추가합니다.
전기 단락
미들웨어 및 응답 처리기에 대한 중요한 아이디어는 중단입니다. 다음 계층을 계속 실행하려면 미들웨어(또는 응답 처리기)가 다음 대리자를 호출하여 실행을 전달해야 합니다. 해당 미들웨어(또는 응답 처리기) 내에서 다음 대리자가 호출되지 않으면 연결된 파이프라인 단락 및 후속 계층이 실행되지 않습니다. 즉, 모든 봇의 로직과 파이프라인 이후의 모든 미들웨어는 건너뜁니다. 미들웨어와 응답 처리기가 턴을 단락하는 사이에는 미묘한 차이가 있습니다.
미들웨어가 턴을 중단시키면 봇 턴 처리기가 호출되지 않지만, 파이프라인에서 이 지점 전에 실행된 모든 미들웨어 코드는 여전히 완료됩니다.
이벤트 처리기의 경우 다음 을 호출하지 않는 것은 미들웨어 건너뛰기 논리와 매우 다른 이벤트가 취소됨을 의미합니다. 나머지 이벤트를 처리하지 않으면 어댑터가 이벤트를 보내지 않습니다.
팁 (조언)
응답 이벤트를 단락시키는 경우, 예를 들어 SendActivities
와 같이, 이는 의도한 동작인지 확인하세요. 그렇지 않으면 버그를 수정하기가 어려울 수 있습니다.
응답 이벤트 처리기
애플리케이션 및 미들웨어 논리 외에도 응답 처리기(이벤트 처리기 또는 활동 이벤트 처리기라고도 함)를 컨텍스트 개체에 추가할 수 있습니다. 이러한 처리기는 실제 응답을 실행하기 전에 현재 컨텍스트 개체에서 연결된 응답이 발생할 때 호출됩니다. 이러한 처리기는 현재 응답의 나머지 부분에 대해 해당 형식의 모든 활동에 대해 실제 이벤트 전후에 작업을 수행하려는 경우에 유용합니다.
경고
각 응답 이벤트 처리기 내에서 활동 응답 메서드를 호출하지 않도록 주의하세요. 예를 들어 on send 활동 처리기 내에서 송신 활동 메서드를 호출합니다. 이렇게 하면 무한 루프가 생성될 수 있습니다.
각 새 활동은 실행할 새 스레드를 가져옵니다. 작업을 처리할 스레드가 만들어지면 해당 작업에 대한 처리기 목록이 해당 새 스레드에 복사됩니다. 해당 시점 이후에 추가된 처리기는 해당 특정 활동 이벤트에 대해 실행되지 않습니다. 컨텍스트 개체에 등록된 처리기는 어댑터가 미들웨어 파이프라인을 관리하는 방법과 유사하게 처리됩니다. 즉, 처리기가 추가된 순서대로 호출되고 다음 대리자를 호출하면 다음 등록된 이벤트 처리기에 컨트롤이 전달됩니다. 처리기가 다음 대리자를 호출하지 않으면 후속 이벤트 처리기가 호출되지 않고 이벤트 단락이 발생하며 어댑터가 채널에 응답을 보내지 않습니다.
미들웨어의 상태 처리
상태를 저장하는 일반적인 방법은 순서 처리기의 끝에서 변경 내용 저장 메서드를 호출하는 것입니다. 다음은 통화에 초점을 맞춘 다이어그램입니다.
이 방법의 문제는 봇의 턴 처리기가 반환된 후에 발생하는 일부 사용자 지정 미들웨어에서 수행된 상태 업데이트가 지속형 스토리지에 저장되지 않는다는 것입니다. 해결 방법은 자동 저장 변경 미들웨어 인스턴스를 미들웨어 스택의 시작 부분에 추가하거나 적어도 상태를 업데이트할 수 있는 미들웨어 앞에 추가하여 사용자 지정 미들웨어가 완료된 후에 변경 내용 저장 메서드에 대한 호출을 이동하는 것입니다. 실행은 다음과 같습니다.
봇 상태 집합 개체로 업데이트해야 하는 상태 관리 개체를 추가한 다음 변경 내용 자동 저장 미들웨어를 만들 때 사용합니다.
추가 리소스
Bot Framework SDK [C# | JS]에서 구현된 대로 기록 로거 미들웨어를 살펴볼 수 있습니다.