Complete Dify Tutorial: Open-Source Platform for Building AI Applications
Dify is an open-source platform that enables developers to build Large Language Model (LLM) powered applications quickly and efficiently. With Dify, you can create chatbots, AI workflows, RAG (Retrieval-Augmented Generation) applications, and AI agents without writing complex infrastructure code from scratch.
The platform provides a visual interface for designing AI workflows, managing prompts, and integrating various LLM models such as OpenAI GPT, Anthropic Claude, Google Gemini, and other open-source models. Dify is ideal for developers who want to focus on the business logic of their AI applications without getting bogged down in infrastructure complexity.
In this tutorial, we will learn how to install Dify, create your first AI application, build complex workflows, implement RAG, and follow best practices for production deployment.
Why Choose Dify?
Before diving into implementation, let's understand why Dify has become a popular choice among AI developers:
Installation and Setup
Prerequisites
Ensure your system has the following:
- Docker and Docker Compose installed
- Minimum 4GB RAM available
- Git for cloning the repository
Installation with Docker Compose
The easiest way to run Dify is using Docker Compose:
# Clone the Dify repository
git clone https://github.com/langgenius/dify.git
cd dify/docker
Copy the environment file
cp .env.example .env
Start all services
docker compose up -d
After all containers are running, open your browser and navigate to http://localhost/install to complete the initial setup. You will be prompted to create an admin account with email and password.
Configuring Model Providers
After logging in, the first step is to configure model providers. Go to Settings > Model Providers and add API keys for the models you want to use:
OpenAI: sk-xxxxx (for GPT-4, GPT-3.5)
Anthropic: sk-ant-xxxxx (for Claude)
Google: AIzaSyxxxxx (for Gemini)
Dify also supports local models through Ollama or vLLM. To use Ollama:
# Make sure Ollama is running
ollama serve
Pull the desired model
ollama pull llama3.1
ollama pull mistral
In Dify, add Ollama as a model provider with the URL http://host.docker.internal:11434.
Creating Your First Chat Application
Application Types in Dify
Dify provides several application types:
Creating a Simple Chatbot
You are a friendly and professional customer support assistant for a technology company.
Answer customer questions clearly and concisely.
If you don't know the answer, direct the customer to contact the support team via email.
Always use polite and easy-to-understand language.
Accessing via API
Every Dify application automatically gets an API endpoint. You can access it with:
import requests
APIBASE = "http://localhost/v1"
APIKEY = "app-xxxxxxxxxxxx" # From Settings > API Access
response = requests.post(
f"{APIBASE}/chat-messages",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {},
"query": "How do I reset my password?",
"responsemode": "blocking",
"user": "user-123"
}
)
result = response.json()
print(result["answer"])
For streaming responses:
import requests
response = requests.post(
f"{APIBASE}/chat-messages",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {},
"query": "Tell me about the premium features",
"responsemode": "streaming",
"user": "user-123"
},
stream=True
)
for line in response.iterlines():
if line:
decoded = line.decode("utf-8")
if decoded.startswith("data: "):
print(decoded[6:])
Building a RAG Application
RAG (Retrieval-Augmented Generation) allows AI to answer questions based on custom documents or knowledge bases. This is extremely useful for creating chatbots that can answer specific questions about products, documentation, or company policies.
Creating a Knowledge Base
- Automatic: Dify will split documents automatically
- Custom: Define your own chunk size and overlap
Recommended settings:
- Chunk size: 500-1000 tokens
- Chunk overlap: 50-100 tokens
- Embedding model: text-embedding-3-small (OpenAI) or bge-large-en-v1.5
- High Quality: Uses embedding model for semantic search
- Economical: Uses keyword-based search (more cost-effective)
Connecting Knowledge Base to Chatbot
After the knowledge base is created and documents are indexed:
Top K: 3-5 (number of chunks retrieved)
Score Threshold: 0.5-0.7 (minimum similarity score)
Retrieval Mode: Hybrid (keyword + semantic)
You are an assistant that answers questions based on the provided documents.
Use the information from the context provided to answer questions.
If the information is not in the context, state that you couldn't find the information
in the available documentation.
Always include references to which section of the document your answer comes from.
Accessing RAG via API
import requests
APIBASE = "http://localhost/v1"
APIKEY = "app-xxxxxxxxxxxx"
Query with knowledge base
response = requests.post(
f"{APIBASE}/chat-messages",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {},
"query": "What features are included in the Enterprise plan?",
"responsemode": "blocking",
"user": "user-456"
}
)
result = response.json()
print("Answer:", result["answer"])
Retrieval metadata is also available
if "metadata" in result:
for source in result["metadata"].get("retrieverresources", []):
print(f"Source: {source['documentname']}, Score: {source['score']}")
Building AI Workflows
Workflows are the most powerful feature in Dify. With workflows, you can design complex AI processes with multiple steps, conditional logic, and tool integrations.
Workflow Components
Dify provides various nodes for building workflows:
- Start: Initial node that receives input
- LLM: Calls a language model to generate text
- Knowledge Retrieval: Fetches information from knowledge bases
- Question Classifier: Classifies input into specific categories
- IF/ELSE: Conditional branching
- Code: Runs custom Python or JavaScript code
- HTTP Request: Calls external APIs
- Template Transform: Transforms data format
- Variable Aggregator: Combines output from multiple branches
- End: Final node that returns output
Example: Multi-Level Customer Support Workflow
Here's an example workflow that classifies customer questions and provides appropriate responses:
[Start] -> [Question Classifier] -> [IF: Technical] -> [Knowledge Retrieval: Tech Docs] -> [LLM: Technical Response] -> [End]
-> [IF: Billing] -> [HTTP Request: Billing API] -> [LLM: Billing Response] -> [End]
-> [IF: General] -> [LLM: General Response] -> [End]
Implementing Code Nodes
Code nodes allow you to run custom logic. Example node for formatting data:
def main(inputs: dict) -> dict:
"""
Format customer data from API response
"""
rawdata = inputs.get("apiresponse", {})
formatted = {
"customername": rawdata.get("name", "Unknown"),
"plan": rawdata.get("subscription", {}).get("plan", "Free"),
"activesince": rawdata.get("createdat", "N/A"),
"ticketcount": len(rawdata.get("tickets", []))
}
summary = (
f"Customer: {formatted['customername']}\n"
f"Plan: {formatted['plan']}\n"
f"Active Since: {formatted['activesince']}\n"
f"Total Tickets: {formatted['ticketcount']}"
)
return {
"formatteddata": formatted,
"summary": summary
}
Implementing HTTP Request Nodes
For integration with external APIs:
Method: GET
URL: https://api.example.com/customers/{{customerid}}
Headers:
Authorization: Bearer {{apitoken}}
Content-Type: application/json
Variables {{customerid}} and {{apitoken}} can be sourced from previous nodes or environment variables.
Creating AI Agents
AI Agents in Dify can use tools to complete complex tasks. The agent will select the right tools based on the user's question.
Agent Configuration
- Web Search (Google, Bing, DuckDuckGo)
- Wikipedia
- Calculator
- Current Time
- Web Scraper
Creating Custom Tools
You can also create custom tools with OpenAPI schemas:
openapi: "3.0.0"
info:
title: "Weather API Tool"
version: "1.0.0"
paths:
/weather:
get:
operationId: getWeather
summary: "Get current weather for a city"
parameters:
- name: city
in: query
required: true
schema:
type: string
description: "City name"
responses:
"200":
description: "Weather data"
content:
application/json:
schema:
type: object
properties:
temperature:
type: number
condition:
type: string
humidity:
type: number
Agent with Multiple Tools
import requests
response = requests.post(
f"{APIBASE}/chat-messages",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {},
"query": "Find the current weather in Jakarta and summarize it",
"responsemode": "blocking",
"user": "user-789"
}
)
result = response.json()
print(result["answer"])
The agent will automatically:
1. Use the Weather tool to get Jakarta weather data
2. Use the LLM to create a summary
Advanced Usage
Conversation Variables
Dify supports conversation variables for maintaining state across messages:
response = requests.post(
f"{APIBASE}/chat-messages",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {
"userpreference": "formal",
"language": "en"
},
"query": "Please help me write an email",
"responsemode": "blocking",
"conversationid": "conv-123",
"user": "user-101"
}
)
Batch Processing with Workflow API
import requests
import json
def runworkflowbatch(items):
results = []
for item in items:
response = requests.post(
f"{APIBASE}/workflows/run",
headers={
"Authorization": f"Bearer {APIKEY}",
"Content-Type": "application/json"
},
json={
"inputs": {
"text": item["text"],
"category": item["category"]
},
"responsemode": "blocking",
"user": "batch-user"
}
)
results.append(response.json())
return results
Example batch processing
items = [
{"text": "This product is amazing!", "category": "review"},
{"text": "Delivery was 3 days late", "category": "complaint"},
{"text": "Is it available in red?", "category": "inquiry"}
]
results = runworkflowbatch(items)
for r in results:
print(json.dumps(r, indent=2))
Embedding Dify Chat Widget
Dify provides a chat widget that can be embedded in any website:
Integration with Python Frameworks
from difyclient import ChatClient
client = ChatClient(
apikey="app-xxxxxxxxxxxx",
baseurl="http://localhost/v1"
)
Conversation with memory
conversationid = None
messages = [
"Hello, I'd like to know about your pricing plans",
"What features does the Enterprise plan include?",
"How much does it cost per month?"
]
for msg in messages:
response = client.createchatmessage(
inputs={},
query=msg,
user="demo-user",
responsemode="blocking",
conversationid=conversationid
)
result = response.json()
conversationid = result.get("conversationid")
print(f"User: {msg}")
print(f"Bot: {result['answer']}\n")
Monitoring and Observability
Logs and Tracing
Dify provides an observability dashboard that displays:
Access through the Logs menu in each application to view interaction details.
Integration with External Monitoring
Dify supports exporting traces to external observability platforms:
# In the .env file, configure tracing
TRACEPROVIDER=langfuse
LANGFUSEHOST=https://cloud.langfuse.com
LANGFUSEPUBLICKEY=pk-xxxxx
LANGFUSESECRETKEY=sk-xxxxx
Besides Langfuse, Dify also supports integration with LangSmith for tracing and monitoring.
Best Practices
1. Prompt Engineering
- Use specific and clear system prompts
- Include output examples (few-shot) when needed
- Limit the scope of answers so AI doesn't respond outside the domain
- Use low temperature (0.1-0.3) for factual answers, higher (0.7-0.9) for creative tasks
2. Knowledge Base Management
- Update knowledge bases regularly as documentation changes
- Use appropriate chunk sizes for different content types (smaller for FAQs, larger for articles)
- Enable hybrid search for more accurate retrieval results
- Monitor retrieval quality through logs to fine-tune parameters
3. Workflow Design
- Start with simple workflows, then increase complexity gradually
- Use Question Classifier for efficient routing
- Add error handling in Code nodes to handle edge cases
- Use Variable Aggregator to combine output from parallel branches
4. Security
- Never expose API keys in client-side code
- Implement rate limiting to prevent abuse
- Enable content moderation to filter harmful content
- Store sensitive data in environment variables, not in prompts
5. Performance Optimization
- Use response streaming for a better user experience
- Cache frequently accessed retrieval results
- Choose models appropriate for the task complexity (don't always use the largest model)
- Monitor token usage and optimize prompt length
6. Production Deployment
# Production deployment with recommended configuration
docker compose -f docker-compose.yaml up -d
.env configuration for production
SECRETKEY=your-random-secret-key-min-32-chars
CONSOLEWEBURL=https://dify.yourdomain.com
SERVICEAPIURL=https://api.dify.yourdomain.com
APPWEBURL=https://app.dify.yourdomain.com
Database configuration
DBHOST=your-postgres-host
DBPORT=5432
DBUSERNAME=dify
DBPASSWORD=secure-password
DBDATABASE=dify
Redis configuration
REDISHOST=your-redis-host
REDISPORT=6379
REDISPASSWORD=secure-redis-password
Storage configuration (S3-compatible)
STORAGETYPE=s3
S3BUCKETNAME=dify-storage
S3ACCESSKEY=your-access-key
S3SECRETKEY=your-secret-key
S3_REGION=ap-southeast-1
Conclusion
Dify is a powerful platform for building AI applications quickly. With its visual workflow builder, integrated RAG pipeline, and multi-model support, Dify enables developers to focus on business logic without building AI infrastructure from scratch.
Key takeaways to remember:
- Start simple: Build a basic chatbot first, then add complexity gradually
- Leverage RAG: Dify's knowledge base is incredibly useful for creating AI that answers based on company-specific data
- Use Workflows: For complex use cases, workflows provide better flexibility and control compared to simple chatbots
- Monitor and iterate: Use logging features to continuously improve AI response quality
- Prioritize security: Always follow security best practices especially when deploying to production
By following this tutorial, you now have a solid foundation for building various AI applications using Dify. The next step is to experiment with your specific use cases and optimize based on user feedback.