2분
Core: Streamlit Chat UI 설계 패턴
프론트엔드 UI 개발 (Streamlit)
Core: Streamlit Chat UI 설계 패턴
통합 프로젝트 > 프론트엔드 UI 개발 (Streamlit)
학습 목표
- st.chat_message와 st.chat_input의 사용법을 이해한다
- 채팅 이력 표시 패턴을 이해한다
- Agent 응답을 스트리밍으로 표시하는 방법을 안다
Streamlit Chat UI 핵심 패턴
기본 구조
import streamlit as st
# 1. 페이지 설정
st.set_page_config(page_title="제조 AI 어시스턴트", page_icon="")
# 2. 세션 초기화
if "messages" not in st.session_state:
st.session_state.messages = []
# 3. 이전 대화 이력 표시
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
# 4. 사용자 입력
if prompt := st.chat_input("설비에 대해 물어보세요..."):
# 사용자 메시지 추가
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Agent 응답
with st.chat_message("assistant"):
response = agent.run(prompt)
st.markdown(response["answer"])
# 응답 저장
st.session_state.messages.append(
{"role": "assistant", "content": response["answer"]}
)
도구 사용 로그 표시
# Agent 응답 시 도구 사용 정보 표시
with st.chat_message("assistant"):
# 도구 사용 로그 (접을 수 있는 영역)
if response.get("tool_calls"):
with st.expander("사용된 도구", expanded=False):
for tc in response["tool_calls"]:
st.markdown(
f"- **{tc['name']}**"
f"(`{tc['args']}`)"
)
# 실제 답변
st.markdown(response["answer"])
agent.run() 이 돌려주는 것은 {"answer", "tool_calls", "messages"} 셋뿐이다.
그래프 데이터는 여기에 실리지 않는다. 채팅 화면에서 관계도를 보여 주고 싶다면
KG 도구가 어떤 설비를 조회했는지 tool_calls 에서 꺼내, 그 ID 를 KG 페이지로 넘긴다.
kg_targets = [
tc["args"].get("entity_id")
for tc in response.get("tool_calls", [])
if tc["name"] == "query_knowledge_graph"
]
if kg_targets:
st.caption(f"관계도를 보려면 Knowledge Graph 페이지에서 {kg_targets[0]} 를 조회하세요.")
설계 문서에 적어 둔 반환값과 실제 구현이 달라지는 일은 흔하다. 달라졌으면
뒤에서 참조하는 쪽을 함께 고쳐야 한다. 여기서는 D1 이 그린 AgentResponse(answer, sources, kg_data) 가 D2 구현에서 셋으로 줄었고, 그 사실을 모른 채 D3 이 옛 설계를
참조하면 존재하지 않는 키를 읽게 된다.
사이드바 활용
# 사이드바에 시스템 정보 표시
with st.sidebar:
st.title("제조 AI 어시스턴트")
st.caption("v0.1.0 MVP")
st.divider()
# 시스템 상태
st.subheader("시스템 상태")
rag_status = "연결됨" if rag_service else "미연결"
kg_status = "연결됨" if kg_service.is_connected else "미연결"
st.markdown(f"- RAG: {rag_status}")
st.markdown(f"- KG: {kg_status}")
st.markdown(f"- LLM: {settings.llm_model}")
st.divider()
# 대화 초기화 버튼
if st.button("대화 초기화", type="secondary"):
st.session_state.messages = []
st.rerun()
# 통계
st.subheader("이번 세션 통계")
st.metric("총 질문 수", st.session_state.get("total_queries", 0))
스트리밍 응답 (선택사항)
# 스트리밍으로 실시간 타이핑 효과
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
for chunk in agent.run_stream(prompt):
if chunk.get("node") == "agent":
# Agent 노드의 출력을 실시간 표시
output = chunk["output"]
if "messages" in output:
last_msg = output["messages"][-1]
if hasattr(last_msg, "content") and last_msg.content:
full_response = last_msg.content
message_placeholder.markdown(full_response + "...")
message_placeholder.markdown(full_response)AI로 학습하기 — 꿀팁
채팅 이력 패턴 코드 생성AI 학습 팁
AI에게 Streamlit 채팅 이력 표시 패턴을 제조 Q&A 맥락으로 완성된 코드로 출력하게 요청하세요.
st.chat_message와 st.chat_input, st.session_state를 사용해서 제조 설비 고장 Q&A 챗봇 Streamlit 앱 전체 코드를 작성해줘. 요구사항: (1) 대화 이력이 화면에 유지됨, (2) 사용자 질문과 AI 답변을 구분된 버블로 표시, (3) 답변은 주입받은 agent 객체의 run(question, history) 를 호출해 만들고, agent 가 없으면 그 사실을 화면에 알릴 것. 더미 응답을 하드코딩해 성공한 것처럼 보이게 하지 말 것. 실행 가능한 완성 코드로 줘.
이 팁이 도움이 됐나요?
핵심 포인트
- • st.chat_message + st.chat_input = 채팅 UI 완성
- • session_state에 대화 이력 저장 (재실행 시 유지)
- • st.expander로 도구 로그를 접을 수 있게
- • @st.cache_resource로 서비스 인스턴스 1회 생성