Недавно нужно было быстро сделать демо-приложение с GPT для презентации клиенту. За час создал полноценный веб-интерфейс с историей чатов и настройками. Делюсь пошаговым гайдом.
Что получится в итоге
Установка зависимостей
pip install streamlit openai
Шаг 1: Базовый интерфейс
Создайте файл `app.py`:
import streamlit as st
from openai import OpenAI
# Настройка страницы
st.set_page_config(
page_title="GPT Chat App",
page_icon="🤖",
layout="wide"
)
# Инициализация клиента
@st.cache_resource
def init_client():
return OpenAI(
api_key=st.secrets.get("LLMKI_API_KEY", "sk-llmki-ai-..."),
base_url="https://llmki.ru/v1"
)
client = init_client()
Шаг 2: История сообщений
# Инициализация истории в session_state
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"])
Шаг 3: Обработка пользовательского ввода
# Поле для ввода
if prompt := st.chat_input("Введите ваше сообщение..."):
# Добавляем сообщение пользователя
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Отправляем запрос к GPT
with st.chat_message("assistant"):
with st.spinner("Думаю..."):
response = client.chat.completions.create(
model="openai/gpt-4o",
messages=[
{"role": m["role"], "content": m["content"]}
for m in st.session_state.messages
],
temperature=0.7,
max_tokens=1000
)
answer = response.choices[0].message.content
st.markdown(answer)
st.session_state.messages.append({"role": "assistant", "content": answer})
Шаг 4: Выбор модели
# Боковая панель с настройками
with st.sidebar:
st.header("⚙️ Настройки")
model = st.selectbox(
"Выберите модель:",
[
"openai/gpt-4o",
"openai/gpt-4o-mini",
"anthropic/claude-3.5-sonnet",
"anthropic/claude-3-haiku",
"google/gemini-pro"
]
)
temperature = st.slider(
"Температура (креативность):",
min_value=0.0,
max_value=2.0,
value=0.7,
step=0.1
)
max_tokens = st.slider(
"Максимум токенов:",
min_value=100,
max_value=4000,
value=1000,
step=100
)
# Кнопка очистки истории
if st.button("🗑️ Очистить историю"):
st.session_state.messages = []
st.rerun()
Шаг 5: Полный код приложения
import streamlit as st
from openai import OpenAI
from datetime import datetime
# Настройка страницы
st.set_page_config(
page_title="GPT Chat App",
page_icon="🤖",
layout="wide"
)
# Инициализация клиента
@st.cache_resource
def init_client():
api_key = st.secrets.get("LLMKI_API_KEY")
if not api_key:
api_key = st.text_input("Введите API ключ LLM_КИ:", type="password")
return OpenAI(
api_key=api_key,
base_url="https://llmki.ru/v1"
)
client = init_client()
# Боковая панель
with st.sidebar:
st.header("⚙️ Настройки")
model = st.selectbox(
"Модель:",
[
"openai/gpt-4o",
"openai/gpt-4o-mini",
"anthropic/claude-3.5-sonnet",
"anthropic/claude-3-haiku",
"google/gemini-pro"
]
)
temperature = st.slider("Температура:", 0.0, 2.0, 0.7, 0.1)
max_tokens = st.slider("Максимум токенов:", 100, 4000, 1000, 100)
if st.button("🗑️ Очистить историю"):
st.session_state.messages = []
st.rerun()
# Статистика
if st.session_state.messages:
st.divider()
st.metric("Сообщений", len(st.session_state.messages) // 2)
# Главная область
st.title("🤖 GPT Chat Application")
st.caption("Веб-приложение для общения с AI через LLM_КИ API")
# Инициализация истории
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("Введите ваше сообщение..."):
# Добавляем сообщение пользователя
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Получаем ответ от AI
with st.chat_message("assistant"):
with st.spinner("Думаю..."):
try:
response = client.chat.completions.create(
model=model,
messages=[
{"role": m["role"], "content": m["content"]}
for m in st.session_state.messages
],
temperature=temperature,
max_tokens=max_tokens
)
answer = response.choices[0].message.content
st.markdown(answer)
st.session_state.messages.append({"role": "assistant", "content": answer})
# Показываем статистику запроса
usage = response.usage
st.caption(f"📊 Использовано токенов: {usage.total_tokens} (вход: {usage.prompt_tokens}, выход: {usage.completion_tokens})")
except Exception as e:
st.error(f"Ошибка: {str(e)}")
st.info("Проверьте API ключ и баланс на [llmki.ru](https://llmki.ru)")
# Экспорт чата
if st.session_state.messages:
st.divider()
col1, col2 = st.columns(2)
with col1:
if st.button("📥 Экспортировать чат"):
chat_text = "\n\n".join([
f"**{m['role'].upper()}:** {m['content']}"
for m in st.session_state.messages
])
st.download_button(
label="Скачать как .txt",
data=chat_text,
file_name=f"chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
mime="text/plain"
)
Шаг 6: Запуск приложения
streamlit run app.py
Приложение откроется в браузере по адресу `http://localhost:8501`
Дополнительные функции
Подсчет стоимости
Добавьте функцию для расчета стоимости:
def calculate_cost(model, prompt_tokens, completion_tokens):
"""Расчет стоимости запроса"""
# Примерные цены (за 1K токенов)
prices = {
"openai/gpt-4o": {"input": 0.30, "output": 1.20},
"openai/gpt-4o-mini": {"input": 0.15, "output": 0.60},
"anthropic/claude-3.5-sonnet": {"input": 0.30, "output": 1.50},
"anthropic/claude-3-haiku": {"input": 0.08, "output": 0.40},
}
if model in prices:
cost = (
prompt_tokens / 1000 * prices[model]["input"] +
completion_tokens / 1000 * prices[model]["output"]
)
return cost
return 0
# В обработке ответа:
usage = response.usage
cost = calculate_cost(model, usage.prompt_tokens, usage.completion_tokens)
st.caption(f"💰 Стоимость: {cost:.4f}₽")
Системный промпт
Добавьте возможность настройки системного промпта:
with st.sidebar:
system_prompt = st.text_area(
"Системный промпт:",
value="Ты полезный ассистент.",
height=100
)
# При отправке сообщения:
messages = [{"role": "system", "content": system_prompt}]
messages.extend([
{"role": m["role"], "content": m["content"]}
for m in st.session_state.messages
])
Поддержка изображений
Добавьте загрузку изображений:
uploaded_file = st.file_uploader("Загрузить изображение", type=["png", "jpg", "jpeg"])
if uploaded_file:
# Отправка изображения в base64
import base64
image_data = base64.b64encode(uploaded_file.read()).decode()
messages.append({
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}}
]
})
Деплой приложения
Streamlit Cloud (бесплатно)
Heroku / Railway
# Создайте requirements.txt
echo "streamlit==1.28.0
openai==1.3.0" > requirements.txt
# Создайте Procfile
echo "web: streamlit run app.py --server.port=$PORT --server.address=0.0.0.0" > Procfile
Заключение
За час у вас получилось полноценное веб-приложение с ChatGPT-подобным интерфейсом. Streamlit делает создание веб-приложений на Python невероятно простым, а API LLM_КИ дает доступ ко всем топовым моделям через один интерфейс.
Что дальше?
Попробуйте сами и делитесь результатами!