【오래된 기사입니다】 작은 재료 - Watson API/Node.js에서 콜백 (또는 Promise)을 의식하지 않고 API를 순차적으로 실행하는 코드를 작성하는 방법
예를 들어 "Assistant의 응답 확신도가 기준값 이하인 경우, Discovery에서 긴 꼬리를 검색하여 답변을 제시"등 여러 Watson API를 동기적으로/순차적으로 호출하고 싶을 수 있습니다.
석가설이지만 Node.js 환경은 비동기 실행 환경이므로 이런 일을하고 싶은 경우의 코드에서는 콜백이나 Promise를 사용해야합니다. 하지만 Promise는 직관적이지 않고, 어쩐지 귀찮다고 생각하고 있었습니다 1 에서 StackOverflow에서 다음 항목을 발견했습니다.
Using Async/Await in WATSON Nodejs SDK
How can I promisify Watson Assistant functions to allow async/await in node?
요점은 Node.js의 V8에서는 promisify가 표준으로 탑재되어 쉽게 비동기를 의식하지 않는 코드를 쓸 수 있다.그렇습니다만, 이 기구가 Watson API에서도 이용할 수 있습니다. 예를 들어 다음과 같은 느낌으로 WatsonAssistant의 인스턴스의 "message"API를 promisify로 와서 await로 호출하면 Watson 측에서 처리가 완료 될 때까지 제어가 대기 상태가되고 완료 후 프로그램으로 제어가 돌아갑니다 = 동기화 적인 코딩이 가능합니다. (비동기의 까다로운 코드가 필요하지 않습니다)
const messagePromise = util.promisify(assistant.message);
var response = await messagePromise.call(assistant, params);
아래는 "Assistant에 묻고 확신도가 기준치를 밑돌면 Discovery에 다시 묻는다"시나리오의 간단한 샘플입니다만, 동기적인=알기 쉬운 코드가 실현되고 있는 것을 볼 수 있다고 생각합니다. 2
app.js
'use strict';
/*
Watson Assistant & Watson Discoveryをpromisifyを使って逐次実行
*/
/* ibmcloud上のnode.jsで実行するならここをコメントアウト
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(port, () => console.log('Example app listening on port %d', port));
*/
const util = require('util');
console.log('==== start=======');
const assistant_iam_apikey ='xxxxxxxxxxxxxx';
const assistant_url ='https://gateway-syd.watsonplatform.net/assistant/api';
const assistant_workspace_id = 'xxxxxxxxxxxx';
const discovery_iam_apikey ='xxxxxxxxxxxxxx';
const dicovery_iam_url ='https://gateway-syd.watsonplatform.net/discovery/api';
const discovery_collection_id ='xxxxxxxxxxxxxx';
const discovery_configuration_id ='xxxxxxxxxxxxxx';
const discovery_environment_id = 'xxxxxxxxxxxxxx';
var AssistantV1 = require('watson-developer-cloud/assistant/v1');
var assistant = new AssistantV1({
version: '2018-09-20',
iam_apikey: assistant_iam_apikey,
url: assistant_url
});
var DiscoveryV1 = require('watson-developer-cloud/discovery/v1');
const discovery = new DiscoveryV1({
url: dicovery_iam_url,
version: '2018-10-15',
iam_apikey: discovery_iam_apikey
});
// Assistant
async function message(text) {
console.log("message Start:[" + text + "]")
var params = {
input: { text: text },
workspace_id: assistant_workspace_id
};
const messagePromise = util.promisify(assistant.message);
var response = await messagePromise.call(assistant, params);
return response;
}
// Discovery
async function query(text) {
console.log("query Start:[" + text + "]")
var params = {
environment_id: discovery_environment_id,
collection_id: discovery_collection_id,
passages: true,
passages_count: 1,
natural_language_query: text
};
const queryPromise = util.promisify(discovery.query);
var response = await queryPromise.call(discovery, params);
return response;
}
//***********************************************
// Promise/非同期を意識したコードを書かずに済んでます
//***********************************************
async function main() {
var min_confidence = 0.6; // 求める確信度。これを下回ったらDiscoveryに聞きなおす
var text = 'Excelで表の必要な部分だけを印刷するにはどうすればいいでしょうか';
var response = await message(text);
console.log('confidence of Assistant:',
JSON.stringify(response.intents[0].confidence, null, 2));
if (response.intents[0].confidence < min_confidence ){
// Assistantの回答の確信度が所定の基準を下回ったらDiscoveryにて再度検索
var response = await query(text);
console.log('message response from Discovery:',
JSON.stringify(response.passages, null, 2));
} else {
// Assistantの回答の確信度が所定の基準以上ならAssistantの回答を提示
console.log('message response from Assistant:',
JSON.stringify(response.output.text[0], null, 2));
}
}
main()
다음은 실행 결과의 예입니다.
==== start=======
message Start:[Excelで表の必要な部分だけを印刷するにはどうすればいいでしょうか]
confidence of Assistant: 0.504277801513672
query Start:[Excelで表の必要な部分だけを印刷するにはどうすればいいでしょうか]
message response from Discovery: [
{
"document_id": "673b0e32529bf4c614c15acaebb47bab",
"passage_score": 40.21290429830693,
"passage_text": "Excelでは、印刷対象を選択して、必要な部分だけを印刷することができます。ここでは
、ご使用のExcelのバージョンに応じた参照先を案内します。\n\n対処方法\n\nExcelで表の必要な部分だけを印
刷する方法については、以下の情報を参照してください。\n※ ご使用のExcelのバージョンに応じた項目をクリ
ックしてください。\n\nExcel 2013の場合\nExcel 2013で表の必要な部分だけを印刷する方法\n\nExcel 2010の
場合\nExcel 2010で表の必要な部分",
"start_offset": 762,
"end_offset": 998,
"field": "text"
}
]
이상입니다.
그럼 Python이라든지 다른 언어 사용하면 좋지 않을까, 라는 츳코미도 있습니다만. 3
코딩의 관점에서 동기적인 이미지로 솔직하게 쓸 수 있다는 것만으로 내부적으로는 비동기/Promise의 기구를 사용하고 있습니다. ↩
이야기를 단순화하기 위해 코드는 nodejs 환경에서 js를 일괄 적으로 실행하는 형태로 만듭니다. 실제로 Watson_API 호출은 AP 서버 환경에서 app.get, app.post 등의 요청을 받으면 사용할 수 있습니다. ↩
Reference
이 문제에 관하여(【오래된 기사입니다】 작은 재료 - Watson API/Node.js에서 콜백 (또는 Promise)을 의식하지 않고 API를 순차적으로 실행하는 코드를 작성하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ishida330/items/2968b3a7fa49fd62fc37텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)