Streamlit으로 ClickHouse 기반 AI 에이전트 빌드하기
Streamlit으로 ClickHouse 기반 AI 에이전트 빌드하기
이 가이드에서는 Streamlit으로 웹 기반 AI 에이전트를 만들어 ClickHouse의 SQL 플레이그라운드와 ClickHouse의 MCP 서버 및 Agno를 통해 상호작용하도록 하는 방법을 배워요.
출처: 문서
본문
이 예제는 ClickHouse 데이터를 조회하는 채팅 인터페이스를 제공하는 완전한 웹 애플리케이션을 만들어요. 이 예제의 소스 코드는 examples 저장소에서 확인할 수 있어요.
준비 사항 (Prerequisites)
- 시스템에 Python이 설치되어 있어야 하고,
uv가 설치되어 있어야 해요. - Anthropic API 키 또는 다른 LLM 제공자의 API 키가 필요해요.
다음 절차를 수행해 Streamlit 애플리케이션을 만들 수 있어요.
1. 라이브러리 설치
다음 명령을 실행해 필요한 라이브러리를 설치해요.
pip install streamlit agno ipywidgets
2. 유틸리티 파일 만들기
다음 두 개의 유틸리티 함수가 있는 utils.py 파일을 만들어요. 첫 번째는 Agno 에이전트의 스트림 응답을 처리하는 비동기 함수 생성자이고, 두 번째는 Streamlit 애플리케이션에 스타일을 적용하는 함수예요.
import streamlit as st
from agno.run.response import RunEvent, RunResponse
async def as_stream(response):
async for chunk in response:
if isinstance(chunk, RunResponse) and isinstance(chunk.content, str):
if chunk.event == RunEvent.run_response:
yield chunk.content
def apply_styles():
st.markdown("""
<style>
hr.divider {
background-color: white;
margin: 0;
}
</style>
<hr class='divider' />""", unsafe_allow_html=True)
3. 자격 증명 설정
Anthropic API 키를 환경 변수로 설정해요.
export ANTHROPIC_API_KEY="your_api_key_here"
다른 LLM 제공자 사용하기 Anthropic API 키가 없고 다른 LLM 제공자를 사용하고 싶다면, Agno “Integrations” 문서에서 자격 증명 설정 방법을 확인할 수 있어요.
4. 필요한 라이브러리 임포트
주 Streamlit 애플리케이션 파일(예: app.py)을 만들고 import를 추가해요.
from utils import apply_styles
import streamlit as st
from textwrap import dedent
from agno.models.anthropic import Claude
from agno.agent import Agent
from agno.tools.mcp import MCPTools
from agno.storage.json import JsonStorage
from agno.run.response import RunEvent, RunResponse
from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp import ClientSession
import asyncio
import threading
from queue import Queue
5. 에이전트 스트리밍 함수 정의
ClickHouse의 SQL 플레이그라운드에 연결해 응답을 스트리밍하는 메인 에이전트 함수를 추가해요.
async def stream_clickhouse_agent(message):
env = {
"CLICKHOUSE_HOST": "sql-clickhouse.clickhouse.com",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "demo",
"CLICKHOUSE_PASSWORD": "",
"CLICKHOUSE_SECURE": "true"
}
server_params = StdioServerParameters(
command="uv",
args=[
'run',
'--with', 'mcp-clickhouse',
'--python', '3.13',
'mcp-clickhouse'
],
env=env
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
mcp_tools = MCPTools(timeout_seconds=60, session=session)
await mcp_tools.initialize()
agent = Agent(
model=Claude(id="claude-3-5-sonnet-20240620"),
tools=[mcp_tools],
instructions=dedent("""\
You are a ClickHouse assistant. Help users query and understand data using ClickHouse.
- Run SQL queries using the ClickHouse MCP tool
- Present results in markdown tables when relevant
- Keep output concise, useful, and well-formatted
"""),
markdown=True,
show_tool_calls=True,
storage=JsonStorage(dir_path="tmp/team_sessions_json"),
add_datetime_to_instructions=True,
add_history_to_messages=True,
)
chunks = await agent.arun(message, stream=True)
async for chunk in chunks:
if isinstance(chunk, RunResponse) and chunk.event == RunEvent.run_response:
yield chunk.content
6. 동기 래퍼 함수 추가
Streamlit에서 비동기 스트리밍을 처리하는 헬퍼 함수를 추가해요.
def run_agent_query_sync(message):
queue = Queue()
def run():
asyncio.run(_agent_stream_to_queue(message, queue))
queue.put(None) # Sentinel to end stream
threading.Thread(target=run, daemon=True).start()
while True:
chunk = queue.get()
if chunk is None:
break
yield chunk
async def _agent_stream_to_queue(message, queue):
async for chunk in stream_clickhouse_agent(message):
queue.put(chunk)
7. Streamlit 인터페이스 만들기
Streamlit UI 컴포넌트와 채팅 기능을 추가해요.
st.title("A ClickHouse-backed AI agent")
if st.button("💬 New Chat"):
st.session_state.messages = []
st.rerun()
apply_styles()
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("What is up?"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
response = st.write_stream(run_agent_query_sync(prompt))
st.session_state.messages.append({"role": "assistant", "content": response})
8. 애플리케이션 실행하기
터미널에서 다음 명령을 실행해 ClickHouse AI 에이전트 웹 애플리케이션을 시작할 수 있어요.
uv run \
--with streamlit \
--with agno \
--with anthropic \
--with mcp \
streamlit run app.py --server.headless true
이러면 웹 브라우저가 열리고 http://localhost:8501로 이동해요. 그곳에서 AI 에이전트와 상호작용하며 ClickHouse SQL 플레이그라운드에 있는 예제 데이터셋에 대해 질문할 수 있어요.