1. 시작하기 전에
이 Codelab에서는 Vision API를 Dialogflow와 통합하여 사용자가 제공한 이미지 입력에 풍부하고 동적인 머신러닝 기반 응답을 제공합니다. 이미지를 입력으로 받아 Vision API에서 처리하고 식별된 랜드마크를 사용자에게 반환하는 챗봇 앱을 만듭니다. 예를 들어 사용자가 타지마할 이미지를 업로드하면 챗봇은 타지마할을 응답으로 반환합니다.
이미지에 있는 항목을 분석하고 얻은 정보에 따라 조치를 취할 수 있으므로 유용합니다. 또한 사용자가 영수증을 업로드하고, 영수증에서 구매 날짜를 추출하고, 적절한 경우 환불을 처리할 수 있도록 환불 처리 시스템을 구축할 수 있습니다.
다음 샘플 대화를 살펴보세요.
사용자: 안녕하세요.
챗봇: 안녕하세요. 사진을 업로드하여 명소를 탐색할 수 있습니다.
사용자: 타지마할이 포함된 이미지를 업로드하세요.
챗봇: 파일이 처리되고 있습니다. 결과는 타지마할, 타지마할 정원, 타지마할입니다.
기본 요건
계속하기 전에 다음 Codelab을 완료해야 합니다.
- Dialogflow로 약속 스케줄러 빌드
- Actions on Google과 Dialogflow 챗봇 통합
- Dialogflow의 항목 이해
- Dialogflow 앱을 위한 프런트엔드 Django 클라이언트 빌드
또한 Dialogflow의 기본 개념과 구성도 이해해야 합니다. 이러한 내용은 Dialogflow로 챗봇 빌드 과정의 다음 동영상에서 얻을 수 있습니다.
학습할 내용
- Dialogflow 에이전트를 만드는 방법
- Dialogflow 에이전트를 업데이트하여 파일을 업로드하는 방법
- Dialogflow fulfillment와 Vision API 연결을 설정하는 방법
- Dialogflow용 Django 프런트엔드 앱 설정 및 실행 방법
- App Engine에서 Google Cloud에 Django 프런트엔드 앱을 배포하는 방법
- 커스텀 프런트엔드에서 Dialogflow 앱을 테스트하는 방법
빌드할 항목
- Dialogflow 에이전트 만들기
- Django 프런트엔드를 구현하여 파일 업로드
- Dialogflow 처리를 구현하여 업로드된 이미지에 Vision API를 호출
필요한 항목
- Python에 관한 기본 지식
- Dialogflow에 관한 기본적인 이해
- Vision API에 대한 기본적인 이해
2. 아키텍처 개요
커스텀 Django 프런트엔드로 새로운 대화형 환경을 만들고 이를 확장하여 Vision API와 통합합니다. Django 프레임워크를 사용하여 프런트엔드를 빌드하고, 로컬에서 실행하고 테스트한 후 App Engine에 배포합니다. 프런트엔드는 다음과 같습니다.
요청 흐름은 다음 이미지와 같이 작동합니다.
- 사용자는 프런트엔드를 통해 요청을 보냅니다.
- 그러면 Dialogflow DetectionIntent API에 대한 호출이 트리거되어 사용자의 발화를 올바른 인텐트에 매핑합니다.
- 탐색 랜드마크 인텐트가 감지되면 Dialogflow fulfillment가 Vision API에 요청을 전송하고 응답을 수신한 후 사용자에게 전송합니다.
전체 아키텍처는 다음과 같습니다.
3. Vision API란 무엇인가요?
Vision API는 이미지에서 유용한 정보를 도출하는 선행 학습된 ML 모델입니다. 이를 통해 이미지 라벨 지정, 얼굴 및 랜드마크 인식, 광학 문자 인식, 선정적인 콘텐츠 태그 등 다양한 정보를 얻을 수 있습니다. 자세한 내용은 Vision AI를 참조하세요.
4. Dialogflow 에이전트 만들기
- Dialogflow 콘솔로 이동합니다.
- 로그인합니다. 처음 사용하는 경우 이메일을 사용하여 가입합니다.
- 이용약관에 동의하면 콘솔로 이동합니다.
- 를 클릭하고 하단으로 스크롤하여 새 에이전트 만들기를 클릭합니다.
- 'VisionAPI'를 입력합니다. Agent name(에이전트 이름)으로 입력합니다.
- 만들기를 클릭합니다.
Dialogflow는 에이전트의 일부로 다음 두 개의 기본 인텐트를 만듭니다.
- 기본 시작 인텐트는 사용자에게 인사합니다.
- 기본 대체 인텐트는 봇이 이해하지 못하는 모든 질문을 포착합니다.
이 시점에서 사용자에게 인사하는 작동하는 봇이 있지만 이미지를 업로드하여 랜드마크를 탐색할 수 있음을 사용자에게 알려야 합니다.
사용자에게 이미지를 업로드하도록 알리도록 기본 시작 인텐트를 업데이트합니다.
- 기본 시작 인텐트를 클릭합니다.
- 응답 >으로 이동합니다. 기본값 > 텍스트 또는 SSML 응답을 클릭하고 'Hi! 사진을 업로드하여 명소를 탐험할 수 있습니다.'
항목 만들기
- 항목을 클릭합니다.
- 항목 만들기를 클릭하고 '파일 이름'으로 이름을 지정합니다. 저장을 클릭합니다.
새 인텐트 만들기
- 인텐트 >를 클릭합니다. 인텐트 만들기
- '업로드된 이미지 탐색'을 입력합니다. 인텐트 이름으로 사용합니다.
- 학습 문구를 클릭합니다. 학습 문구를 추가하고 'file is
demo.jpg
'를 입력합니다. '파일이taj.jpeg
임' @filename을 항목으로 갖는 사용자 표현으로 제공합니다.
- 응답을 클릭합니다. 응답 추가 > 기본값 > 텍스트 또는 SSML 응답. '파일 평가 중'을 입력하세요. 응답 추가를 클릭합니다.
- fulfillment를 클릭합니다. fulfillment 사용 설정 및 이 인텐트에 웹훅 호출 사용 설정을 설정합니다.
5. fulfillment를 설정하여 Vision API와 통합
- Fulfillment를 클릭합니다.
- 인라인 편집기를 사용 설정합니다.
- 다음 코드로
index.js
를 업데이트하고YOUR-BUCKET-NAME
을 Cloud Storage 버킷 이름으로 업데이트합니다.
'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"
}
}
- 저장을 클릭합니다.
6. 프런트엔드 앱 다운로드 및 실행
- 이 저장소를 로컬 머신에 클론합니다.
https://github.com/priyankavergadia/visionapi-dialogflow.git
- 코드가 있는 디렉터리로 변경합니다. 또는 zip 파일로 샘플을 다운로드하고 압축을 풉니다.
cd visionapi-dialogflow
7. 로컬 환경 설정
배포된 앱은 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]
또는 콘솔에서 인스턴스를 클릭하여 인스턴스 연결 이름을 가져올 수 있습니다.
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 사용자 및 데이터베이스를 만듭니다.
- polls-instance라는 Cloud SQL 인스턴스용 Google Cloud 콘솔을 사용하여 새 데이터베이스를 만듭니다. 예를 들어 'polls'를 입력할 수 있습니다. 을 이름으로 사용하겠습니다.
- polls-instance라는 Cloud SQL 인스턴스용 Cloud 콘솔을 사용하여 새 사용자를 만듭니다. <ph type="x-smartling-placeholder"></ph>
데이터베이스 설정 구성
- 수정할
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
를 닫고 저장합니다.
8. 서비스 계정 설정
- Dialogflow 콘솔에서 를 클릭합니다. 일반 탭에서 Google 프로젝트로 이동합니다. 프로젝트 ID를 클릭하고 Google Cloud 를 클릭하여 Cloud 콘솔을 엽니다.
- 탐색 메뉴 ❯를 클릭합니다. IAM 및 관리 > 서비스 계정을 선택한 다음 Dialogflow 통합 옆에 있는 를 클릭하고 키 만들기를 클릭합니다.
- JSON 파일이 컴퓨터에 다운로드되며 다음 설정 섹션에서 필요합니다.
9. 앱에서 호출되도록 Dialogflow DetectionIntent 엔드포인트를 설정합니다.
- 채팅 폴더에서
key-sample.json
을 사용자 인증 정보 JSON 파일로 바꾸고 이름을key.json
로 지정합니다. - 채팅 폴더의
views.py
에서GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>"
를 프로젝트 ID로 변경합니다.
10. Cloud Storage 버킷 만들기
프런트엔드 정적 객체용 Cloud Storage 버킷 만들기
- Cloud 콘솔에서 탐색 탐색 메뉴 맞춤형 > 저장용량.
- 버킷 만들기를 클릭합니다.
- 전역적으로 고유한 이름을 제공합니다.
- 데이터 저장 위치를 선택합니다. 리전을 선택하고 필요에 가장 적합한 위치를 선택합니다.
- 기본 스토리지 클래스로 표준을 선택합니다.
- 버킷 수준에서 균일하게 권한 설정 (버킷 정책 전용)을 선택한 다음 계속을 클릭하여 버킷을 만듭니다.
- 버킷이 만들어지면 탐색 메뉴 ❯ >를 클릭합니다. 스토리지 > 브라우저로 이동하고 앞서 만든 버킷을 찾습니다.
- 해당 버킷 옆에 있는 를 클릭하고 버킷 권한 수정을 클릭합니다.
- 구성원 추가를 클릭하고 새 구성원을 클릭한 다음 'allUsers'를 입력합니다. 역할 선택을 클릭합니다. 스토리지 객체 뷰어. 이렇게 하면 allUsers에게 정적 프런트엔드 파일에 대한 보기 액세스 권한이 제공됩니다. 이 설정은 파일에 이상적인 보안 설정은 아니지만 이 Codelab의 목적에 맞게 작동합니다.
사용자가 업로드한 이미지를 위한 Cloud Storage 버킷 만들기
동일한 안내에 따라 사용자 이미지를 업로드할 별도의 버킷을 만듭니다. 권한을 'allUsers'로 설정 스토리지 객체 생성자 및 스토리지 객체 뷰어를 역할로 선택합니다.
11. 프런트엔드 앱에서 Cloud Storage 버킷 구성
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 버킷을 호출하여 파일을 선택하고 예측합니다.
12. 로컬에서 앱 빌드 및 실행
로컬 컴퓨터에서 Django 앱을 실행하려면 Python, pip 및 virtualenv를 포함한 Python 개발 환경을 설정해야 합니다. 자세한 내용은 Python 개발 환경 설정을 참조하세요.
- 격리된 Python 환경을 만들고 종속 항목을 설치합니다.
virtualenv env source env/bin/activate pip install -r requirements.txt
- Django 마이그레이션을 실행하여 모델을 설정합니다.
python3 manage.py makemigrations python3 manage.py makemigrations polls python3 manage.py migrate
- 로컬 웹 서버를 시작합니다.
python3 manage.py runserver
- 웹브라우저에서 http://localhost:8000/으로 이동합니다. 다음과 같은 간단한 웹페이지가 표시됩니다.
샘플 앱 페이지는 컴퓨터에서 실행되는 Django 웹 서버에서 제공됩니다. 계속 진행할 준비가 되면 Control+C
(Macintosh의 경우 Command+C
)를 눌러 로컬 웹 서버를 중지합니다.
Django 관리 콘솔 사용
- 수퍼유저를 만듭니다.
python3 manage.py createsuperuser
- 로컬 웹 서버를 시작합니다.
python3 manage.py runserver
- 웹브라우저에서 http://localhost:8000/admin/으로 이동합니다. 관리 사이트에 로그인하려면
createsuperuser
실행 시 생성한 사용자 이름과 비밀번호를 입력하세요.
13. App Engine 표준 환경에 앱 배포
다음 명령어를 실행하여 모든 정적 콘텐츠를 하나의 폴더에 수집합니다. 이 명령어는 앱의 모든 정적 파일을 settings.py
의 STATIC_ROOT
에서 지정한 폴더로 이동합니다.
python3 manage.py collectstatic
app.yaml
파일이 있는 앱 디렉터리에서 다음 명령어를 실행하여 앱을 업로드합니다.
gcloud app deploy
업데이트가 완료되었다는 메시지가 표시될 때까지 기다립니다.
14. 프런트엔드 앱 테스트
웹브라우저에서 https://<your_project_id>.appspot.com으로 이동합니다.
이번에는 App Engine 표준 환경에서 실행되는 웹 서버에서 요청을 처리합니다.
app deploy
명령어는 app.yaml
에 설명된 대로 앱을 배포하고 새로 배포된 버전을 기본 버전으로 설정하여 모든 새 트래픽을 처리합니다.
15. 프로덕션
프로덕션에 콘텐츠를 제공할 준비가 되면 mysite/settings.py
에서 DEBUG
변수를 False
로 변경합니다.
16. 챗봇 테스트
시뮬레이터에서 챗봇을 테스트하거나 이전에 구축한 웹 또는 Google Home 통합을 사용할 수 있습니다.
- 사용자: "안녕하세요"
- 챗봇: "안녕하세요. 사진을 업로드하여 명소를 탐험할 수 있습니다.'
- 사용자가 이미지를 업로드합니다.
이 이미지를 다운로드하고 이름을 demo.jpg
로 지정하고 사용하세요.
- 챗봇: "파일이 처리되고 있습니다. 결과는 금문교, 금문교,금문교,금문교,금문교,금문교입니다."
전체적으로 다음과 같이 표시됩니다.
17. 삭제
다른 Dialogflow Codelab을 완료하려면 이 섹션을 건너뛰고 나중에 다시 확인하세요.
Dialogflow 에이전트 삭제
- 기존 에이전트 옆에 있는 를 클릭합니다.
- General 탭에서 아래로 스크롤하여 Delete This Agent를 클릭합니다.
- 나타나는 창에 삭제를 입력하고 삭제를 클릭합니다.
18. 축하합니다
Dialogflow에서 챗봇을 만들어 Vision API와 통합했습니다. 챗봇 개발자가 되셨습니다!
자세히 알아보기
자세한 내용은 Dialogflow GitHub 페이지의 코드 샘플을 확인하세요.