지난 글에서는 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. 실행 화면
앱을 실행하면,
- 사용자가 이메일 내용을 입력
- GPT가 이메일 요약 및 주요 엔티티 추출
- SerpAPI로 발신자 정보 검색
- 리포트 형식으로 결과 출력
의 과정을 거치게 됩니다.
실행 화면은 다음과 같습니다:

오류는 정말 많지만 그래도 뭐 작동은 됩니다..!
마무리
이번에 Streamlit으로 구현해보니, 단순히 코드 실행 결과를 확인하는 것과는 달리 대화형 인터페이스에서 훨씬 직관적으로 결과를 확인할 수 있었습니다.
특히,
- LangChain의 OutputParser + Pydantic으로 구조화된 데이터 추출,
- SerpAPI로 외부 검색 결합,
- Streamlit으로 인터페이스 제공
이라는 세 가지 요소가 합쳐져, 작은 규모지만 꽤 실용적인 미니 프로젝트를 완성할 수 있었네요.