ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การส่งผ่าน URL | บริการเว็บอเมซอน

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การส่งผ่าน URL | บริการเว็บอเมซอน

ในโลกดิจิทัลปัจจุบัน ผู้บริโภคส่วนใหญ่ต้องการหาคำตอบสำหรับคำถามเกี่ยวกับบริการลูกค้าด้วยตนเองแทนที่จะใช้เวลาในการติดต่อกับธุรกิจและ/หรือผู้ให้บริการ โพสต์บล็อกนี้สำรวจโซลูชันที่เป็นนวัตกรรมใหม่ในการสร้างคำถามและคำตอบของแชทบอท อเมซอน เล็กซ์ ที่ใช้คำถามที่พบบ่อยจากเว็บไซต์ของคุณ เครื่องมือที่ขับเคลื่อนด้วย AI นี้สามารถให้การตอบสนองอย่างรวดเร็วและแม่นยำต่อการสอบถามในโลกแห่งความจริง ทำให้ลูกค้าสามารถแก้ปัญหาทั่วไปได้อย่างรวดเร็วและง่ายดายโดยอิสระ

การนำเข้า URL เดียว

องค์กรหลายแห่งมีชุดคำตอบสำหรับคำถามที่พบบ่อยสำหรับลูกค้าที่เผยแพร่บนเว็บไซต์ของตน ในกรณีนี้ เราต้องการเสนอแชทบอทให้กับลูกค้าที่สามารถตอบคำถามของพวกเขาจากคำถามที่พบบ่อยที่เผยแพร่ของเรา ในบล็อกโพสต์ชื่อ ปรับปรุง Amazon Lex ด้วยคุณสมบัติคำถามที่พบบ่อยเกี่ยวกับการสนทนาโดยใช้ LLMเราได้สาธิตวิธีที่คุณสามารถใช้การรวมกันของ Amazon Lex และ LlamaIndex เพื่อสร้างแชทบอทที่ขับเคลื่อนโดยแหล่งความรู้ที่คุณมีอยู่ เช่น เอกสาร PDF หรือ Word เพื่อสนับสนุนคำถามที่พบบ่อยโดยอ้างอิงจากเว็บไซต์คำถามที่พบบ่อย เราจำเป็นต้องสร้างกระบวนการนำเข้าที่สามารถรวบรวมข้อมูลเว็บไซต์และสร้างการฝังที่ LlamaIndex สามารถใช้เพื่อตอบคำถามของลูกค้าได้ ในกรณีนี้ เราจะสร้างบอทที่สร้างขึ้นใน โพสต์บล็อกก่อนหน้าซึ่งค้นหาการฝังเหล่านั้นด้วยคำพูดของผู้ใช้และส่งคืนคำตอบจากคำถามที่พบบ่อยของเว็บไซต์

แผนภาพต่อไปนี้แสดงให้เห็นว่ากระบวนการนำเข้าและบอต Amazon Lex ทำงานร่วมกันอย่างไรสำหรับโซลูชันของเรา

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.

ในเวิร์กโฟลว์ของโซลูชัน เว็บไซต์ที่มีคำถามที่พบบ่อยจะถูกส่งผ่าน AWS แลมบ์ดา. ฟังก์ชัน Lambda นี้จะรวบรวมข้อมูลเว็บไซต์และจัดเก็บข้อความผลลัพธ์ในรูปแบบ บริการจัดเก็บข้อมูลอย่างง่ายของ Amazon ที่ฝากข้อมูล (Amazon S3) จากนั้นบัคเก็ต S3 จะทริกเกอร์ฟังก์ชัน Lambda ที่ใช้ LlamaIndex เพื่อสร้างการฝังที่จัดเก็บไว้ใน Amazon S3 เมื่อมีคำถามจากผู้ใช้ปลายทาง เช่น "นโยบายการคืนสินค้าของคุณคืออะไร" บอต Amazon Lex จะใช้ฟังก์ชัน Lambda เพื่อค้นหาการฝังโดยใช้แนวทาง RAG กับ LlamaIndex สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแนวทางนี้และข้อกำหนดเบื้องต้น โปรดดูที่บล็อกโพสต์ ปรับปรุง Amazon Lex ด้วยคุณสมบัติคำถามที่พบบ่อยเกี่ยวกับการสนทนาโดยใช้ LLM.

หลังจากทำข้อกำหนดเบื้องต้นจากบล็อกข้างต้นเสร็จสิ้นแล้ว ขั้นตอนแรกคือนำคำถามที่พบบ่อยไปไว้ในที่เก็บเอกสารที่ LlamaIndex สามารถทำเวกเตอร์และจัดทำดัชนีได้ รหัสต่อไปนี้แสดงวิธีการดำเนินการนี้:

import logging
import sys
import requests
import html2text
from llama_index.readers.schema.base import Document
from llama_index import GPTVectorStoreIndex
from typing import List logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout)) class EZWebLoader: def __init__(self, default_header: str = None): self._html_to_text_parser = html2text() if default_header is None: self._default_header = {"User-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"} else: self._default_header = default_header def load_data(self, urls: List[str], headers: str = None) -> List[Document]: if headers is None: headers = self._default_header documents = [] for url in urls: response = requests.get(url, headers=headers).text response = self._html2text.html2text(response) documents.append(Document(response)) return documents url = "http://www.zappos.com/general-questions"
loader = EZWebLoader()
documents = loader.load_data([url])
index = GPTVectorStoreIndex.from_documents(documents)

ในตัวอย่างก่อนหน้านี้ เรานำ URL ของเว็บไซต์คำถามที่พบบ่อยที่กำหนดไว้ล่วงหน้าจาก Zappos และนำเข้าโดยใช้ EZWebLoader ระดับ. ในชั้นเรียนนี้ เราได้นำทางไปยัง URL และโหลดคำถามทั้งหมดที่อยู่ในหน้าลงในดัชนี ตอนนี้เราสามารถถามคำถามเช่น "Zappos มีบัตรของขวัญหรือไม่" และรับคำตอบโดยตรงจากคำถามที่พบบ่อยบนเว็บไซต์ ภาพหน้าจอต่อไปนี้แสดงคอนโซลทดสอบบอต Amazon Lex ที่ตอบคำถามนั้นจากคำถามที่พบบ่อย

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.

เราทำได้สำเร็จเพราะเรารวบรวมข้อมูล URL ในขั้นตอนแรก และสร้างการฝังที่ LlamaIndex สามารถใช้เพื่อค้นหาคำตอบสำหรับคำถามของเรา ฟังก์ชัน Lambda ของบอทของเราแสดงให้เห็นว่าการค้นหานี้ทำงานอย่างไรเมื่อใดก็ตามที่ส่งคืนความตั้งใจทางเลือก:

import time
import json
import os
import logging
import boto3
from llama_index import StorageContext, load_index_from_storage logger = logging.getLogger()
logger.setLevel(logging.DEBUG) def download_docstore(): # Create an S3 client s3 = boto3.client('s3') # List all objects in the S3 bucket and download each one
try: bucket_name = 'faq-bot-storage-001' s3_response = s3.list_objects_v2(Bucket=bucket_name) if 'Contents' in s3_response: for item in s3_response['Contents']: file_name = item['Key'] logger.debug("Downloading to /tmp/" + file_name) s3.download_file(bucket_name, file_name, '/tmp/' + file_name) logger.debug('All files downloaded from S3 and written to local filesystem.') except Exception as e: logger.error(e)
raise e #download the doc store locally
download_docstore() storage_context = StorageContext.from_defaults(persist_dir="/tmp/")
# load index
index = load_index_from_storage(storage_context)
query_engine = index.as_query_engine() def lambda_handler(event, context): """
Route the incoming request based on intent.
The JSON body of the request is provided in the event slot. """ # By default, treat the user request as coming from the America/New_York time zone. os.environ['TZ'] = 'America/New_York' time.tzset() logger.debug("===== START LEX FULFILLMENT ====") logger.debug(event) slots = {} if "currentIntent" in event and "slots" in event["currentIntent"]: slots = event["currentIntent"]["slots"] intent = event["sessionState"]["intent"] dialogaction = {"type": "Delegate"} message = [] if str.lower(intent["name"]) == "fallbackintent": #execute query from the input given by the user response = str.strip(query_engine.query(event["inputTranscript"]).response) dialogaction["type"] = "Close" message.append({'content': f'{response}', 'contentType': 'PlainText'}) final_response = { "sessionState": { "dialogAction": dialogaction, "intent": intent }, "messages": message } logger.debug(json.dumps(final_response, indent=1)) logger.debug("===== END LEX FULFILLMENT ====") return final_response

โซลูชันนี้ทำงานได้ดีเมื่อหน้าเว็บเดียวมีคำตอบทั้งหมด อย่างไรก็ตาม ไซต์คำถามที่พบบ่อยส่วนใหญ่ไม่ได้สร้างขึ้นในหน้าเดียว ตัวอย่างเช่น ในตัวอย่าง Zappos ของเรา หากเราถามคำถามว่า "คุณมีนโยบายการจับคู่ราคาหรือไม่" เราก็จะได้รับคำตอบที่ไม่ค่อยน่าพอใจดังที่แสดงในภาพหน้าจอต่อไปนี้

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.

ในการโต้ตอบก่อนหน้านี้ คำตอบของนโยบายการจับคู่ราคาไม่เป็นประโยชน์สำหรับผู้ใช้ของเรา คำตอบนี้สั้นเนื่องจากคำถามที่พบบ่อยที่อ้างอิงคือลิงก์ไปยังหน้าเฉพาะเกี่ยวกับนโยบายการจับคู่ราคา และการรวบรวมข้อมูลเว็บของเรามีไว้สำหรับหน้าเดียวเท่านั้น การได้รับคำตอบที่ดีขึ้นหมายถึงการรวบรวมข้อมูลลิงก์เหล่านี้ด้วย ส่วนถัดไปจะแสดงวิธีรับคำตอบสำหรับคำถามที่ต้องมีความลึกของหน้าตั้งแต่สองระดับขึ้นไป

การคลานระดับ N

เมื่อเรารวบรวมข้อมูลหน้าเว็บสำหรับความรู้คำถามที่พบบ่อย ข้อมูลที่เราต้องการจะอยู่ในหน้าที่เชื่อมโยง ตัวอย่างเช่น ในตัวอย่าง Zappos เราถามคำถามว่า "คุณมีนโยบายการจับคู่ราคาหรือไม่" และคำตอบคือ “ได้ โปรดเยี่ยมชม เพื่อเรียนรู้เพิ่มเติม” หากมีคนถามว่า “นโยบายการจับคู่ราคาของคุณคืออะไร” จากนั้นเราต้องการให้คำตอบที่สมบูรณ์พร้อมนโยบาย การบรรลุเป้าหมายนี้หมายความว่าเราจำเป็นต้องสำรวจลิงก์เพื่อรับข้อมูลที่แท้จริงสำหรับผู้ใช้ปลายทางของเรา ในระหว่างขั้นตอนการนำเข้า เราสามารถใช้ตัวโหลดเว็บของเราเพื่อค้นหาจุดยึดลิงก์ไปยังหน้า HTML อื่นๆ แล้วข้ามผ่านหน้าเหล่านั้น การเปลี่ยนแปลงโค้ดต่อไปนี้สำหรับโปรแกรมรวบรวมข้อมูลเว็บของเราช่วยให้เราสามารถค้นหาลิงก์ในหน้าเว็บที่เรารวบรวมข้อมูลได้ นอกจากนี้ยังมีตรรกะเพิ่มเติมบางอย่างเพื่อหลีกเลี่ยงการรวบรวมข้อมูลแบบวงกลมและอนุญาตให้ใช้ตัวกรองตามคำนำหน้า

import logging
import requests
import html2text
from llama_index.readers.schema.base import Document
from typing import List
import re def find_http_urls_in_parentheses(s: str, prefix: str = None): pattern = r'((https?://[^)]+))' urls = re.findall(pattern, s) matched = [] if prefix is not None: for url in urls: if str(url).startswith(prefix): matched.append(url) else: matched = urls return list(set(matched)) # remove duplicates by converting to set, then convert back to list class EZWebLoader: def __init__(self, default_header: str = None): self._html_to_text_parser = html2text if default_header is None: self._default_header = {"User-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"} else: self._default_header = default_header def load_data(self, urls: List[str], num_levels: int = 0, level_prefix: str = None, headers: str = None) -> List[Document]: logging.info(f"Number of urls: {len(urls)}.") if headers is None: headers = self._default_header documents = [] visited = {} for url in urls: q = [url] depth = num_levels for page in q: if page not in visited: #prevent cycles by checking to see if we already crawled a link logging.info(f"Crawling {page}") visited[page] = True #add entry to visited to prevent re-crawling pages response = requests.get(page, headers=headers).text response = self._html_to_text_parser.html2text(response) #reduce html to text documents.append(Document(response)) if depth > 0: #crawl linked pages ingest_urls = find_http_urls_in_parentheses(response, level_prefix) logging.info(f"Found {len(ingest_urls)} pages to crawl.") q.extend(ingest_urls) depth -= 1 #reduce the depth counter so we go only num_levels deep in our crawl else: logging.info(f"Skipping {page} as it has already been crawled") logging.info(f"Number of documents: {len(documents)}.") return documents url = "http://www.zappos.com/general-questions"
loader = EZWebLoader()
#crawl the site with 1 level depth and prefix of "/c/" for customer service root
documents = loader.load_data([url], num_levels=1, level_prefix="https://www.zappos.com/c/")
index = GPTVectorStoreIndex.from_documents(documents)

ในโค้ดก่อนหน้า เราแนะนำความสามารถในการรวบรวมข้อมูลในระดับลึก N และเราให้คำนำหน้าที่ช่วยให้เราสามารถจำกัดการรวบรวมข้อมูลเฉพาะสิ่งที่ขึ้นต้นด้วยรูปแบบ URL บางอย่างเท่านั้น ในตัวอย่าง Zappos ของเรา หน้าบริการลูกค้าทั้งหมดมีรากมาจาก zappos.com/cดังนั้นเราจึงรวมสิ่งนั้นไว้เป็นคำนำหน้าเพื่อจำกัดการรวบรวมข้อมูลของเราให้อยู่ในชุดย่อยที่เล็กลงและมีความเกี่ยวข้องมากขึ้น รหัสแสดงวิธีที่เราสามารถเจาะลึกได้ถึงสองระดับ ลอจิกแลมบ์ดาของบอทของเรายังคงเหมือนเดิมเพราะไม่มีอะไรเปลี่ยนแปลง ยกเว้นโปรแกรมรวบรวมข้อมูลจะนำเข้าเอกสารเพิ่มเติม

ขณะนี้เรามีการจัดทำดัชนีเอกสารทั้งหมดแล้ว และเราสามารถถามคำถามโดยละเอียดเพิ่มเติมได้ ในภาพหน้าจอต่อไปนี้ บอทของเราให้คำตอบที่ถูกต้องสำหรับคำถาม "คุณมีนโยบายการจับคู่ราคาหรือไม่"

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.

ขณะนี้เรามีคำตอบที่สมบูรณ์สำหรับคำถามของเราเกี่ยวกับการจับคู่ราคา แทนที่จะได้รับแจ้งเพียงว่า "ใช่ ดูนโยบายของเรา" ระบบจะให้รายละเอียดจากการรวบรวมข้อมูลระดับที่สองแก่เรา

ทำความสะอาด

เพื่อหลีกเลี่ยงค่าใช้จ่ายในอนาคต ให้ดำเนินการลบทรัพยากรทั้งหมดที่ถูกปรับใช้เป็นส่วนหนึ่งของแบบฝึกหัดนี้ เราได้จัดทำสคริปต์เพื่อปิดจุดสิ้นสุดของ Sagemaker อย่างสวยงาม รายละเอียดการใช้งานอยู่ใน README นอกจากนี้ เพื่อลบทรัพยากรอื่นๆ ทั้งหมดที่คุณเรียกใช้ได้ cdk destroy ในไดเร็กทอรีเดียวกันกับคำสั่ง cdk อื่นๆ เพื่อยกเลิกการจัดเตรียมทรัพยากรทั้งหมดในสแตกของคุณ

สรุป

ความสามารถในการรวมชุดคำถามที่พบบ่อยเข้าไปในแชทบอทช่วยให้ลูกค้าของคุณสามารถค้นหาคำตอบสำหรับคำถามของพวกเขาด้วยคำถามที่ใช้ภาษาที่เป็นธรรมชาติและตรงไปตรงมา ด้วยการรวมการสนับสนุนในตัวใน Amazon Lex สำหรับการจัดการสำรองด้วยโซลูชัน RAG เช่น LlamaIndex เราสามารถจัดเตรียมเส้นทางที่รวดเร็วสำหรับลูกค้าของเราในการได้รับคำตอบที่น่าพึงพอใจ คัดสรร และอนุมัติสำหรับคำถามที่พบบ่อย ด้วยการใช้การรวบรวมข้อมูลระดับ N ในโซลูชันของเรา เราสามารถให้คำตอบที่อาจครอบคลุมลิงก์คำถามที่พบบ่อยหลายลิงก์ และให้คำตอบที่ลึกขึ้นสำหรับข้อสงสัยของลูกค้า เมื่อทำตามขั้นตอนเหล่านี้ คุณจะสามารถรวมความสามารถ Q และ A ที่ใช้ LLM ที่มีประสิทธิภาพและการส่งผ่าน URL ที่มีประสิทธิภาพเข้ากับแชทบอท Amazon Lex ของคุณได้อย่างราบรื่น ซึ่งส่งผลให้มีการโต้ตอบกับผู้ใช้อย่างแม่นยำ ครอบคลุม และรับรู้ตามบริบทมากขึ้น


เกี่ยวกับผู้แต่ง

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.แม็กซ์ เฮงเค็ล-วอลเลซ เป็นวิศวกรพัฒนาซอฟต์แวร์ที่ AWS Lex เขาสนุกกับการใช้ประโยชน์จากเทคโนโลยีเพื่อเพิ่มความสำเร็จของลูกค้า นอกเวลางานเขาหลงใหลในการทำอาหาร ใช้เวลากับเพื่อน ๆ และแบกเป้เที่ยว

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.ซ่งเฟิง เป็นนักวิทยาศาสตร์ประยุกต์อาวุโสที่ AWS AI Labs ซึ่งเชี่ยวชาญด้านการประมวลผลภาษาธรรมชาติและปัญญาประดิษฐ์ งานวิจัยของเธอสำรวจแง่มุมต่าง ๆ ของสาขาเหล่านี้ รวมถึงการสร้างแบบจำลองบทสนทนาที่มีพื้นฐานจากเอกสาร การให้เหตุผลสำหรับบทสนทนาที่เน้นงาน และการสร้างข้อความโต้ตอบโดยใช้ข้อมูลหลายรูปแบบ

ปรับปรุง Amazon Lex ด้วย LLM และปรับปรุงประสบการณ์คำถามที่พบบ่อยโดยใช้การนำเข้า URL | Amazon Web Services PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.จอห์นเบเกอร์ เป็น SDE หลักที่ AWS ซึ่งเขาทำงานเกี่ยวกับการประมวลผลภาษาธรรมชาติ โมเดลภาษาขนาดใหญ่ และโครงการอื่นๆ ที่เกี่ยวข้องกับ ML/AI เขาทำงานกับ Amazon มานานกว่า 9 ปี และเคยทำงานใน AWS, Alexa และ Amazon.com ในเวลาว่าง จอห์นชอบเล่นสกีและกิจกรรมกลางแจ้งอื่นๆ ทั่วแปซิฟิกตะวันตกเฉียงเหนือ

ประทับเวลา:

เพิ่มเติมจาก AWS Machine Learning AWS