Skip to Content

좋아요/싫어요 알림 받아보기

EMF란?

EMF (Embedded Metric Format)는 Amazon CloudWatch에서 사용되는 JSON 형식의 로그 포맷입니다. 이 포맷을 사용하면 로그 데이터와 함께 메트릭 데이터를 동시에 전송할 수 있어, 별도의 메트릭 API 호출 없이도 CloudWatch에서 메트릭을 자동으로 추출하고 처리할 수 있습니다.

이번 파트에서는 EMF를 통해 Sentiment 메트릭을 CloudWatch에 전송하고, 이를 통해 좋아요/싫어요 알림을 받아보겠습니다.

  1. 다음 Python 코드를 이용해 CloudWatchSentiment 메트릭을 전송해 보겠습니다.

    current_time = int(time.time() * 1000) customMetricJson = { "_aws": { "Timestamp": current_time, "CloudWatchMetrics": [ { "Namespace": "Chatbot-Sentiment", "Dimensions": [["modelId"]], "Metrics": [ { "Name": "sentiment", "Unit": "Count", "StorageResolution": 60, } ] } ] }, "modelId": MODEL_ID, "sentiment": st.session_state.thumb_feedback, "feedback": st.session_state.text_feedback } cwLogEvent = json.dumps(customMetricJson) response = logsClient.put_log_events( logGroupName='/chatbot/feedback', logStreamName='default', logEvents=[ { 'timestamp': current_time, 'message': cwLogEvent } ] )
  2. 아래와 같이 demo3.py 파일을 입력합니다.

    vi demo3.py
    # demo3.py import logging from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough, RunnableParallel from langchain_core.output_parsers import StrOutputParser from langchain_aws import ChatBedrock, AmazonKnowledgeBasesRetriever import boto3 from botocore.exceptions import ClientError import streamlit as st import time import json from config import (REGION,MODEL_ID, KB_ID, MAX_TOKENS, TEMPERATURE, TOP_K, TOP_P) st.set_page_config(page_title='Amazon Bedrock 기반 고객상담 챗봇') # Store LLM generated responses if "messages" not in st.session_state.keys(): st.session_state.messages = [{"role": "assistant", "content": "How may I assist you today?"}] # log client 생성 logsClient = boto3.client(service_name = 'logs', region_name=REGION) def setup_langchain(): bedrock_runtime = boto3.client( service_name="bedrock-runtime", region_name=REGION, ) model_kwargs = { "temperature": TEMPERATURE, "max_tokens": MAX_TOKENS, "top_k": TOP_K, "top_p": TOP_P, "stop_sequences": ["\n\nHuman"] } template = ''' Answer the question based on the context below. Context: {context}` Question: {question} ''' prompt = ChatPromptTemplate.from_template(template) retriever = AmazonKnowledgeBasesRetriever( knowledge_base_id=KB_ID, retrieval_config={"vectorSearchConfiguration": {"numberOfResults": 4}}, region_name=REGION, credentials_profile_name=None ) model = ChatBedrock( client=bedrock_runtime, model_id=MODEL_ID, model_kwargs=model_kwargs, ) return ( RunnableParallel({"context": retriever, "question": RunnablePassthrough()}) .assign(response = prompt | model | StrOutputParser()) .pick(["response", "context"]) ) # @xray_recorder.capture('process_chat') def process_chat(chain, user_prompt, streaming: bool = False): if streaming: return chain.stream(user_prompt) else: response = chain.invoke(user_prompt) return response def setup_log_group(): try: logsClient.create_log_group( logGroupName='/chatbot/feedback' ) except ClientError as e: if e.response['Error']['Code'] != 'ResourceAlreadyExistsException': raise def setup_log_stream(): try: logsClient.create_log_stream( logGroupName='/chatbot/feedback', logStreamName='default' ) except ClientError as e: if e.response['Error']['Code'] != 'ResourceAlreadyExistsException': raise def submit_feedback(): current_time = int(time.time() * 1000) # 밀리초 단위로 통일 customMetricJson = { "_aws": { "Timestamp": current_time, "CloudWatchMetrics": [ { "Namespace": "Chatbot-Sentiment", "Dimensions": [["modelId"]], "Metrics": [ { "Name": "sentiment", "Unit": "Count", "StorageResolution": 60, } ] } ] }, "modelId": MODEL_ID, "sentiment": st.session_state.thumb_feedback, "feedback": st.session_state.text_feedback } cwLogEvent = json.dumps(customMetricJson) response = logsClient.put_log_events( logGroupName='/chatbot/feedback', logStreamName='default', logEvents=[ { 'timestamp': current_time, # 동일한 타임스탬프 사용 'message': cwLogEvent } ] ) # 메인 애플리케이션 로직 with st.sidebar: st.title('Amazon Bedrock 기반 고객상담 챗봇') streaming_enabled = st.toggle('Enable Streaming', False) with st.form("feedback_form", enter_to_submit=True, clear_on_submit=True, border=False): st.session_state.thumb_feedback = st.feedback("thumbs") st.session_state.text_feedback = st.text_input( "Feedback", placeholder="Enter your feedback here" ) submit = st.form_submit_button("Submit Feedback") if submit: submit_feedback() chain = setup_langchain() # Display chat messages for message in st.session_state.messages: with st.chat_message(message["role"]): st.write(message["content"]) # Chat Input - User Prompt if prompt := st.chat_input(): st.session_state.messages.append({"role": "user", "content": prompt}) with st.chat_message("user"): st.write(prompt) # Chain - Invoke with st.chat_message("assistant"): response_placeholder = st.empty() # 스트리밍을 위한 플레이스홀더 full_response = "" context = None if streaming_enabled: # 스트리밍 모드 for chunk in process_chat(chain, prompt, streaming=True): if 'context' in chunk: context = chunk['context'] if 'response' in chunk: full_response += chunk['response'] response_placeholder.write(full_response) else: # 일반 모드 response = process_chat(chain, prompt) full_response = response['response'] contenxt = response['context'] response_placeholder.write(full_response) with st.expander("Show source details >"): if context: st.write(context) else: st.write('No source details available') st.session_state.messages.append({"role": "assistant", "content": full_response}) setup_log_group() setup_log_stream()
  3. 아래 명령어를 통해 서버를 재시작합니다.

    streamlit run demo3.py --server.port 80 --server.address 0.0.0.0
  4. 챗봇에게 질문을 하고, 이에 대한 만족도를 평가해 보겠습니다.

  5. 질문에 대한 답변의 만족도를 선택하고 Feedback을 작성한 후 Submit 버튼을 클릭합니다. 해당버튼은 위 EMF 로그를 포함한 Logging 정보를 Cloudwatch 로 전송합니다.

    sentiment-1

  6. 위 형식의 EMF 로그는 CloudWatch에 전송되어 자동으로 Chatbot-Sentiment 네임스페이스를 생성합니다.

    CloudWatch > 지표 > 모든 지표로이동한 후, Chatbot-Sentiment 네임스페이스를 클릭합니다.

    sentiment-2

  7. 해당 네임스페이스에서는 modelId 별로 Sentiment 값을 확인할 수 있습니다. 이를 통해 사용자들의 만족도를 실시간으로 확인할 수 있습니다.

    원하는 모델 ID를 선택하고 경보 생성 버튼을 클릭합니다.

    sentiment-3

  8. Bedrock 챗봇의 만족도가 95% 미만이 되면 알람이 발생하도록 설정해 보겠습니다.

    지표 및 조건 지정 페이지에서 다음과 같이 설정합니다.

    • 경보 조건 : 보다 작음 < 임계값
    • …보다 : 0.95
    • 추가 구성 > 누락된 데이터 처리 : 누락된 데이터를 양호(임계값 위반 안 함)(으)로 처리
  9. 작업 구성 페이지에서 알림을 받을 새로운 SNS를 추가하기 위해 다음과 같이 설정 후, 주제 생성 버튼을 클릭합니다.

    • 다음 SNS 주제에 알림을 보냅니다 : 새 주제 생성
    • 알림을 수신할 이메일 엔드포인트… : 알림을 받을 이메일 주소

    sentiment-4

  10. 이름 및 설명 추가 페이지에서 경보 이름을 입력하고 다음 > 경보 생성 버튼을 클릭해 경보를 생성합니다.

    sentiment-5

  11. 본인의 이메일로 이동해 구독 확인 링크를 클릭하여 구독을 활성화합니다.

    sentiment-6

  12. 다음과 같은 화면이 나타난다면 성공적으로 구독이 완료된 것입니다.

    sentiment-7

    이제 Bedrock 챗봇의 만족도가 95% 미만이 되면 알람이 발생하도록 설정되었습니다. 만족도가 낮아지면 다음과 같은 알람이 이메일로 발신됩니다.

    sentiment-8

    해당 알람을 통해 낮은 만족도에 즉각적으로 대응해 보세요!

Last updated on