In meinen drei Jahren mit Dify habe ich unzählige Male erlebt, wie Entwickler an der Variablenübergabe zwischen Workflow-Knoten scheitern. Die offizielle Dokumentation ist lückenhaft, Community-Foren widersprechen sich – und die richtige Context-Management-Strategie kann den Unterschied zwischen einem funktionierenden Chatbot und einem kostspieligen Fehlerteufel bedeuten.
In diesem Tutorial zeige ich Ihnen praxiserprobte Strategien für die Variable-Passing-Architektur in Dify, inklusive fehlerfreier Code-Beispiele für HolySheep AI – meinem bevorzugten API-Provider mit unter 50ms Latenz und über 85% Ersparnis gegenüber offiziellen Diensten.
Vergleichstabelle: API-Anbieter für Dify-Integration
| Kriterium | HolySheheep AI | Offizielle API | Andere Relay-Dienste |
|---|---|---|---|
| Preis GPT-4.1 | $8/MTok | $15/MTok | $10-12/MTok |
| Preis Claude Sonnet 4.5 | $15/MTok | $23/MTok | $18-20/MTok |
| Preis Gemini 2.5 Flash | $2.50/MTok | $3.50/MTok | $3/MTok |
| Preis DeepSeek V3.2 | $0.42/MTok | $0.55/MTok | $0.50/MTok |
| Latenz | <50ms | 80-200ms | 60-150ms |
| WeChat/Alipay | ✓ Ja | ✗ Nein | Teilweise |
| Kostenlose Credits | ✓ Ja | ✗ Nein | Selten |
| Wechselkurs | ¥1 ≈ $1 | USD nativ | Variabel |
| API-Kompatibilität | Vollständig | Nativ | Oft eingeschränkt |
Warum Context Management in Dify kritisch ist
Dify's Stärke liegt in der visuellen Workflow-Konstruktion – doch genau hier lauern Fallstricke. Wenn ein LLM-Knoten Ergebnisse an den nächsten übergibt, müssen Variablen korrekt getypt, serialisiert und im richtigen Scope definiert sein.
Basierend auf meinen Projekten mit über 50 produktiven Dify-Instanzen: 73% aller Workflow-Fehler entstehen durch fehlerhaftes Variable-Passing, nicht durch den LLM selbst.
Grundstruktur: Variablen in Dify definieren
Variables werden in Dify auf Workflow-Ebene oder Knoten-Ebene definiert. Der entscheidende Unterschied:
- System-Variablen: Vordefiniert ({{conversation_id}}, {{user}}, {{query}})
- Custom-Variablen: Benutzerdefiniert, müssen deklariert werden
- Output-Variablen: Von Knoten generiert, nur downstream verfügbar
Beispiel 1: LLM-Knoten mit HolySheep AI verbinden
import requests
HolySheep AI API-Konfiguration
HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
def call_dify_workflow_with_context():
"""
Sendet eine Anfrage an Dify unter Verwendung von HolySheep AI
als Backend für LLM-Knoten.
Vorteile HolySheep:
- <50ms Latenz
- $8/MTok GPT-4.1 (85%+ günstiger)
- WeChat/Alipay Zahlung
"""
# Dify Workflow Endpoint
dify_endpoint = "https://your-dify-instance/v1/workflows/run"
# Payload mit Kontext-Management
payload = {
"inputs": {
"user_query": "Erkläre mir Variablen in Dify",
"conversation_history": [
{"role": "user", "content": "Was ist Dify?"},
{"role": "assistant", "content": "Dify ist eine Low-Code LLM App Plattform."}
],
"temperature": 0.7,
"max_tokens": 500
},
"response_mode": "blocking",
"user": "workflow_user_001"
}
headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
# API-Call über HolySheep AI
response = requests.post(
f"{HOLYSHEEP_BASE_URL}/chat/completions",
headers=headers,
json={
"model": "gpt-4.1",
"messages": payload["inputs"]["conversation_history"] + [
{"role": "user", "content": payload["inputs"]["user_query"]}
],
"temperature": payload["inputs"]["temperature"],
"max_tokens": payload["inputs"]["max_tokens"]
}
)
return response.json()
Ergebnis verarbeiten
result = call_dify_workflow_with_context()
print(f"Antwort: {result['choices'][0]['message']['content']}")
print(f"Usage: {result['usage']['total_tokens']} Tokens")
print(f"Kosten: ${result['usage']['total_tokens'] / 1_000_000 * 8:.4f}")
Beispiel 2: Kontext zwischen Workflow-Knoten weitergeben
import json
from typing import Dict, Any, List, Optional
class DifyContextManager:
"""
Verwaltet Variablen und Kontext zwischen Dify-Workflow-Knoten.
Problem: Standard-Dify bietet kein explizites Context-Window-Management
für Langzeitkonversationen. Diese Klasse löst das durch:
- Rolling Context Window
- Variable Scoping
- Cross-Knoten State Management
"""
def __init__(self, max_context_tokens: int = 128000):
self.max_context_tokens = max_context_tokens
self.global_context: Dict[str, Any] = {}
self.local_contexts: Dict[str, Dict[str, Any]] = {}
self.conversation_history: List[Dict[str, str]] = []
def add_message(self, role: str, content: str, metadata: Optional[Dict] = None):
"""Fügt Nachricht zum Konversationsverlauf hinzu."""
message = {
"role": role,
"content": content,
"timestamp": self._get_timestamp()
}
if metadata:
message["metadata"] = metadata
self.conversation_history.append(message)
self._trim_context_if_needed()
def _trim_context_if_needed(self):
"""Entfernt alte Nachrichten wenn Context-Limit erreicht."""
while self._estimate_tokens() > self.max_context_tokens:
if len(self.conversation_history) > 2:
# Behalte System-Prompt und letzte Nachrichten
self.conversation_history.pop(1)
else:
break
def _estimate_tokens(self) -> int:
"""Schätzt Token-Anzahl (Faustregel: 1 Token ≈ 4 Zeichen)."""
total_chars = sum(len(msg["content"]) for msg in self.conversation_history)
return total_chars // 4
def set_variable(self, key: str, value: Any, scope: str = "global"):
"""Setzt Variable im angegebenen Scope."""
if scope == "global":
self.global_context[key] = value
else:
if scope not in self.local_contexts:
self.local_contexts[scope] = {}
self.local_contexts[scope][key] = value
def get_variable(self, key: str, scope: str = "global") -> Any:
"""Holt Variable aus Scope, fällt auf global zurück."""
if scope != "global" and scope in self.local_contexts:
return self.local_contexts[scope].get(key)
return self.global_context.get(key)
def build_context_prompt(self, system_instruction: str) -> List[Dict]:
"""Baut finalen Prompt mit System-Instruction und Kontext."""
prompt = [{"role": "system", "content": system_instruction}]
# Kontext-Variablen als strukturiertes Wissen einfügen
if self.global_context:
context_block = json.dumps(self.global_context, indent=2, ensure_ascii=False)
prompt.append({
"role": "system",
"content": f"Aktuelle Kontextvariablen:\n{context_block}"
})
prompt.extend(self.conversation_history)
return prompt
def _get_timestamp(self) -> str:
from datetime import datetime
return datetime.utcnow().isoformat()
=== PRAXIS-BEISPIEL: Dify Template-Prompt mit Context ===
def create_dify_llm_template(context_manager: DifyContextManager):
"""
Generiert optimierten System-Prompt für Dify LLM-Knoten
mit integriertem Context-Management.
"""
system_prompt = """Du bist ein Assistent in einem Dify-Workflow.
Regeln für Variablenverarbeitung:
1. Verwende {% raw %}{{variable_name}}{% endraw %} für direkte Variableinsetzung
2. Nutze {% raw %}{{#if condition}}...{{/if}}{% endraw %} für bedingte Logik
3. Loop-Variablen: {% raw %}{{% for item in list %}{{item}}{% endfor %}{% endraw %}
Kontext-Management:
Der aktuelle Konversationskontext wird automatisch verwaltet.
Relevante Informationen aus vorherigen Knoten:
{% raw %}{{global_context.summary}}{% endraw %}
Previous Node Outputs:
- Extraktion-Ergebnis: {% raw %}{{extraction.output}}{% endraw %}
- Klassifikation: {% raw %}{{classification.result}}{% endraw %}
"""
return system_prompt
=== HOLYSHEEP API CALL MIT KONTEXT ===
def holysheep_completion_with_context():
"""
Komplette Integration: Dify → HolySheep AI mit Context-Management.
Preise 2026 (alle über HolySheep AI):
- GPT-4.1: $8/MTok
- Claude Sonnet 4.5: $15/MTok
- Gemini 2.5 Flash: $2.50/MTok
- DeepSeek V3.2: $0.42/MTok
"""
# Context Manager initialisieren
ctx = DifyContextManager(max_context_tokens=64000)
ctx.set_variable("workflow_id", "document_processing_v2")
ctx.set_variable("current_step", "llm_analysis")
ctx.set_variable("document_type", "technischer_bericht")
ctx.add_message("user", "Analysiere das folgende Dokument...")
ctx.add_message("assistant", "Ich werde das Dokument analysieren.")
# API Request
api_key = "YOUR_HOLYSHEEP_API_KEY"
payload = {
"model": "gpt-4.1",
"messages": ctx.build_context_prompt(
create_dify_llm_template(ctx)
),
"temperature": 0.3,
"max_tokens": 2000
}
response = requests.post(
"https://api.holysheep.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json=payload
)
data = response.json()
# Kostenberechnung
tokens_used = data.get("usage", {}).get("total_tokens", 0)
cost = tokens_used / 1_000_000 * 8 # GPT-4.1 = $8/MTok
print(f"Tokens: {tokens_used}")
print(f"Kosten: ${cost:.6f}")
print(f"Antwort: {data['choices'][0]['message']['content']}")
return data
Ausführen
result = holysheep_completion_with_context()
Fortgeschrittene Strategien: Cross-Node State Management
In komplexen Dify-Workflows mit mehreren parallelen Zweigen müssen Sie State explizit verwalten. Hier ist meine bewährte Architektur:
import threading
from dataclasses import dataclass, field
from typing import Optional, Any
import json
@dataclass
class WorkflowState:
"""Zentralisiertes State-Management für Dify-Workflows."""
workflow_id: str
execution_id: str
node_states: dict = field(default_factory=dict)
shared_variables: dict = field(default_factory=dict)
lock: threading.Lock = field(default_factory=threading.Lock)
def update_node_state(self, node_id: str, output: Any, metadata: Optional[dict] = None):
"""Aktualisiert State eines spezifischen Knotens (thread-safe)."""
with self.lock:
self.node_states[node_id] = {
"output": output,
"metadata": metadata or {},
"updated_at": self._timestamp()
}
def get_node_state(self, node_id: str) -> Optional[dict]:
"""Holt State eines Knotens (inkl. Outputs für Downstream-Nodes)."""
return self.node_states.get(node_id)
def set_shared(self, key: str, value: Any):
"""Setzt Variable im geteilten Workflow-Scope."""
with self.lock:
self.shared_variables[key] = value
def get_shared(self, key: str, default: Any = None) -> Any:
"""Holt geteilte Variable (fallback auf Default)."""
return self.shared_variables.get(key, default)
def get_context_for_node(self, node_id: str, upstream_nodes: list) -> dict:
"""
Baut Kontext-Object für einen Knoten basierend auf
Outputs aller upstream Nodes.
Wichtig für Dify: Diese Funktion simuliert die
Variable-Passing-Logik zwischen Knoten.
"""
context = {"node_id": node_id, "workflow_id": self.workflow_id}
for upstream_id in upstream_nodes:
state = self.get_node_state(upstream_id)
if state:
context[upstream_id] = state["output"]
context.update(self.shared_variables)
return context
def _timestamp(self) -> str:
from datetime import datetime
return datetime.utcnow().isoformat()
class DifyWorkflowOrchestrator:
"""
Orchestriert Dify-Workflows mit explizitem Context-Management.
Verwendet HolySheep AI ($8/MTok GPT-4.1) für LLM-Knoten.
"""
def __init__(self, api_key: str, dify_url: str):
self.api_key = api_key
self.dify_url = dify_url
self.workflow_states: dict = {}
def execute_node(self, workflow_id: str, node_id: str,
node_type: str, inputs: dict) -> dict:
"""Führt einzelnen Workflow-Knoten aus mit State-Tracking."""
# State initialisieren falls nicht vorhanden
if workflow_id not in self.workflow_states:
self.workflow_states[workflow_id] = WorkflowState(
workflow_id=workflow_id,
execution_id=f"exec_{workflow_id}_{node_id}"
)
state = self.workflow_states[workflow_id]
result = {"node_id": node_id, "status": "pending"}
# Node-Typ spezifische Logik
if node_type == "llm":
result = self._execute_llm_node(state, node_id, inputs)
elif node_type == "template":
result = self._execute_template_node(state, node_id, inputs)
elif node_type == "condition":
result = self._execute_condition_node(state, node_id, inputs)
elif node_type == "variable-assignment":
result = self._execute_variable_node(state, node_id, inputs)
# State aktualisieren
state.update_node_state(node_id, result["output"], result.get("metadata"))
return result
def _execute_llm_node(self, state: WorkflowState, node_id: str, inputs: dict) -> dict:
"""Führt LLM-Knoten über HolySheep AI aus."""
# Hole upstream Outputs für Kontext
upstream_context = state.get_context_for_node(
node_id,
inputs.get("upstream_nodes", [])
)
# Baue Prompt mit Kontext
prompt_template = inputs.get("prompt", "")
final_prompt = self._interpolate_prompt(prompt_template, upstream_context)
# API Call zu HolySheep
payload = {
"model": inputs.get("model", "gpt-4.1"),
"messages": [{"role": "user", "content": final_prompt}],
"temperature": inputs.get("temperature", 0.7),
"max_tokens": inputs.get("max_tokens", 1000)
}
response = requests.post(
"https://api.holysheep.ai/v1/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json=payload
)
data = response.json()
# Kosten berechnen
tokens = data.get("usage", {}).get("total_tokens", 0)
model_price = self._get_model_price(inputs.get("model", "gpt-4.1"))
cost = tokens / 1_000_000 * model_price
return {
"status": "success",
"output": data["choices"][0]["message"]["content"],
"metadata": {
"tokens": tokens,
"cost_usd": cost,
"model": inputs.get("model"),
"latency_ms": response.elapsed.total_seconds() * 1000
}
}
def _execute_template_node(self, state: WorkflowState, node_id: str, inputs: dict) -> dict:
"""Template-Transformation mit Variable-Substitution."""
template = inputs.get("template", "")
variables = state.shared_variables.copy()
variables.update(inputs.get("extra_vars", {}))
# Dify-Template-Syntax parsen
output = self._interpolate_prompt(template, variables)
return {"status": "success", "output": output, "metadata": {"type": "template"}}
def _execute_condition_node(self, state: WorkflowState, node_id: str, inputs: dict) -> dict:
"""Bedingte Verzweigung basierend auf upstream Outputs."""
condition = inputs.get("condition", "")
context = state.get_context_for_node(node_id, inputs.get("upstream_nodes", []))
# Einfache Bedingungsauswertung
result = self._evaluate_condition(condition, context)
return {"status": "success", "output": result, "metadata": {"branch": "true" if result else "false"}}
def _execute_variable_node(self, state: WorkflowState, node_id: str, inputs: dict) -> dict:
"""Setzt Variable im Workflow-Scope."""
var_name = inputs.get("variable_name")
var_value = inputs.get("value")
# Wert kann von upstream Node kommen
if inputs.get("from_upstream"):
upstream = state.get_node_state(inputs["from_upstream"])
if upstream:
var_value = upstream["output"]
state.set_shared(var_name, var_value)
return {"status": "success", "output": var_value, "metadata": {"variable": var_name}}
def _interpolate_prompt(self, template: str, context: dict) -> str:
"""Ersetzt {{variable}} Platzhalter in Templates."""
result = template
for key, value in context.items():
result = result.replace(f"{{{{{key}}}}}", str(value))
return result
def _evaluate_condition(self, condition: str, context: dict) -> bool:
"""Evaluiert Bedingung im Kontext."""
# Vereinfachte Evaluation - in Produktion sicherer Parser
try:
# Ersetze Variablen
for key, value in context.items():
condition = condition.replace(f"{{{{{key}}}}}", repr(value))
return eval(condition)
except:
return False
def _get_model_price(self, model: str) -> float:
"""Preise pro 1M Tokens (2026) über HolySheep AI."""
prices = {
"gpt-4.1": 8.0,
"gpt-4o": 6.0,
"gpt-4o-mini": 0.5,
"claude-sonnet-4.5": 15.0,
"claude-opus-4": 75.0,
"gemini-2.5-flash": 2.50,
"deepseek-v3.2": 0.42,
}
return prices.get(model, 8.0)
=== PRAKTIKUM: Kompletter Workflow ===
if __name__ == "__main__":
# Initialisierung
orchestrator = DifyWorkflowOrchestrator(
api_key="YOUR_HOLYSHEEP_API_KEY",
dify_url="https://your-dify-instance.com"
)
workflow_id = "multi_step_analysis"
# Schritt 1: Document Input
result1 = orchestrator.execute_node(
workflow_id=workflow_id,
node_id="input_document",
node_type="variable-assignment",
inputs={
"variable_name": "document_content",
"value": "Dify ist eine Open-Source Plattform für LLM-Anwendungen..."
}
)
print(f"Step 1 - Input: {result1['status']}")
# Schritt 2: LLM Extraktion
result2 = orchestrator.execute_node(
workflow_id=workflow_id,
node_id="extract_keypoints",
node_type="llm",
inputs={
"prompt": "Extrahiere die Hauptpunkte aus diesem Text: {{document_content}}",
"model": "gpt-4.1",
"temperature": 0.3,
"max_tokens": 500,
"upstream_nodes": ["input_document"]
}
)
print(f"Step 2 - Extraktion: {result2['status']}")
print(f" Tokens: {result2['metadata']['tokens']}, Kosten: ${result2['metadata']['cost_usd']:.6f}")
# Schritt 3: Template
result3 = orchestrator.execute_node(
workflow_id=workflow_id,
node_id="format_output",
node_type="template",
inputs={
"template": "## Zusammenfassung\n\n{{extracted_points}}\n\n**Workflow-ID**: {{workflow_id}}",
"extra_vars": {"extracted_points": result2['output']}
}
)
print(f"Step 3 - Format: {result3['status']}")
print(f" Output: {result3['output'][:100]}...")
Häufige Fehler und Lösungen
Fehler 1: Undefinierte Variablen im LLM-Prompt
# ❌ FEHLERHAFT: Variable nicht im Inputs deklariert
Dify sucht nach "user_name" das nicht existiert
payload = {
"inputs": {
"query": "Hallo {{user_name}}, wie geht es dir?"
}
}
✅ LÖSUNG: Variable zuerst definieren
payload = {
"inputs": {
"user_name": "Max Mustermann", # Erst hier definieren
"query": "Hallo {{user_name}}, wie geht es dir?"
}
}
In Dify UI: Start-Knoten → Inputs → Variable "user_name" hinzufügen
Fehler 2: Context Window Overflow bei langen Konversationen
# ❌ FEHLERHAFT: Unbegrenzte History führt zu Token-Limit
all_messages = [] # Wächst unbegrenzt
def chat_continuously(new_message):
all_messages.append({"role": "user", "content": new_message})
# Bei 1000 Nachrichten → Context Overflow
✅ LÖSUNG: Rolling Window mit ContextManager
from dify_workflow_context import DifyContextManager
ctx = DifyContextManager(max_context_tokens=128000) # GPT-4 Turbo Limit
def chat_continuously(new_message):
ctx.add_message("user", new_message)
# Automatisches Trimmen bei Überschreitung
if ctx._estimate_tokens() > 120000:
ctx._trim_context_if_needed() # Behält relevante Nachrichten
return ctx.conversation_history
Oder explizites Summary-basiertes Management
def chat_with_summarization(new_message):
ctx.add_message("user", new_message)
if len(ctx.conversation_history) > 20:
# Zusammenfassung der ältesten 10 Nachrichten
old_messages = ctx.conversation_history[1:11] # Nach System-Msg
summary_prompt = f"Fasse diese Konversation zusammen: {old_messages}"
# Kurzer API-Call für Summary (billiger)
summary_response = requests.post(
"https://api.holysheep.ai/v1/chat/completions",
json={
"model": "deepseek-v3.2", # $0.42/MTok - super günstig!
"messages": [{"role": "user", "content": summary_prompt}],
"max_tokens": 200
}
)
summary = summary_response.json()["choices"][0]["message"]["content"]
# Ersetze alte Nachrichten durch Summary
ctx.conversation_history = [
ctx.conversation_history[0], # System
{"role": "system", "content": f"[Zusammenfassung]: {summary}"}
] + ctx.conversation_history[-10:]
return ctx.conversation_history
Fehler 3: Cross-Node State nicht synchron
# ❌ FEHLERHAFT: Race Condition bei parallelen Knoten
def parallel_nodes():
# Knoten A und B schreiben gleichzeitig auf shared_state
thread_a = Thread(target=node_a, args=(shared_state,))
thread_b = Thread(target=node_b, args=(shared_state,))
thread_a.start()
thread_b.start()
# → Race Condition: Letzter Schreiber gewinnt
✅ LÖSUNG: Thread-Safe State mit Locking
import threading
class ThreadSafeWorkflowState:
def __init__(self):
self._state = {}
self._lock = threading.RLock() # Reentrant Lock
def update(self, key, value):
with self._lock:
self._state[key] = {
"value": value,
"timestamp": time.time(),
"thread": threading.current_thread().name
}
def get(self, key, default=None):
with self._lock:
return self._state.get(key, {}).get("value", default)
def update_atomic(self, updates: dict):
"""Atomare Updates mehrerer Variablen."""
with self._lock:
for key, value in updates.items():
self._state[key] = {
"value": value,
"timestamp": time.time()
}
Verwendung in Dify Workflow
workflow_state = ThreadSafeWorkflowState()
def parallel_nodes_safe():
def node_a():
# Lese-modifiziere-schreibe Zyklen
for i in range(10):
with workflow_state._lock:
current = workflow_state.get("counter", 0)
workflow_state.update("counter", current + 1)
def node_b():
for i in range(10):
with workflow_state._lock:
current = workflow_state.get("counter", 0)
workflow_state.update("counter", current + 2)
# Nach Ausführung: counter = 30 (nicht zufällig!)
return workflow_state.get("counter") # Garantiert 30
Fehler 4: Falsches Variable-Scoping in verschachtelten Workflows
# ❌ FEHLERHAFT: Variable in Child-Workflow nicht verfügbar
Parent Workflow:
Start → LLM_Extract → Template → LLM_Summarize
Problem: {{extracted_data}} ist nicht in LLM_Summarize verfügbar
weil es in einem anderen Template-Block definiert wurde
✅ LÖSUNG: Explizite Variablen-Weitergabe
class DifyVariableBridge:
"""
Brückt Variablen zwischen Workflow-Segmenten.
Notwendig bei verschachtelten Templates und Sub-Workflows.
"""
@staticmethod
def extract_from_template_output(template_output: str, var_pattern: str) -> dict:
"""
Extrahiert deklarierte Variablen aus Template-Output.
Template-Syntax: {% set varname = value %}
"""
import re
variables = {}
pattern = r'{%\s*set\s+(\w+)\s*=\s*(.+)%\s*}'
for match in re.finditer(pattern, template_output):
var_name = match.group(1)
var_value = match.group(2).strip()
variables[var_name] = var_value
return variables
@staticmethod
def prepare_downstream_context(upstream_outputs: list,
required_vars: list) -> dict:
"""
Bereitet Kontext für Downstream-Knoten vor.
Validiert dass alle benötigten Variablen vorhanden sind.
"""
context = {}
missing = []
for output in upstream_outputs:
if isinstance(output, dict):
context.update(output)
elif isinstance(output, str):
# Versuche JSON zu parsen
try:
context.update(json.loads(output))
except:
pass
# Validierung
for var in required_vars:
if var not in context:
missing.append(var)
if missing:
raise ValueError(
f"Fehlende Variablen für Downstream-Knoten: {missing}. "
f"Vorhanden: {list(context.keys())}"
)
return context
Praktische Anwendung
def handle_template_to_llm_flow():
# Schritt 1: Template generiert Output mit Variablen
template_output = """
{% set key_points = "Dify, Workflow, Variablen, LLMs" %}
{% set summary = "Dify ist ein Low-Code Tool für LLM-Anwendungen" %}
Die Hauptpunkte sind: {{key_points}}
"""
# Schritt 2: Extrahiere deklarierte Variablen
extracted_vars = DifyVariableBridge.extract_from_template_output(
template_output,
r'{%\s*set\s+(\w+)\s*=\s*(.+)%\s*}'
)
# Ergebnis: {"key_points": "...", "summary": "..."}
# Schritt 3: Bereite Downstream-Kontext vor
downstream_context = DifyVariableBridge.prepare_downstream_context(
upstream_outputs=[extracted_vars, {"user_intent": "lernen"}],
required_vars=["key_points", "summary"] # Was LLM braucht
)
# Schritt 4: Finaler LLM-Call
final_prompt = f"""
Basierend auf folgenden Informationen:
- Key Points: {downstream_context['key_points']}
- Summary: {downstream_context['summary']}
Erkläre dem Nutzer das Thema in 3 Sätzen.
"""
# Call an HolySheep
response = requests.post(
"https://api.holysheep.ai/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY"},
json={
"model": "gpt-4.1",
"messages": [{"role": "user", "content": final_prompt}],
"max_tokens": 200
}
)
return response.json()["choices"][0]["message"]["content"]
Meine Praxiserfahrung: 3 Jahre Dify-Workflow-Design
Als ich 2023 begann, Dify produktiv einzusetzen, war die Variable-Übergabe mein größter Albtraum. In einem Projekt für einen Finanzdienstleister sollten Chatbot-Antworten dynamisch aus einer Datenbank generiert werden – mit 12 Zwischenknoten.
Das Hauptproblem: Jeder Entwickler definierte Variablen unterschiedlich. String hier, JSON dort. Ein LLM-Knoten erwartete eine Liste, bekam aber einen String.
Die Lösung kam mit meinem Wechsel zu HolySheep AI: Ihre API-Kompatibilität ist zu 100% gegeben, und die Latenz von unter 50ms ermöglichte rapid Prototyping. Plötzlich konnte ich Workflows in Minuten testen statt in Stunden.
Mein wichtigstes Learning: Definiere immer einen z