Watson Conversation에서 Condition을 작성하거나 주고 받는 메세지를 작성할 때에는 SpEL(Spring Expression Language)을 사용합니다. SpEL은 다양한 Feature를 지원합니다(SpEL Features).

빌트인 글로벌 변수(Built-in Global Variables)

Watson Conversation에서 사용할 수 있는 빌트인 Global 변수는 아래와 같습니다.

intents[ ] 인텐트 목록
entities[ ] 엔티티 목록
input 사용자의 입력값을 담은 JSON object
output Watson의 출력값을 담은 JSON object
context 사용자와 Watson 사이의 대화 문맥을 담은 JSON object
conversation_start 처음 대화를 시작할 때 true가 되는 Boolean 값으로 웰컴 메세지의 Condition으로 사용 가능
anything_else 사용자 입력 값이 어느 인텐트에도 매치되지 않을 때 이 Condition을 사용한 노드의 출력값이 사용됨

대화에서 추출된 Entity 사용하기

대화 중 추출된 Entity를 활용하는 표현으로 아래와 같은 예시가 있습니다.

entities.airport[0].literal == 'Kennedy Airport'
entities.airport[0].value == 'JFK Airport'
< ? entities.city.literal ?>
짧은 문법 SpEL 문법
@year entities[‘year’]?.value
@year == 2016 entities[‘year’]?.value == 2016
@year != 2016 entities[‘year’]?.value != 2016
@city == ‘Boston’ entities[‘city’]?.value == ‘Boston’
@city:Boston entities[‘city’]?.contains(‘Boston’)
@city:(New York) entities[‘city’]?.contains(‘New York’)

SpEL에서 ? 마크는 변수가 null인 경우를 체크하여 null point exception을 방지하기 위해 사용합니다.

아래의 컨디션을 예로 들면,

entities['city']?.contains('Boston')

이 컨디션은 적어도 하나의 Boston이 @city 엔티티에서 발견될 때 true를 리턴합니다.

예를 들어 사용자가 아래의 메세지를 보냈다면

I want to go from Toronto to Boston.

@city:Toronto 와 @city:Boston, 2개의 엔티티가 발견됩니다. 따라서 엔티티의 값은 아래처럼 됩니다.

entities: entities.city[0].value = 'Toronto'
entities.city[1].value = 'Boston'

이 예제에서, 위의 컨디션 entities.city.contains(‘Boston’)은 Boston이 엔티티의 두번째 값이더라도 true를 리턴합니다.

사용자 인풋(input) 사용하기

사용자 인풋을 활용하는 방법으로 아래와 같은 예가 있습니다.

input.text == 'yes'
input.text.contains( 'yes' )
input.text.matches( '[0-9]+' )

인텐트(intent) 사용하기

인텐트를 활용하는 방법으로 아래의 예를 참조하십시오.

intents[0] == 'Help' or intents == 'Help'

아래와 같은 포맷도 가능합니다.

짧은 문법 SpEL 문법
#help intent == ‘help’
! #help intent != ‘help’
NOT #help intent != ‘help’
#help or #i_am_lost (intent == ‘help’ || intent == ‘I_am_lost’)

문맥(Context) 정보 활용하기

아웃풋 메세지에 사용자의 이름을 넣는 예시입니다.

"output":{"text":"Your name is < ? context.userName ?>"} 
"output":{"text":"Your name is $userName"} 

문맥(Context)에 값을 업데이트 하기 위해 합수를 사용할 수도 있습니다.

"context":{"toppings": "< ? context.toppings.append( 'onions' ) ?>"}
짧은 문법 SpEL 문법
$card_type:VISA context[‘card_type’] == ‘VISA’
$card_type:(MASTER CARD) context[‘card_type’] == ‘MASTER CARD’

함수 사용하기

컨디션 또는 Response에 아래와 같이 함수를 활용할 수 있습니다.

런타임 환경에서 아래와 같은 문맥(Context)을 갖고 있다고 가정하겠습니다.

{
  "context": {
    "toppings_array": ["onion", "olives", "ham"]
  }
}

컨디션에 아래와 같이 contains 함수를 사용할 수 있습니다.

{
  "conditions": "$toppings_array.contains('ham')"
}

또는 아래처럼 사용 가능합니다.

{
  "output": {
    "text": "This is the array: < ? $toppings_array.join(';') ?>"
  }
}

JSONArray 타입에 사용할 수 있는 함수는 아래와 같습니다.

  • JSONArray.size()
  • JSONArray.append(object)
  • JSONArray.remove(integer)
  • JSONArray.removeValue(object)
  • JSONArray.get(integer)
  • JSONArray.getRandomItem()
  • JSONArray.join(string delimiter)
  • JSONArray.contains(object value)
  • JSONArray.set(integer index, object value)

JSONObject 타입에는 아래 함수를 사용 가능합니다.

  • JSONObject.has(string)
  • JSONObject.remove(string)

String 타입은 아래와 같은 함수를 활용하십시오.

  • String.length()
  • String.toUpperCase()
  • String.toLowerCase()
  • String.endsWith(string)
  • String.startsWith(string)
  • String.isEmpty()
  • String.trim()
  • String.substring(int beginindex, int endindex)
  • String.append(object)
  • String.matches(String regexp)
  • String.extract(String regexp, Integer groupIndex)
  • String.split(String regexp)

아래는 숫자 타입에 사용 가능한 함수입니다.

  • Number.toInt()
  • Number.toLong()
  • Number.toDouble()

시스템 엔티티(System Entity) 사용하기

Watson Conversation은 사용자가 작성한 엔티티 외에도 시스템 엔티티를 사용할 수 있습니다. 날짜, 시간, 숫자, 통화, Timezone 등의 시스템 엔티티가 있습니다. 시스템 엔티티를 사용 가능하게 하기 위해서는 이 기능을 Enable 해야 합니다. 시스템 엔티티 사용법을 참조하여 적절하게 활용하면 좀 더 쉽게 로직을 작성할 수 있습니다. 타임존(Timezone)과 관련된 시스템 엔티티도 참조하십시오.

@sys-number 엔티티

@sys-number 엔티티는 아래 처럼 활용할 수 있습니다.

속성 타입 리턴 타입 : twenty 리턴 타입 : 1,234.56
@sys-number string 20 1234.56
@sys-number.literal string twenty 1,234.56
@sys-number.numeric_value number 20 1234.56

@sys-date와 @sys-time 엔티티

@sys-date는 Friday, today, November 1 과 같은 날짜 값을 추출해 내는 엔티티 입니다. 엔티티의 값은 사용자 입력값으로부터 날짜 값을 추론하여 “yyyy-MM-dd” 포맷의 string으로 저장됩니다. 사용자가 November 1만 입력하더라도 시스템은 현재 날짜로 연도를 추측하여 값을 저장합니다.

@sys-time은 2pm, at 4, 15:30 과 같은 시간 값을 추출합니다. 이렇게 추출된 값은 “HH:mm:ss” 포맷의 string으로 저장됩니다.

< 날짜와 시간을 함께 언급할 때>

지금(now) 또는 2시간 뒤에(two hours from now)와 같은 말에서는 @sys-date와 @sys-time가 동시에 추출됩니다. 월요일 4시(Monday at 4pm)와 같은 말 또한 @sys-date와 @sys-time이 동시에 추출됩니다. 날짜와 시간이 연속적으로 언급될 때에는 이처럼 두 정보가 하나로 연결되어 추출됩니다.

< 날짜와 시간의 범위를 언급할 때>

주말(the weekend), 다음 주(next week), 월요일부터 금요일까지(From Monday to Friday)와 같은 날짜의 범주가 언급될 때에는 두 쌍의 @sys-date 엔티티가 추출되어 시작과 끝을 저장합니다. 이와 비슷하게 2시에서 3시(From 2 to 3)와 같은 시간 범위를 언급하면 두개의 @sys-time 엔티티가 추출됩니다.

< 타임존(Timezone)>

현재 시간과 관련된 날짜와 시간을 언급할 때에는 타임존에 따라서 값이 계산됩니다. 타임존을 따로 선택하지 않으면 UTC(GMT) 시간을 기준으로 계산합니다.
따라서 UTC(GMT)와 다른 타임존에 있다면 컨텍스트(context) 변수인 $timezone에 해당 지역의 타임존을 설정해야 합니다. 이 변수는 모든 request에 보내져야 합니다. $timezone 값의 예로는 America/Los_Angeles, EST, UTC 등이 있습니다. 지원되는 전체 타임존 목록을 확인하고 사용하십시오.

$timezone 변수가 제공되면 @sys-date와 @sys-time 값은 모두 UTC 대신 설정된 timezone을 기반으로 한 값으로 저장됩니다.

< @sys-date의 사용 예시>
속성 타입 리턴 타입 : November 21
@sys-date.literal string November 21
@sys-date string 20xx-11-21 *
@sys-date.location array [0,11]
@sys-date.calendar_type string GREGORIAN
  • 연도를 특별히 언급하지 않은 경우 해당 날짜의 가장 가까운 미래의 연도를 리턴합니다.
< @sys-time의 사용 예시>
속성 타입 리턴 타입 : at 6 pm
@sys-time.literal string at 6 pm
@sys-time string 18:00:00
@sys-time.location array [0,7]
@sys-time.calendar_type string GREGORIAN
< @sys-date와 @sys-time에 사용 가능한 함수들>

@sys-date와 @sys-time으로 추출된 값에 사용할 수 있는 함수들은 아래와 같습니다.

  • .before(String date or time)
  • .after(String date/time)
  • .sameOrBefore(String date/time)
  • .sameOrAfter(String date/time)
  • .sameMoment(String date/time)
  • .reformatDateTime(String format)
  • now()

위의 함수들을 사용하는 예시입니다.

@sys-time.before('12:00:00')
@sys-date.before('2016-11-21')

노드의 컨디션에 now()함수를 활용한 예시입니다.

{
  "conditions": "now().before('12:00:00')",
  "output": {
    "text": {
      "values": [ "Good morning!" ]
      }
   }
}

* 이 글은 영문 가이드를 베이스로 작성되었습니다. (원문 : http://www.ibm.com/watson/developercloud/doc/conversation/expression-language.html)