Overview
Dify is an open-source platform for building LLM-powered applications. It provides a visual workflow editor for orchestrating complex AI pipelines, built-in RAG engine, model management across multiple providers, and tools for prompt engineering. Dify supports chatbots, agents, text generators, and workflow-based applications out of the box.
The platform abstracts away the complexity of integrating LLMs, vector databases, and external tools. It offers a web-based studio for non-developers while exposing comprehensive APIs for programmatic control. Dify supports OpenAI, Anthropic, local models via Ollama, and dozens of other providers through a unified interface.
Installation
Docker Compose (Recommended)
git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
docker compose up -d
Access the web UI at http://localhost/install to set up the admin account.
From Source
git clone https://github.com/langgenius/dify.git
cd dify
# Start backend
cd api
cp .env.example .env
pip install -r requirements.txt
flask db upgrade
flask run --host 0.0.0.0 --port 5001
# Start frontend (new terminal)
cd web
npm install
npm run build
npm run start
Environment Variables
# .env key settings
SECRET_KEY=your-secret-key
OPENAI_API_KEY=sk-...
CONSOLE_WEB_URL=http://localhost:3000
SERVICE_API_URL=http://localhost:5001
DB_USERNAME=postgres
DB_PASSWORD=difypassword
DB_HOST=db
DB_PORT=5432
DB_DATABASE=dify
REDIS_HOST=redis
REDIS_PORT=6379
VECTOR_STORE=weaviate
Core Concepts
Application Types
| Type | Description | Use Case |
|---|
| Chatbot | Conversational AI with memory | Customer support, Q&A |
| Agent | Autonomous tool-using AI | Research, task execution |
| Text Generator | Single prompt-response | Content creation, summarization |
| Workflow | Multi-step orchestration | Complex data pipelines |
API Usage
# Create a chat message
curl -X POST 'http://localhost/v1/chat-messages' \
-H 'Authorization: Bearer app-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"inputs": {},
"query": "What is RAG?",
"response_mode": "streaming",
"conversation_id": "",
"user": "user-123"
}'
# Upload a file for RAG
curl -X POST 'http://localhost/v1/files/upload' \
-H 'Authorization: Bearer app-YOUR_API_KEY' \
-F 'file=@document.pdf' \
-F 'user=user-123'
# Get conversation history
curl -X GET 'http://localhost/v1/messages?conversation_id=conv-123&user=user-123' \
-H 'Authorization: Bearer app-YOUR_API_KEY'
# Send feedback
curl -X POST 'http://localhost/v1/messages/msg-id/feedbacks' \
-H 'Authorization: Bearer app-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"rating": "like", "user": "user-123"}'
Knowledge Base (RAG)
Creating a Knowledge Base
# Create knowledge base via API
curl -X POST 'http://localhost/v1/datasets' \
-H 'Authorization: Bearer dataset-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "Product Documentation",
"description": "Company product docs",
"indexing_technique": "high_quality",
"permission": "only_me"
}'
# Add document to knowledge base
curl -X POST 'http://localhost/v1/datasets/{dataset_id}/document/create_by_text' \
-H 'Authorization: Bearer dataset-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "product-guide.txt",
"text": "Your document content here...",
"indexing_technique": "high_quality",
"process_rule": {
"mode": "automatic"
}
}'
# Upload file to knowledge base
curl -X POST 'http://localhost/v1/datasets/{dataset_id}/document/create_by_file' \
-H 'Authorization: Bearer dataset-YOUR_API_KEY' \
-F 'file=@manual.pdf' \
-F 'data={"indexing_technique":"high_quality","process_rule":{"mode":"automatic"}}'
Retrieval Settings
| Parameter | Description | Default |
|---|
search_method | keyword_search, semantic_search, hybrid_search | semantic_search |
top_k | Number of chunks to retrieve | 3 |
score_threshold | Minimum relevance score (0-1) | 0.5 |
reranking_model | Model for reranking results | None |
Configuration
Model Provider Setup
# Supported model providers
providers:
- openai # GPT-4, GPT-3.5
- anthropic # Claude 3/4
- azure_openai # Azure-hosted OpenAI
- huggingface # Open-source models
- ollama # Local models
- xinference # Local model serving
- tongyi # Alibaba Cloud
- zhipuai # GLM models
- minimax # MiniMax models
Docker Compose Customization
# docker-compose.override.yml
services:
api:
environment:
- LOG_LEVEL=DEBUG
- CELERY_BROKER_URL=redis://redis:6379/1
deploy:
resources:
limits:
memory: 4G
worker:
environment:
- CELERY_WORKER_AMOUNT=4
web:
ports:
- "3000:3000"
weaviate:
environment:
- PERSISTENCE_DATA_PATH=/var/lib/weaviate
volumes:
- weaviate_data:/var/lib/weaviate
Nginx Reverse Proxy
server {
listen 80;
server_name dify.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /v1 {
proxy_pass http://localhost:5001/v1;
proxy_set_header Host $host;
proxy_read_timeout 300s;
}
location /console/api {
proxy_pass http://localhost:5001/console/api;
proxy_set_header Host $host;
}
}
Advanced Usage
Workflow Nodes
| Node Type | Purpose |
|---|
| LLM | Call language model |
| Knowledge Retrieval | Query RAG knowledge base |
| Code | Execute Python/JavaScript |
| HTTP Request | Call external APIs |
| Condition | Branch logic |
| Variable Aggregator | Combine variables |
| Template Transform | Jinja2 text templates |
| Question Classifier | Route by intent |
| Iteration | Loop over arrays |
# Register an external tool via OpenAPI schema
curl -X POST 'http://localhost/console/api/workspaces/current/tool-provider/api/create' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"schema_type": "openapi",
"schema": "openapi: 3.0.0\ninfo:\n title: Weather\n version: 1.0\npaths:\n /weather:\n get:\n summary: Get weather\n parameters:\n - name: city\n in: query\n required: true\n schema:\n type: string",
"credentials": {
"api_key": "your-weather-api-key"
}
}'
Webhook Integration
import requests
DIFY_API_KEY = "app-YOUR_API_KEY"
BASE_URL = "http://localhost/v1"
def send_message(query, conversation_id=""):
response = requests.post(
f"{BASE_URL}/chat-messages",
headers={"Authorization": f"Bearer {DIFY_API_KEY}"},
json={
"inputs": {},
"query": query,
"response_mode": "blocking",
"conversation_id": conversation_id,
"user": "webhook-user"
}
)
return response.json()
result = send_message("Summarize latest sales data")
print(result["answer"])
Troubleshooting
| Issue | Solution |
|---|
| Docker containers fail to start | Check .env file, ensure ports 80, 5432, 6379 are free |
| Model provider connection error | Verify API keys in Settings > Model Providers |
| Knowledge base indexing stuck | Check worker logs: docker compose logs worker |
| Out of memory during embedding | Reduce batch size or increase Docker memory limits |
| SSO login not working | Verify CONSOLE_WEB_URL matches your actual URL |
| Slow response times | Enable model load balancing, check Redis connection |
| File upload fails | Check UPLOAD_FILE_SIZE_LIMIT env var (default 15MB) |
| Database migration errors | Run flask db upgrade manually in the API container |
# View logs for debugging
docker compose logs -f api
docker compose logs -f worker
docker compose logs -f web
# Restart all services
docker compose restart
# Reset database (WARNING: destroys data)
docker compose down -v
docker compose up -d