상태 관리

적용 대상: 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원본 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

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

대화 상태는 다음과 같은 대화의 컨텍스트를 추적하는 데 적합합니다.

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

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

  • 중요하지 않은 사용자 정보(예: 이름 및 기본 설정, 경보 설정 또는 경고 기본 설정)
  • 봇과의 마지막 대화에 대한 정보
    • 예를 들어 제품 지원 봇에서는 사용자가 질문한 제품을 추적할 수 있습니다.

프라이빗 대화 상태는 그룹 대화를 지원하지만 사용자와 대화 특정 정보를 모두 추적하려는 채널에 적합합니다. 예를 들어 클래스룸 원격 제어 봇이 있는 경우 다음과 같습니다.

  • 봇에서 지정된 질문에 대한 학생의 응답을 집계하고 표시할 수 있습니다.
  • 봇에서 각 학생의 성적을 집계하고, 세션이 끝날 때 개인적으로 다시 전달할 수 있습니다.

이러한 미리 정의된 버킷을 사용하는 방법에 대한 자세한 내용은 상태 사용 방법 문서를 참조하세요.

여러 데이터베이스에 연결

봇에서 여러 데이터베이스에 연결해야 하는 경우 각 데이터베이스에 대한 스토리지 계층을 만듭니다. 봇이 보안, 동시성 또는 데이터 위치 요구 사항이 다른 정보를 수집하는 경우 여러 데이터베이스를 사용하도록 선택할 수 있습니다.

각 스토리지 계층에 대해 상태 속성을 지원하는 데 필요한 상태 관리 개체를 만듭니다.

상태 속성 접근자

상태 속성 접근자는 실제로 상태 속성 중 하나를 읽거나 쓰는 데 사용되며, get, setdelete 메서드를 제공하여 단일 턴 내에서 상태 속성에 액세스합니다. 접근자를 만들려면 일반적으로 봇을 초기화할 때 발생하는 속성 이름을 제공해야 합니다. 그런 다음, 해당 접근자를 사용하여 봇의 상태에 대한 속성을 가져오고 조작할 수 있습니다.

접근자를 사용하면 SDK를 통해 기본 스토리지에서 상태를 가져오고 사용자에 대한 봇의 상태 캐시를 업데이트할 수 있습니다. 상태 캐시는 사용자에 대한 상태 개체를 저장하는 봇에서 유지 관리되는 로컬 캐시이며, 기본 스토리지에 액세스하지 않고도 읽기 및 쓰기 작업을 허용합니다. 아직 캐시에 없는 경우 접근자의 get 메서드를 호출하면 상태를 검색하고 이를 캐시에 배치합니다. 일단 검색되면 상태 속성은 로컬 변수처럼 조작할 수 있습니다.

접근자의 delete 메서드는 캐시에서 속성을 제거하고 기본 스토리지에서도 해당 속성을 삭제합니다.

중요

접근자의 get 메서드에 대한 첫 번째 호출의 경우 상태에 개체가 아직 없으면 해당 개체를 만드는 팩터리 메서드를 제공해야 합니다. 팩터리 메서드가 제공되지 않으면 예외가 발생합니다. 팩터리 메서드를 사용하는 방법에 대한 자세한 내용은 상태 사용 방법 문서에서 확인할 수 있습니다.

접근자에서 가져온 상태 속성에 대한 변경 내용을 유지하려면 상태 캐시의 속성을 업데이트해야 합니다. 이렇게 하려면 속성 값을 캐시에 설정하고 나중에 이를 읽거나 업데이트해야 하는 경우 사용할 수 있는 set 메서드 호출을 통해 수행할 수 있습니다. 실제로 해당 데이터를 기본 스토리지에 유지하려면(이에 따라 현재 턴 이후에 사용할 수 있도록 설정) 상태를 저장해야 합니다.

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

접근자 메서드는 봇에서 상태와 상호 작용하는 기본 방법입니다. 각각의 작동 방식과 기본 계층에서 상호 작용하는 방식은 다음과 같습니다.

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

대화 상자의 상태

대화 라이브러리는 봇의 대화 상태에 정의된 대화 상태 속성 접근자를 사용하여 대화에서 대화의 위치를 유지합니다. 대화 상태 속성을 사용하면 각 대화 상자가 턴 사이에 일시적 정보를 저장할 수도 있습니다.

적응형 대화 상자에는 보다 정교한 메모리 범위 구조가 있어 구성 및 인식 결과에 더 쉽게 액세스할 수 있습니다. 대화 관리자는 사용자 및 대화 상태 관리 개체를 사용하여 이러한 메모리 범위를 제공합니다.

대화 라이브러리에 대한 자세한 내용은 대화 상자 라이브러리 문서를 참조 하세요 .

상태 저장

접근자의 set 메서드를 호출하여 업데이트된 상태를 기록하면 해당 상태 속성이 지속형 스토리지에 아직 저장되지 않고 봇의 상태 캐시에만 대신 저장됩니다. 변경 내용을 지속됨 상태로 상태 캐시에 저장하려면, 위에서 언급한 봇 상태 클래스의 구현(예: 사용자 상태 또는 대화 상태)에서 사용할 수 있는 상태 관리 개체의 변경 내용 저장 메서드를 호출해야 합니다.

위에서 언급한 버킷과 같이 상태 관리 개체에 대한 변경 내용 저장 메서드를 호출하면 해당 버킷에 대해 해당 지점으로 설정한 상태 캐시의 모든 속성이 저장되지만 봇 상태에 있을 수 있는 다른 버킷에는 저장되지 않습니다.

봇 상태는 마지막 쓰기가 이전에 쓴 상태를 덮어쓰는 "마지막으로 성공한 쓰기" 동작을 구현합니다. 이 동작은 많은 애플리케이션에서 제대로 작동할 수 있지만, 특히 진행 중인 일정 수준의 동시성 또는 대기 시간이 있을 수 있는 규모 확장 시나리오에 영향을 줍니다.

턴 처리기가 완료된 후에 상태를 업데이트할 수 있는 일부 사용자 지정 미들웨어가 있는 경우 미들웨어의 처리 상태를 고려하세요.

추가 리소스