Bỏ qua tới nội dung chính
Quay lại tin tức

Xây dựng giao diện người dùng Streamlit cho tác nhân AI LangGraph của tôi

Towards Data Science· Soner Yıldırım· 8/8/2026general

Xây dựng giao diện web sẵn sàng cho sản xuất cho một tác nhân LangGraph có trạng thái Bài viết Xây dựng giao diện người dùng Streamlit cho tác nhân AI LangGraph của tôi xuất hiện lần đầu trên Towards Data Science.

AI Tác nhân Xây dựng giao diện người dùng Streamlit cho tác nhân AI LangGraph của tôi Xây dựng giao diện web sẵn sàng sản xuất cho tác nhân LangGraph có trạng thái Soner Yıldırım Ngày 8/8/2026 6 phút đọc Ảnh của Towfiqu barbhuiya trên Unsplash Trong bài viết trước, tôi đã trình bày cách tôi xây dựng một tác nhân AI dựa trên LangGraph để tự động hóa phiên đặt lịch dịch vụ khách hàng kéo dài 15 phút. Tác nhân xử lý toàn bộ quy trình đặt lịch như một nhân viên dịch vụ khách hàng thực thụ. Đây là một tác nhân dựa trên LangGraph điều phối các hoạt động sau: Phản hồi các truy vấn của khách hàng và hiểu nhu cầu của họ. Tính toán giá dịch vụ và thông báo cho khách hàng. Xử lý việc khách hàng chấp nhận hoặc từ chối. Đề xuất các khung giờ tối ưu. Xác nhận và ghi lại cuộc hẹn. Trong phiên bản đầu tiên của tác nhân, tôi không tập trung nhiều vào phần UI/UX (giao diện người dùng/trải nghiệm người dùng). Tôi chỉ xây dựng một CLI (giao diện dòng lệnh) Python để kiểm tra chức năng của tác nhân. Tác nhân dịch vụ khách hàng chạy hoàn toàn trong terminal. CLI hoạt động tốt để kiểm tra nhưng đó không phải là cách tốt nhất để trình bày trải nghiệm đặt lịch hướng tới khách hàng. Mã nguồn đầy đủ của dự án này có sẵn trên GitHub tại customer-service-agent. Bạn có thể sao chép kho lưu trữ và tự kiểm tra. Trong bài viết này, chúng ta sẽ xây dựng một giao diện người dùng Streamlit sạch sẽ, tương tác trên nền tảng tác nhân LangGraph hiện có. Một lưu ý nhanh về thuật ngữ: Trong suốt bài viết này, tôi sử dụng tác nhân và đồ thị thay thế cho nhau. Trong LangGraph, kiến trúc tác nhân được định nghĩa và thực thi dưới dạng một đối tượng đồ thị trạng thái đã biên dịch, vì vậy chúng về cơ bản có cùng ý nghĩa trong bài viết này. Giao diện người dùng cho tác nhân Về mặt triển khai, Streamlit không khác nhiều so với một CLI Python. Cả hai đều đóng vai trò là một lớp bao bọc cho tác nhân LangGraph. Streamlit, tất nhiên, thân thiện với người dùng hơn nhiều và trông hấp dẫn hơn. Giao diện CLI thu thập đầu vào, gọi đồ thị và in phản hồi. Trang Streamlit sẽ làm tương tự nhưng nó cũng sẽ hiển thị thông tin có cấu trúc được trích xuất từ trạng thái đồ thị như chi tiết đặt lịch hiện tại, báo giá và các nút chấp nhận. Kiến trúc vẫn nằm trong cùng một ứng dụng. Streamlit chỉ trình bày trạng thái cho người dùng và gửi các hành động của người dùng trở lại tác nhân. Trang Streamlit Vì chúng ta đang sử dụng poetry để quản lý các phần phụ thuộc, chúng ta có thể cài đặt streamlit bằng cách: poetry add streamlit Điều này cập nhật cả tệp pyproject.toml và poetry.lock. Sau đó, chúng ta tạo một tệp mới streamlit_app.py. Chúng ta bắt đầu bằng cách nhập trình xây dựng đồ thị, các mô hình và các tiện ích quan sát. from __future__ import annotations import os from datetime import datetime from typing import Any from uuid import uuid4 import streamlit as st from dotenv import load_dotenv from langchain_core.messages import AIMessage, HumanMessage from langchain_openai import ChatOpenAI from customer_service_agent.graph import build_graph from customer_service_agent.models import ( AgentState, BookingDetails, TimeOption, ) from customer_service_agent.observability import ( create_langfuse_handler, flush_langfuse, graph_config, ) Đồ thị tác nhân không bao gồm bất kỳ logic cụ thể nào của Streamlit. Sự tách biệt này rất quan trọng vì nó cho phép chúng ta chạy đồ thị từ CLI, API, WhatsApp hoặc một giao diện người dùng khác sau này. Đồ thị mong đợi một Trạng thái tác nhân được khởi tạo (graph = StateGraph(AgentState)) vì vậy chúng ta thêm đoạn mã sau vào streamlit_app.py: INITIAL_STATE: AgentState = { "messages": [], "booking_details": BookingDetails(), "calculated_price": None, "time_options": [], "selected_slot": None, "status": "gathering_info", } Sau lượt đầu tiên (tức là tin nhắn đầu tiên của khách hàng), bộ kiểm tra của LangGraph sẽ giữ lại trạng thái. Streamlit chạy lại toàn bộ tập lệnh Python mỗi khi người dùng tương tác với một widget (ví dụ: gửi tin nhắn trò chuyện, nhấp vào nút, chọn một cuộc hẹn), do đó không thể sử dụng các biến cục bộ. Để duy trì cuộc hội thoại giữa các lần chạy Streamlit, cần sử dụng session_state. Có thể khởi tạo phiên như sau: def initialize_session() -> None: if "graph" in st.session_state: return llm = ChatOpenAI( model=os.getenv("OPENAI_MODEL", "gpt-4o-mini"), temperature=0, ) handler = create_langfuse_handler() st.session_state.graph = build_graph(llm) st.session_state.handler = handler st.session_state.config = graph_config( str(uuid4()), handler, ) st.session_state.agent_state = INITIAL_STATE.copy() st.session_state.started = False Hàm này trước tiên kiểm tra xem biểu đồ đã được tạo cho phiên trình duyệt này chưa (nếu "graph" trong st.session_state). Nếu không có kiểm tra này, mỗi lần chạy lại Streamlit sẽ thay thế biểu đồ. Hàm graph_config tạo ra một UUID để sử dụng làm thread_id, đây là yêu cầu của LangGraph để xác định một cuộc hội thoại. Nếu một UUID mới được tạo ra trong mỗi lần chạy lại Streamlit, LangGraph sẽ coi mỗi tin nhắn thuộc về một cuộc hội thoại mới. Ngoài ra, tích hợp theo dõi Langfuse cũng nằm trong hàm này. Trình xử lý được lưu để các lệnh gọi biểu đồ tiếp theo có thể sử dụng cùng một cấu hình theo dõi. Sau đó, có hàm _invoke để xử lý đầu vào của người dùng. def _invoke(customer_text: str) -> None: """Gửi một lượt của khách hàng đến biểu đồ và giữ lại trạng thái mới nhất của nó.""" graph_input: dict[str, Any] = {"messages": [HumanMessage(content=customer_text)]} if not st.session_state.started: graph_input.update(INITIAL_STATE) graph_input["messages"] = [HumanMessage(content=customer_text)] st.session_state.started = True try: result = st.session_state.graph.invoke(graph_input, config=st.session_state.config) st.session_state.agent_state = result flush_langfuse(st.session_state.handler) except Exception: st.session_state.started = bool(st.session_state.agent_state.get("messages")) st.error("Trợ lý không thể xử lý yêu cầu đó. Vui lòng thử lại.") Hàm này gửi hành động của khách hàng đến tác nhân LangGraph và lưu trạng thái kết quả cho S.

Nguồn tin: Towards Data Science — Tác giả: Soner Yıldırım. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.