Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Streamlit으로 ClickHouse 기반 AI 에이전트를 구축하는 방법

이 가이드에서는 Streamlit을 사용해 웹 기반 AI 에이전트를 구축하고, ClickHouse의 SQL 플레이그라운드ClickHouse MCP 서버, Agno를 통해 상호작용하는 방법을 알아봅니다.

사전 요구 사항

  • 시스템에 Python이 설치되어 있어야 합니다. uv도 설치되어 있어야 합니다.
  • Anthropic API Key 또는 다른 LLM 제공업체의 API Key가 필요합니다.

다음 단계에 따라 Streamlit 애플리케이션을 만들 수 있습니다.

라이브러리 설치

다음 명령을 실행해 필요한 라이브러리를 설치합니다.

pip install streamlit agno ipywidgets

유틸리티 파일 생성

두 개의 유틸리티 함수를 담은 utils.py 파일을 만드십시오. 첫 번째는 Agno agent의 스트림 응답을 처리하는 비동기 함수 생성기이고, 두 번째는 Streamlit 애플리케이션에 스타일을 적용하는 함수입니다:

utils.pypython
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)

자격 증명 설정

Anthropic API Key를 환경 변수로 설정하세요:

export ANTHROPIC_API_KEY="your_api_key_here"

필요한 라이브러리 가져오기

먼저 기본 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

agent 스트리밍 함수 정의하기

ClickHouse's SQL Playground에 연결하고 응답을 스트리밍하는 기본 agent 함수를 추가합니다:

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

동기 래퍼 함수 추가

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)

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})

애플리케이션 실행

ClickHouse AI agent 웹 애플리케이션을 시작하려면 터미널에서 다음 명령을 실행하십시오:

uv run \
  --with streamlit \
  --with agno \
  --with anthropic \
  --with mcp \
  streamlit run app.py --server.headless true

웹 브라우저가 열리고 http://localhost:8501로 이동합니다. 여기에서 AI 에이전트와 상호작용하며 ClickHouse의 SQL Playground에서 사용할 수 있는 예시 데이터셋에 대해 질문할 수 있습니다.

Navigation