728x90
반응형

지난 글에서는 PydanticOutputParser와 SerpAPI를 활용해서 이메일 본문을 요약하고, 발신자 정보를 자동으로 검색해주는 미니 프로젝트를 소개했습니다.

 

오늘은 그 프로젝트를 한 단계 더 확장해서, Streamlit을 활용해 웹 애플리케이션 형태로 구현해봤습니다.

 

즉, 단순히 코드로만 실행하던 것을 이제는 대화형 UI에서 이메일 내용을 입력 → 요약/검색 → 리포트 생성까지 한 번에 경험할 수 있도록 만든 것이죠.


1. 프로젝트 개요

이번 Streamlit 앱의 주요 기능은 다음과 같습니다.

  • 📩 이메일 본문 입력: 사용자가 이메일 내용을 입력
  • 🔎 PydanticOutputParser: 발신자, 수신자, 제목, 요약 등 주요 엔티티 자동 추출
  • 🌐 SerpAPI 검색: 발신자 관련 정보를 구글에서 자동 수집
  • 📑 최종 리포트 생성: 이메일 요약 + 발신자 정보가 포함된 리포트 출력
  • 💬 채팅 UI: Streamlit의 st.chat_message를 활용해 대화형 인터페이스 제공

2. 핵심 코드 설명

(1) Streamlit 기본 구조

먼저 Streamlit UI를 세팅합니다.

  • st.title("Email 요약기 💬")로 타이틀 생성
  • st.sidebar에 초기화 버튼 배치
  • st.session_state를 사용해 대화 기록 관리
st.title("Email 요약기 💬")

if "messages" not in st.session_state:
    st.session_state["messages"] = []

with st.sidebar:
    clear_btn = st.button("대화 초기화")


(2) 이메일 파싱 체인

이메일 본문에서 주요 정보를 뽑아내기 위해 PydanticOutputParser를 사용합니다.

아래처럼 EmailSummary 모델을 정의하고, 체인을 구성합니다.

class EmailSummary(BaseModel):
    sender_name: str
    sender_email: str
    recipient_name: str
    recipient_email: str
    subject: str
    meeting_date: str
    meeting_time: str
    meeting_location: str
    summary: str

def create_email_parsing_chain():
    output_parser = PydanticOutputParser(pydantic_object=EmailSummary)
    prompt = PromptTemplate.from_template("""
    You are a helpful assistant. Please answer the following questions in KOREAN.
    #QUESTION:
    다음의 이메일 내용 중에서 주요 내용을 추출해 주세요.
    #EMAIL CONVERSATION:
    {email_conversation}
    #FORMAT:
    {format}
    """)
    prompt = prompt.partial(format=output_parser.get_format_instructions())
    chain = prompt | ChatOpenAI(model="gpt-4-turbo") | output_parser
    return chain


(3) 발신자 정보 검색 (SerpAPI)

이메일에서 추출된 발신자 이름 + 이메일을 검색어로 활용합니다.

SerpAPI를 통해 구글 검색 결과를 JSON 형태로 받아와 리스트로 변환한 뒤, 요약 리포트에 활용합니다.

params = {"engine": "google", "gl": "kr", "hl": "ko", "num": "3"}
search = SerpAPIWrapper(params=params)

search_query = f"{answer.sender_name} {answer.sender_email}"
search_result = search.run(search_query)
search_result = eval(search_result)
search_result_string = "\\n".join(search_result)


(4) 최종 리포트 생성

추출된 이메일 요약과 검색 결과를 하나로 합쳐, 마크다운 형식의 리포트를 생성합니다.

report_chain = create_report_chain()
report_chain_input = {
    "sender": answer.sender_name,
    "additional_information": search_result_string,
    "recipient": answer.recipient_name,
    "subject": answer.subject,
    "meeting_date": answer.meeting_date,
    "meeting_time": answer.meeting_time,
    "meeting_location": answer.meeting_location,
    "summary": answer.summary,
}

response = report_chain.stream(report_chain_input)
with st.chat_message("assistant"):
    container = st.empty()
    ai_answer = ""
    for token in response:
        ai_answer += token
        container.markdown(ai_answer)

이렇게 하면, 사용자가 입력한 이메일을 대화형 리포트 형태로 즉시 확인할 수 있습니다.


3. 실행 화면

앱을 실행하면,

  1. 사용자가 이메일 내용을 입력
  2. GPT가 이메일 요약 및 주요 엔티티 추출
  3. SerpAPI로 발신자 정보 검색
  4. 리포트 형식으로 결과 출력

의 과정을 거치게 됩니다.

실행 화면은 다음과 같습니다:

 

 

오류는 정말 많지만 그래도 뭐 작동은 됩니다..!


마무리

이번에 Streamlit으로 구현해보니, 단순히 코드 실행 결과를 확인하는 것과는 달리 대화형 인터페이스에서 훨씬 직관적으로 결과를 확인할 수 있었습니다.

특히,

  • LangChain의 OutputParser + Pydantic으로 구조화된 데이터 추출,
  • SerpAPI로 외부 검색 결합,
  • Streamlit으로 인터페이스 제공

이라는 세 가지 요소가 합쳐져, 작은 규모지만 꽤 실용적인 미니 프로젝트를 완성할 수 있었네요.

728x90
반응형

+ Recent posts