대화처리 기술

대화처리 기술

ETRI에서 개발한 대화처리 기술(GenieDialog)은 특정 업무를 대화로 수행하는 목적지향 대화시스템 기술입니다. 목적지향 대화처리 시스템의 예로는 각종 정보 검색, 일정 관리, 상품 주문이나 호텔 및 음식점 예약 등이 있습니다. 목적지향 대화시스템은 대상 도메인 의 목적에 맞추어 대화가 가능하도록 하기 위해 대화 지식이나 데이터를 구축하는 것을 선행하여야 합니다. 본 서비스에서는 이를 위한 대화처리 응용개발도구를 제공하고 있습니다.

대화처리 응용개발도구

GenieDialog 대화처리 응용개발도구를 통해 대화처리를 위한 도메인별 대화모델을 개발하실 수 있습니다. 도구 사용은 구글 크롬 브라우저 환경에서 진행하시기를 권장합니다.

대화처리 응용개발도구의 URL주소는 다음과 같습니다.

대화처리 응용개발도구 사용을 위한 자세한 메뉴얼은 첨부파일을 참고하시기 바랍니다.

http://geniedialog.etri.re.kr:8090/EtriDialog/

다음은 접속하게 되는 초기 화면입니다.

GenieDialog 접속 초기 화면

도구에서 오른쪽 화면에 제공되는 Quick Start 동영상(GENIE Dialog Quick Guide)을 보시고 대화 모델을 개발하시면 쉽게 작업을 시작하실 수 있습니다. 도구 사용을 위한 자세한 매뉴얼은 첨부 파일(다운로드 링크)을 참고하시기 바랍니다

대화처리 응용개발도구를 사용하기 위해서는 발급받으신 API Key정보를 이용한 사용자 등록이 필요합니다. 사용자 등록 단계는 다음과 같습니다.

(1) 도구 화면(도구의 초기 접속 화면)에서 사용자 등록 메뉴(오른쪽 상단)을 클릭합니다.

(2) 사용자 등록 화면(아래 그림)에서 API Key를 입력하고 아이디와 패스워드를 생성하여 등록한다.

GenieDialog 사용자 등록 화면
대화처리 API 란?

대화처리 API는 open API사용자가 직접 개발한 도메인의 대화모델을 기반으로 일반사용자의 발화를 분석하여 그에 적합한 시스템 응답을 제공합니다.

대화처리 API는 대화처리 응용개발도구에서 개발한 응용도메인의 대화 처리를 HTTP 기반의 REST API 인터페이스로 JSON 포맷 기반의 입력 및 출력으로 지원하며, 본 사이트에서 제공하는API Key인증을 통해 사용할 수 있는 Open API입니다.

API 호출 1일 허용량
기술명 API명 1일 허용량
대화처리 API 사용하기

대화처리 API는 REST API이며, HTTP 통신으로 ETRI Open API 서버에 전달하면 됩니다. 서버가 제공하는 REST API의 URL는 다음과 같으며 POST 방식으로 호출해야 합니다.

http://aiopen.etri.re.kr:8000/Dialog

대화처리 API는 대화할 도메인을 선택하고 이전 대화 내용을 고려한 대화가 가능하기 위해 다음 3개의 POST 방식의 API method로 구성되어 있습니다.

  • open_dialog : 대화할 도메인 이름으로 새로운 대화를 오픈합니다. 서버에서는 대화 섹션을 관리하기 위한 uuid 키 값을 발급합니다.
  • dialog : 사용자의 입력을 분석하고 시스템 응답을 제공합니다. open_dialog method 호출 시에 발급받은 uuid 키로 대화 도메인과 이력을 유지합니다.
  • close_dialog : 대화 섹션 종료를 제공합니다.

다음 개념도는 대화처리 API에서 위의 3가지 방식으로 대화 섹션을 오픈하고 대화를 진행 및 종료하는 것을 나타내고 있습니다. 먼저 open_dialog method 방식으로 대화할 도메인을 선정하여 대화섹션 오픈을 요청하시면, 그 결과로 요청한 도메인의 첫 시스템 발화와 대화 섹션을 유지할 uuid 키 값을 발급받습니다. 그리고, dialog method 방식으로 사용자 입력과 발급받은 uuid 키 값을 대화서버 API에 전달하면 uuid 키 값으로 이전 대화 내용을 참고한 시스템 응답을 출력받습니다. 시스템 발화 응답이 요청한 도메인의 마지막 시스템 응답이었으면 종료 표시를 알리고 대화 섹션이 종료됩니다. 대화서버 API를 통해 현재 대화섹션을 종료하고자 하면, close_dialog method로 종료할 수도 있습니다.

대화처리 API 개념도
1) open_dialog method의 HTTP 요청/응답 메시지

HTTP 요청으로 대화할 도메인에 대한 새로운 대화 섹션을 오픈합니다. 사전 준비 사항에서 발급받은 API key 정보와 대화처리 응용개발도구에서 개발한 도메인 이름을 요청하는 본문에 포함시켜야 합니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 요청 메시지 예입니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “open_dialog”,
		"name": “DOMAIN_NAME(Ex. Weather)”,
		"access_method": “ACCESS_METHOD”
		}
}
							

상기 access_method는 다음 2가지가 가능합니다.

  • internal_data : 대화처리 응용개발도구에서 도메인을 구축하면서 사용한 instance data base 정보에 기반하여 대화하는 방식입니다. 도메인 관련 정보가 변경되지 않는 경우에는 이 방식을 채택하시면 됩니다.
  • external_data : 대화처리 응용개발도구에서 도메인을 구축하면서 사용한 instance data base 정보를 이용하지 않고 새로운 data 정보를 대화 서버에 제공하여 대화처리를 하는 방식입니다. 예를 들어, 날씨 도메인의 경우에 도메인 구축 시에는 예제로 임의의 날씨 정보를 넣어서 개발할 수 있지만 실제로는 매일 새롭게 정보가 변경되기에 관련 날씨 사이트 및 날씨정보 제공 API를 통하여 얻은 데이터로 대화를 해야 합니다. 이를 위해 날씨의 실제 데이터를 대화서버에 제공하여 대화가 가능하게 해야 합니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 응답 예제 입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {
		method : "open_dialog",
		uuid : "OPEN_DIALOG_UUID",
		result : {
			system_text : "",
			state : "start",
			maessage : ""
		}
	}
}
							
2) dialog method의 HTTP 요청/응답 메시지

dialog method는 open_dialog method에서 domain에 대한 access_method가 “internal_data”인 경우와 “external_data”인 경우로 구분할 수 있습니다.

internal data

access_method가 internal_data 방식인 경우에는 대화처리 응용개발도구에서 기구축한 데이터를 사용하기 때문에 추가적인 요청없이 사용자 입력에 바로 시스템 응답을 출력하도록 HTTP 요청과 응답 메시지 한쌍으로 구성됩니다.

HTTP 요청으로 method가 dialog이고, 제공받은 access_key와 uuid로 현재 대화 섹션을 유지하는 정보와 사용자 입력 발화를 포함합니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 dialog method의 HTTP 요청 메시지 예입니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “dialog”,
		"uuid": “DIALOG_API_UUID”,
		"text": “YOUR_QUESTION”
		}
}
										

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 응답 예제 입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {
		method : "dialog",
		uuid : "OPEN_DIALOG_UUID",
		result : {
			system_text : "",
			state : "dialog",
			maessage : ""
		}
	}
}
										

dialog method의 HTTP 응답 “result”에서 “state”은 다음과 같이 3가지가 있을 수 있습니다.

  • dialog : 사용자 입력에 시스템 응답을 성공적으로 수행함을 표시합니다.
  • end : 시스템 응답이 마지막 대화여서 더 이상 대화 진행이 불가능하여 대화 섹션이 종료됨을 표시합니다.
  • error : 요청 메시지의 잘못된 입력으로 인해 발생하는 오류 상태를 표시합니다. 그리고, message에 그 오류 유형을 출력합니다.
external data

access_method가 external_data 방식의 경우에는 대화처리 응용개발도구에서 기구축한 데이터를 사용하지 않기에 internal_data 방식과 비교하여 사용자 입력을 분석하여 필요한 외부 데이터를 요청하고 이를 다시 입력으로 받는 과정이 더 필요합니다.

external_data 방식에서도 사용자 입력 처리에 대한 요청은 internal_data 방식과 같습니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 요청 메시지 예입니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “dialog”,
		"uuid": “DIALOG_API_UUID”,
		"text": “YOUR_QUESTION”
	}
}
										

대화처리 서버에서 주어진 요청의 입력을 분석하여 새로운 데이터가 필요없이 응답이 가능하면 internal_data 방식과 같이 바로 응답 메시지를 출력합니다.

하지만, 응답하기 위해 데이터가 필요하다고 판단되면 다음과 같은 데이터 요청을 응답 메시지로 출력합니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 응답 예제 입니다.

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {
		method : "dialog",
		uuid : "OPEN_DIALOG_UUID",
		result : {
			data_request : [
									{
										slots : ["Wether.city", "Weather.date", "Weather.info"],
										condition : "Weather.date=\"오늘\""
									}
			],
			state : "data_request",
			message : ""
		}
	}
}
										

HTTP 응답 “result”의 “state”가 “data_request”이면, 외부의 새로운 데이터 요청을 표시합니다. 필요한 데이터의 종류와 조건은 “result”의 “data_request”에 array 형태로 표시됩니다. 사용자 입력 분석 결과로 필요한 외부 데이터가 다수 개의 다른 Entity Class(대화처리 응용개발도구에서 정의함)의 값들일 수 있기에 array 형태로 표시됩니다. 따라서, data_request array의 entry 정보는 각 Entity Class에 대한 것입니다. 각 entry 정보는 해당 Entity Class에서 값이 필요한 slot 이름들과 그 값을 검색하는 조건입니다. 상기 예에서는 slots에 표시된 Weather.city, Weather.data, Weather.info 정보들을 “Weather.date”이 “오늘”인 조건에 맞는 제공해 달라는 의미입니다. 여기에 언급된 slots 이름들은 대화처리 응용개발도구에서 도메인을 개발하면서 정의한 것들입니다. condition에서는 and, or와 “( )”로 관계를 표시할 수 있습니다. slot과 slot 값 사이에 연산자로는 “=”, “~=”(not equal), “>”, “<=”, “<”, “<=”로 표시합니다. 예를 들어, “condition”: “(Weather.city=\”서울\” or Weather.city=\”부산\”) and (Weather.date=\”오늘\” or Weather.date=\”내일\”)” 이 가능합니다.

이러한 요청을 받게 되면, 관련 데이터를 제공하는 외부 서버 및 API를 접근하여 그 정보를 추출하여 다음과 같은 형식으로 HTTP 메시지로 ETRI Open API로 전송하시면 됩니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 요청 메시지 예입니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “dialog”,
		"uuid": “DIALOG_API_UUID”,
		"text": “YOUR_QUESTION”,
		"data": [
							{
								"Weather.city": "서울",
								"Weather.date": "오늘",
								"Weather.info": "맑음"
							},
							{
								"Weather.city": "부산",
								"Weather.date": "오늘",
								"Weather.info": "흐림"
							},
							{
								"Weather.city": "<count>124</count>",
								"Weather.date": "오늘",
								"Weather.info": "<count>124</count>"
							}
		]
	}
}
										

상기 data에는 “data_request”에 의해 추출한 값들을 record array로 입력하시면 됩니다. “data_request”의 slots에서 요구한 slot과 그 값 쌍들을 record 형태로 구성합니다. “data_request”의 조건에 만족하는 record가 다수 개일 수 있기에 array로 입력합니다. 만약 조건에 맞는 데이터가 너무 많으면 모든 데이터를 입력으로 할 경우에 통신과 처리 비용이 증가하게 됩니다. 도메인에서 시스템 응답 설계 시에 잘 정의하시면, 모든 데이터를 대화처리 서버로 전달할 필요가 없습니다.

대부분의 경우, 시스템 응답은 record 수가 몇 개 이상인 경우에는 검색 결과가 너무 많아서 다른 조건을 요청하는 것이 일반적입니다. 따라서, 모든 데이터를 입력으로 넣는 것은 부적합합니다. 그럴 경우에, 상기 예에서처럼 실제 값들을 몇 개 record에 넣고, 마지막 record에 검색된 모든 데이터 record 개수를 적어서 전달하는 것이 좋습니다. 검색된 record 수는 각 slot에 “<count>” 태그를 사용하셔서 상기 예처럼 작성하시면 됩니다. 그러면 대화처리 서버에서 현재 조건에 맞는 각 slot의 값 개수를 파악하여 적절한 대답이 가능합니다.

“external_data” 방식의 access_method에서 “data_request” state 이후에 상기처럼 외부 data를 입력 메시지로 받은 후에 다음과 같은 HTTP 메시지로 ETRI Open API로 전송하시면 됩니다.

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 응답 메시지 예입니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “dialog”,
		"uuid": “DIALOG_API_UUID”,
		"text": “YOUR_QUESTION”
	}
}
										

상기 dialog method의 응답 메시지는 “internal_data” 방식 및 “external_data” 방식에서 “data_request” state가 없는 응답 메시지와 동일한 구조입니다.

3) close_dialog method의 HTTP 요청/응답 메시지

open_dialog method로 오픈한 대화 섹션을 종료시키는 요청 메시지입니다. close_dialog method의 요청 메시지에는 access key와 발급받은 uuid를 포함합니다. 그 요청 메시지의 예는 다음과 같습니다.

[HTTP Request Body]
{
	"request_id": "reserved field",
	"access_key": “YOUR_ACCESS_KEY”,
	"argument": {
		"method" : “close_dialog”,
		"uuid": “DIALOG_API_UUID”
		}
}
							

상세한 파라미터 설명은 API 레퍼런스 가이드(링크)를 참조하시기 바랍니다. 다음은 HTTP 응답 예제 입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {
		method : "close_dialog",
		uuid : "OPEN_DIALOG_UUID",
		result : {
			state : "end",
			maessage : ""
		}
	}
}
							

구현 예제
Java

JSON parsing을 위해 Gson 라이브러리를 사용하여 제공하고 있습니다. Gson 라이브러리에 대한 자세한 설명은 https://github.com/google/gson 에서 확인 하실 수 있습니다.

////////////////////////// OPEN DIALOG //////////////////////////
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;

public class Example {

	static public void main ( String[] args ) {
		String openApiURL = "http://aiopen.etri.re.kr:8000/Dialog";
		String accessKey = "YOUR_ACCESS_KEY";    // 발급받은 API Key
		String domain = "DOMAIN_NAME";			// 도메인 명
		String access_method = "METHOD_TYPE";	// 도메인 방식
		String method = "open_dialog";						// method 호출 방식
		Gson gson = new Gson();

		Map<String, Object> request = new HashMap<>();
		Map<String, String> argument = new HashMap<>();

		////////////////////////// OPEN DIALOG //////////////////////////

		argument.put("name", domain);
		argument.put("access_method", access_method);
		argument.put("method", method);

		request.put("access_key", accessKey);
		request.put("argument", argument);


		URL url;
		Integer responseCode = null;
		String responBody = null;
		try {
				url = new URL(openApiURL);
				HttpURLConnection con = (HttpURLConnection)url.openConnection();
				con.setRequestMethod("POST");
				con.setDoOutput(true);

				DataOutputStream wr = new DataOutputStream(con.getOutputStream());
				wr.write(gson.toJson(request).getBytes("UTF-8"));
				wr.flush();
				wr.close();

				responseCode = con.getResponseCode();
				InputStream is = con.getInputStream();
				byte[] buffer = new byte[is.available()];
				int byteRead = is.read(buffer);
				responBody = new String(buffer);

				////////////////////////// GET UUID /////////////////////////
				Map<String, Object> result = new HashMap<>();
				result = gson.fromJson(responseCode, Map.class);
				uuid = result.get("uuid").toString();

				System.out.println("[responseCode] " + responseCode);
				System.out.println("[responBody]");
				System.out.println(responBody);

		} catch (MalformedURLException e) {
				e.printStackTrace();
		} catch (IOException e) {
				e.printStackTrace();
		}
	}
}

////////////////////////// DIALOG //////////////////////////
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;

public class Example {

	static public void main ( String[] args ) {
		String openApiURL = "http://aiopen.etri.re.kr:8000/Dialog";
		String accessKey = "YOUR_ACCESS_KEY";    // 발급받은 API Key
		String uuid = "UUID_FROM_OPEN_DIALOG";	// Open Dialog로 부터 생성된 UUID
		String method = "dialog";			// method 호출 방식
		String text = "YOUR_TEXT";			// method 호출 방식
		Gson gson = new Gson();

		Map<String, Object> request = new HashMap<>();
		Map<String, String> argument = new HashMap<>();

		////////////////////////// OPEN DIALOG //////////////////////////

		argument.put("uuid", uuid);
		argument.put("method", method);
		argument.put("text", text;

		request.put("access_key", accessKey);
		request.put("argument", argument);


		URL url;
		Integer responseCode = null;
		String responBody = null;
		try {
				url = new URL(openApiURL);
				HttpURLConnection con = (HttpURLConnection)url.openConnection();
				con.setRequestMethod("POST");
				con.setDoOutput(true);

				DataOutputStream wr = new DataOutputStream(con.getOutputStream());
				wr.write(gson.toJson(request).getBytes("UTF-8"));
				wr.flush();
				wr.close();

				responseCode = con.getResponseCode();
				InputStream is = con.getInputStream();
				byte[] buffer = new byte[is.available()];
				int byteRead = is.read(buffer);
				responBody = new String(buffer);

				////////////////////////// GET UUID /////////////////////////
				Map<String, Object> result = new HashMap<>();
				result = gson.fromJson(responseCode, Map.class);
				uuid = result.get("uuid").toString();

				System.out.println("[responseCode] " + responseCode);
				System.out.println("[responBody]");
				System.out.println(responBody);

		} catch (MalformedURLException e) {
				e.printStackTrace();
		} catch (IOException e) {
				e.printStackTrace();
		}
	}
}
										
PHP
//////////////////////////// OPEN DIALOG
<?php
	$openApiURL = "http://aiopen.etri.re.kr:8000/Dialog";
	$accessKey = "YOUR_ACCESS_KEY";
	$method = "open_dialog";
	$name = "DOMAIN_NAME";
	$access_method = "ACCESS_METHOD";

	$request = array(
			"access_key" => $accessKey,
					"argument" => array (
						"method" => $method,
						"name" => $name,
						"access_method" => $access_method
					)
	);

	try {
			$server_output = "";
			$ch = curl_init();
			$header = array(
				"Content-Type:application/json; charset=UTF-8",
			);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
			curl_setopt($ch, CURLOPT_URL, $openApiURL);
			curl_setopt($ch, CURLOPT_VERBOSE, true);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode ( $request) );

			$server_output = curl_exec ($ch);
			if($server_output === false) {
				echo "Error Number:".curl_errno($ch)."\n";
				echo "Error String:".curl_error($ch)."\n";
			}

			curl_close ($ch);
	} catch ( Exception $e ) {
		echo $e->getMessage ();
	}

	echo "result = " . var_dump($server_output);
?>

//////////////////////////// DIALOG
<?php
	$openApiURL = "http://aiopen.etri.re.kr:8000/Dialog";
	$accessKey = "YOUR_ACCESS_KEY";
	$uuid = "UUID_FROM_OPEN_DAILOG";
	$method = "dialog";
	$text = "YOUR_PASSAGE";

	$request = array(
			"access_key" => $accessKey,
			"argument" => array (
						"method" => $method,
						"text" => $text,
						"uuid" => $uuid,
					)
	);

	try {
			$server_output = "";
			$ch = curl_init();
			$header = array(
				"Content-Type:application/json; charset=UTF-8",
			);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
			curl_setopt($ch, CURLOPT_URL, $openApiURL);
			curl_setopt($ch, CURLOPT_VERBOSE, true);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode ( $request) );

			$server_output = curl_exec ($ch);
			if($server_output === false) {
				echo "Error Number:".curl_errno($ch)."\n";
				echo "Error String:".curl_error($ch)."\n";
			}

			curl_close ($ch);
	} catch ( Exception $e ) {
		echo $e->getMessage ();
	}

	echo "result = " . var_dump($server_output);
?>


										
C++

JSON parsing을 위해 jsoncpp 라이브러리를 사용하여 제공하고 있습니다. jsoncpp 라이브러리에 대한 자세한 설명은 https://github.com/open-source-parsers/jsoncpp 에서 확인 하실 수 있습니다.

HTTP 통신을 위해 curl 라이브러리를 사용하여 제공하고 있습니다. curl 라이브러리에 대한 자세한 설명은 https://curl.haxx.se/libcurl 에서 확인 하실 수 있습니다.

컴파일을 위해서는 아래와 같이 추가된 LIB에 대한 옵션을 추가해야 합니다.
g++ (c++파일명) (JSONCPP)/json/json.h (JSONCPP)/json/json-forwards.h (JSONCPP)/jsoncpp.cpp ?I(CURL)/include -lcurl

//////////////////////////////////// OPEN DIALOG
#include <curl/curl.h>
#include <json/json.h>
#include <iostream>
#include <string>

using namespace std;

size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, std::string stream);

int main() {
	char* openApiURL = (char*)"http://aiopen.etri.re.kr:8000/Dialog";
	string accessKey = "YOUR_ACCESS_KEY";
	string method = "open_dialog";
	string access_method = "ACCESS_METHOD";
	string name = "DOMAIN_NAME";

	Json::Value request;
	Json::Value argument;

	argument["method"] = method;
	argument["access_method"] = access_method;
	argument["name"] = name;

	request["access_key"] = accessKey;
	request["argument"] = argument;

	CURL *curl;
	curl_slist* responseHeaders = NULL;
	curl = curl_easy_init();

	if( curl == NULL ) {
		cout << "Unable to initialize cURL interface" << endl ;
	} else {
		responseHeaders = curl_slist_append( responseHeaders , "Content-Type: application/json; charset=UTF-8" ) ;
		string requestJson = request.toStyledString();
		long statusCode;
		string response;

		curl_easy_setopt(curl, CURLOPT_URL, openApiURL);
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, responseHeaders ) ;
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestJson.c_str());
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataFunc);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

		curl_easy_perform(curl);

		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
		curl_easy_cleanup(curl);

		cout << "[responseCode] " << statusCode << endl;
		cout << "[responBody]" << endl;
		cout << response << endl;
	}

	return 0;
	}

	size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, std::string stream) {
	size_t realsize = size * nmemb;
	std::string temp(static_cast<const char*>(ptr), realsize);
	stream.append(temp);
	return realsize;
}

//////////////////////////////////// DIALOG
#include <curl/curl.h>
#include <json/json.h>
#include <iostream>
#include <string>

using namespace std;

size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, std::string stream);

int main() {
	char* openApiURL = (char*)"http://aiopen.etri.re.kr:8000/Dialog";
	string accessKey = "YOUR_ACCESS_KEY";
	string uuid = "UUID_FROM_OPEN_DIALOG";
	string text = "YOUR_PASSAGE";
	string method = "dialog";

	Json::Value request;
	Json::Value argument;

	argument["method"] = method;
	argument["text"] = text;
	argument["uuid"] = uuid;

	request["access_key"] = accessKey;
	request["argument"] = argument;

	CURL *curl;
	curl_slist* responseHeaders = NULL;
	curl = curl_easy_init();

	if( curl == NULL ) {
		cout << "Unable to initialize cURL interface" << endl ;
	} else {
		responseHeaders = curl_slist_append( responseHeaders , "Content-Type: application/json; charset=UTF-8" ) ;
		string requestJson = request.toStyledString();
		long statusCode;
		string response;

		curl_easy_setopt(curl, CURLOPT_URL, openApiURL);
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, responseHeaders ) ;
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestJson.c_str());
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataFunc);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

		curl_easy_perform(curl);

		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode);
		curl_easy_cleanup(curl);

		cout << "[responseCode] " << statusCode << endl;
		cout << "[responBody]" << endl;
		cout << response << endl;
	}

	return 0;
	}

	size_t writeDataFunc(void *ptr, size_t size, size_t nmemb, std::string stream) {
	size_t realsize = size * nmemb;
	std::string temp(static_cast<const char*>(ptr), realsize);
	stream.append(temp);
	return realsize;
}

										
Python

python 3.0을 기준으로 작성되었습니다.

HTTP 통신을 위해 urllib3 라이브러리를 사용하여 제공하고 있습니다. Python 3.0 이하의 버전에서 예제를 실행하기 위해서는 별도로 urllib3의 설치가 필요합니다. 설치에 대한 설명은 https://pypi.python.org/pypi/urllib3 를 참고하시기 바랍니다. urllib3 라이브러리에 대한 자세한 설명은 https://urllib3.readthedocs.io/en/latest/ 에서 확인 하실 수 있습니다.

############################# OPEN DIALOG
#-*- coding:utf-8 -*-
import urllib3
import json

openApiURL = "http://aiopen.etri.re.kr:8000/Dialog"
accessKey = "YOUR_ACCESS_KEY"
access_method = "YOUR_QUESTION"
method = "open_dialog"
name = "DOMAIN_NAME"

requestJson = {
	"access_key": accessKey,
	"argument": {
		"name": name,
		"method": method,
		"access_method": access_method
	}
}

http = urllib3.PoolManager()
response = http.request(
	"POST",
	openApiURL,
	headers={"Content-Type": "application/json; charset=UTF-8"},
	body=json.dumps(requestJson)
)

print("[responseCode] " + str(response.status))
print("[responBody]")
print(str(response.data,"utf-8"))

############################# DIALOG
#-*- coding:utf-8 -*-
import urllib3
import json

openApiURL = "http://aiopen.etri.re.kr:8000/Dialog"
accessKey = "YOUR_ACCESS_KEY"
uuid = "UUID_FROM_OPEN_DIALOG"
text = "YOUR_TEXT"
method = "dialog"

requestJson = {
	"access_key": accessKey,
	"argument": {
		"method": method,
		"text": text,
		"uuid": uuid
	}
}

http = urllib3.PoolManager()
response = http.request(
	"POST",
	openApiURL,
	headers={"Content-Type": "application/json; charset=UTF-8"},
	body=json.dumps(requestJson)
)

print("[responseCode] " + str(response.status))
print("[responBody]")
print(str(response.data,"utf-8"))


										
Node.js
# OPEN DIALOG
var openApiURL = 'http://aiopen.etri.re.kr:8000/Dialog';
var access_key = 'YOUR_ACCESS_KEY';
var name = "DOMAIN_NAME";
var access_method = "ACCESS_METHOD";
var method = "open_dialog"

var requestJson = {
	'access_key': access_key,
	'argument': {
				'method': method,
				'name': name,
				'access_method': access_method
			}
	};

	var request = require('request');
	var options = {
			url: openApiURL,
			body: JSON.stringify(requestJson),
			headers: {'Content-Type':'application/json; charset=UTF-8'}
	};
			request.post(options, function (error, response, body) {
			console.log('responseCode = ' + response.statusCode);
			console.log('responseBody = ' + body);
});

////////////////////////////////////////// DIALOG
var openApiURL = 'http://aiopen.etri.re.kr:8000/Dialog';
var access_key = 'YOUR_ACCESS_KEY';
var uuid = "UUID_FROM_OPEN_DIALOG"
var text = "YOUR_TEXT"
var method = "dialog"

var requestJson = {
	'access_key': access_key,
	'argument': {
				'uuid': uuid,
				'method': method,
				'text': text
			}
	};

	var request = require('request');
	var options = {
			url: openApiURL,
			body: JSON.stringify(requestJson),
			headers: {'Content-Type':'application/json; charset=UTF-8'}
	};
			request.post(options, function (error, response, body) {
			console.log('responseCode = ' + response.statusCode);
			console.log('responseBody = ' + body);
});
										
대화처리 API 레퍼런스
요청 파라미터 - OPEN DIALOG

대화처리 API에 필요한 요청 본문에 다음과 같은 파라미터를 작성해야 합니다.

[HTTP Request Body]
{
	“access_key”: “YOUR_ACCESS_KEY”,
	“argument”: {
		“method”: “open_dialog”,
		“name”: “YOUR_DOMAIN_NAME”,
		“access_method”: “ACCESS_METHOD”
	}
}
										

다음은 파라미터에 대한 설명입니다.

Field 명 타입 필수 여부 설명
access_key String API 사용을 위해 ETRI에서 발급한 사용자 API Key
argument Object API 사용 요청 시 분석을 위해 전달할 내용
method String open_dialog : 대화할 도메인 이름으로 새로운 대화를 오픈합니다. 서버에서는 대화 섹션을 관리하기 위한 uuid 키 값을 발급
name String 대화할 도메인 이름 로서 UTF-8 인코딩된 텍스트만 지원
access_method String
  • internal_data : 대화처리 응용개발도구에서 도메인을 구축하면서 사용한 instance data base 정보를 이용하여 대화하는 방식입니다. 도메인 관련 정보가 변경되지 않는 도메인의 경우에는 이 방식을 채택하시면 됩니다.
  • external_data : 대화처리 응용개발도구에서 도메인을 구축하면서 사용한 instance data base 정보를 이용하지 않고 새로운 data 정보를 대화 서버에 제공하여 대화처리를 하는 방식입니다. 예를 들어, 날씨 도메인의 경우에 도메인 구축 시에는 예제로 날씨 정보를 넣어서 개발할 수 있지만 실제로는 매일 새롭게 정보가 변경되기에 관련 날씨 사이트 및 날씨정보 제공 API를 통하여 얻은 데이터를 대화서버에 제공하여 대화가 가능하게 하는 방식입니다.
응답 - OPEN DIALOG

대화처리 API는 요청된 질문의 분석된 결과를 JSON 형태의 Text 데이터로 반환합니다.

다음은 정상적인 요청 처리에 대한 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:50783
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {대화처리 OPEN_DIALOG 결과 JSON}
}
										

다음은 오류가 발생한 요청 처리에 대한 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": -1,
	"reason": {오류 메시지}
}
										

분석된 결과는 다음과 같은 내용이 포함되어 있습니다.

구분 JSON Key 이름 설명
대화처리
기본정보
method 사용자의 요청 방식
uuid 도메인으로 생성 된 KEY
result
system_text 시스템 메시지
state
  • start : 요청한 도메인에 대한 대화섹션을 성공적으로 시작함을 표시
  • end : 요청한 도메인을 시작과 동시에 종료된 상태를 표시, 요청한 도메인이 시작과 동시에 종료하도록 설계된 경우에 발생합니다. 그러므로, 도메인을 잘못 설계하지 않으면 발생하지 않습니다.
  • error : 도메인 오픈 요청 메시지의 입력 오류로 발생하는 오류 상태를 표시하며, “message”에 그 오류 유형을 출력합니다. HTTP 요청 메시지의 각 입력 항목이 잘못된 경우가 대부분입니다.
message 오류 발생 유형
요청 파라미터 - DIALOG

대화처리 API에 필요한 요청 본문에 다음과 같은 파라미터를 작성해야 합니다.

[HTTP Request Body]
{
	“access_key”: “YOUR_ACCESS_KEY”,
	“argument”: {
		“method”: “dialog”,
		“uuid”: “UUID_FROM_OPEN_DIALOG”,
		“text”: “YOUR_DIALOG”
	}
}
										

다음은 파라미터에 대한 설명입니다.

Field 명 타입 필수 여부 설명
access_key String API 사용을 위해 ETRI에서 발급한 사용자 API Key
argument Object API 사용 요청 시 분석을 위해 전달할 내용
method String dialog : 사용자의 입력을 분석하고 시스템 응답을 제공하며, open dialog method 호출 시에 발급받은 uuid 키로 대화 도메인과 이력을 유지
text String 대화할 내용으로서 UTF-8 인코딩된 형태 지원
uuid String open dialog method 호출 시에 발급받은 uuid 키
요청 파라미터 - DIALOG(external data)

external data의 경우 요청에 추가적으로 다음과 같은 파라미터의 작성이 필요할 수 있습니다.

[HTTP Request Body]
{
	“access_key”: “YOUR_ACCESS_KEY”,
	“argument”: {
		“method”: “dialog”,
		“uuid”: “UUID_FROM_OPEN_DIALOG”,
		“data”: [
					{
							“DATA_SLOTS”
					}
			]
	}
}
										

다음은 파라미터에 대한 설명입니다.

Field 명 타입 필수 여부 설명
access_key String API 사용을 위해 ETRI에서 발급한 사용자 API Key
argument Object API 사용 요청 시 분석을 위해 전달할 내용
method String dialog : 사용자의 입력을 분석하고 시스템 응답을 제공하며, open dialog method 호출 시에 발급받은 uuid 키로 대화 도메인과 이력을 유지
data List 사용자 입력 분석에 필요한 외부 data
uuid String open dialog method 호출 시에 발급받은 uuid 키
응답 - DIALOG

대화처리 API는 요청된 질문의 분석된 결과를 JSON 형태의 Text 데이터로 반환합니다.

다음은 정상적인 요청 처리에 대한 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:50783
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {대화처리 DIALOG 결과 JSON}
}
										
응답 - DIALOG(external data)

다음은 external data 요청 시 도메인에 대한 데이터가 필요한 경우의 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:50783
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {
			"method": "dialog",
			"uuid": "",
			"result": {
					"data_request":
					[
							{
							"slots": [],
							"condition": ""
							}
					],
					"state": "data_request",
					"message" : ""
			}
	}
}
										

응답 결과는 다음과 같은 내용이 포함되어 있습니다.

구분 JSON Key 이름 설명
대화처리
external data
method 사용자의 요청 방식
uuid 도메인으로 생성 된 KEY
result
data_request 외부 데이터 요청
slots Entity Class에 필요한 Slot 이름(대화처리 응용개발도구에서 정의한 이름)
condition Slot 간의 관계 표현
state 상태

다음은 오류가 발생한 요청 처리에 대한 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": -1,
	"reason": {오류 메시지}
}
										

분석된 결과는 다음과 같은 내용이 포함되어 있습니다.

구분 JSON Key 이름 설명
대화처리
기본정보
method 사용자의 요청 방식
uuid 도메인으로 생성 된 KEY
result
system_text 시스템 메시지
state
  • dialog : 사용자 입력에 시스템 응답을 성공적으로 수행함을 표시
  • end : 시스템 응답이 마지막 대화여서 더 이상 대화 진행이 불가능하여 대화 섹션이 종료됨을 표시
  • error : 요청 메시지의 잘못된 입력으로 인해 발생하는 오류 상태를 표시합니다. 그리고, “message”에 그 오류 유형을 출력합니다.
message 오류 발생 유형
요청 파라미터 - CLOSE

대화처리 API에 필요한 요청 본문에 다음과 같은 파라미터를 작성해야 합니다.

[HTTP Request Body]
{
	“access_key”: “YOUR_ACCESS_KEY”,
	“argument”: {
		“method”: “close_dialog”,
		“uuid”: “UUID_FROM_OPEN_DIALOG”
	}
}
										

다음은 파라미터에 대한 설명입니다.

Field 명 타입 필수 여부 설명
access_key String API 사용을 위해 ETRI에서 발급한 사용자 API Key
argument Object API 사용 요청 시 분석을 위해 전달할 내용
method String close_dialog : open dialog method 호출 시에 발급받은 uuid 키로 대화 도메인과 이력을 삭제
uuid String open dialog method 호출 시에 발급받은 uuid 키
응답 파라미터 - CLOSE

대화처리 API에 필요한 요청 본문에 다음과 같은 파라미터를 작성해야 합니다.

Access-Control-Allow-Origin:*
Connection:close
Content-Length:50783
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": 0,
	"return_type": "com.google.gson.internal.LinkedTreeMap",
	"return_object": {대화처리 OPEN_DIALOG 결과 JSON}
}
										

다음은 오류가 발생한 요청 처리에 대한 HTTP 응답 예입니다.

[HTTP Respone Header]
Access-Control-Allow-Origin:*
Connection:close
Content-Length:0
Content-Type:application/json; charset=UTF-8

[HTTP Respone Body]
{
	"request_id": "reserved field",
	"result": -1,
	"reason": {오류 메시지}
}
										

분석된 결과는 다음과 같은 내용이 포함되어 있습니다.

구분 JSON Key 이름 설명
대화처리
기본정보
method 사용자의 요청 방식
uuid 도메인으로 생성 된 KEY
result
system_text 시스템 메시지
state
  • end : 시스템 응답이 마지막 대화여서 더 이상 대화 진행이 불가능하여 대화 섹션이 종료됨을 표시
message 오류 발생 유형
오류 코드

대화 처리 API의 오류 코드 목록은 다음과 같습니다.

method message 에러 내용 조치사항
모든 method 공통
(open_dialog
dialog
close_dialog)
Invalid access key API key가 허용되지 않은 키 값인 경우입니다. 이 오류를 내지 않아도 open에서 Open error를 출력합니다. 아래 참조하시기 바랍니다.
Invalid method method가 올바르지 않은 경우입니다 (open_dialog, close_dialog, 또는 dialog가 아닌 경우) method 이름을 다시 입력합니다.
JSON parsing error, error type: [영어로 된 오류 타입], offset: [바이트 위치] JSON 데이터 파싱 실패 시 발생합니다. 입력 JSON 데이터를 다시 한 번 확인합니다.
JSON error: parsed, but this is not valid JSON object. JSON 데이터 파싱은 성공했으나, 올바르지 않은 object인 경우 발생합니다. 입력 JSON 데이터를 다시 한 번 확인합니다.
open_dialog Open error: invalid domain name or domain knowledge 도메인 지식을 로딩을 실패했습니다. 원인이 도메인 이름이 틀렸거나 지식이 올바르지 않기 때문입니다. 도메인 이름 또는 access key를 확인하시고, 도메인 이름과 access key가 정확하면 대화처리 응용개발도구에서 도메인 지식을 제대로 다시 학습해야 합니다.
Open error: invalid domain knowledge 도메인 지식을 로딩을 실패했습니다. 원인이 도메인 지식이 올바르지 않기 때문입니다. 대화처리 응용개발도구에서 도메인 지식을 제대로 다시 학습해야 합니다.
Open error: invalid access_method (only internal_data or external_data is allowed) access_method에 틀린 정보 입력한 경우입니다. access_method가 internal_data 또는 external_data가 맞는지 확인해야 합니다.
Open error: memory allocation error 대화섹션을 열기에 메모리가 부족한 경우입니다. 너무 많은 호출로 더 이상 오픈할 수가 없습니다.
Open error: invalid status 지식 오픈 도중 알 수 없는 오류입니다. 발생하지 않겠지만 발생 시 더 이상 대화를 진행할 수 없기에 대화를 종료합니다.
dialog Dialog engine: unexpected error 대화 엔진 내부적으로 예기치 않은 오류가 발생한 것입니다. 대화를 종료해야됩니다. close_dialog method를 호출하여 대화 세션을 종료합니다.
Dialog engine: not found external_data external_data access_method에서 data_request state 이후에 data를 주지 않은 오류입니다. data를 형식에 맞추어서 주기 바랍니다.
close_dialog 500 Internal Server Error: thread closing failure. Dialog 세션 종료 실패시 발생합니다. 이미 종료한 섹션이거나 uuid, access key, 도메인 등에 대한 정보가 오류입니다.

http status code result reason 설명
400 -1 Required arguments is empty 필수 파라미터의 값이 없는 경우
400 -1 One or more arguments are not valid 파라미터의 값이 유효하지 않는 경우
413 -1 Request Entity Too Large 요청 문장 또는 어휘의 크기가 서버가 처리 할 수 있는 것보다 큰 경우
429 -1 Too Many Requests 사용자가 주어진 시간 내에 서버에 너무 많은 요청을 하는 경우
404 -1 Unknown Handler 등록되지 않는 서비스를 요청한 경우
408 -1 Handler Timeout 서버의 요청 대기가 시간을 초과한 경우
500 -1 ETRI service server connection refused ETRI 분석 서버에서 요청을 받지 못하는 경우
500 -1 ETRI service server is not exists 수행 가능한 ETRI 분석 서버가 없는 경우
500 -1 Recipient Failure ETRI 분석 서버에서 요청을 처리하지 못하는 경우
500 -1 Unknown ReplyFailure API 요청에 알 수 없는 내부 오류가 발생한 경우
500 -1 Unknown Exception 알 수 없는 내부 오류가 발생한 경우