A starter template for building AI agent apps with FastAPI + LangGraph backend and Next.js + assistant-ui frontend.
Features:
- LangGraph agent with tool use (web search, web scraping, Python code execution)
- SSE streaming with thinking indicators, tool traces, and status updates
- Thread management with sidebar (create, rename, delete, switch)
- Regeneration support (re-run assistant responses)
- Dark mode support
- Mobile-responsive layout
- Deploy-ready with Render blueprint
┌──────────────────────┐ SSE ┌──────────────────────┐
│ Next.js Frontend │◄────────────►│ FastAPI Backend │
│ │ │ │
│ assistant-ui │ REST API │ LangGraph Agent │
│ LocalRuntime │◄────────────►│ MemorySaver │
│ Thread management │ │ In-memory threads │
└──────────────────────┘ └──────────────────────┘
│
┌──────┴──────┐
│ Tools │
│ - Search │
│ - Scrape │
│ - Python │
└─────────────┘
cd backend
cp .env.example .env
# Edit .env with your API keysConfigure your LLM in app/agent/llms.py — uncomment one of the examples (Anthropic, OpenAI, Google, Groq).
Then install an LLM provider package. For example:
# Pick one:
uv add langchain-anthropic # Claude
uv add langchain-openai # GPT
uv add langchain-google-genai # Gemini
uv add langchain-groq # GroqStart the backend:
uv sync
uv run uvicorn app.main:app --reloadBackend runs at http://localhost:8000. Verify: curl http://localhost:8000/health
cd frontend
cp .env.example .env.local
npm install
npm run devFrontend runs at http://localhost:3000.
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI app, CORS, health check
│ │ ├── agent/
│ │ │ ├── __init__.py # get_agent() singleton
│ │ │ ├── agent.py # Agent class (stream, invoke, thread ops)
│ │ │ ├── state.py # AgentState (MessagesState + user_id)
│ │ │ ├── nodes.py # LLM node with retry logic
│ │ │ ├── graph.py # LangGraph workflow (analyst → tools → loop)
│ │ │ ├── llms.py # ⚙️ Configure your LLM here
│ │ │ ├── context/
│ │ │ │ ├── builder.py # System prompt builder
│ │ │ │ └── prompts/
│ │ │ │ └── system.md # ⚙️ Customize the system prompt
│ │ │ └── tools/
│ │ │ ├── search.py # Tavily web search
│ │ │ ├── python_sandbox.py # Python code execution
│ │ │ └── firecrawl.py # Web scraping
│ │ ├── routers/
│ │ │ ├── chat.py # POST /api/chat (SSE streaming)
│ │ │ └── threads.py # Thread CRUD endpoints
│ │ ├── threads/
│ │ │ └── store.py # In-memory thread store
│ │ ├── schemas/ # Pydantic models
│ │ └── utils/
│ │ └── title_generator.py # Auto-generate thread titles
│ ├── pyproject.toml
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ │ ├── layout.tsx # Root layout
│ │ │ ├── page.tsx # Renders ChatLayout
│ │ │ └── globals.css # Theme + prose styling
│ │ ├── components/
│ │ │ ├── chat/
│ │ │ │ ├── ChatLayout.tsx # Sidebar + Thread
│ │ │ │ ├── RuntimeProvider.tsx # SSE adapter
│ │ │ │ └── Thread.tsx # Chat UI
│ │ │ ├── Sidebar.tsx # Thread list
│ │ │ └── ToastProvider.tsx
│ │ ├── contexts/
│ │ │ ├── ThreadContext.tsx # Thread lifecycle state
│ │ │ └── ThemeContext.tsx # Light/dark theme
│ │ └── utils/
│ │ └── constants.ts # API_BASE_URL
│ └── package.json
├── render.yaml # Render deploy blueprint
└── README.md
Edit backend/app/agent/context/prompts/system.md to change the agent's behavior and instructions.
Add new tools in backend/app/agent/tools/ following the existing pattern:
- Create a new file with a
@tooldecorated async function - Import it in
backend/app/agent/nodes.py - Add it to the
TOOLSlist
Edit backend/app/agent/llms.py to change the LLM provider or model.
Edit the CSS variables in frontend/src/app/globals.css to customize colors.
To add authentication:
- Backend: Add a
dependencies.pywith your auth middleware (e.g., JWT validation) - Backend: Add
Depends(get_user)to router endpoints inchat.pyandthreads.py - Backend: Replace
DEFAULT_USER_IDwith the authenticated user's ID - Frontend: Add your auth provider wrapper in
layout.tsx - Frontend: Add auth token to fetch headers in
RuntimeProvider.tsxandSidebar.tsx
To replace the in-memory store with a database:
- Backend: Add
asyncpg(or your ORM) topyproject.toml - Backend: Create DB models and CRUD functions (replace
threads/store.py) - Backend: Replace
MemorySaverinagent.pywithAsyncPostgresSaverfromlanggraph-checkpoint-postgres - Backend: Add DB initialization in the
lifespanfunction inmain.py
- Push to GitHub
- Go to Render Dashboard → New → Blueprint
- Connect your repo, select
render.yaml - Fill in environment variables
- Deploy
The backend is a standard FastAPI app and the frontend is a standard Next.js app — they can be deployed anywhere that supports Python and Node.js respectively.