적용 대상: SDK v4
봇 내의 상태는 최신 웹 애플리케이션과 동일한 패러다임을 따르며, Bot Framework SDK는 상태 관리를 더 쉽게 하기 위해 몇 가지 추상화를 제공합니다.
웹앱과 마찬가지로, 봇은 기본적으로 상태를 저장하지 않습니다. 봇의 다른 인스턴스에서 대화의 지정된 턴을 처리할 수 있습니다. 일부 봇의 경우 이러한 단순성을 선호합니다. 즉, 봇은 추가 정보 없이 작동할 수 있거나 필요한 정보가 들어오는 메시지 내에 있도록 보장됩니다. 다른 사용자의 경우 봇이 유용한 대화를 하려면 상태(예: 대화가 중단된 위치 또는 사용자에 대해 이전에 받은 데이터)가 필요합니다.
상태가 왜 필요한가요?
상태를 유지하면 사용자 또는 대화에 대한 특정 항목을 기억하여 봇이 더 의미 있는 대화를 할 수 있습니다. 예를 들어 이전에 사용자와 대화한 적이 있는 경우 이전 정보를 저장하여 다시 요청할 필요가 없도록 할 수 있습니다. 또한 상태는 현재 턴보다 더 오래 데이터를 유지하므로 봇은 다중 턴 대화 과정에서 정보를 유지합니다.
봇과 관련하여 상태를 사용하는 데는 스토리지 계층, 상태 관리(아래 다이어그램의 봇 상태에 포함됨) 및 상태 속성 접근자 등 몇 가지 계층이 있습니다. 이 다이어그램에서는 메서드 호출을 나타내는 단색 화살표와 응답을 나타내는 파선 화살표(반환 값 포함 또는 제외)를 사용하여 이러한 레이어 간의 상호 작용 시퀀스의 일부를 보여 줍니다.
이 다이어그램의 흐름은 다음 섹션에서 이러한 각 계층에 대한 세부 정보를 설명합니다.
스토리지 계층
상태 정보가 실제로 저장되는 백 엔드부터 스토리지 계층입니다. 메모리 내, Azure 또는 타사 서버와 같은 실제 스토리지로 간주할 수 있습니다.
Bot Framework SDK에는 스토리지 계층에 대한 몇 가지 구현이 포함되어 있습니다.
- 메모리 스토리지 는 테스트를 위해 메모리 내 스토리지를 구현합니다. 메모리 내 데이터 스토리지는 이 스토리지가 일시적이고 일시적이기 때문에 로컬 테스트용으로만 사용됩니다. 봇을 다시 시작할 때마다 데이터가 지워집니다.
- Azure Blob Storage 는 Azure Blob Storage 개체 데이터베이스에 연결합니다.
- Azure Cosmos DB 분할된 스토리지 는 분할된 Cosmos DB NoSQL 데이터베이스에 연결됩니다.
중요합니다
Cosmos DB 스토리지 클래스는 더 이상 사용되지 않습니다. 원래 CosmosDbStorage를 사용하여 만든 컨테이너에는 파티션 키 집합이 없으며 기본 파티션 키 "/_partitionKey"가 지정되었습니다.
Cosmos DB 스토리지로 만든 컨테이너는 Cosmos DB 분할 스토리지와 함께 사용할 수 있습니다. 자세한 내용은 Azure Cosmos DB 분할을 읽어보세요.
또한 레거시 Cosmos DB 스토리지와 달리 Cosmos DB 분할된 스토리지는 Cosmos DB 계정 내에서 데이터베이스를 자동으로 만들지 않습니다. 새 데이터베이스를 수동으로 만들어야 하지만 CosmosDbPartitionedStorage에서 컨테이너를 만들므로 컨테이너를 수동으로 만드는 작업은 건너뜁니다.
다른 스토리지 옵션에 연결하는 방법에 대한 지침은 스토리지에 직접 쓰기를 참조하세요.
상태 관리
상태 관리는 기본 스토리지 계층에 대한 봇 상태 읽기 및 쓰기를 자동화합니다. 상태는 상태 속성으로 저장되며, 이는 봇이 특정 기본 구현에 대해 걱정하지 않고 상태 관리 개체를 통해 읽고 쓸 수 있는 사실상 키-값 쌍입니다. 이러한 상태 속성은 해당 정보가 저장되는 방법을 정의합니다. 예를 들어 특정 클래스 또는 개체로 정의한 속성을 검색할 때 해당 데이터가 어떻게 구성되는지 알 수 있습니다.
이러한 상태 속성은 범위가 지정된 "버킷"으로 일괄화되며 이러한 속성을 구성하는 데 도움이 되는 컬렉션일 뿐입니다. SDK에는 다음 세 가지 "버킷"이 포함됩니다.
- 사용자 상태
- 대화 상태
- 비공개 대화 상태
이러한 버킷은 모두 서로 다른 범위의 다른 유형의 버킷을 정의하기 위해 파생될 수 있는 봇 상태 클래스의 하위 클래스입니다.
이러한 미리 정의된 버킷들은 버킷에 따라 특정 가시성으로 제한됩니다.
- 사용자 상태는 대화에 관계없이 봇이 해당 채널에서 해당 사용자와 대화하는 순서로 사용할 수 있습니다.
- 대화 상태는 그룹 대화와 같이 사용자에 관계없이 특정 대화에서 언제든지 사용할 수 있습니다.
- 비공개 대화 상태는 특정 대화와 해당 특정 사용자로 범위가 지정됩니다.
팁 (조언)
사용자 및 대화 상태 모두 채널별로 범위가 지정됩니다. 서로 다른 채널을 사용하여 봇에 액세스하는 동일한 사용자는 각 채널마다 하나씩, 각각 고유한 사용자 상태를 가진 다른 사용자로 표시됩니다.
이러한 미리 정의된 각 버킷에 사용되는 키는 사용자 및 대화 또는 둘 다에 따라 다릅니다. 상태 속성의 값을 설정할 때 각 사용자 또는 대화가 올바른 버킷 및 속성에 배치되도록 턴 컨텍스트에 포함된 정보와 함께 키가 내부적으로 정의됩니다. 특히 키는 다음과 같이 정의됩니다.
- 사용자 상태는 채널 ID 및 from ID를 사용하여 키를 만듭니다. 예를 들어 {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
- 대화 상태는 채널 ID 및 대화 ID를 사용하여 키를 만듭니다. 예를 들어 {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
- 프라이빗 대화 상태는 채널 ID, from ID 및 대화 ID를 사용하여 키를 생성합니다. 예를 들어 {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName
각 상태 유형을 사용해야 하는 경우
대화 상태는 다음과 같이 대화의 컨텍스트를 추적하는 데 적합합니다.
- 봇이 사용자에게 질문을 했는지 여부와 그 질문
- 대화의 현재 주제 또는 마지막 항목이 무엇인지
사용자 상태는 다음과 같은 사용자 정보를 추적하는 데 적합합니다.
- 이름 및 기본 설정, 경보 설정 또는 경고 기본 설정과 같은 중요하지 않은 사용자 정보
- 봇과의 마지막 대화에 대한 정보
- 예를 들어 제품 지원 봇은 사용자가 요청한 제품을 추적할 수 있습니다.
비공개 대화 상태는 그룹 대화를 지원하지만 사용자 및 대화 관련 정보를 모두 추적하려는 채널에 적합합니다. 예를 들어 교실에서 사용하는 클릭봇이 있는 경우:
- 봇은 지정된 질문에 대한 학생 응답을 집계하고 표시할 수 있습니다.
- 봇은 각 학생의 성과를 집계하고 세션이 끝날 때 이를 비공개로 릴레이할 수 있습니다.
이러한 미리 정의된 버킷 사용에 대한 자세한 내용은 상태 방법 문서를 참조하세요.
여러 데이터베이스에 연결
봇이 여러 데이터베이스에 연결해야 하는 경우 각 데이터베이스에 대한 스토리지 계층을 만듭니다. 봇이 보안, 동시성 또는 데이터 위치 요구 사항이 다른 정보를 수집하는 경우 여러 데이터베이스를 사용하도록 선택할 수 있습니다.
각 스토리지 계층에 대해 상태 속성을 지원하는 데 필요한 상태 관리 개체를 만듭니다.
상태 속성 접근자
상태 속성 접근자는 실제로 상태 속성 중 하나를 읽거나 쓰는 데 사용되며, 턴 내에서 상태 속성에 액세스하기 위한 get, set 및 delete 메서드를 제공합니다. 접근자를 만들려면 봇을 초기화할 때 보통 속성 이름을 제공해야 합니다. 그런 다음, 해당 접근자를 사용하여 봇 상태의 해당 속성을 가져오고 조작할 수 있습니다.
접근자를 사용하면 SDK가 기본 스토리지에서 상태를 가져와서 봇의 상태 캐시 를 업데이트할 수 있습니다. 상태 캐시는 기본 스토리지에 액세스하지 않고도 읽기 및 쓰기 작업을 허용하는 상태 개체를 저장하는 봇에서 유지 관리하는 로컬 캐시입니다. 캐시에 아직 없는 경우 접근자의 get 메서드를 호출하면 상태를 검색하고 캐시에 배치합니다. 검색된 상태 속성은 지역 변수처럼 조작할 수 있습니다.
접근자의 delete 메서드는 캐시에서 속성을 제거하고 기본 스토리지에서도 삭제합니다.
중요합니다
접근자의 get 메서드에 대한 첫 번째 호출 시, 상태에 아직 없는 경우 개체를 생성할 수 있도록 팩터리 메서드를 제공해야 합니다. 팩터리 메서드가 지정되지 않으면 예외가 발생합니다. 팩터리 메서드를 사용하는 방법에 대한 자세한 내용은 상태 방법 문서에서 확인할 수 있습니다.
접근자에서 가져오는 상태 속성에 대한 변경 내용을 유지하려면 상태 캐시의 속성을 업데이트해야 합니다. 이 작업은 캐시에서 속성 값을 설정하는 set 메서드를 호출하여 수행할 수 있으며, 나중에 필요하면 이를 읽거나 업데이트할 수 있습니다. 실제로 해당 데이터를 기본 스토리지에 유지하려면(따라서 현재 전환 후 사용할 수 있도록) 상태를 저장해야 합니다.
상태 속성 접근자 메서드의 작동 방식
접근자 메서드는 봇이 상태와 상호 작용하는 기본 방법입니다. 각 계층의 작동 방식 및 기본 계층의 상호 작용 방식은 다음과 같습니다.
- 접근자의 get 메서드:
- 접근자가 상태 캐시에서 속성을 요청합니다.
- 속성이 캐시에 있으면 반환합니다. 그렇지 않으면 상태 관리 개체에서 가져옵니다. (아직 상태가 아닌 경우 접근자 get call에 제공된 팩터리 메서드를 사용합니다.)
- 접근자의 set 메서드:
- 상태 캐시를 새 속성 값으로 업데이트합니다.
- 상태 관리 개체의 변경 내용 저장 메서드:
- 상태 캐시의 속성 변경 내용을 확인합니다.
- 스토리지에 해당 속성을 씁니다.
대화 상자에서의 상태
대화 라이브러리는 봇의 대화 상태에 정의된 대화 상태 속성 접근자를 사용하여 대화에서 대화의 위치를 유지합니다. 또한 대화 상태 속성을 사용하면 각 대화 상자가 턴 사이에 일시적 정보를 저장할 수 있습니다.
적응형 대화 상자에는 보다 정교한 메모리 범위 구조가 있어 구성 및 인식 결과에 더 쉽게 액세스할 수 있습니다. 대화 관리자는 사용자 및 대화 상태 관리 개체를 사용하여 이러한 메모리 범위를 제공합니다.
대화 라이브러리에 대한 자세한 내용은 대화 상자 라이브러리 문서를 참조하세요.
- 구성 요소 및 폭포 대화 상자와 관련된 정보를 보려면 해당 대화 상자를 참조하세요.
- 적응형 대화와 관련된 정보는 적응형 대화 상자 문서의 적응형 대화 및 상태 관리 소개를 참조하세요.
상태 저장
접근자의 set 메서드를 호출하여 업데이트된 상태를 기록하는 경우 해당 상태 속성은 아직 지속형 스토리지에 저장되지 않고 대신 봇의 상태 캐시에만 저장됩니다. 상태 캐시의 변경 내용을 지속형 상태로 저장하려면 위에서 언급한 봇 상태 클래스(예: 사용자 상태 또는 대화 상태)의 구현에서 사용할 수 있는 상태 관리 개체의 변경 내용 저장 메서드를 호출해야 합니다.
위에서 언급한 버킷과 같은 상태 관리 개체에 대한 변경 내용 저장 메서드를 호출하면 해당 버킷에 대해 해당 지점으로 설정한 상태 캐시의 모든 속성이 저장되지만 봇의 상태에 있을 수 있는 다른 버킷에는 저장되지 않습니다.
팁 (조언)
봇 상태는 "마지막 쓰기 우선" 동작을 구현합니다. 여기서 마지막 쓰기는 이전에 작성된 상태에 스탬프를 찍습니다. 이는 많은 애플리케이션에서 작동할 수 있지만, 특히 일정 수준의 동시성 또는 대기 시간이 있을 수 있는 스케일 아웃 시나리오에서 의미가 있습니다.
턴 처리기가 완료된 후 상태를 업데이트할 수 있는 사용자 지정 미들웨어가 있는 경우 미들웨어에서 상태를 처리하는 것이 좋습니다.