Chatwoot + Dify — the classic AI support combo
Chatwoot as the omnichannel inbox and human-in-the-loop surface; Dify as the AI brain and knowledge base. The safest starter combo for SMB teams.
- Scenario
- SMB SaaS / e-commerce teams replacing Intercom while keeping AI controllable
- Monthly cost
- $40 - $120 (excluding LLM tokens)
- Difficulty
- Medium
What this combo solves#
Four pain points cluster together for most SMB teams that want self-hosted AI support:
- SaaS is expensive — Intercom AI seats break $20k/yr easily
- Existing platforms are not “AI-native” — bolting LLMs onto traditional ticketing is painful
- Channels are scattered — web, WhatsApp, email, WeChat live in silos
- Vendor lock-in is unacceptable — teams want to swap models and KBs on demand
Chatwoot + Dify is the consensus 2026 “default starter” — sane licensing, mature components, ample docs.
Architecture#
Component roles#
| Component | Role | Required |
|---|---|---|
| Chatwoot | Channels, agent desk, ticketing | Yes |
| Dify | AI brain — prompts, KB, workflow, model governance | Yes |
| PostgreSQL | Shared relational DB (separate databases recommended) | Yes |
| Redis | Queues, cache | Yes |
| Weaviate | Vector store (or pgvector / Milvus) | Yes |
| Sidekiq worker | Chatwoot async tasks (in the image) | Yes |
| n8n | Business orchestration (orders, CRM writes) | Optional |
| Postmark / SES | Email delivery | Strongly recommended |
Hardware and cost#
Test / POC (single host)#
| Resource | Count | Unit (mo) | Notes |
|---|---|---|---|
| 4 vCPU / 8 GB / 80 GB VPS | 1 | $20-40 | Hetzner CPX31 / DigitalOcean s-4vcpu-8gb |
| LLM tokens (~5k convs/mo) | — | $5-30 | Lower with DeepSeek / Doubao |
| Domain + Postmark | — | $5-15 | |
| Total | $30-85 / mo |
Small production (two hosts)#
| Resource | Count | Unit (mo) |
|---|---|---|
| 4C/8G Chatwoot node | 1 | $30 |
| 8C/16G Dify node | 1 | $60 |
| Managed Postgres (small) | 1 | $25 |
| Total | $115-150 / mo |
Mid production (3 hosts + heavier LLM)#
$250-500/mo including LLM tokens.
Deployment (45-90 min)#
1. Server + DNS#
# Ubuntu 24.04
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# DNS:
# support.example.com → server IP
# dify.example.com → server IP
2. Bring up Dify#
git clone https://github.com/langgenius/dify
cd dify/docker
cp .env.example .env
# Key env:
# CONSOLE_WEB_URL=https://dify.example.com
# APP_API_URL=https://dify.example.com
# SECRET_KEY=$(openssl rand -base64 42)
docker compose up -d
Open https://dify.example.com, register admin, Settings → Model Providers → add LLM (DeepSeek to start) + Embedding (bge-m3 via SiliconFlow for Chinese).
3. Create a Dify chatbot#
- Type: Chat Assistant or Agent (Agent if tool calls needed)
- Upload KB docs (FAQ, product, refund policy, etc.)
- Chunking: Parent-Child (outperforms default)
- Prompt prefix with hard constraints:
You are [Brand]'s support assistant. Rules: 1. Answer only from "Reference" 2. If insufficient, reply "No info, handing off to a human" 3. Never invent amounts or dates - Publish and copy the API key (
app-xxxxxxxx)
4. Bring up Chatwoot#
git clone https://github.com/chatwoot/chatwoot
cd chatwoot
cp docker/.env.example .env
# Edit FRONTEND_URL, SMTP, SECRET_KEY_BASE
docker compose -f docker-compose.production.yaml \
run --rm rails bundle exec rails db:chatwoot_prepare
docker compose -f docker-compose.production.yaml up -d
Open https://support.example.com, register, create Account / Inbox.
5. Wire Dify as Agent Bot#
Chatwoot → Settings → Agent Bots → New:
| Field | Value |
|---|---|
| Name | Dify Bot |
| Outgoing URL | https://dify.example.com/v1/chat-messages |
| Auth Header | Authorization: Bearer app-xxxxxxxx |
Set this bot as the default in the target Inbox.
6. Verify#
Send a test message via the widget:
- Chatwoot picks up the conversation
- Bot auto-replies in < 3 s
- Dify shows the call in Application Logs
- Low confidence (< 0.5) triggers a human handoff
Key tuning#
KB preparation#
- Clean scattered Notion / Lark exports first (drop TOCs, emoji titles, empty images)
- Chunk by H2 / H3 headings, not by character count
- Run a regression eval weekly (see KB preparation in practice)
Fallback design#
| Situation | Behavior |
|---|---|
| Top-1 score < 0.5 | Auto reply “handing off” + create ticket |
| Workflow error | Failure branch returns degraded answer + alert |
| LLM token quota hit | Dify auto-stops app + alert |
| Sensitive keyword (complaint, refund) | n8n hands to human + ping on-call |
Human-in-the-loop#
Don’t have AI fully replace agents. The safe pattern is AI drafts → human reviews → one-click send:
- Chatwoot forwards customer message to Dify
- Dify writes its reply back as a draft (not sent)
- Agent clicks send or edits then sends
- Edits flow into the improvement queue for the prompt engineer’s Monday review
KPI targets#
| Metric | Target | Observed (6 mo) |
|---|---|---|
| First response time (FRT) | < 3 s | 1.2-2.4 s |
| AI deflection rate | 45-70% | KB-dependent |
| 24h return rate | < 10% | 8% |
| CSAT (AI leg) | > 4.0 / 5 | 4.2-4.4 |
| Cost per conversation | < $0.05 | $0.02-0.04 |
Common pitfalls#
- Email fails — SMTP must be Postmark / SES with
MAILER_SENDER_EMAILinside the verified domain - Dify returns zero hits — switched embedding without rebuilding the vector store; delete and re-ingest
- Cloudflare Tunnel 502 — container bound to
127.0.0.1instead of0.0.0.0 - AI goes off-topic — prompt missing constraints; KB contaminated by stale docs
- Token bill explodes — workflow loop or bot traffic; set monthly cap per app + Cloudflare Turnstile
Evolution path#
| Stage | Add | When |
|---|---|---|
| 1. Start | Chatwoot + Dify | Day 1 |
| 2. Business integration | n8n (orders / CRM) | > 2k conv/mo |
| 3. KB upgrade | RAGFlow (complex PDFs) | High doc complexity |
| 4. Multi-LLM | Dify multi-model | Cost pressure |
| 5. HA | Split DBs + Swarm / K8s | > 30k conv/mo |
| 6. Local inference | Ollama + Qwen 14B/32B | Compliance kicks in |