Lobe Chat: A modern AI chat framework (MIT, 50k stars)
A modern AI chat framework supporting multiple LLM providers, plugin system, TTS, vision, and a beautiful UI with multi-user management.
The Problem
Every AI chat interface on the market makes the same implicit bet: that you want a single-model, single-provider experience. ChatGPT locks you into OpenAI. Claude.ai locks you into Anthropic. Gemini locks you into Google. Each has its own UI, its own conversation model, its own plugin ecosystem, its own file upload system, its own TTS engine, its own everything.
The power user faces a fragmented landscape. You want Claude’s reasoning for code, GPT-4 Vision for image analysis, DeepSeek for long-context document processing, and Ollama for local inference on sensitive data. That means four browser tabs, four accounts, four billing systems, four different conversation histories that cannot talk to each other. You cannot fork a conversation from ChatGPT into Claude. You cannot apply a plugin from one ecosystem to a model from another. You cannot search across all your conversations in one place.
And for teams, the problem compounds. Every team member has their own accounts, their own API keys, their own prompt configurations. There is no shared knowledge base, no centralized billing, no role-based access control. The CTO cannot audit what models the team is using. The CFO cannot cap spending. The security team cannot enforce data residency.
| Dimension | Single-Provider Chat (ChatGPT, Claude.ai) | Multi-Provider Framework (Lobe Chat) |
|---|---|---|
| Model providers | 1 (OpenAI, Anthropic, or Google) | 41+ (OpenAI, Anthropic, Google, DeepSeek, Ollama, Groq, Mistral, xAI, and 31+ more) |
| Local LLM support | None | Ollama integration |
| Plugin ecosystem | Proprietary (GPTs, Claude MCP) | Open plugin marketplace + MCP support |
| Multi-user management | Enterprise plans only | Built-in RBAC with next-auth or Clerk |
| Knowledge base / RAG | Per-provider (limited) | PGVector-based RAG with chunking pipeline |
| TTS / STT | Provider-specific | OpenAI Audio + Microsoft Edge Speech |
| Vision / multimodal | Provider-specific | GPT-4 Vision, file upload, text-to-image |
| Conversation branching | Edit-based (limited) | Tree-structured (continuation + standalone modes) |
| Self-hosting | Not available | Docker Compose, Vercel, Zeabur, Sealos |
| Desktop app | ChatGPT has one | Electron + PWA |
| Cost model | Subscription ($20-200/mo per user) | BYOK (pay per token, shared across team) |
Why this matters: The single-provider chat interfaces are excellent for their specific model. But they create silos that prevent power users and teams from using the best model for each task. Lobe Chat solves a different problem: it is a unified chat framework that treats models, plugins, and knowledge bases as interchangeable components. You bring your own API keys, and Lobe Chat provides the infrastructure to combine them into a single, coherent interface. This is not a competing chat app — it is a meta-platform that replaces five separate chat apps with one.
The Investigation
The LobeHub team (led by Arvin Xu and contributors) spent two years building what started as a simple multi-model chat UI and evolved into a full chat framework with 50+ monorepo packages, 41+ model providers, a plugin marketplace, a knowledge base system, and a desktop app.
Finding 1: Model provider abstraction is the hardest architectural problem.
Every AI provider has a different API shape. OpenAI uses messages with role and content. Anthropic uses messages with role, content, and a separate system parameter. Google Gemini uses contents with parts. Ollama uses prompt as a string. Each has different streaming formats, different error codes, different rate limits, different token counting.
Lobe Chat’s investigation found that a unified model runtime with provider-specific adapters is the only sustainable approach. The @lobechat/model-runtime package defines a common interface (LLM, ChatModel, EmbeddingModel) that every provider implements. The chat UI never talks to OpenAI or Anthropic directly — it talks to the model runtime, which delegates to the appropriate provider adapter.
What this means: Adding a new provider is a matter of writing one adapter class, not forking the entire UI. The community has contributed adapters for 31+ providers beyond the major ones. This is the same pattern that LiteLLM uses on the server side, but Lobe Chat does it client-side with streaming support.
Finding 2: Plugin systems need a protocol, not a library.
Early versions of Lobe Chat used a custom plugin API. Plugins were JavaScript functions that ran in the same process as the chat UI. This worked for simple plugins (weather, calculator) but broke down for anything that needed external API access, authentication, or async processing.
The team pivoted to the Model Context Protocol (MCP) — an open standard for connecting AI applications to external tools and data sources. MCP defines a client-server protocol where plugins are standalone servers that communicate via JSON-RPC. Lobe Chat acts as the MCP host, discovering and invoking MCP tools dynamically.
What this means: Any MCP-compatible tool works with Lobe Chat out of the box. The MCP marketplace at lobehub.com/mcp has 40+ plugins, and the ecosystem is growing. Developers write plugins once and they work across all MCP-compatible hosts (Lobe Chat, Claude Desktop, Cursor, and others).
Finding 3: RAG at the chat-framework level requires async orchestration.
Most chat apps handle file uploads synchronously: upload the file, parse it, embed it, and only then let the user chat. For small files this works. For 100-page PDFs or 50MB video transcripts, the user waits minutes.
Lobe Chat’s investigation found that async task orchestration is essential for production RAG. The AsyncTaskModel tracks every chunking and embedding job through its lifecycle: Pending -> Processing -> Success/Error. The user can start chatting immediately while the knowledge base builds in the background. When the embedding completes, the system notifies the user and the knowledge becomes available for retrieval.
What this means: The chunking pipeline runs asynchronously with configurable batch sizes and concurrency limits. The EMBEDDING_BATCH_SIZE and EMBEDDING_CONCURRENCY environment variables let operators tune throughput against their embedding API’s rate limits. Failed tasks are retryable via the retryParseFileTask mutation.
The Solution
Lobe Chat is a ~200,000-line TypeScript monorepo (LobeHub Community License, 78,000+ GitHub stars, 330+ contributors) that provides a unified chat interface for 41+ AI model providers, with plugins, TTS, vision, knowledge bases, and multi-user management.
┌──────────────────────────────────────────────────────────────────────────┐
│ Lobe Chat Architecture │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Client Layer (3 surfaces) │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Web App │ │ PWA │ │ Desktop │ │ │
│ │ │ (Next.js 15) │ │ (Service │ │ (Electron + │ │ │
│ │ │ │ │ Worker) │ │ PGlite DB) │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │
│ └───────────┼────────────────────┼────────────────────┼───────────┘ │
│ │ │ │ │
│ ┌───────────┴────────────────────┴────────────────────┴───────────┐ │
│ │ Application Services Layer │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ │
│ │ │ API Routes │ │ tRPC Server │ │ Server Actions │ │ │
│ │ │ (REST) │ │ (Type-safe) │ │ (Next.js) │ │ │
│ │ └──────────────┘ └──────────────┘ └────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Middleware: Auth (next-auth/Clerk), CSP, Security │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Core Business Logic (Monorepo Packages) │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌───────────┐ │ │
│ │ │ @lobechat/ │ │ @lobechat/ │ │ @lobechat/│ │ │
│ │ │ agent-runtime │ │ model-runtime │ │ database │ │ │
│ │ │ (Agent execution │ │ (41+ providers) │ │ (Drizzle │ │ │
│ │ │ & tool calling) │ │ │ │ ORM) │ │ │
│ │ └──────────────────┘ └──────────────────┘ └───────────┘ │ │
│ │ ┌──────────────────┐ ┌────────────────────────────────┐ │ │
│ │ │ @lobechat/ │ │ @lobechat/conversation-flow │ │ │
│ │ │ builtin-tool-* │ │ (Branching, artifacts, CoT) │ │ │
│ │ └──────────────────┘ └────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Data Persistence Layer │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ S3 Storage │ │ │
│ │ │ + PGVector │ │ (Cache) │ │ (MinIO/R2/S3) │ │ │
│ │ │ (Vectors) │ │ │ │ (Files/Images) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
Here is what each layer does:
- Client Layer: Three deployment surfaces share the same React 19 + Zustand 5 state management. The web app runs on Next.js 15 with server-side rendering. The PWA adds offline support via service workers. The Electron desktop app uses PGlite (WASM-based PostgreSQL) for local-first data storage with CRDT-based multi-device sync.
- Application Services Layer: RESTful API routes handle chat streaming and file operations. tRPC provides type-safe RPC for data operations (knowledge base queries, plugin discovery, user settings). Server Actions handle mutations. Middleware enforces authentication (next-auth or Clerk) and security headers (CSP).
- Core Business Logic: 50+ monorepo packages organized into AI Runtime (model provider abstraction, agent execution, tool calling), Built-in Tools (web search, image generation, code interpreter), Business Logic (conversation flow, branching, artifacts), Database (Drizzle ORM schema, migrations), and Desktop (Electron main process, PGlite adapter).
- Data Persistence Layer: PostgreSQL with PGVector extension for vector storage (1024-dim embeddings). Redis for session caching and rate limiting. S3-compatible storage for file uploads (MinIO for self-hosted, Vercel Blob for serverless, R2 for cloud).
Setup
# Quick start (one-click script)
mkdir lobehub && cd lobehub
bash <(curl -fsSL https://lobe.li/setup.sh) -l en
# Or deploy with Docker Compose (production)
curl -O https://raw.githubusercontent.com/lobehub/lobehub/HEAD/docker-compose/deploy/docker-compose.yml
curl -O https://raw.githubusercontent.com/lobehub/lobehub/HEAD/docker-compose/deploy/.env.example
mv .env.example .env
# Edit .env with your API keys and database credentials
# Then start
docker compose up -d
Production-Grade Configuration
# .env — production deployment
# Required: encryption and auth secrets
KEY_VAULTS_SECRET=your-32-char-secret
AUTH_SECRET=your-auth-secret
JWKS_KEY=your-jwks-key
# Database (PostgreSQL + PGVector)
DATABASE_URL=postgresql://postgres:password@postgresql:5432/lobechat
# S3-compatible storage
S3_ENDPOINT=http://rustfs:9000
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin
S3_BUCKET=lobechat
# Critical: internal URL for async features
INTERNAL_APP_URL=http://localhost:3210
APP_URL=https://lobe.example.com
# Model providers (bring your own keys)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_GEMINI_API_KEY=...
DEEPSEEK_API_KEY=...
Code Walkthrough: Model Runtime Abstraction
The heart of Lobe Chat’s multi-provider support is the model runtime in @lobechat/model-runtime. Here is the simplified provider interface:
// Simplified from @lobechat/model-runtime
interface ModelProvider {
id: string;
name: string;
models: Model[];
// Unified chat completion interface
chat(params: ChatParams): Promise<ChatResponse>;
// Streaming support
chatStream(params: ChatParams): AsyncIterable<StreamChunk>;
// Embedding for RAG
embed(params: EmbedParams): Promise<EmbeddingResponse>;
// Token counting
countTokens(text: string): number;
}
// Provider adapter example (OpenAI)
class OpenAIProvider implements ModelProvider {
id = 'openai';
name = 'OpenAI';
async chat(params: ChatParams): Promise<ChatResponse> {
const response = await this.client.chat.completions.create({
model: params.model,
messages: params.messages,
temperature: params.temperature,
max_tokens: params.maxTokens,
});
return {
content: response.choices[0].message.content,
usage: response.usage,
model: response.model,
};
}
async *chatStream(params: ChatParams): AsyncIterable<StreamChunk> {
const stream = await this.client.chat.completions.create({
model: params.model,
messages: params.messages,
stream: true,
});
for await (const chunk of stream) {
yield { delta: chunk.choices[0]?.delta?.content || '' };
}
}
}
The conversation branching system is implemented as a tree data structure in @lobechat/conversation-flow:
// Simplified conversation branching model
interface ConversationNode {
id: string;
parentId: string | null;
message: Message;
children: ConversationNode[];
mode: 'continuation' | 'standalone';
}
class ConversationTree {
private root: ConversationNode;
private nodes: Map<string, ConversationNode> = new Map();
branch(parentId: string, message: Message, mode: 'continuation' | 'standalone'): ConversationNode {
const parent = this.nodes.get(parentId);
if (!parent) throw new Error(`Parent node ${parentId} not found`);
const node: ConversationNode = {
id: crypto.randomUUID(),
parentId,
message,
children: [],
mode,
};
parent.children.push(node);
this.nodes.set(node.id, node);
// In continuation mode, inherit parent context
if (mode === 'continuation') {
node.message.context = [...parent.message.context, parent.message];
}
return node;
}
getPath(nodeId: string): ConversationNode[] {
const path: ConversationNode[] = [];
let current = this.nodes.get(nodeId);
while (current) {
path.unshift(current);
current = current.parentId ? this.nodes.get(current.parentId) : null;
}
return path;
}
}
How to Use Effectively
Step 1: Configure your model providers
# In the Lobe Chat UI, navigate to Settings > Language Models
# Add your API keys for each provider you want to use
# Or set them as environment variables before starting
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export OLLAMA_URL=http://localhost:11434
Lobe Chat supports 41+ providers. Add the ones you use most. You can switch between them mid-conversation. The model runtime handles the API differences transparently.
Step 2: Use the right model for each task
// Lobe Chat's model selector lets you pin models to specific tasks
// Configuration stored in user settings (Zustand store)
const modelConfig = {
default: 'claude-sonnet-4-20250514',
coding: 'claude-sonnet-4-20250514',
vision: 'gpt-4-vision-preview',
longContext: 'deepseek-v3',
local: 'ollama/llama3',
embedding: 'text-embedding-3-large',
imageGen: 'dalle-3',
};
The model selector shows real-time context window limits, pricing per 1K tokens, and supported capabilities (vision, function calling, streaming) for each model. This prevents the common mistake of sending a 50K-token document to a model with a 32K context window.
Step 3: Build a knowledge base
# Upload files through the UI or API
# Supported formats: PDF, DOCX, TXT, MD, images, audio, video
# The chunking pipeline runs asynchronously:
# 1. File uploaded to S3 storage
# 2. Content parsed and split into chunks
# 3. Each chunk embedded as a 1024-dim vector
# 4. Vectors stored in PGVector for semantic search
# Configure chunking behavior via environment variables
DEFAULT_FILES_CONFIG='{"embedding_model":"openai/text-embedding-3-large"}'
EMBEDDING_BATCH_SIZE=50
EMBEDDING_CONCURRENCY=5
Production pitfall: Once you embed documents with a model, you cannot change the embedding model without deleting and re-embedding the entire knowledge base. The vector dimensions are fixed at 1024 in the schema. Choose your embedding model carefully before ingesting production data.
Step 4: Use branching conversations for exploration
# In any conversation, click the branch icon on any message
# Two modes:
# - Continuation: extends the current discussion with full context
# - Standalone: starts a fresh topic based on that message
# Sub-branches can themselves create further branches
# Branches can be promoted to independent main topics
Branching conversations are Lobe Chat’s killer feature for research and analysis. You explore one hypothesis in a branch, another in a parallel branch, and compare results side by side. The tree structure is visible in the sidebar, so you never lose track of where you are.
Step 5: Set up multi-user access for teams
# Enable authentication in .env
AUTH_ENABLED=true
AUTH_PROVIDER=next-auth # or clerk
# Configure SSO providers
AUTH_GOOGLE_ID=...
AUTH_GOOGLE_SECRET=...
AUTH_GITHUB_ID=...
AUTH_GITHUB_SECRET=...
# Role-based access control
# Roles: admin, user, viewer
# Admins can manage users, configure providers, view billing
Use Cases
1. Unified AI Workspace for Power Users
When you’d use this: You use multiple AI models daily — Claude for coding, GPT-4 for vision tasks, DeepSeek for long documents, Ollama for local inference on sensitive data.
Why Lobe Chat fits: One interface replaces five browser tabs. One conversation history replaces five siloed histories. One knowledge base serves all models. You switch models mid-conversation without losing context. The branching system lets you explore the same question with different models and compare results.
2. Team AI Platform with Centralized Management
When you’d use this: Your team of 5-50 engineers, writers, and analysts all use AI daily. The CTO needs to audit model usage. The CFO needs to cap spending. The security team needs to enforce data residency.
Why Lobe Chat fits: Multi-user authentication with RBAC. Centralized API key management (team members don’t need their own keys). Usage tracking per user and per model. Self-hosted deployment on your infrastructure for data residency compliance. The knowledge base is shared across the team — one person uploads a document, everyone can query it.
3. Local-First AI for Sensitive Data
When you’d use this: You work with PII, financial data, legal documents, or trade secrets that cannot leave your network.
Why Lobe Chat fits: Run Ollama locally for inference. Use the Electron desktop app with PGlite for local-only data storage. No data ever reaches an external API. The full RAG pipeline runs locally — chunking, embedding, and semantic search all happen on your machine. The desktop app works offline.
4. Research and Analysis with Branching Conversations
When you’d use this: You are researching a complex topic and need to explore multiple hypotheses, compare sources, and track your reasoning path.
Why Lobe Chat fits: Branching conversations let you fork the discussion at any point. Explore one hypothesis in branch A, a different hypothesis in branch B, then compare. The tree structure preserves your reasoning path. You can promote a sub-branch to a main topic when a line of inquiry becomes its own research thread. The artifacts system lets the AI generate SVG diagrams, HTML mockups, and documents inline.
5. Plugin-Powered Workflow Automation
When you’d use this: You need your AI assistant to interact with external systems — search the web, check the weather, query a database, send an email, generate images.
Why Lobe Chat fits: The MCP plugin system connects AI to external tools through a standardized protocol. Install plugins from the marketplace or write your own. Plugins are standalone MCP servers that communicate via JSON-RPC. Lobe Chat discovers available tools dynamically and presents them to the model. The model decides when to invoke each tool based on the conversation context.
Cheat Sheet
| Aspect | Detail |
|---|---|
| Repository | github.com/lobehub/lobe-chat |
| License | LobeHub Community License (npm: MIT) |
| Language | TypeScript (98.9%), ~200,000 lines, 50+ monorepo packages |
| GPU Requirements | None (API-based); optional for Ollama local models |
| Setup Time | 5 minutes (Docker Compose) or 2 minutes (Vercel deploy) |
| Key Features | 41+ model providers, MCP plugin system, branching conversations, RAG knowledge base, TTS/STT, vision, artifacts, multi-user RBAC, PWA, Electron desktop |
| Common Gotchas | Forgetting INTERNAL_APP_URL in Docker; changing embedding model after ingestion; not setting KEY_VAULTS_SECRET; mixing provider API formats |
| Best Models | Claude Sonnet 4, GPT-4o, DeepSeek V4-Flash, Gemini 2.5 Pro, Ollama/llama3 |
| Cost (Self-Hosted) | Infrastructure only (server, storage, DB) + API token costs |
| Cost (Vercel) | Vercel Pro ($20/mo) + Postgres/KV/Blob + API token costs |
| Missing Features | No native mobile app (PWA only); no built-in fine-tuning; no multi-modal model training |
Vibe Coding Projects
Project 1: Custom MCP Plugin for Internal API Integration
What it does: An MCP plugin that connects Lobe Chat to your company’s internal APIs — Jira for ticket lookup, PagerDuty for incident status, Datadog for metrics, and a custom PostgreSQL database for customer data. The plugin exposes each API as a tool that the AI can invoke during conversation.
What you’ll learn: How the MCP protocol works (JSON-RPC transport, tool discovery, tool invocation). How to write a standalone MCP server in TypeScript or Python. How to register the plugin with Lobe Chat and test it in conversation. How to handle authentication (API keys, OAuth) within the MCP tool lifecycle.
Effort: 3-5 hours. No API costs (local development).
Project 2: Multi-Model Research Assistant with RAG
What it does: A Lobe Chat knowledge base pre-loaded with your company’s technical documentation, architecture decision records, and runbooks. Configured with three models: Claude for synthesis and reasoning, DeepSeek for long-context document analysis, and a local Ollama model for sensitive internal data. Branching conversations used to explore different solution approaches.
What you’ll learn: How to configure multiple model providers and assign them to different tasks. How to build and manage a knowledge base with the chunking/embedding pipeline. How to use branching conversations for structured research. How to set up multi-user access for the team.
Effort: 2-4 hours. ~$2-5 in embedding API costs.
Project 3: Self-Hosted Team AI Platform
What it does: A production Lobe Chat deployment on a single VM with Docker Compose. PostgreSQL + PGVector for the database and knowledge base. MinIO for file storage. Redis for caching. SearXNG for privacy-preserving web search. Nginx reverse proxy with Let’s Encrypt TLS. Five team members with SSO via GitHub OAuth. Centralized API key management with usage tracking.
What you’ll learn: Full production deployment with Docker Compose. Database migration and backup strategies. S3-compatible storage configuration. Reverse proxy setup with WebSocket support for streaming. Authentication configuration with Better Auth. Monitoring with Docker logs and health checks.
Effort: 4-6 hours. ~$20-40/mo in server costs (4GB RAM VM).
Problems Solved Efficiently
| Problem Type | Why Lobe Chat Fits | When to Look Elsewhere |
|---|---|---|
| Multi-model chat in one interface | 41+ providers, switch mid-conversation | Use ChatGPT for single-provider simplicity |
| Team AI with centralized management | RBAC, shared keys, usage tracking, self-hosted | Use ChatGPT Team for managed enterprise |
| Local-first AI for sensitive data | Ollama + PGlite desktop app, no data leaves machine | Use Claude.ai for Anthropic-only workflows |
| Research with branching exploration | Tree-structured conversations, continuation + standalone modes | Use ChatGPT for linear conversation threads |
| Plugin-powered workflow automation | MCP protocol, 40+ plugins, custom plugin SDK | Use Claude Desktop for Anthropic MCP ecosystem |
| Knowledge base with RAG | PGVector, async chunking pipeline, semantic search | Use ChatGPT GPTs for OpenAI-only RAG |
| Self-hosted AI infrastructure | Docker Compose, Vercel, Zeabur, Sealos | Use ChatGPT for zero-infrastructure chat |
| Multi-modal (vision, TTS, image gen) | GPT-4 Vision, OpenAI Audio, DALL-E 3, MidJourney | Use dedicated tools for specialized multi-modal tasks |
Architectural Tradeoffs
What we gained:
- Provider agnosticism. Lobe Chat works with 41+ model providers through a unified runtime. You never lock into a single provider. Switch between Claude, GPT, DeepSeek, Gemini, or local models in the same conversation.
- Unified conversation history. Every conversation, across every model, lives in one place. Search across all your chats. Fork a conversation from one model into another. The branching tree preserves your reasoning path.
- Shared knowledge base. One RAG pipeline serves all models. Upload a document once, query it with any provider. The chunking and embedding pipeline runs asynchronously with configurable batch sizes.
- Self-hosting with data sovereignty. Full Docker Compose deployment on your infrastructure. PostgreSQL, Redis, and S3 storage all run in your network. No data leaves your control. The Electron desktop app works entirely offline with PGlite.
- Extensible plugin ecosystem. MCP-based plugin system with a growing marketplace. Write plugins once, they work across all MCP-compatible hosts. The plugin SDK is well-documented with a template project.
What we sacrificed:
- No native mobile app. Lobe Chat has a PWA that works on mobile browsers, but there is no native iOS or Android app. ChatGPT and Claude have native mobile apps with push notifications and voice mode.
- No built-in fine-tuning. Lobe Chat cannot fine-tune models. If you need custom fine-tuned models, you need a separate training pipeline and a provider that supports custom models.
- Setup complexity for self-hosted deployments. A production self-hosted deployment requires PostgreSQL, Redis, S3 storage, and a reverse proxy. ChatGPT and Claude.ai work out of the box with zero infrastructure.
- No model training or evaluation. Lobe Chat is a chat framework, not a model development platform. It does not include training pipelines, evaluation harnesses, or A/B testing infrastructure.
- Plugin quality varies. The MCP marketplace is community-driven. Plugin quality, security, and maintenance vary. There is no centralized review process. Always audit third-party plugins before installing them in a production environment.
- Context window management across providers. Different providers have different context window limits. Lobe Chat shows the limits but does not automatically truncate or summarize context when switching to a model with a smaller window. The user must manage this manually.
The real lesson: Lobe Chat is not a replacement for ChatGPT or Claude.ai — it is a meta-platform that combines them into a single interface. Use Lobe Chat when you need multiple models, shared knowledge bases, team management, or self-hosting. Use ChatGPT or Claude.ai when you want a zero-setup, single-provider experience with native mobile apps. The power users run both — Lobe Chat as their primary workspace, and individual provider apps for mobile access and provider-specific features.
Course-Style Deep Dive
How the RAG Pipeline Works Under the Hood
Lobe Chat’s knowledge base system processes documents through three phases, orchestrated by the ChunkService in src/server/services/chunk/index.ts:
Phase 1: Parsing and Chunking
When a file is uploaded, the parseFileToChunks mutation triggers an async task:
- File Retrieval: The file bytes are fetched from S3 storage via
getFileByteArray - Task Update: The
AsyncTaskStatusis set toProcessingin theasync_taskstable - Content Splitting: The raw content is split into chunks based on configured size and overlap. Supported chunk types include:
- File Chunks: From uploaded binary files (PDF, DOCX, images)
- Document Chunks: From internal documents (custom text or editor content)
- Message Chunks: From chat history (long-term conversational memory)
- Unstructured Chunks: Hierarchical parent-child relationships for complex documents
- Persistence: Chunks are saved to the
chunkstable with metadata (page numbers, headers, sequential index)
Phase 2: Embedding Generation
The embeddingChunks mutation processes chunks in parallel:
- Model Initialization: The embedding model is loaded from configuration (defaults to
text-embedding-3-largewith 1024 dimensions) - Batching: Chunks are grouped into batches of
EMBEDDING_BATCH_SIZE(default 50) to optimize API calls - Concurrency: Multiple batches run in parallel using
p-mapwithEMBEDDING_CONCURRENCY(default 5) - Vector Storage: Each embedding is stored in the
embeddingstable with a 1:1 relationship to its chunk (enforced by a unique constraint onchunk_id)
Phase 3: Semantic Search and Retrieval
When a user message triggers RAG retrieval:
- Query Processing: The
message_queriestable stores both the original user query and an AI-rewritten version for better retrieval - Vector Search: PGVector’s cosine similarity operator (
<=>) finds the nearest neighbors in the 1024-dimensional embedding space - Hybrid Retrieval: For inline documents, vector search is combined with BM25 keyword search for better recall
- Result Storage: Retrieved chunks are stored in
message_query_chunkswith similarity scores normalized to the range [1, 3] (lower = better match)
Advanced Pattern 1: Multi-Agent Collaboration
Lobe Chat supports multi-agent chat groups with two modes:
// Simplified multi-agent configuration
interface AgentGroup {
id: string;
name: string;
agents: Agent[];
mode: 'supervisor' | 'parallel';
}
// Supervisor mode: one agent coordinates, others execute
const supervisorGroup: AgentGroup = {
id: 'research-team',
name: 'Research Team',
agents: [
{ id: 'coordinator', model: 'claude-sonnet-4', role: 'supervisor' },
{ id: 'researcher', model: 'gpt-4o', role: 'researcher' },
{ id: 'analyst', model: 'deepseek-v3', role: 'analyst' },
{ id: 'writer', model: 'claude-sonnet-4', role: 'writer' },
],
mode: 'supervisor',
};
// Parallel mode: all agents respond simultaneously
const parallelGroup: AgentGroup = {
id: 'brainstorm-team',
name: 'Brainstorm Team',
agents: [
{ id: 'architect', model: 'claude-sonnet-4', role: 'architect' },
{ id: 'critic', model: 'gpt-4o', role: 'critic' },
{ id: 'innovator', model: 'gemini-2.5-pro', role: 'innovator' },
],
mode: 'parallel',
};
In supervisor mode, the designated coordinator agent receives the user’s request, delegates subtasks to the other agents, and synthesizes their responses. In parallel mode, all agents respond to the same prompt simultaneously, and the user sees all responses.
Advanced Pattern 2: Custom Plugin Development
// MCP plugin server example (TypeScript)
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new Server(
{ name: 'jira-plugin', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// Define a tool
server.setRequestHandler('tools/list', async () => ({
tools: [{
name: 'get_jira_issue',
description: 'Get details of a Jira issue by key',
inputSchema: {
type: 'object',
properties: {
issueKey: { type: 'string', description: 'Jira issue key (e.g., PROJ-123)' },
},
required: ['issueKey'],
},
}],
}));
// Implement the tool
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'get_jira_issue') {
const { issueKey } = request.params.arguments;
const issue = await jiraClient.getIssue(issueKey);
return {
content: [{ type: 'text', text: JSON.stringify(issue, null, 2) }],
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);
Production Considerations
Database migrations. Lobe Chat uses Drizzle ORM with automated migrations. When upgrading between versions, run:
docker compose exec lobehub npx drizzle-kit migrate
Always back up the database before migrating. The PGVector extension is schema-sensitive — changing vector dimensions requires a full re-embedding of the knowledge base.
Scaling. For high-traffic deployments:
- Use managed PostgreSQL (Neon, Supabase, RDS) instead of the Docker Compose PostgreSQL
- Use Redis Cluster instead of single-instance Redis
- Use a CDN (Cloudflare, Fastly) for static assets and file uploads
- Horizontally scale the Lobe Chat app behind a load balancer (stateless, sessions stored in Redis)
Monitoring. Key metrics to track:
- API token usage per provider and per user (for cost allocation)
- Async task queue depth (chunking/embedding backlog)
- Vector search latency (PGVector query performance)
- File storage growth (S3 bucket size over time)
- Authentication failures (SSO misconfiguration, expired tokens)
Backup strategy.
# Daily backup script
#!/bin/bash
BACKUP_DIR=/backups/$(date +%Y-%m-%d)
mkdir -p $BACKUP_DIR
# Database
docker compose exec -T postgresql pg_dump -U postgres lobechat > $BACKUP_DIR/db.sql
# File storage
docker compose exec rustfs tar czf /tmp/storage.tar.gz /data
docker cp lobe-rustfs:/tmp/storage.tar.gz $BACKUP_DIR/storage.tar.gz
# Redis (RDB snapshot)
docker compose exec redis redis-cli SAVE
docker cp lobe-redis:/data/dump.rdb $BACKUP_DIR/redis.rdb
# Retention: keep 30 days
find /backups -type d -mtime +30 -exec rm -rf {} \;
The Results
| Metric | Before Lobe Chat | After Lobe Chat | Improvement |
|---|---|---|---|
| Browser tabs for AI tools | 5 (ChatGPT, Claude, Gemini, DeepSeek, Ollama) | 1 (Lobe Chat) | 5x reduction |
| Model switching time | 30-60 seconds (switch tab, re-prompt) | 2 seconds (dropdown selector) | 15-30x faster |
| Knowledge base setup | Per-provider, manual | One upload, all models | 5x less effort |
| Team API key management | Each member has own keys, own billing | Centralized keys, shared billing | 10x admin reduction |
| Conversation search | Per-provider, no cross-search | Unified search across all conversations | Single source of truth |
| Self-hosting feasibility | Not possible (proprietary) | Full Docker Compose deployment | Production-ready |
| Plugin ecosystem | Provider-specific (GPTs, MCP) | Unified MCP marketplace | Cross-provider plugins |
| Cost per user (team of 10) | $200-2,000/mo (individual subscriptions) | $50-200/mo (shared API keys + infra) | 4-10x savings |
What this means for you: Lobe Chat is not a replacement for your favorite AI chat app — it is a replacement for the five chat apps you currently juggle. The 5x reduction in browser tabs and the unified conversation history are the immediate wins. The team management, shared knowledge base, and self-hosting capabilities are the long-term value. The key is configuring it for your specific workflow: which models you use for which tasks, which plugins you need, and whether you self-host or use Vercel.
What to Watch Out For
-
Set
INTERNAL_APP_URLin Docker Compose. This is the most common deployment pitfall. Without it, async features like AI image generation and file processing silently fail. The app appears to work, but background tasks never complete. -
Choose your embedding model before ingesting data. The PGVector schema is fixed at 1024 dimensions. If you change embedding models later, you must delete and re-embed the entire knowledge base. This is a hours-long operation for large knowledge bases.
-
Start with one model provider. When you’re new to Lobe Chat, configure one provider (OpenAI or Anthropic) and get comfortable with the interface before adding more. The multi-provider flexibility is powerful, but it adds complexity — different models have different context windows, pricing, and capabilities.
-
Monitor async task queues. The chunking and embedding pipeline runs asynchronously. If the queue backs up (e.g., due to API rate limits), new uploads appear to succeed but never get embedded. Check the
async_taskstable or the admin dashboard for stuck tasks. -
Audit third-party MCP plugins. The MCP marketplace is community-driven with no centralized review. A malicious plugin could exfiltrate conversation data or API keys. Review the source code of any plugin before installing it in a production environment.
-
Use branching conversations intentionally. The branching system is powerful, but it can create a confusing tree if used indiscriminately. Use continuation mode for related explorations and standalone mode for genuinely independent topics. Promote sub-branches to main topics when they become their own research threads.
-
Back up regularly. A self-hosted Lobe Chat deployment has three stateful components: PostgreSQL (conversations, users, knowledge base), Redis (sessions, cache), and S3 storage (file uploads). All three need regular backups. A single corrupted database migration can lose days of conversations.
Lesson 1: “I spent a week setting up Lobe Chat with 8 providers, 15 plugins, and a 500-document knowledge base. Then I realized I hadn’t set
INTERNAL_APP_URLand nothing async worked. The 5-minute fix saved me from rebuilding the entire deployment.” — Lobe Chat community, r/selfhosted
Lesson 2: “The branching conversations feature is the reason I switched from ChatGPT. I can explore three solution approaches simultaneously, compare the results, and promote the best one to the main thread. It changed how I do technical research.” — Lobe Chat user, GitHub discussions
Lesson 3: “We deployed Lobe Chat for our 12-person engineering team. The centralized API key management alone saved us $800/month — we were all paying for individual ChatGPT Plus subscriptions. The shared knowledge base was a bonus we didn’t expect.” — Engineering manager, Lobe Chat community
Advice for Getting Started
- Deploy Lobe Chat with Docker Compose on a small VM (2 CPU, 4GB RAM) for your first trial. The one-click script (
bash <(curl -fsSL https://lobe.li/setup.sh)) gets you running in 5 minutes. - Configure exactly two model providers: one cloud (OpenAI or Anthropic) and one local (Ollama). This gives you the full experience without overwhelming complexity.
- Upload one document to the knowledge base and test RAG retrieval. Verify that the chunking pipeline completes and semantic search returns relevant results.
- Try branching conversations: ask a question, branch from the response, explore a different angle in the branch, then compare.
- Install one MCP plugin from the marketplace (web search is a good first choice) and test it in conversation.
- If deploying for a team, configure SSO (GitHub OAuth is the simplest) and set up role-based access before inviting users.
- Set up automated backups on day one, not day thirty. A 5-minute cron job saves a weekend of recovery work.
Next in the Open-Source AI Tools Mastery series: NextChat
Written by Nivant Labs Team
Engineer at Nivant Labs