Chatbot - 상태 관리


상태 관리

상태가 필요한 이유!

상태를 유지하고 관리하면 사용자나 대화에 대한 특정 정보를 기억해서 더 의미 있는 대화를 할 수 있다. 예를 들어 이전에 사용자와 대화한 적이 있으면 이 이전 정보를 저장할 수 있어서 다시 요청할 필요가 없게 된느 것이다.

또한 상태는 현재 turn보다 오래 유지하므로 다중 turn 대화를 수행하는 동안 봇에서 정보를 유지할 수 있다.

bot-builder-state

이 그림에서는 계층간의 상호작용 시퀀스를 보여준다.

스토리지 계층

상태 정보가 실제로 저장되는 백 엔드에서 시작하는 스토리지 계층이다.

Bot Framework SDK에는 스토리지 계층에 대한 몇 가지 구현이 이미 되어 있는 것이 있다.

  • 메모리 스토리지 : 테스트를 위한 메모리 내 스토리지를 구현한다. 메모리 내 데이터 스토리지는 휘발성, 임시 스토리지이므로 로컬 테스트 전용으로만 사용된다. 데이터는 봇이 다시 시작될떄마다 지워진다.
  • Azure Blob Storage : Azure Blob Storage 개체 데이터베이스에 연결된다.
  • Azure Cosmos DB 분할 스토리지 : 분할 Cosmos DB NoSQL 데이터베이스에 연결된다.

Cosmos DB 스토리지 클래스는 더 이상 사용되지 않는다. _Cosmos DB Storage_를 사용해서 생성된 컨테이너는 compatibilityMode 플래그가 추가된 _Cosmos DB 분할 스토리지_와 함꼐 사용할 수 있다. Cosmos DB 분할 된 저장소는 Cosmos DB 계정 내에서 데이터베이스를 자동으로 만들지 않는다. 새 DB를 만들때 Cosmos DB는 자동으로 데이터베이스 내에 컨테이너를 만든다

상태 관리

상태 관리는 기본 스토리지 계층에 대한 봇 상태의 읽기, 쓰기를 자동화한다.

상태는 봇에서 따로 구현할 필요 없이 “키-값” 쌍인 상태 속성으로 저장된다.

이런 상태 속성은 정보가 저장되는 방법을 정의한다.

상태 속성은 범위가 지정된 “버킷”으로 묶인다. SDK에 포함된 세가지 “버킷”은 다음과 같다.

  • 사용자 상태 : 대화와 관계없이 봇이 해당 채널에서 해당 사용자와 대화하는 모든 턴에서 사용 가능
  • 대화 상태 : 사용자와 관계없이 특정 대화의 모든 턴에서 사용 가능
  • 프라이빗 대화 상태 : 특정 대화와 특정 사용자 모두에 대한 범위로 지정됨

사용자랑 대화 상태는 모두 채널별로 범위가 지정된다. 만약 한 사용자가 다른 채널을 이용해서 봇에 액세스하는 경우에는 각 채널마다 하나씩 고유한 사용자 상태가 있는 다른 사용자로 인식이 된다.

미리 정의된 각 버킷에 사용되는 키는 사용자, 대화 각각이나 모두와 관련이 있다. 상태 속성에 대한 값을 설정할 때 사용자나 대화가 올바른 버킷과 속성에 배치되도록 turn context에 포함된 정보를 사용하여 내부적으로 키가 정의된다.

  • 사용자 상태는 채널 ID 및 원본 ID를 사용하여 키를 만듭니다. 예: {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
  • 대화 상태는 채널 ID 및 대화 ID를 사용하여 키를 만듭니다. 예: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
  • 프라이빗 대화 상태는 채널 ID, 원본 ID 및 대화 ID를 사용하여 키를 만듭니다. 예: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName

각 유형의 상태를 사용하는 경우

사용자 상태

다음과 같은 사용자에 대한 정보를 추적하는데 적합하다.

  • 중요하지 않은 사용자 정보(이름, 기본 설정, 경보 설정, 경고 기본 설정 등)
  • 봇과의 마지막 대화에 대한 정보

대화 상태

다음과 같은 대화의 context를 추적하는데 적합하다.

  • 봇에서 사용자에게 질문을 했는지 여부, 어떤 질문이었는지
  • 대화의 현재 주제가 무엇인지, 마지막 주제는 무엇인지

프라이빗 대화 상태

그룹 대화를 지원하지만 사용자와 대화 특정 정보를 모두 추적하려는 채널에 적합. 예를 들어 교실 원격 제어 봇이 있는 경우에,

  • 봇에서 지정된 질문에 대한 학생의 응답을 집계하고 표시하기 가능
  • 봇에서 각 학생의 성적을 집계하고 세션이 끝날 때 개인적으로 다시 전달 가능

상태 속성 접근자

상태 속성 접근자는 상태 속성 중 하나를 읽거나 쓰는데 사용된다.

get, set, delete method를 제공하여 단일 턴 내에서 상태 속성에 액세스한다.

접근자를 만드려면 일반적으로 봇을 초기화할 때 생기는 속성 이름을 제공해야 한다.

그 다음 해당 접근자를 사용해서 봇의 상태에 대한 속성을 가져오고 조작할 수 있다.

접근자를 사용하면 SDK를 통해 기본 스토리지에서 상태를 가져오고 사용자에 대한 봇의 상태 캐시를 업데이트 할 수 있다. 이 상태 캐시는 사용자에 대한 상태 개체를 저장하는 봇에서 유지 관리되는 로컬 캐시고, 기본 스토리지에 액세스하지 않고도 읽기, 쓰기 작업을 허용한다.

컴퓨터 구조 시간에 배웠던 캐시처럼 얘도 기본 스토리지에 액세스할 수고를 덜어주는 것 같다.

캐시에 없는 경우 접근자의 get 메서드를 호출하면 상태를 검색해서 캐시에 배치한다.

검색된 상태 속성은 로컬 변수처럼 조작할 수 있다.

delete 메서드 같은 경우는 캐시에서 속성을 제거하고 기본 스토리지에서도 속성을 제거한다.

접근자에서 가져온 상태 속성에 대한 변경 내용을 유지하려면 상태 캐시의 속성을 업데이트 해야 한다.

이것은 set 메서드(속성 값을 캐시에 설정하고 나중에 이거를 읽거나 업데이트 해야하는 경우 사용)를 통해 할 수 있다.

이 데이터를 기본 스토리지에 유지하려면 상태를 저장해야 한다.

상태 속성 접근자 메서드의 작동 방식

  • 접근자의 get 메서드
    • 접근자가 상태 캐시에서 속성을 요청합니다.
    • 속성이 캐시에 있으면 이를 반환합니다. 그렇지 않으면 상태 관리 개체에서 가져옵니다. (상태에 아직 없는 경우 접근자의 get 호출에 제공된 팩터리 메서드를 사용합니다.)
  • 접근자의 set 메서드
    • 상태 캐시를 새 속성 값으로 업데이트합니다.
  • 상태 관리 개체의 변경 내용 저장 메서드
    • 상태 캐시에서 속성에 대한 변경 내용을 확인합니다.
    • 해당 속성을 스토리지에 씁니다.

상태 저장

접근자의 set 메서드를 사용해서 업데이트 된 상태를 기록하면 상태 속성이 지속형 스토리지에 저장되는 것이 아니라 봇의 상태 캐시에만 저장된다.

변경 내용을 지속되는 상태로 상태 캐시에 저장하려면 위에 있는 상태 클래스의 구현에서 사용할 수 있는 상태 관리 개체의 변경 내용 저장 메서드를 호출해야 한다.