새소식

반응형
IT Trends

[AI Agent] 코드 100줄로 쏘카 팀이 만든 고객 서비스 챗봇 만들기

  • -
728x90
반응형

쏘카가 디자인한 시나리오 기반 LLM 봇

  • 1) 백엔드에서 고객 서비스 매뉴얼 파일 업로드 하고, 이를 vector store 데이터베이스에 업로드
  • 2) 유저의 텍스트 인풋에 따라 상담의 의도를 LLM이 파악
  • 3) RAG, Vector Search를 같이 사용해 LLM 에이전트가 상담 매뉴얼 DB에서 정확한 결과 검색
  • 4) 할루시네이션이 나오면 후처리해서 LLM이 답하는 것보다 인간 상담원에게 연결할 수 있도록 디자인

 

 

* 필요한 라이브러리 모듈 불러오기

import dotenv
dotenv.load_dotenv()
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_openai import ChatOpenAI
from langchain.agents.agent_toolkits import create_retriever_tool

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import AgentExecutor, ConversationalChatAgent
import streamlit as st
from langchain_community.chat_message_histories import StreamlitChatMessageHistory
from langchain.memory import ConversationBufferMemory

from langchain_community.callbacks import StreamlitCallbackHandler
from langchain_core.runnables import RunnableConfig

 

 

1) 벡터 스토어에 데이터 저장

# 벡터 스토어에 데이터 저장
loader = WebBaseLoader("https://dalpha.so/ko/howtouse?scrollTo=custom")
data = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
all_splits = text_splitter.split_documents(data)

vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()

 

 

2) 에이전트가 사용할 툴 지정 - 검색

# 에이전트가 사용할 툴
tool = create_retriever_tool(
    retriever,
    "customer_service",
    "Searches and returns documents regarding the customer service guide."
)
tools = [tool]

 

 

 

3) 메모리 부여 (멀티 턴 대화)

# 메모리 부여
msgs = StreamlitChatMessageHistory(key="langchain_messages")
memory = ConversationBufferMemory(
    chat_memory=msgs, return_messages=True, memory_key="chat_history", output_key="output")

 

 

 

4) 에이전트 생성

# 에이전트 생성
system_messages = """You are a nice customer service agent. 
Do your best to answer the questions. 
Feel free to use any tools available to look up relevant information, only if necessary.
Do not generate false answers to questions that are not related to the customer service guide.
If you don't know the answer, just say that you don't know. Don't try to make up an answer.
항상 한국어로 답변해."""

llm = ChatOpenAI(temperature=0, streaming=True)
agent = ConversationalChatAgent.from_llm_and_tools(llm=llm, tools=tools)
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    system_message=system_messages,
    verbose=True,
    return_intermediate_steps=True,
    handle_parsing_errors=True,
)

 

 

 

5) 프론트 페이지 (streamlit)

# Front 
st.set_page_config(page_title="ChatWebsite", page_icon="🔗")
st.title("Customer Service")

if "openai_model" not in st.session_state:
    st.session_state["openai_model"] = "gpt-3.5-turbo"
    
# Initialize chat history
if len(msgs.messages) == 0 or st.sidebar.button("Reset chat history"):
    msgs.clear()
    msgs.add_ai_message("무엇을 도와드릴까요?")
    st.session_state.steps = {}
    st.session_state["messages"] = []

 

 

  • LLM 모델 선택 (gpt-3.5-turbo)
  • 메세지가 없거나, Reset 버튼을 누르면 "무엇을 도와드릴까요?"라고 먼저 묻기

 

 

 

 

 

 

 

 

 

5-1) 기존 대화 내역 보여주기

# Display chat messages from history on app rerun
avatars = {"human": "user", "ai": "assistant"}
for idx, msg in enumerate(msgs.messages):
    with st.chat_message(avatars[msg.type]):
        # Render intermediate steps if any were saved
        for step in st.session_state.steps.get(str(idx), []):
            if step[0].tool == "_Exception":
                continue
            with st.status(f"**{step[0].tool}**: {step[0].tool_input}", state="complete"):
                st.write(step[0].log)
                st.write(step[1])
        st.write(msg.content)

 

 

 

5-2) 새로운 채팅이 들어오면, LLM 으로 결과를 생성해 보여주기

# Accept user input
if prompt := st.chat_input(placeholder="What is up?"):
    st.chat_message("user").write(prompt)
    
    with st.chat_message("assistant"):
        st_cb = StreamlitCallbackHandler(st.container(), expand_new_thoughts=False)
        cfg = RunnableConfig()
        cfg["callbacks"] = [st_cb]
        response = agent_executor.invoke(prompt, cfg)
        st.write(response["output"])
        st.session_state.steps[str(len(msgs.messages) - 1)] = response["intermediate_steps"]

 

 

 

 

REF :

 

[Part 2] 코드 100줄로 쏘카 팀이 만든 고객 서비스 챗봇 10분 안에 만들어보기 (RAG, 할루시네이션 처

저번 포스트에 이어서 올리는

disquiet.io

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.