Gradio — самый быстрый способ обернуть вашего LangChain/LangGraph агента в веб-интерфейс. Чат, загрузка файлов, стриминг токенов, кастомные компоненты — всё за 50 строк кода. Разбираем полный стек для продакшен-демо.
Архитектура: Gradio UI → Event Bridge → Agent Core → стриминг ответа обратно пользователю
Gradio 4+ предоставляет компонент ChatInterface, который за 10 строк даёт полноценный чат с историей, аватарками и Markdown-рендерингом. Передаём функцию-обработчик — и чат готов. Ниже подключаем простого LangChain-агента с поисковым инструментом.
import gradio as gr from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain.tools import tool llm = ChatOpenAI(model="gpt-4o", temperature=0) @tool def search_web(query: str) -> str: """Ищет информацию в интернете по запросу.""" return f"Результаты поиска по '{query}': ..." agent = create_openai_functions_agent(llm, [search_web], "Ты — полезный ассистент.") executor = AgentExecutor(agent=agent, tools=[search_web], verbose=True) def respond(message, history): result = executor.invoke({"input": message}) return result["output"] demo = gr.ChatInterface( fn=respond, title="🤖 AI Агент с поиском", description="Задайте вопрос — агент найдёт ответ" ) demo.launch()
Пользователи не любят ждать. Gradio поддерживает генераторы — если функция возвращает yield вместо return, интерфейс показывает промежуточные значения. Для LangGraph-агентов используем astream_events, чтобы ловить каждый LLM-токен и отправлять в UI.
async def stream_agent(message, history): """Стриминг ответа агента токен за токеном.""" partial = "" async for event in graph.astream_events( {"messages": [HumanMessage(content=message)]}, version="v2" ): kind = event["event"] if kind == "on_chat_model_stream": token = event["data"]["chunk"].content partial += token yield partial # Gradio обновляет чат на каждом yield! demo = gr.ChatInterface( fn=stream_agent, title="⚡ Стриминг AI Агент" ) demo.queue() # Включаем очередь для поддержки генераторов demo.launch()
Gradio поддерживает компонент File и MultimodalTextbox. Агент может принимать PDF-документы, изображения для анализа и аудиофайлы. Используем gr.MultimodalTextbox для приёма текста + файлов в одном поле ввода.
def multimodal_agent(message: dict, history): text = message["text"] files = message.get("files", []) contents = [text] for f in files: if f.endswith(".pdf"): import PyPDF2 reader = PyPDF2.PdfReader(f) pdf_text = " ".join(p.extract_text() for p in reader.pages) contents.append(f"[PDF]\n{pdf_text[:3000]}") elif f.endswith((".png", ".jpg")): contents.append({"type": "image_url", "image_url": {"url": f}}) result = llm.invoke(contents) return result.content demo = gr.ChatInterface( fn=multimodal_agent, multimodal=True, title="📎 Мультимодальный AI Агент" ) demo.launch()
ChatInterface удобен, но для сложных агентов нужен полный контроль. gr.Blocks позволяет собрать интерфейс как конструктор: боковая панель с настройками, выбор модели, загрузка системного промпта, счётчик токенов и история сессий через gr.State.
with gr.Blocks(title="AI Agent Studio", theme=gr.themes.Soft()) as demo: session_state = gr.State({"history": [], "token_count": 0}) with gr.Row(): # Левая боковая панель — настройки with gr.Column(scale=1, min_width=240): gr.Markdown("## ⚙️ Настройки") model_choice = gr.Dropdown( choices=["gpt-4o", "claude-3-opus", "gemini-1.5-pro"], value="gpt-4o", label="Модель" ) temperature = gr.Slider(0, 2, value=0.7, label="Temperature") system_prompt = gr.Textbox( value="Ты — полезный ассистент.", label="System Prompt", lines=4 ) token_counter = gr.Markdown("Токенов: **0**") clear_btn = gr.Button("🗑️ Очистить историю") # Правая часть — чат with gr.Column(scale=3): chatbot = gr.Chatbot(type="messages", height=500) msg = gr.Textbox(placeholder="Введите запрос...", container=False) def user_input(message, history, state): state["history"].append({"role": "user", "content": message}) return "", history + [{"role": "user", "content": message}], state def bot_response(history, state, model, temp, sprompt): llm = ChatOpenAI(model=model, temperature=temp) # ... execute agent with streaming ... return history, state msg.submit(user_input, [msg, chatbot, session_state], [msg, chatbot, session_state]) \ .then(bot_response, [chatbot, session_state, model_choice, temperature, system_prompt], [chatbot, session_state]) demo.launch(server_name="0.0.0.0", server_port=7860)
Gradio идеально интегрируется с HuggingFace Spaces — бесплатный хостинг с GPU T4. Добавляем requirements.txt, app.py, и через 2 минуты агент доступен по URL. Для кастомного домена настраиваем CNAME на huggingface.co.
# requirements.txt gradio>=4.0 langchain>=0.3 langchain-openai langgraph python-dotenv httpx # app.py (полный файл) import os import gradio as gr def create_agent_app(): # ... вся логика агента ... demo = gr.ChatInterface(fn=agent_fn, title="AI Agent") return demo if __name__ == "__main__": app = create_agent_app() app.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", 7860))) # Деплой: git push на HF Space — и готово! # huggingface.co/spaces/username/my-agent
Gradio — мощнейший инструмент для быстрого прототипирования и демонстрации AI-агентов. ChatInterface даёт чат за 10 строк, генераторы включают живой стриминг, MultimodalTextbox принимает файлы всех форматов, а Blocks позволяет собрать кастомный интерфейс любой сложности. Деплой на HuggingFace Spaces бесплатный и занимает минуты. Дальше — аутентификация через gr.LoginButton и мониторинг через LangSmith.