Spaces:
Running
Running
Update index.html
Browse files- index.html +378 -19
index.html
CHANGED
|
@@ -1,19 +1,378 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="de" class="scroll-smooth">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Tutorial: Multi-Agenten-Systeme mit Haystack 2.0</title>
|
| 7 |
+
|
| 8 |
+
<!-- Tailwind CSS -->
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
|
| 11 |
+
<!-- Highlight.js for Code Formatting -->
|
| 12 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
| 13 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
| 14 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
|
| 15 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/xml.min.js"></script>
|
| 16 |
+
|
| 17 |
+
<!-- Google Fonts -->
|
| 18 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
|
| 19 |
+
|
| 20 |
+
<script>
|
| 21 |
+
tailwind.config = {
|
| 22 |
+
theme: {
|
| 23 |
+
extend: {
|
| 24 |
+
fontFamily: {
|
| 25 |
+
sans: ['Inter', 'sans-serif'],
|
| 26 |
+
mono: ['Fira Code', 'monospace'],
|
| 27 |
+
},
|
| 28 |
+
colors: {
|
| 29 |
+
primary: '#2563eb', // Blue-600
|
| 30 |
+
sidebar: '#0f172a', // Slate-900
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
</script>
|
| 36 |
+
|
| 37 |
+
<style>
|
| 38 |
+
body { font-family: 'Inter', sans-serif; }
|
| 39 |
+
pre code { font-family: 'Fira Code', monospace; border-radius: 0.5rem; }
|
| 40 |
+
.prose h2 { margin-top: 2.5rem; margin-bottom: 1rem; font-weight: 700; font-size: 1.5rem; color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.5rem; }
|
| 41 |
+
.prose h3 { margin-top: 2rem; margin-bottom: 0.75rem; font-weight: 600; font-size: 1.25rem; color: #334155; }
|
| 42 |
+
.prose p { margin-bottom: 1.25rem; line-height: 1.75; color: #475569; }
|
| 43 |
+
.prose table { width: 100%; border-collapse: collapse; margin-bottom: 2rem; }
|
| 44 |
+
.prose th, .prose td { border: 1px solid #cbd5e1; padding: 0.75rem; text-align: left; }
|
| 45 |
+
.prose th { background-color: #f1f5f9; font-weight: 600; color: #1e293b; }
|
| 46 |
+
.copy-btn { position: absolute; top: 0.5rem; right: 0.5rem; background: rgba(255,255,255,0.1); color: #fff; border: none; padding: 0.25rem 0.5rem; border-radius: 0.25rem; cursor: pointer; font-size: 0.75rem; transition: background 0.2s; }
|
| 47 |
+
.copy-btn:hover { background: rgba(255,255,255,0.2); }
|
| 48 |
+
.code-wrapper { position: relative; margin-bottom: 1.5rem; }
|
| 49 |
+
</style>
|
| 50 |
+
</head>
|
| 51 |
+
<body class="bg-slate-50 text-slate-800 flex flex-col md:flex-row min-h-screen">
|
| 52 |
+
|
| 53 |
+
<!-- Mobile Header -->
|
| 54 |
+
<div class="md:hidden bg-sidebar text-white p-4 flex justify-between items-center sticky top-0 z-50">
|
| 55 |
+
<h1 class="font-bold text-lg">Haystack 2.0 Tutorial</h1>
|
| 56 |
+
<button id="mobile-menu-btn" class="text-white focus:outline-none">
|
| 57 |
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
|
| 58 |
+
</button>
|
| 59 |
+
</div>
|
| 60 |
+
|
| 61 |
+
<!-- Sidebar Navigation -->
|
| 62 |
+
<nav id="sidebar" class="hidden md:flex flex-col w-full md:w-64 bg-sidebar text-slate-300 h-screen sticky top-0 overflow-y-auto shrink-0 transition-all duration-300 z-40">
|
| 63 |
+
<div class="p-6 hidden md:block">
|
| 64 |
+
<h1 class="text-2xl font-bold text-white tracking-tight">The Infinite Cookbook</h1>
|
| 65 |
+
<p class="text-xs text-slate-400 mt-2">MAS mit Haystack & Hugging Face</p>
|
| 66 |
+
</div>
|
| 67 |
+
<ul class="flex-1 px-4 pb-6 space-y-2 text-sm">
|
| 68 |
+
<li><a href="#intro" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">1. Einleitung & Architektur</a></li>
|
| 69 |
+
<li><a href="#hf-infra" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">2. Hugging Face Infrastruktur</a></li>
|
| 70 |
+
<li><a href="#agent1" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">3. Agent 1: Forschung & Suche</a></li>
|
| 71 |
+
<li><a href="#agent2" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">4. Agent 2: Struktur & Pydantic</a></li>
|
| 72 |
+
<li><a href="#agent3" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">5. Agent 3: Visionär (Bildgen.)</a></li>
|
| 73 |
+
<li><a href="#agent4" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">6. Agent 4: Meta-Aggregator (HTML)</a></li>
|
| 74 |
+
<li><a href="#orchestration" class="block py-2 px-3 rounded hover:bg-slate-800 hover:text-white transition">7. Orchestrierung & Fehlerbehandlung</a></li>
|
| 75 |
+
</ul>
|
| 76 |
+
</nav>
|
| 77 |
+
|
| 78 |
+
<!-- Main Content -->
|
| 79 |
+
<main class="flex-1 w-full max-w-4xl mx-auto p-6 md:p-10 lg:p-12">
|
| 80 |
+
<div class="prose max-w-none">
|
| 81 |
+
|
| 82 |
+
<!-- Hero -->
|
| 83 |
+
<div class="bg-blue-50 border-l-4 border-blue-500 p-6 rounded-r-lg mb-10">
|
| 84 |
+
<h1 class="text-3xl font-bold text-blue-900 mb-2">Tutorial: Bau eines Autonomen Kulinarischen Systems</h1>
|
| 85 |
+
<p class="text-blue-800 m-0">In diesem Tutorial setzen wir die Architektur aus dem Bericht <strong>"Architekturen autonomer kulinarischer Wissenssysteme"</strong> in Code um. Wir bauen "The Infinite Cookbook" mit Haystack 2.0 und der Hugging Face Inference-Infrastruktur.</p>
|
| 86 |
+
</div>
|
| 87 |
+
|
| 88 |
+
<section id="intro">
|
| 89 |
+
<h2>1. Die technologische Basis: Haystack 2.0</h2>
|
| 90 |
+
<p>Der Übergang von Haystack 1.x zu 2.0 markiert einen Paradigmenwechsel. Frühere Versionen waren lineare Ketten; Haystack 2.0 nutzt <strong>Komponenten und Pipelines als dynamische Rechengraphen</strong>. Dies unterstützt Kontrollflüsse, Schleifen und präzise Datenflusssteuerung – die Grundlage für echte Agenten.</p>
|
| 91 |
+
<p>Anstatt ein einzelnes, überfordertes LLM zu nutzen, orchestrieren wir eine Koalition spezialisierter Einheiten. Typprüfung an den Ein- und Ausgabesockets sichert die Stabilität.</p>
|
| 92 |
+
</section>
|
| 93 |
+
|
| 94 |
+
<section id="hf-infra">
|
| 95 |
+
<h2>2. Hugging Face Inference Provider</h2>
|
| 96 |
+
<p>Die Integration von Open-Source-Modellen erfolgt primär über die <code>HuggingFaceAPIChatGenerator</code>-Komponente. Seit Juli 2025 sind <code>chat_completion</code>-Endpunkte der Standard. Hier ist eine Übersicht der Infrastruktur-Optionen:</p>
|
| 97 |
+
|
| 98 |
+
<div class="overflow-x-auto">
|
| 99 |
+
<table>
|
| 100 |
+
<thead>
|
| 101 |
+
<tr>
|
| 102 |
+
<th>Infrastruktur-Option</th>
|
| 103 |
+
<th>Charakteristika</th>
|
| 104 |
+
<th>Anwendungsfall im MAS</th>
|
| 105 |
+
</tr>
|
| 106 |
+
</thead>
|
| 107 |
+
<tbody>
|
| 108 |
+
<tr>
|
| 109 |
+
<td><strong>Serverless Inference API</strong></td>
|
| 110 |
+
<td>Kostenlos/Rate-limited, schnell für Experimente</td>
|
| 111 |
+
<td>Prototyping und einfache Zusammenfassungen.</td>
|
| 112 |
+
</tr>
|
| 113 |
+
<tr>
|
| 114 |
+
<td><strong>Inference Endpoints</strong></td>
|
| 115 |
+
<td>Dedizierte Instanzen, stundenbasierte Abrechnung</td>
|
| 116 |
+
<td>Produktion, hohe Last, garantierte Latenz für Bildgenerierung.</td>
|
| 117 |
+
</tr>
|
| 118 |
+
<tr>
|
| 119 |
+
<td><strong>Text Generation Inference (TGI)</strong></td>
|
| 120 |
+
<td>Optimiertes Serving, unterstützt JSON-Guiding</td>
|
| 121 |
+
<td>Komplexe Datenextraktion mit strikter Schema-Einhaltung.</td>
|
| 122 |
+
</tr>
|
| 123 |
+
<tr>
|
| 124 |
+
<td><strong>Lokale Transformer</strong></td>
|
| 125 |
+
<td>Volle Kontrolle, erfordert eigene GPU-Ressourcen</td>
|
| 126 |
+
<td>Datenschutz-kritische Anwendungen oder Offline-Betrieb.</td>
|
| 127 |
+
</tr>
|
| 128 |
+
</tbody>
|
| 129 |
+
</table>
|
| 130 |
+
</div>
|
| 131 |
+
</section>
|
| 132 |
+
|
| 133 |
+
<section id="agent1">
|
| 134 |
+
<h2>3. Agent 1: Der kulinarische Forschungs-Spezialist</h2>
|
| 135 |
+
<p>Dieser Agent durchsucht das Web iterativ nach authentischen Rezepten. Er nutzt Suchmaschinen, extrahiert HTML, bereinigt es und rankt die Ergebnisse nach Relevanz (Context Optimization).</p>
|
| 136 |
+
|
| 137 |
+
<div class="code-wrapper">
|
| 138 |
+
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
|
| 139 |
+
<pre><code class="language-python">from haystack import Pipeline
|
| 140 |
+
from haystack.components.websearch import SerperDevWebSearch
|
| 141 |
+
from haystack.components.fetchers import LinkContentFetcher
|
| 142 |
+
from haystack.components.converters import HTMLToDocument
|
| 143 |
+
from haystack.components.rankers import TransformersSimilarityRanker
|
| 144 |
+
|
| 145 |
+
# Pipeline-Definition für den Forschungs-Agenten
|
| 146 |
+
research_pipe = Pipeline()
|
| 147 |
+
|
| 148 |
+
# Komponenten hinzufügen
|
| 149 |
+
research_pipe.add_component("search", SerperDevWebSearch(api_key="DEIN_API_KEY"))
|
| 150 |
+
research_pipe.add_component("fetcher", LinkContentFetcher())
|
| 151 |
+
research_pipe.add_component("html_converter", HTMLToDocument())
|
| 152 |
+
research_pipe.add_component("ranker", TransformersSimilarityRanker(model="cross-encoder/ms-marco-MiniLM-L-6-v2"))
|
| 153 |
+
|
| 154 |
+
# Graph verbinden
|
| 155 |
+
research_pipe.connect("search.links", "fetcher.urls")
|
| 156 |
+
research_pipe.connect("fetcher.streams", "html_converter.sources")
|
| 157 |
+
research_pipe.connect("html_converter.documents", "ranker.documents")
|
| 158 |
+
|
| 159 |
+
# Ausführungssimulation (Im echten System orchestriert durch den Koordinator)
|
| 160 |
+
# result = research_pipe.run({"search": {"query": "authentische neapolitanische Pizza"}, "ranker": {"query": "authentische neapolitanische Pizza"}})
|
| 161 |
+
</code></pre>
|
| 162 |
+
</div>
|
| 163 |
+
</section>
|
| 164 |
+
|
| 165 |
+
<section id="agent2">
|
| 166 |
+
<h2>4. Agent 2: Der Struktur-Architekt für Rezeptdaten</h2>
|
| 167 |
+
<p>Die unstrukturierten Forschungsnotizen müssen in ein maschinenlesbares Format überführt werden. Haystack 2.0 unterstützt die Generierung strukturierter Ausgaben nativ über <strong>Pydantic-Modelle</strong>.</p>
|
| 168 |
+
|
| 169 |
+
<div class="code-wrapper">
|
| 170 |
+
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
|
| 171 |
+
<pre><code class="language-python">from pydantic import BaseModel
|
| 172 |
+
from typing import List, Dict, Literal
|
| 173 |
+
|
| 174 |
+
# Definition des Pydantic-Schemas laut Spezifikation
|
| 175 |
+
class Ingredient(BaseModel):
|
| 176 |
+
name: str
|
| 177 |
+
amount: float
|
| 178 |
+
unit: str
|
| 179 |
+
|
| 180 |
+
class RecipeStructure(BaseModel):
|
| 181 |
+
recipe_title: str
|
| 182 |
+
servings: int
|
| 183 |
+
ingredients: List[Ingredient]
|
| 184 |
+
instructions: List[str]
|
| 185 |
+
nutrients: Dict[str, float]
|
| 186 |
+
difficulty: Literal["Einfach", "Mittel", "Schwer"]
|
| 187 |
+
|
| 188 |
+
# Nutzung im HuggingFace Chat Generator (mit TGI & JSON Guiding)
|
| 189 |
+
# generator = HuggingFaceAPIChatGenerator(
|
| 190 |
+
# api_type="text_generation_inference",
|
| 191 |
+
# generation_kwargs={"response_format": RecipeStructure.schema_json()}
|
| 192 |
+
# )
|
| 193 |
+
</code></pre>
|
| 194 |
+
</div>
|
| 195 |
+
<p>Durch die Erzwingung dieses Schemas werden Halluzinationen in der Struktur eliminiert. Der Agent wird zudem angewiesen, <em>keine eigenen Fakten zu erfinden</em>, sondern sich streng an den Kontext von Agent 1 zu halten.</p>
|
| 196 |
+
</section>
|
| 197 |
+
|
| 198 |
+
<section id="agent3">
|
| 199 |
+
<h2>5. Agent 3: Der Visionär - Bildgenerierung</h2>
|
| 200 |
+
<p>Ein Kochbuch braucht Bilder. Da Standard-Generatoren textbasiert sind, implementieren wir eine <strong>benutzerdefinierte Komponente</strong> mit dem <code>@component</code>-Dekorator, die z.B. Stable Diffusion XL (SDXL) über die Hugging Face <code>diffusers</code> Bibliothek anspricht.</p>
|
| 201 |
+
|
| 202 |
+
<div class="code-wrapper">
|
| 203 |
+
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
|
| 204 |
+
<pre><code class="language-python">from haystack import component
|
| 205 |
+
from haystack.dataclasses import ImageContent
|
| 206 |
+
# import diffusers ...
|
| 207 |
+
|
| 208 |
+
@component
|
| 209 |
+
class StableDiffusionGenerator:
|
| 210 |
+
def __init__(self, model_id="stabilityai/stable-diffusion-xl-base-1.0"):
|
| 211 |
+
self.model_id = model_id
|
| 212 |
+
# self.pipe = DiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
|
| 213 |
+
# Optimierungen wie CPU-Offloading hier initialisieren
|
| 214 |
+
|
| 215 |
+
@component.output_types(image=ImageContent)
|
| 216 |
+
def run(self, prompt: str):
|
| 217 |
+
# Optimierter Prompt z.B.: "Dampfende Lasagne in einer rustikalen Keramikform..."
|
| 218 |
+
|
| 219 |
+
# image = self.pipe(prompt).images[0]
|
| 220 |
+
# Bild in Base64 umwandeln für Multimodalen Fluss
|
| 221 |
+
# base64_str = image_to_base64(image)
|
| 222 |
+
|
| 223 |
+
# Rückgabe als Haystack 2.0 ImageContent Objekt
|
| 224 |
+
return {"image": ImageContent.from_base64(base64_str)}
|
| 225 |
+
</code></pre>
|
| 226 |
+
</div>
|
| 227 |
+
</section>
|
| 228 |
+
|
| 229 |
+
<section id="agent4">
|
| 230 |
+
<h2>6. Agent 4: Der Meta-Aggregator und HTML-Designer</h2>
|
| 231 |
+
<p>Der letzte Agent empfängt das strukturierte Rezept (JSON) und das Bild (Base64) und verpackt es mithilfe von <strong>Jinja2-Templating</strong> in ansprechendes HTML. Dies erfordert keine externen Abhängigkeiten mehr.</p>
|
| 232 |
+
|
| 233 |
+
<div class="code-wrapper">
|
| 234 |
+
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
|
| 235 |
+
<pre><code class="language-xml"><!-- Jinja2 Template für den HTML-Agenten -->
|
| 236 |
+
<div class="recipe-card">
|
| 237 |
+
<h1>{{ recipe_title }}</h1>
|
| 238 |
+
|
| 239 |
+
<!-- Das Bild wird direkt als Base64 eingebettet -->
|
| 240 |
+
<img src="data:image/png;base64,{{ image_base64 }}" alt="{{ recipe_title }}">
|
| 241 |
+
|
| 242 |
+
<div class="meta">
|
| 243 |
+
<span>Zeit: {{ prep_time + cook_time }} min</span>
|
| 244 |
+
<span>Schwierigkeit: {{ difficulty }}</span>
|
| 245 |
+
</div>
|
| 246 |
+
|
| 247 |
+
<h3>Zutaten</h3>
|
| 248 |
+
<ul>
|
| 249 |
+
{% for ingredient in ingredients %}
|
| 250 |
+
<li>{{ ingredient.amount }} {{ ingredient.unit }} {{ ingredient.name}}</li>
|
| 251 |
+
{% endfor %}
|
| 252 |
+
</ul>
|
| 253 |
+
|
| 254 |
+
<h3>Zubereitung</h3>
|
| 255 |
+
<ol>
|
| 256 |
+
{% for step in instructions %}
|
| 257 |
+
<li>{{ step }}</li>
|
| 258 |
+
{% endfor %}
|
| 259 |
+
</ol>
|
| 260 |
+
</div></code></pre>
|
| 261 |
+
</div>
|
| 262 |
+
</section>
|
| 263 |
+
|
| 264 |
+
<section id="orchestration">
|
| 265 |
+
<h2>7. Orchestrierung und das Zusammenspiel der Agenten</h2>
|
| 266 |
+
<p>Die Koordination erfolgt über den <strong>"Agent-as-a-Tool"</strong>-Ansatz. Ein Haupt-Agent (Coordinator) übersetzt die Nutzeranfrage (z.B. <em>"Erstelle ein Rezept für ein thailändisches grünes Curry..."</em>) in Tool-Aufrufe.</p>
|
| 267 |
+
<ol class="list-decimal pl-6 mb-6 space-y-2 text-slate-600">
|
| 268 |
+
<li><strong>Recherche-Delegation:</strong> Aufruf von <code>research_tool</code>.</li>
|
| 269 |
+
<li><strong>Strukturierungs-Delegation:</strong> Aufruf von <code>recipe_summary_tool</code> (liefert Pydantic-Objekt).</li>
|
| 270 |
+
<li><strong>Visualisierungs-Delegation:</strong> Aufruf von <code>image_generation_tool</code>.</li>
|
| 271 |
+
<li><strong>Meta-Verpackung:</strong> Aufruf von <code>html_packaging_tool</code>.</li>
|
| 272 |
+
</ol>
|
| 273 |
+
|
| 274 |
+
<h3>Fehlerbehandlung mit Routern</h3>
|
| 275 |
+
<p>Falls ein Sub-Agent scheitert (z.B. keine Quellen gefunden), greift Haystacks Kontrollfluss-Logik ein:</p>
|
| 276 |
+
|
| 277 |
+
<div class="overflow-x-auto">
|
| 278 |
+
<table>
|
| 279 |
+
<thead>
|
| 280 |
+
<tr>
|
| 281 |
+
<th>Mechanismus</th>
|
| 282 |
+
<th>Komponente (Haystack)</th>
|
| 283 |
+
<th>Nutzen im kulinarischen MAS</th>
|
| 284 |
+
</tr>
|
| 285 |
+
</thead>
|
| 286 |
+
<tbody>
|
| 287 |
+
<tr>
|
| 288 |
+
<td><strong>Tool Invocation</strong></td>
|
| 289 |
+
<td><code>ToolInvoker</code></td>
|
| 290 |
+
<td>Führt die geplanten Aktionen (Suche, Bildgen) aus.</td>
|
| 291 |
+
</tr>
|
| 292 |
+
<tr>
|
| 293 |
+
<td><strong>State Management</strong></td>
|
| 294 |
+
<td>Agent State</td>
|
| 295 |
+
<td>Speichert das Rezeptobjekt über Agenten-Grenzen hinweg.</td>
|
| 296 |
+
</tr>
|
| 297 |
+
<tr>
|
| 298 |
+
<td><strong>Exit Conditions</strong></td>
|
| 299 |
+
<td><code>exit_conditions</code></td>
|
| 300 |
+
<td>Beendet den Loop, sobald der finale HTML-Code vorliegt.</td>
|
| 301 |
+
</tr>
|
| 302 |
+
<tr>
|
| 303 |
+
<td><strong>Fehlerkorrektur</strong></td>
|
| 304 |
+
<td><code>ConditionalRouter</code></td>
|
| 305 |
+
<td>Leitet bei Tool-Fehlern den Fluss zurück zur Modifikation (z.B. neuer Such-Prompt).</td>
|
| 306 |
+
</tr>
|
| 307 |
+
</tbody>
|
| 308 |
+
</table>
|
| 309 |
+
</div>
|
| 310 |
+
|
| 311 |
+
<div class="mt-8 p-4 bg-slate-100 rounded-lg text-sm text-slate-600 border border-slate-200">
|
| 312 |
+
<strong>Fazit:</strong> Durch die Zerlegung in spezialisierte Pipelines und die Nutzung von Hugging Face Modellen (Qwen, Llama-3, Mistral, FLUX) über Haystack 2.0 entsteht ein robustes, schema-treues System, das den neuen Standard für KI-gestützte Content-Generierung definiert.
|
| 313 |
+
</div>
|
| 314 |
+
</section>
|
| 315 |
+
|
| 316 |
+
<footer class="mt-16 pt-8 border-t border-slate-200 text-sm text-slate-500 text-center">
|
| 317 |
+
<p>Basierend auf dem Bericht: "Architekturen autonomer kulinarischer Wissenssysteme". Generiert für das "The Infinite Cookbook" Projekt.</p>
|
| 318 |
+
</footer>
|
| 319 |
+
</div>
|
| 320 |
+
</main>
|
| 321 |
+
|
| 322 |
+
<script>
|
| 323 |
+
// Syntax Highlighting initialisieren
|
| 324 |
+
document.addEventListener('DOMContentLoaded', (event) => {
|
| 325 |
+
hljs.highlightAll();
|
| 326 |
+
});
|
| 327 |
+
|
| 328 |
+
// Mobile Menu Toggle
|
| 329 |
+
const btn = document.getElementById('mobile-menu-btn');
|
| 330 |
+
const sidebar = document.getElementById('sidebar');
|
| 331 |
+
|
| 332 |
+
btn.addEventListener('click', () => {
|
| 333 |
+
sidebar.classList.toggle('hidden');
|
| 334 |
+
});
|
| 335 |
+
|
| 336 |
+
// Smooth scroll adjustment for fixed header (mobile)
|
| 337 |
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
| 338 |
+
anchor.addEventListener('click', function (e) {
|
| 339 |
+
e.preventDefault();
|
| 340 |
+
if(window.innerWidth < 768) {
|
| 341 |
+
sidebar.classList.add('hidden'); // Close menu on click on mobile
|
| 342 |
+
}
|
| 343 |
+
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
| 344 |
+
behavior: 'smooth'
|
| 345 |
+
});
|
| 346 |
+
});
|
| 347 |
+
});
|
| 348 |
+
|
| 349 |
+
// Copy to clipboard function
|
| 350 |
+
function copyCode(button) {
|
| 351 |
+
const codeBlock = button.nextElementSibling.querySelector('code');
|
| 352 |
+
const textToCopy = codeBlock.innerText;
|
| 353 |
+
|
| 354 |
+
// Clipboard API fallback
|
| 355 |
+
const textArea = document.createElement("textarea");
|
| 356 |
+
textArea.value = textToCopy;
|
| 357 |
+
document.body.appendChild(textArea);
|
| 358 |
+
textArea.select();
|
| 359 |
+
|
| 360 |
+
try {
|
| 361 |
+
document.execCommand('copy');
|
| 362 |
+
const originalText = button.innerText;
|
| 363 |
+
button.innerText = 'Kopiert!';
|
| 364 |
+
button.classList.add('bg-green-600');
|
| 365 |
+
|
| 366 |
+
setTimeout(() => {
|
| 367 |
+
button.innerText = originalText;
|
| 368 |
+
button.classList.remove('bg-green-600');
|
| 369 |
+
}, 2000);
|
| 370 |
+
} catch (err) {
|
| 371 |
+
console.error('Kopieren fehlgeschlagen', err);
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
document.body.removeChild(textArea);
|
| 375 |
+
}
|
| 376 |
+
</script>
|
| 377 |
+
</body>
|
| 378 |
+
</html>
|