이 Codelab에서는 Vision API를 Dialogflow와 통합하여 사용자가 제공한 이미지 입력에 풍부한 동적 머신러닝 기반 응답을 제공합니다. 이미지를 입력으로 하여 Vision API에서 처리하고, 식별된 랜드마크를 사용자에게 반환하는 챗봇 앱을 만듭니다. 예를 들어 사용자가 타지마할의 이미지를 업로드하면 챗봇이 타지마할을 반환합니다.
이미지에 있는 항목을 분석하고 확보한 정보에 대해 조치를 취할 수 있기 때문에 유용합니다. 사용자가 영수증 업로드, 영수증의 구매 날짜 추출, 적절한 경우 환불 처리를 지원하는 환불 처리 시스템을 구축할 수도 있습니다.
다음 샘플 대화상자를 살펴보세요.
사용자: 안녕하세요.
챗봇: 안녕하세요. 사진을 업로드하여 명소를 탐험할 수 있습니다.
사용자: 타지마할이 포함된 이미지를 업로드합니다.
챗봇: 파일 처리 중입니다. 타지마할, 타지마할 가든, 타지마할입니다.
기본 요건
계속하기 전에 다음 Codelab을 완료해야 합니다.
- Dialogflow로 약속 스케줄러 빌드
- Actions on Google에 Dialogflow 챗봇 통합
- Dialogflow 항목 이해하기
- Dialogflow 앱용 프런트엔드 샌드박스 클라이언트 빌드
또한 Dialogflow로 챗봇 빌드 과정의 다음 동영상에서 활용할 수 있는 Dialogflow의 기본 개념과 구성에 대해서도 알아야 합니다.
학습할 내용
- Dialogflow 에이전트를 만드는 방법
- Dialogflow 에이전트를 업데이트하여 파일을 업로드하는 방법
- Dialogflow 처리를 통한 Vision API 연결 설정 방법
- Dialogflow를 위한 샌드박스 프런트엔드 앱 설정 및 실행 방법
- Bazel 프런트엔드 앱을 App Engine의 Google Cloud에 배포하는 방법
- 커스텀 프런트엔드에서 Dialogflow 앱을 테스트하는 방법
빌드할 항목
- Dialogflow 에이전트 만들기
- 샌드박스 프런트엔드를 구현하여 파일 업로드
- Dialogflow 처리를 구현하여 업로드된 이미지에 대해 Vision API 호출
필요한 항목
- Python에 관한 기본 지식
- Dialogflow에 대한 기본적인 이해
- Vision API에 관한 기본적 이해
커스텀 Bazel 프런트엔드로 새로운 대화 경험을 만들고 확장하여 Vision API와 통합합니다. npm 프레임워크로 프런트엔드를 빌드하고 로컬에서 실행 및 테스트한 후 App Engine에 배포합니다. 프런트엔드는 다음과 같습니다.
요청 흐름은 다음 이미지와 같이 작동합니다.
- 사용자가 프런트엔드를 통해 요청을 보냅니다.
- Dialogflow detectIntent API를 호출하여 사용자의 발화를 올바른 인텐트에 매핑합니다.
- 랜드마크 탐색 인텐트가 감지되면 Dialogflow fulfillment는 Vision API에 요청을 보내고 응답을 받은 후 사용자에게 전송합니다.
전반적인 아키텍처는 다음과 같이 표시됩니다.
Vision API는 이미지에서 유용한 정보를 도출하는 선행 학습된 ML 모델입니다. 이미지 라벨링, 얼굴 및 랜드마크 인식, 광학 문자 인식, 유해성 콘텐츠 태깅 등의 다양한 통계를 얻을 수 있습니다. 자세한 내용은 Vision AI를 참조하세요.
- Dialogflow 콘솔로 이동합니다.
- 로그인합니다. (신규 사용자인 경우 이메일을 사용하여 가입하세요.)
- 이용약관에 동의하면 콘솔에 표시됩니다.
를 클릭하고 하단으로 스크롤한 후 새 에이전트 만들기를 클릭합니다.
5. 에이전트 이름으로 "VisionAPI"를 입력합니다.
- 만들기를 클릭합니다.
Dialogflow는 에이전트의 일부로 다음 두 가지 기본 인텐트를 만듭니다.
- 기본 시작 인텐트는 사용자에게 인사할 때 사용됩니다.
- 기본 대체 인텐트는 봇이 이해하지 못하는 모든 질문을 포착합니다.
이 시점에는 사용자에게 환영 인사를 할 수 있는 제대로 작동하는 봇이 있지만 사용자에게 이미지를 업로드하여 랜드마크를 탐색할 수 있음을 사용자에게 알려야 합니다.
기본 시작 인텐트를 업데이트하여 사용자에게 이미지 업로드 알림
- 기본 시작 인텐트를 클릭합니다.
- Responses > Default > Text or SSML Response로 이동하여 "Hi! 사진을 업로드하여 랜드마크를 탐색할 수 있습니다.
항목 만들기
- 항목을 클릭합니다.
- 항목 만들기를 클릭하고 이름을 '이름'으로 지정하고 저장을 클릭합니다.
새 인텐트 만들기
- 인텐트 >, 인텐트 만들기를 클릭합니다.
- 인텐트 이름으로 '업로드된 이미지 탐색'을 입력합니다.
- 학습 문구 > Add Training Phrases(학습 문구 추가)를 클릭하고 "file is
demo.jpg
" and "file istaj.jpeg
" as user 시간과 with @filename을 항목으로 입력합니다.
- Responses > Add Response > Default > Text or SSML Response를 클릭합니다. '파일 평가'를 입력하고 응답 추가를 클릭합니다.
- Fulfillment >, 처리 사용 설정을 클릭하고 이 인텐트에 웹훅 호출 사용 설정을 사용 설정합니다.
- 처리를 클릭합니다.
- 인라인 편집기를 사용 설정합니다.
- 다음 코드를 사용하여
index.js
를 업데이트하고 Cloud Storage 버킷 이름으로YOUR-BUCKET-NAME
를 업데이트합니다.
'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const vision = require('@google-cloud/vision');
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
const bucketName = 'YOUR-BUCKET-NAME';
const timeZone = 'America/Los_Angeles';
const timeZoneOffset = '-07:00';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log("Parameters", agent.parameters);
function applyML(agent){
const filename = agent.parameters.filename;
console.log("filename is: ", filename);
// call vision API to detect text
return callVisionApi(agent, bucketName, filename).then(result => {
console.log(`result is ${result}`);
agent.add(`file is being processed, here are the results: ${result}`);
//agent.add(`file is being processed ${result}`);
}).catch((error)=> {
agent.add(`error occurred at apply ml function` + error);
});
}
let intentMap = new Map();
intentMap.set('Explore uploaded image', applyML);
agent.handleRequest(intentMap);
});
async function callVisionApi(agent, bucketName, fileName){
// [START vision_text_detection_gcs]
// Imports the Google Cloud client libraries
// Creates a client
const client = new vision.ImageAnnotatorClient();
try {
// Performs text detection on the gcs file
const [result] = await client.landmarkDetection(`gs://${bucketName}/${fileName}`);
const detections = result.landmarkAnnotations;
var detected = [];
detections.forEach(text => {
console.log(text.description);
detected.push(text.description);
});
return detected;
}
catch(error) {
console.log('fetch failed', error);
return [];
}
}
- 내용을
package.json
에 붙여넣어 내용을 바꿉니다.
{
"name": "dialogflowFirebaseFulfillment",
"description": "Dialogflow fulfillment for the bike shop sample",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "6"
},
"scripts": {
"lint": "semistandard --fix \"**/*.js\"",
"start": "firebase deploy --only functions",
"deploy": "firebase deploy --only functions"
},
"dependencies": {
"firebase-functions": "2.0.2",
"firebase-admin": "^5.13.1",
"actions-on-google": "2.2.0",
"googleapis": "^27.0.0",
"dialogflow-fulfillment": "^0.6.1",
"@google-cloud/bigquery": "^1.3.0",
"@google-cloud/storage": "^2.0.0",
"@google-cloud/vision": "^0.25.0"
}
}
- 저장을 클릭합니다.
- 저장소를 로컬 머신에 클론합니다.
https://github.com/priyankavergadia/visionapi-dialogflow.git
- 코드가 포함된 디렉터리로 변경합니다. 또는 샘플을 zip으로 다운로드하여 추출할 수 있습니다.
cd visionapi-dialogflow
배포된 앱은 App Engine 표준 환경에 기본 제공되는 Cloud SQL 프록시를 사용하여 Cloud SQL 인스턴스와 통신합니다. 그러나 앱을 로컬에서 테스트하려면 개발 환경에서 Cloud SQL 프록시의 로컬 사본을 설치하고 사용해야 합니다. 자세한 내용은 Cloud SQL 프록시 정보를 참조하세요.
Cloud SQL 인스턴스에서 기본 클라이언트 작업을 수행하려면 MySQL용 Cloud SQL 클라이언트를 사용하면 됩니다.
Cloud SQL 프록시 설치
다음 명령어를 사용하여 Cloud SQL 프록시를 다운로드하고 설치합니다. Cloud SQL 프록시는 로컬에서 실행 중인 Cloud SQL 인스턴스에 연결하는 데 사용됩니다.
프록시를 다운로드합니다.
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
프록시를 실행 가능하게 만듭니다.
chmod +x cloud_sql_proxy
Cloud SQL 인스턴스 만들기
- MySQL 2세대용 Cloud SQL 인스턴스를 만듭니다. "polls-instance" 또는 유사한 이름을 입력합니다. 인스턴스가 준비되는 데 몇 분 정도 걸릴 수 있습니다. 준비되면 인스턴스 목록에 표시됩니다.
- 이제 gcloud 명령줄 도구를 사용하여 다음 명령어를 실행합니다. 여기서
[YOUR_INSTANCE_NAME]
는 Cloud SQL 인스턴스의 이름을 나타냅니다. 다음 단계를 위해connectionName
에 표시된 값을 기록해 둡니다.[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]
형식으로 표시됩니다.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
또는 Console에서 인스턴스를 클릭하여 인스턴스 연결 이름을 가져올 수 있습니다.
Cloud SQL 인스턴스 초기화
이전 섹션의 connectionName
를 사용하여 Cloud SQL 프록시를 시작합니다.
./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306
[YOUR_INSTANCE_CONNECTION_NAME]
를 이전 섹션에서 기록한 값으로 바꿉니다. 이렇게 하면 로컬 테스트를 위해 로컬 컴퓨터에서 Cloud SQL 인스턴스로 연결이 설정됩니다. 앱을 로컬에서 테스트하는 내내 Cloud SQL 프록시를 계속 실행합니다.
다음으로 새 Cloud SQL 사용자와 데이터베이스를 만듭니다.
- Google Cloud Console을 사용하여 polls-instance라는 Cloud SQL 인스턴스를 위한 새 데이터베이스를 만듭니다. 예를 들어 이름으로 "polls"를 입력할 수 있습니다.
- Cloud SQL 인스턴스를 사용하여 polls-instance라는 새 사용자를 만듭니다.
데이터베이스 설정 구성
- 수정할
mysite/settings-changeme.py
을 엽니다. - 파일 이름을
setting.py
으로 바꿉니다. - 두 위치에서
[YOUR-USERNAME]
및[YOUR-PASSWORD]
를 이전 섹션에서 만든 데이터베이스 사용자 이름과 비밀번호로 바꿉니다. 이렇게 하면 App Engine 배포 및 로컬 테스트의 데이터베이스 연결을 설정할 수 있습니다. ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANC
E_NAME]'번째 줄에서[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]
을 이전 섹션에서 가져온 인스턴스 이름으로 바꿉니다.- 다음 명령어를 실행하고 다음 단계를 위해 출력된
connectionName
값을 복사합니다.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
[YOUR-CONNECTION-NAME]
를 이전 단계에서 기록한 값으로 바꿉니다.[YOUR-DATABASE]
을 이전 섹션에서 선택한 이름으로 바꿉니다.
# [START db_setup] if os.getenv('GAE_APPLICATION', None): # Running on production App Engine, so connect to Google Cloud SQL using # the unix socket at /cloudsql/<your-cloudsql-connection string> DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]', 'USER': '[YOUR-USERNAME]', 'PASSWORD': '[YOUR-PASSWORD]', 'NAME': '[YOUR-DATABASE]', } } else: # Running locally so connect to either a local MySQL instance or connect to # Cloud SQL via the proxy. To start the proxy via command line: # $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 # See https://cloud.google.com/sql/docs/mysql-connect-proxy DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': '3306', 'NAME': '[YOUR-DATABASE]', 'USER': '[YOUR-USERNAME]', 'PASSWORD': '[YOUR-PASSWORD]' } } # [END db_setup]
settings.py
를 닫고 저장합니다.
- Dialogflow 콘솔에서
를 클릭합니다. General(일반) 탭에서 Project(프로젝트)로 이동하여 Project ID(프로젝트 ID)로 이동하고 Google Cloud
를 클릭하여 Cloud Console을 엽니다.
- 탐색 메뉴 ☰ > IAM 및amp; 관리자 > 서비스 계정을 클릭한 다음 Dialogflow 통합 옆의
를 클릭하고 키 만들기를 클릭합니다.
- JSON 파일이 컴퓨터에 다운로드되며 다음 설정 섹션에 필요합니다.
- 채팅 폴더에서
key-sample.json
를 사용자 인증 정보 JSON 파일로 바꾸고 이름을key.json
로 지정합니다. - 채팅 폴더의
views.py
에서GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>"
를 프로젝트 ID로 변경합니다.
프런트엔드 정적 객체용 Cloud Storage 버킷 만들기
- Cloud Console에서 탐색 탐색 메뉴 ☰ > 스토리지를 클릭합니다.
- 버킷 만들기를 클릭합니다.
- 전역적으로 고유한 이름을 입력합니다.
- 데이터 저장 위치를 선택합니다. 지역을 선택하고 가장 적합한 위치를 선택합니다.
- 표준을 기본 스토리지 클래스로 선택합니다.
- 버킷 수준에서 균일하게 권한 설정 (버킷 정책만 해당)을 선택한 다음 계속을 클릭하여 버킷을 만듭니다.
- 버킷이 생성되면 탐색 메뉴 ☰ > 스토리지> 브라우저를 클릭하고 직접 만든 버킷을 찾습니다.
- 해당 버킷 옆에 있는
를 클릭하고 버킷 권한 수정을 클릭합니다.
- 구성원 추가를 클릭하고 새 구성원을 클릭하고 "allUsers,"를 입력한 다음 역할 선택 >스토리지 객체 뷰어를 클릭합니다. 이렇게 하면 allUsers에 대한 정적 프런트엔드 파일에 대한 보기 액세스 권한을 제공할 수 있습니다. 이 방법은 파일의 이상적인 보안 설정은 아니지만 특정 Codelab의 목적을 위해 작동하는 것입니다.
사용자가 업로드한 이미지를 위한 Cloud Storage 버킷 만들기
동일한 안내에 따라 사용자 이미지 업로드를 위한 별도의 버킷을 만듭니다. 권한을 다시 "allUsers"로 설정하되 역할로 스토리지 객체 생성자와 스토리지 객체 뷰어를 선택합니다.
settings.py에서 Cloud Storage 버킷 구성하기
mysite/setting.py
를 엽니다.GCS_BUCKET
변수를 찾아‘<YOUR-GCS-BUCKET-NA
ME>'를 Cloud Storage 정적 버킷으로 바꿉니다.GS_MEDIA_BUCKET_NAME
변수를 찾아‘<YOUR-GCS-BUCKET-NAME-MED
IA>'를 이미지의 Cloud Storage 버킷 이름으로 바꿉니다.GS_STATIC_BUCKET_NAME
변수를 찾아‘<YOUR-GCS-BUCKET-NAME-STAT
IC>'를 정적 파일의 Cloud Storage 버킷 이름으로 바꿉니다.- 파일을 저장합니다.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'
home.html에서 Cloud Storage 버킷 구성하기
- 채팅 폴더를 열고
templates
를 열고home-changeme.html
이름을home.html
로 바꿉니다. <YOUR-GCS-BUCKET-NAME-MEDIA>
을 찾아 사용자가 업로드한 파일을 저장할 버킷 이름으로 바꿉니다. 이렇게 하면 사용자가 업로드한 항목을 프런트엔드에 저장하고 정적 애셋을 Cloud Storage 버킷에 보관할 수 없습니다. Vision API는 Cloud Storage 버킷을 호출하여 파일을 선택하고 예측합니다.
ADB 앱을 로컬 컴퓨터에서 실행하려면 Python, pip, androidx를 포함한 Python 개발 환경을 설정해야 합니다. 자세한 내용은 Python 개발 환경 설정을 참조하세요.
- 격리된 Python 환경을 만들고 종속 항목을 설치합니다.
virtualenv env source env/bin/activate pip install -r requirements.txt
- Bazel 이전을 실행하여 모델을 설정합니다.
python3 manage.py makemigrations python3 manage.py makemigrations polls python3 manage.py migrate
- 로컬 웹 서버를 시작합니다.
python3 manage.py runserver
- 웹브라우저에서 http://localhost:8000/으로 이동합니다. 다음과 같은 간단한 웹페이지가 표시됩니다.
샘플 앱 페이지는 컴퓨터에서 실행되는 장갑 웹 서버에서 제공됩니다. 계속할 준비가 되면 Control+C
(Macintosh의 경우 Command+C
)를 눌러 로컬 웹 서버를 중지하세요.
Django 관리 콘솔 사용
- 수퍼유저를 만듭니다.
python3 manage.py createsuperuser
- 로컬 웹 서버를 시작합니다.
python3 manage.py runserver
- 웹브라우저에서 http://localhost:8000/admin/으로 이동합니다. 관리자 사이트에 로그인하려면
createsuperuser
을 실행할 때 만든 사용자 이름과 비밀번호를 입력합니다.
다음 명령어를 실행하여 모든 정적 콘텐츠를 한 폴더로 수집합니다. 그러면 앱의 모든 정적 파일이 settings.py
의 STATIC_ROOT
에 지정된 폴더로 이동합니다.
python3 manage.py collectstatic
app.yaml
파일이 있는 앱 디렉터리에서 다음 명령어를 실행하여 앱을 업로드합니다.
gcloud app deploy
업데이트가 완료되었음을 알리는 메시지가 표시될 때까지 기다립니다.
웹브라우저에서 https://<your_project_id>.appspot.com으로 이동합니다.
이번에는 App Engine 표준 환경에서 실행되는 웹 서버에서 요청을 처리합니다.
app deploy
명령어는 app.yaml
에 설명된 대로 앱을 배포하고 새로 배포된 버전을 기본 버전으로 설정하여 모든 새 트래픽을 제공합니다.
프로덕션에서 콘텐츠를 게재할 준비가 되면 mysite/settings.py
에서 DEBUG
변수를 False
로 변경합니다.
시뮬레이터에서 챗봇을 테스트하거나 이전에 빌드한 웹 또는 Google Home 통합을 사용할 수 있습니다.
- 사용자: "hi"
- 챗봇: "안녕하세요. 사진을 업로드하여 랜드마크를 탐색할 수 있습니다.
- 사용자가 이미지를 업로드합니다.
이 이미지를 다운로드하고 이름을 demo.jpg
로 지정한 후 사용하세요.
- 챗봇: "파일이 처리 중입니다. 골든게이트교, 골든게이트교, 골든게이트교, 골든게이트교, 골든게이트교가 있습니다."
전체적으로 다음과 같이 표시됩니다.
다른 Dialogflow Codelab을 완료하려면 이 섹션을 건너뛰고 나중에 돌아가세요.
Dialogflow 에이전트 삭제
- 기존 에이전트 옆에 있는
를 클릭합니다.
- General(일반) 탭에서 아래로 스크롤하여 Delete Agent(에이전트 삭제)를 클릭합니다.
- 표시되는 창에 삭제를 입력하고 삭제를 클릭합니다.
Dialogflow에서 챗봇을 만들고 Vision API와 통합했습니다. 이제 챗봇 개발자가 되셨습니다!
자세히 알아보기
자세한 내용은 Dialogflow GitHub 페이지의 코드 샘플을 확인하세요.