Chapter 11: Dify — Knowledge Bases & RAG
Chapter 11: Dify — Knowledge Bases & RAG
Last Updated: 2026-03
11.2 Knowledge Base Architecture
Document Input
│
▼
Chunking Split document into segments (e.g., 1000 chars, 100 overlap)
│
▼
Embedding Each chunk → vector via text-embedding-3-small (1536 dims)
│
▼
Storage Vector stored in PostgreSQL via pgvector
│ Metadata stored in PostgreSQL
│
At Query Time:
│
Query Embedding User query → vector
│
▼
Vector Search Find top-K chunks by cosine similarity
│
▼
Reranking (Optional) rerank results for precision
│
▼
Injection Chunks injected into LLM system prompt
│
▼
LLM Response Model generates answer grounded in retrieved context
11.3 Creating a Knowledge Base
- Open Dify console at
http://localhost:3000. - Navigate to Knowledge in the top navigation.
- Click Create Knowledge.
- Choose the data source:
- File Upload — PDF, DOCX, TXT, Markdown, HTML
- URL Sync — Crawl a web page or sitemap
- Notion — Sync from a Notion workspace
- Configure chunking:
- Automatic — Dify determines chunk size based on content type.
- Custom — Set chunk size (characters) and overlap manually.
- Choose the embedding model:
text-embedding-3-small(OpenAI) is the ITI default. - Click Save and Process.
Dify submits the indexing job to the Celery worker queue. Processing time depends on document size — a 100-page PDF typically takes 2–5 minutes.
11.4 Chunking Strategy
Chunk size and overlap significantly affect retrieval quality. ITI defaults:
| Setting | ITI Default | Notes |
|---|---|---|
| Chunk size | 1000 characters | Good for dense technical content |
| Overlap | 100 characters | Prevents context loss at chunk boundaries |
| Separator | Paragraph \n\n |
Preserves semantic units |
When to adjust:
- Long-form narrative content (articles, reports): larger chunks (1500–2000 chars) preserve more context per retrieved segment.
- Structured data (tables, FAQs, Q&A pairs): smaller chunks (500 chars) with exact sentence separators.
- Legal or regulatory content: preserve paragraph boundaries; use
\n\nas separator with 1000-char chunks.
11.5 Retrieval Testing
Before integrating a knowledge base into a product workflow, always test retrieval quality.
- Open the knowledge base in the Dify console.
- Click Retrieval Testing (top right).
- Enter representative queries that users will actually ask.
- Review:
- Are the top results relevant? Score should be > 0.7 for a well-configured KB.
- Is the retrieved text complete enough? If chunks are cut mid-sentence, increase chunk size or adjust separators.
- Are irrelevant results appearing? Consider reducing the top-K value or adding metadata filters.
Interpreting retrieval scores
| Score Range | Meaning |
|---|---|
| > 0.85 | Excellent match — very relevant content |
| 0.70–0.85 | Good match — relevant, may need refinement |
| 0.50–0.70 | Weak match — may introduce noise |
| < 0.50 | Poor match — likely irrelevant |
Configure the Score Threshold in the KB settings to filter out results below a minimum score.
11.6 Re-indexing a Knowledge Base
Re-index when:
- The embedding model has changed.
- Retrieval quality has degraded.
- The chunking configuration was changed.
- New documents were added that need consistent chunking.
Via Dify UI: Knowledge > select dataset > Re-index button.
Via Dify API:
curl -X POST "http://localhost:3001/console/api/datasets/<dataset-id>/indexing-estimate" \
-H "Authorization: Bearer <dify-api-key>" \
-H "Content-Type: application/json"
Note: Re-indexing deletes all existing embeddings for the dataset and regenerates them. For large datasets, this can take 10–30 minutes and will temporarily affect retrieval for any active workflows using that KB.
11.7 Integrating Dify KBs with n8n
The standard pattern for calling a Dify knowledge base from an n8n workflow:
// HTTP Request node configuration
{
url: "http://iti-dify-nginx:80/v1/datasets/<dataset-id>/retrieve",
method: "POST",
headers: {
"Authorization": "Bearer {{ $credentials.difyApiKey }}",
"Content-Type": "application/json"
},
body: {
query: "{{ $json.userQuery }}",
retrieval_model: {
search_method: "semantic_similarity",
top_k: 5,
score_threshold: 0.70,
score_threshold_enabled: true
}
}
}
Note: Within the Docker network, n8n nodes use the internal container name (
iti-dify-nginx) rather thanlocalhost. The internal port is80(not3001which is the host-exposed port).
11.8 Dify API Reference (Common Endpoints)
All endpoints are called against http://localhost:3001 from external clients, or http://iti-dify-nginx:80 from within the Docker network.
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/console/api/datasets |
List all knowledge bases |
POST |
/console/api/datasets |
Create a new knowledge base |
GET |
/console/api/datasets/ |
Get KB metadata |
POST |
/v1/datasets/ |
Query a KB (retrieve chunks) |
POST |
/console/api/datasets/ |
Upload a document |
GET |
/console/api/datasets/ |
List documents in a KB |
DELETE |
/console/api/datasets/ |
Remove a document |
Authentication: Authorization: Bearer . The Dify API key is found in the Dify console under Settings > API Keys.
11.9 Troubleshooting Dify
Documents stuck in “Indexing” state
The Dify worker may be backed up or crashed.
# Check worker status
docker compose ps iti-dify-worker
# Check worker logs
docker compose logs iti-dify-worker --tail 50
# Check Redis queue depth
docker exec iti-redis redis-cli llen celery
# Restart worker if stuck
docker compose restart iti-dify-worker
Retrieval returns no results
- Verify the dataset ID is correct.
- Check that at least one document in the KB has status “Available” (not “Indexing” or “Error”).
- Lower the score threshold to 0.5 and test again.
- Verify the embedding model is configured correctly in the KB settings.
Dify console not loading (3000)
docker compose logs iti-dify-web --tail 20
docker compose restart iti-dify-web
Previous: Chapter 10 — n8n Debugging & Operations | Next: Chapter 12 — The ITI Workflow Adapter
