ใน Codelab นี้คุณจะได้เรียนรู้การสร้าง LINE Chatbot ให้สามารถโต้ตอบได้แบบ Generative AI ผ่านการเชื่อมต่อ Bard(PaLM API) โดยใช้ Cloud Functions for Firebase 2nd Gen กัน
จุดเริ่มต้นของการพัฒนา LINE Chatbot คือคุณจะต้องสร้าง LINE OA(LINE Official Account) และเปิดใช้งาน Messaging API
หลังจากที่เรามี LINE OA เรียบร้อยแล้ว ขั้นตอนนี้จะพาทุกคนไปเพิ่มความสามารถให้ LINE OA ของเรากลายเป็น LINE Chatbot ได้
ขั้นตอนนี้เราจะเข้าไปใช้งาน LINE Developers Console ซึ่งเป็นเว็บไซต์สำหรับการบริหารจัดการ LINE Chatbot(LINE OA ที่เปิดใช้งาน Messaging API แล้ว) ในส่วนของนักพัฒนา
เบื้องหลังของ Chatbot ตัวนี้ เราจะใช้บริการใน Firebase อย่าง Cloud Functions for Firebase และ Cloud Firestore ดังนั้นขั้นตอนนี้เราจะมาสร้างโปรเจค Firebase เพื่อใช้งานกัน
เนื่องจาก Cloud Functions for Firebase มีเงื่อนไขว่า หากต้องการไป request ตัว APIs ที่อยู่ภายนอก Google คุณจำเป็นจะต้องใช้ Blaze plan(เราจะต้องไปเรียก Messaging API ของ LINE)
Firebase CLI เป็นเครื่องมือที่จำเป็นสำหรับการ deploy ตัวฟังก์ชันที่เราพัฒนาขึ้น อีกทั้งยังสามารถจำลองการทำงานฟังก์ชัน(Emulate) ภายในเครื่องที่เราพัฒนาอยู่(Locally) ได้
npm install -g firebase-tools
firebase --version
firebase login
mkdir bot
cd bot
firebase init functions
ขั้นตอนนี้เราจะสร้าง Webhook ขึ้นมาเพื่อให้ LINE Chatbot สามารถรับข้อมูลและโต้ตอบกับผู้ใช้งานได้ผ่าน Messaging API
ใน Codelab นี้เราจะใช้ axios มาเป็นตัวช่วยในการสร้าง request ซึ่งเราจะต้องทำการติดตั้ง dependency ตัวนี้ก่อน โดยให้เปิด command line แล้วเข้าไปที่ /functions จากนั้นใช้คำสั่ง
npm install axios --save
ถัดไปเราจะสร้าง Environment Variable โดยให้ไปสร้างไฟล์ .env ใน /functions แล้วให้ไป copy ค่า Channel Access Token ของ Messaging API Channel ที่ issue ไว้ก่อนหน้านี้มาระบุลงไป
CHANNEL_ACCESS_TOKEN=YOUR-CHANNEL-ACCESS-TOKEN
จากนั้นให้เปิดไฟล์ /functions/index.js แล้วให้ copy โค้ดด้านล่างนี้ไปแทนที่โค้ดเดิม เพื่อเตรียมรับ Webhook event ประเภท text จาก LINE และตอบกลับผู้ใช้งาน
// Import dependencies
const {onRequest} = require("firebase-functions/v2/https");
const axios = require("axios");
// Create a webhook via HTTP requests
exports.webhook = onRequest(async (req, res) => {
if (req.method === "POST") {
const events = req.body.events;
for (const event of events) {
switch (event.type) {
case "message":
if (event.message.type === "text") {
const msg = event.message.text;
await reply(event.replyToken, [{ type: "text", text: msg }]);
}
break;
}
}
}
res.send(req.method);
});
// Create a reply function with Messaging API
const reply = (token, payload) => {
return axios({
method: "post",
url: `https://api.line.me/v2/bot/message/reply`,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.CHANNEL_ACCESS_TOKEN}`
},
data: { replyToken: token, messages: payload }
});
};
แล้วก็ให้เปิด command line ขึ้นมาอีกครั้ง และให้แน่ใจว่าเราอยู่ที่ functions/ จากนั้นใช้คำสั่งด้านล่างนี้เพื่อ deploy ตัว webhook ของเราขึ้น production
firebase deploy --only functions
เมื่อ deploy เสร็จเรียบร้อยเราจะเห็น Webhook URL โผล่อยู่ใน command line เลย ก็ให้เรา copy มา หรือกรณีที่ไม่พบก็ให้เข้าไปที่ Firebase console เลือกโปรเจคที่เราสร้างไว้ แล้วเลือกเมนู Build > Functions จะเจอชื่อฟังก์ชันและ Webhook URL ที่นั่น
เมื่อได้ Webhook URL มาแล้ว ก็ให้เอา URL นี้ไปอัพเดทที่ Messaging API Channel ใน LINE Developers console ตามที่ได้สร้างไว้ และให้มั่นใจว่าได้เปิดใช้ Use webhook แล้ว
ขั้นตอนนี้เราจะไปเปิดใช้งาน PaLM API พร้อมสร้าง API Key เพื่อนำไปเชื่อต่อกับ LINE Chatbot
ให้เข้าสู่เว็บไซต์ MakerSuite
จากนั้นให้กดปุ่ม Create an API key แล้วจะพบทางเลือกที่ให้เราสร้าง API key ด้วยการสร้างโปรเจคใหม่ หรือเลือกโปรเจคที่มีอยู่แล้วใน Google Cloud ก็ได้(ถ้ามี) ซึ่งเมื่อสร้างเสร็จ เราก็จะได้ API key มา
ให้เราเพิ่มตัวแปร API_KEY ใน Environment Variable โดยเปิดไฟล์ .env ใน /functions แล้วให้เอา API key ระบุลงไป
CHANNEL_ACCESS_TOKEN=YOUR-CHANNEL-ACCESS-TOKEN
API_KEY=YOUR-PALM-API-KEY
การใช้งาน Natural Language Processing(NLP) ใน PaLM API จะมีอยู่ 2 รูปแบบ ซึ่งใน Codelab นี้จะพาทุกท่านไปเขียนโปรแกรมเชื่อมต่อทั้ง 2 แบบ โดยเริ่มจากทำการติดตั้ง dependencies 2 ตัวที่ชื่อ google-auth-library และ @google-ai/generativelanguage ก่อน โดยให้เปิด command line แล้วเข้าไปที่ /functions จากนั้นใช้คำสั่ง
npm install google-auth-library @google-ai/generativelanguage --save
เพื่อให้โค้ดในไฟล์ /functions/index.js ไม่ยาวจนเกินไป ขั้นตอนนี้จึงขอแยก module ของ PaLM API ออกมาเป็นไฟล์ /functions/palm.js โดยจะมีทั้งฟังก์ชันสำหรับ Text และ Chat services อยู่ในนี้
// Import dependencies
const { TextServiceClient, DiscussServiceClient } = require("@google-ai/generativelanguage").v1beta2;
const { GoogleAuth } = require("google-auth-library");
// Get PaLM API key from Environment Variable
const API_KEY = process.env.API_KEY;
// Text service
const text = async (prompt) => {
const client = new TextServiceClient({ authClient: new GoogleAuth().fromAPIKey(API_KEY) });
return await client.generateText({
model: "models/text-bison-001",
prompt: { text: prompt }
});
};
// Chat service
const chat = async (prompt) => {
const client = new DiscussServiceClient({ authClient: new GoogleAuth().fromAPIKey(API_KEY) });
return await client.generateMessage({
model: "models/chat-bison-001",
prompt: {
context: "You are a Community Manager who works with many of developer communities in Thailand and want to help developers succeed by using LINE APIs.",
examples: [
{
input: { content: "What APIs does LINE provide?" },
output: { content: "Messaging API, LIFF, LINE Login, LINE Beacon, LINE Notify, LINE Things, and LINE MINI App."},
},
{
input: { content: "What can I do with the Messaging API?" },
output: { content: "Build a chatbot to interact with users on LINE."},
},
{
input: { content: "What can I do with the LIFF?" },
output: { content: "Build a web app that run within LINE."},
},
{
input: { content: "How to get started with LINE APIs?" },
output: { content: "You can go to LINE Developers Thailand website at https://linedevth.line.me and explore APIs that fit with your use case."},
}
],
messages: [{ content: prompt }]
}
});
};
module.exports = { text, chat };
แล้วก็ให้เราไปอัพเดทโค้ดในไฟล์ /functions/index.js เพื่อดึงเอา module ดังกล่าวมาใช้งาน
const {onRequest} = require("firebase-functions/v2/https");
const axios = require("axios");
const palm = require("./palm"); // import palm module
จะเป็นการโต้ตอบแบบครั้งเดียว ไม่ต้องการบริบทก่อนหน้า ถามมาตอบไปแล้วจบ ซึ่งตัว AI จะใช้ความรู้ที่เรียนมาหาคำตอบมาให้เรา เช่น "Please tell me how to cook Tom Yum Kung"
ให้ปรับโค้ดในส่วนที่เช็คเงื่อนไขข้อความประเภท text เป็น
if (event.message.type === "text") {
const result = await palm.text(event.message.text);
const msg = result[0].candidates[0].output;
await reply(event.replyToken, [{ type: "text", text: msg }]);
}
จากนั้นก็ deploy ผ่าน command line ด้วยคำสั่ง
firebase deploy --only functions
เสร็จแล้วก็มาทดสอบกันดูหน่อย...ผลคือ มันตอบได้ถูก ละเอียด โดยเฉพาะโค้ดก็สามารถเอาไปใช้ได้เลย
จะเป็นการโต้ตอบไปมาแบบสนทนา สามารถระบุบริบทให้กับ AI และสามารถยกตัวอย่างบทสนทนาเพื่อให้ AI ได้เรียนรู้และเข้าใจคำตอบที่เฉพาะเจาะจงกับ use case นั้นๆได้ เช่น กำหนด context ให้ AI เป็น "You are a Community Manager who works with many of developer communities in Thailand and want to help developers succeed by using LINE APIs."
ให้ปรับโค้ดในส่วนที่เช็คเงื่อนไขข้อความประเภท text เป็น
if (event.message.type === "text") {
const result = await palm.chat(event.message.text);
const msg = result[0].candidates[0].content;
await reply(event.replyToken, [{ type: "text", text: msg }]);
}
จากนั้นก็ deploy ผ่าน command line ด้วยคำสั่ง
firebase deploy --only functions
เสร็จแล้วก็มาทดสอบกันดูหน่อย...ผลคือมันเข้าใจบริบทที่เราป้อนให้ โดยมีการสร้างความรู้เกี่ยวกับเรื่องนั้นๆเสริมเข้าไปด้วย
ยินดีด้วยครับ ถึงตรงนี้คุณก็มี LINE Chatbot สำหรับการรายงานราคาทองคำเป็นของคุณเองแล้ว!!!