Building a Multi-User AI Agent with FastAPI and Streamlit: From Script to Service

Turn a local AI agent into a reusable multi-user service with FastAPI and Streamlit, featuring per-session memory, streaming responses, and zero API costs.

axonn bots
axonn bots
·3 min read
This tutorial demonstrates how to convert a local AI agent into a multi-user REST API service using FastAPI and Streamlit, with per-session memory via unique user IDs, streaming responses, and local LLM inference through Ollama and Qwen.

Most AI agents start as Python scripts running in a terminal. You type a message, the agent responds, and everything happens in a single session. That works for development, but it breaks down when you want other people or applications to interact with the agent. The natural next step is wrapping the agent in a REST API and adding a lightweight frontend.

The Stack

This tutorial uses FastAPI for the backend, Streamlit for the UI, LangChain v1 for the agent framework, and Ollama with Qwen as the local language model. The agent has two tools: one for checking the current time and another for counting words. Everything runs locally, so there are no per-call API charges.

FastAPI provides the HTTP layer with a single /chat/stream endpoint. Pydantic validates incoming requests. LangChain handles the agent loop, tool calling, and short-term memory. Streamlit sits on top as a thin client that calls the API and displays results.

Multi-User Memory

The critical detail for multi-user support is the user_id sent with each request. It serves as the thread identifier, allowing the checkpointer to keep each user's conversation history separate. The agent is created once at startup and reused across requests, avoiding the overhead of rebuilding the model and tool list every time. Inside the endpoint, the backend uses agent.stream_events() to generate responses as a stream, wrapped in FastAPI's StreamingResponse so the frontend receives output gradually.

The Frontend Experience

The Streamlit app generates a UUID on first load and stores it in session state. When the user sends a message, the app posts it to the API with the session ID and streams the response chunk by chunk, creating a live typing effect. Two browser sessions running side by side on the same endpoint produce different answers to the same question because each session's response is based on its own prior messages.

What Comes Next

The tutorial produces a minimal but functional system: a reusable FastAPI backend, a Streamlit chat interface, per-user conversation history, and streaming responses. Extensions could include authentication, persistent storage, structured logging, monitoring, and more robust deployment. For those who want a polished self-hosted chat UI without building from scratch, projects like Open WebUI and LibreChat provide richer interfaces out of the box.

The core lesson: turning a local script into an API makes the agent reusable, and adding per-session memory makes it multi-user. From there, the same service can grow into a production-ready tool.