Weiter zum Inhalt

Qwen 3.7 Max API-Tutorial: Baue einen selbstprüfenden Produktivitätsagenten

Lerne, wie du mit Qwen 3.7 Max über OpenRouter einen Produktivitätsagenten baust, der in einer Streamlit-App plant, recherchiert, schreibt und sein eigenes Ergebnis überprüft.
Aktualisiert 18. Sept. 2026  · 15 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Die meisten KI-Demos wirken noch wie Chatbots: Du stellst eine Frage, das Modell antwortet, und die Interaktion ist vorbei. Echte Produktivitätsarbeit läuft aber selten in einem Schritt ab. Ein hilfreicher Assistent muss eine vage Anfrage herunterbrechen, Kontext sammeln, Optionen vergleichen, ein nutzbares Artefakt erstellen und vor der Übergabe die eigene Arbeit prüfen.

Qwen 3.7 Max ist ein agentisches Modell des Qwen-Teams, entwickelt für agentenzentrierte Workloads wie Coding, Office-Aufgaben und langlaufende Ausführungen. Es ist ein Agent-First-Modell, das nicht nur eine einzelne Eingabe gut beantwortet, sondern über längere Workflows hinweg kohärent bleibt – inklusive Planung, Toolnutzung, Schreiben und Selbstkorrektur. 

In diesem Tutorial bauen wir einen kompakten Produktivitätsagenten mit Qwen 3.7 Max und Streamlit. Die App nimmt eine vage Business-Anfrage, zum Beispiel die Vorbereitung einer Wettbewerbsanalyse von Vektordatenbanken, und verwandelt sie in eine ausformulierte competitive_analysis.md-Datei.

Am Ende dieses Tutorials weißt du, wie du:

  • Einen festen Fünf-Schritte-Agentenworkflow aufsetzt

  • enable_thinking=True und preserve_thinking=True nutzt

  • Leichtgewichtige parallele Recherchen einbaust

  • Ein Markdown-Artefakt schreibst und patchst

  • Eine einfache Streamlit-UI um den Workflow baust

Der komplette Code liegt im GitHub-Repository. 

Das Projekt ist bewusst klein gehalten. Die Hauptlogik ist aufgeteilt in agent.py für die Streamlit-App und thinking_agent.py für den Backend-Workflow.

Wenn du neu im Thema agentische KI bist, starte am besten mit unserem AI Agent Fundamentals-Lernpfad.

Was ist Qwen 3.7 Max?

Qwen 3.7 Max ist Alibabas neues Flaggschiffmodell, veröffentlicht am 20. Mai 2026. Es ist für agentische Workflows gebaut. Das bedeutet: Statt nur für One-Shot-Chat ausgelegt zu sein, ist es optimiert für Aufgaben, die Planung, Toolnutzung, Coding, Office-Automatisierung, Reasoning mit langem Kontext und mehrstufige Ausführung erfordern. 

Das Qwen-Team beschreibt es als Modell für das „Agenten-Zeitalter“ – stark bei Coding-Agenten, Produktivitätsassistenten, MCP-basierten Workflows und autonomen Langläufern.

Spannend ist hier nicht nur die reine Benchmark-Leistung, sondern vor allem die Fähigkeit, über eine mehrstufige Aufgabe konsistent zu bleiben, bei der jede Phase einen anderen Zweck hat, darunter:

  • Planung
  • Evidenzsynthese
  • Langform-Schreiben
  • Selbstkritik
  • Überarbeitung

Auf X berichteten Nutzer, dass das Modell bei langlaufenden Coding-Aufgaben mit Opus 4.7 und GPT 5.5 mithält.

X-Post: Qwen 3.7 Max vs. Opus 4.7

Stärken und Benchmark-Leistung von Qwen 3.7 Max

Qwen 3.7 Max überzeugt in Agenten- und Reasoning-Benchmarks. In Coding-Agent-Tests erzielt es 

  • 69,7 auf Terminal-Bench 2.0-Terminus
  • 60,6 auf SWE-bench Pro
  • 78,3 auf SWE-bench Multilingual
  • 47,2 auf NL2Repo
  • 53,5 auf SciCode

In General-Agent-Benchmarks erreicht es 

  • 60,8 auf MCP-Mark
  • 76,4 auf MCP-Atlas
  • 67,2 auf CoWorkBench
  • 87,0 auf SpreadSheetBench-v1

Qwen 3.7 Max Benchmarks

Quelle: Qwen Developer Blog

Zur Einordnung: Alle diese Ergebnisse liegen vor den Werten von DeepSeek V4 Pro; meist knapp, aber bei langlaufenden Coding-Aufgaben gibt es einen deutlichen Abstand (47,2 vs. 35,5 in NL2Repo).

Ein Highlight aus dem Release: Der Long-Horizon-Kernel-Optimierungslauf von Qwen 3.7 Max. Das Modell lief rund 35 Stunden, rief 1.158 Tools auf, führte 432 Kernel-Evaluierungen durch und erzielte einen geometrischen mittleren Speedup von 10,0x gegenüber einer Triton-Referenzimplementierung. 

Das ist wichtig, weil hier iterative toolgestützte Verbesserungen bewertet werden – nicht nur statische Benchmark-Fragen.

Kurz: Qwen 3.7 Max passt sehr gut zu dieser Demo, weil es für Workflows gebaut ist, in denen das Modell denken, Tools nutzen, Kontext bewahren und ein Artefakt über mehrere Schritte verbessern muss.

Einen „Thinking-Preserving“ Produktivitätsagenten mit Qwen 3.7 Max bauen

In diesem Projekt zeigen wir drei praktische Ideen:

  • Aus einer vagen Nutzereingabe wird ein strukturierter, mehrstufiger Workflow.
  • Tool-Ausgaben fließen schrittweise in den Denkprozess ein, statt in einem einzigen langen Prompt zu landen.
  • Ein Modell kann sein eigenes Ergebnis per Chain-of-Thought-Prompting gegenlesen und verbessern, bevor es das finale Artefakt übergibt.

Projektüberblick

Wir bauen eine einfache Anwendung mit einem Eingabefeld und einem Button. Die Nutzerin gibt eine vage Anfrage ein wie:

I need to prepare a competitive analysis of the top 3 vector databases
for a team presentation next week. I have no idea where to start.

Demo

Anschließend läuft der Agent durch einen festen Fünf-Schritte-Workflow:

User prompt
Turn 1: Plan the work
Parallel research for Pinecone, Weaviate, and Qdrant
Turn 2: Summarize research
Turn 3: Build comparison matrix
Turn 4: Write competitive_analysis.md
Turn 5: Self-review and patch the markdown file
Streamlit file preview

Die UI zeigt jeden Schritt als Fortschrittskarte. Während der Workflow durchläuft, wechseln die Karten von „wartend“ zu „fertig“. Am Ende kann die Nutzerin jede Phase prüfen: Planung, Recherche, Synthese, Entwurf, Selbstreview und finale Dateivorschau.

So wird der Agenten-Workflow sichtbar, statt alles hinter einer einzelnen Chat-Antwort zu verstecken.

Das Repo ist bewusst klein. Die Hauptbausteine sind:

  • thinking_agent.py: Enthält die Backend-Agentenlogik, z. B. Modellaufrufe, Prompts, Thinking Preservation, Recherche, Retries, Dateischreiben und Selbstreview.

  • agent.py: Beinhaltet die Streamlit-Oberfläche, inkl. Seitenlayout, Prompt-Feld, Fortschrittsbalken, Schritt-Karten, Ergebniswahl, Markdown-Vorschau und Download-Button.

  • requirements.txt: Laufzeit-Abhängigkeiten für die Demo

Im Backend steht eine ThinkingAgent-Klasse im Zentrum, die eine feste Fünf-Schritte-Sequenz ausführt und strukturierte Turn-Records zurückgibt. Die UI muss nicht wissen, wie Modellaufrufe, Retries oder Research-Fanout funktionieren – sie rendert nur die eingehenden Turns.

Den vollständigen Code findest du auf GitHub.

Hinweis: Ich habe OpenRouter verwendet, um auf Qwen 3.7 Max zuzugreifen. Du kannst das Modell aber auch über die offizielle Qwen API Platform nutzen. 

Schritt 1: Umgebung einrichten

Bevor wir den Qwen 3.7 Max Produktivitätsagenten bauen, richten wir eine kleine Python-Umgebung mit Streamlit, dem OpenAI-kompatiblen Client und httpx für eine leichtgewichtige Websuche ein.

In diesem Tutorial nutzen wir OpenRouter als Model Gateway, aber das Backend ist im OpenAI-kompatiblen API-Format geschrieben. Das heißt, die gleiche Struktur lässt sich später für Alibaba Cloud Model Studio oder andere kompatible Anbieter anpassen.

In diesem Schritt werden wir:

  • Eine virtuelle Umgebung erstellen

  • Benötigte Abhängigkeiten installieren

  • OPENROUTER_API_KEY oder QWEN_API_KEY setzen

  • Prüfen, dass die App mit Streamlit startet

Virtuelle Umgebung erstellen und aktivieren:

python3 -m venv .venv
source .venv/bin/activate

Projektabhängigkeiten installieren:

pip install -r requirements.txt

Die requirements.txt ist bewusst schlank:

httpx>=0.23.0
openai>=1.30.0
streamlit>=1.45.0

Wir nutzen streamlit für die interaktive Weboberfläche, openai für Aufrufe an Qwen 3.7 Max über eine OpenAI-kompatible API und httpx, um schlanke Live-Suchergebnisse für den Recherche-Schritt abzurufen.

Schritt 2: Qwen 3.7 Max Client konfigurieren

Das Backend nutzt das OpenAI Python SDK, weil OpenRouter einen OpenAI-kompatiblen Endpunkt bereitstellt. Die Datei thinking_agent.py definiert einige Defaults:

from openai import OpenAI
DEFAULT_MODEL = "qwen/qwen3.7-max"
DEFAULT_BASE_URL = "https://openrouter.ai/api/v1"
DEFAULT_REFERER = "https://qwen.ai"
DEFAULT_TITLE = "Qwen3.7-Max Productivity Agent"

Dann erstellen wir einen Client:

def build_client(
   api_key: str | None = None,
   base_url: str | None = None,
   referer: str = DEFAULT_REFERER,
   title: str = DEFAULT_TITLE,
) -> OpenAI:
   return OpenAI(
       base_url=base_url or DEFAULT_BASE_URL,
       api_key=api_key,
       default_headers={
           "HTTP-Referer": referer,
           "X-Title": title,
       },
   )

Die Funktion build_client() bündelt alle providerspezifischen Einstellungen. Der Rest der App muss nicht wissen, ob die Anfrage über OpenRouter, Alibaba Cloud Model Studio oder einen anderen kompatiblen Endpunkt läuft.

Sobald der Client konfiguriert ist, kann das Backend Qwen 3.7 Max mit dem Standardformat für Chat Completions aufrufen.

Jetzt bauen wir den Kern-Workflow des ThinkingAgent.

Schritt 3: Fünf-Schritte-Agentenworkflow

Nachdem der Modellclient steht, definieren wir den Backend-Workflow. Statt Qwen 3.7 Max einen kompletten Bericht in einem Rutsch generieren zu lassen, teilen wir die Aufgabe in fünf gesteuerte Phasen.

  • Planung: Macht aus dem vagen Prompt einen strukturierten Aufgabenplan.

  • Recherche: Sammelt und fasst Belege aus externen Snippets zusammen.

  • Synthese: Erstellt aus der Recherche eine Vergleichsmatrix.

  • Entwurf: Schreibt den ersten competitive_analysis.md-Bericht.

  • Selbstreview: Prüft und patcht den Bericht vor der finalen Übergabe.

class ThinkingAgent:
   def run(
       self,
       goal: str,
       preserve_thinking: bool = True,
       data_mode: str = "live",
       on_turn: Callable[[TurnRecord], None] | None = None,
   ) -> ThinkingRunResult:
       history = [{"role": "system", "content": SYSTEM_PROMPT}]
       turns = []
       backend = self._build_search_backend(data_mode)
       turn1 = self._run_turn(
           history=history,
           turn_index=1,
           phase="planning",
           user_prompt=_planning_prompt(goal),
           preserve_thinking=preserve_thinking,
       )
       search_results = self._run_research(backend)
       turn2 = self._run_turn(
           history=history,
           turn_index=2,
           phase="research",
           user_prompt=_research_prompt(goal, search_results),
           preserve_thinking=preserve_thinking,
       )


       turn3 = self._run_turn(
           history=history,
           turn_index=3,
           phase="synthesis",
           user_prompt=_synthesis_prompt(),
           preserve_thinking=preserve_thinking,
       )
       turn4 = self._run_turn(
           history=history,
           turn_index=4,
           phase="draft",
           user_prompt=_draft_prompt(goal),
           preserve_thinking=preserve_thinking,
       )
       turn5 = self._run_turn(
           history=history,
           turn_index=5,
           phase="self_review",
           user_prompt=_self_review_prompt(draft_markdown),
           preserve_thinking=preserve_thinking,
       )

Die run()-Methode ist die Hauptorchestrierung. Sie startet mit einem Systemprompt, legt eine Gesprächshistorie an, baut ein Recherche-Backend und führt dann die fünf Turns nacheinander aus.

Jeder Aufruf von _run_turn() hat eine klare Phase. So lässt sich der Workflow besser debuggen, weil jeder Modellaufruf eine eindeutige Verantwortung hat. Die Planungsphase plant. Die Recherchephase interpretiert externe Snippets. Die Synthesephase baut Struktur. Die Entwurfsphase schreibt. Die Selbstreview-Phase verbessert den Output.

Die Recherche liegt zwischen Turn 1 und Turn 2, weil das Modell erst die Aufgabe verstehen soll, bevor externe Informationen in den Workflow einfließen.

Im nächsten Schritt fügen wir die Qwen-spezifische Thinking-Preservation-Logik hinzu, damit das Modell über die Turns hinweg konsistent bleibt.

Schritt 4: Denken über Turns hinweg bewahren

Der Hauptgrund für Qwen 3.7 Max in dieser Demo ist die Unterstützung für Thinking-Preservation-Workflows. Der Agent behandelt Modellaufrufe nicht als isolierte Prompts. Stattdessen kann er das Reasoning früherer Turns bewahren und in spätere Turns mitgeben.

In diesem Schritt werden wir:

  • Modelldenken aktivieren.
  • Reasoning über Turns hinweg bewahren.
  • Assistant-Antworten zurück in die gemeinsame Historie schreiben.
response = self.client.chat.completions.create(
   model=self.config.model,
   messages=request_messages,
   extra_body={
       "enable_thinking": True,
       "preserve_thinking": preserve_thinking,
   },
)

Das Flag enable_thinking=True erlaubt Qwen 3.7 Max, während der Antwort Reasoning-Inhalte zu erzeugen. Das Flag preserve_thinking steuert, ob diese Reasoning-Inhalte in späteren Turns verfügbar bleiben.

Nach der Modellantwort extrahiert das Backend sowohl die sichtbare Antwort als auch das Reasoning:

message = response.choices[0].message
assistant_content = _normalize_text(getattr(message, "content", ""))
reasoning_content = _extract_reasoning_content(message)
The visible answer is what the app can show to the user. The reasoning content is used internally to help the next turn stay aligned with the earlier plan.
Then the backend appends the assistant message back into the conversation history:
```python
assistant_message = {
   "role": "assistant",
   "content": assistant_content,
}
if preserve_thinking and reasoning_content:
   assistant_message["reasoning_content"] = reasoning_content
history.append(assistant_message)

Wenn die Planungsphase entscheidet, dass der Abschlussbericht Vektordatenbanken nach Bereitstellungsmodell, Skalierbarkeit, Developer Experience, Hybrid Search und Enterprise-Tauglichkeit vergleicht, können spätere Turns diese Kriterien weiterverwenden. Ohne Thinking Preservation würden Turns leichter driften: Die Synthese könnte andere Kriterien als die Planung wählen oder die Selbstreview gegen ein anderes Ziel prüfen.

Als Nächstes fügen wir die Rechercheebene hinzu, um dem Agenten externen Kontext zu geben, bevor er den Bericht schreibt.

Schritt 5: Parallele Recherche mit Fallback-Daten

Bevor das Modell eine Wettbewerbsanalyse schreibt, braucht es externen Kontext. In dieser Demo halten wir den Rechercheumfang konstant und vergleichen drei Vektordatenbanken: Pinecone, Weaviate und Qdrant.

In diesem Schritt werden wir:

  • Zieldatenbanken festlegen.
  • Rechercheaufrufe parallel ausführen.
  • Bei Ausfall der Live-Suche deterministische Fixture-Daten nutzen.
DATABASES = ("Pinecone", "Weaviate", "Qdrant")

Die Zielliste ist bewusst fest. So bleibt die Demo stabil und leichter zu erklären. Später kannst du das Projekt erweitern, damit das Modell die Vergleichsobjekte dynamisch wählt.

Als Nächstes startet das Backend parallele Rechercheaufrufe:

from concurrent.futures import ThreadPoolExecutor, as_completed
with ThreadPoolExecutor(max_workers=3) as executor:
   future_map = {
       executor.submit(backend.search, database, query): database
       for database, query in queries.items()
   }
   for future in as_completed(future_map):
       database = future_map[future]
       results[database] = future.result()

Der ThreadPoolExecutor startet pro Datenbank eine Suche. Das ist schneller als nacheinander, weil die Recherche zu Pinecone, Weaviate und Qdrant parallel läuft.

try:
   results[database] = future.result()
except Exception as exc:
   fallback = FixtureSearchBackend().search(database, queries[database])
   fallback.warning = (
       f"Live search failed for {database} ({exc}). "
       "Fallback demo research was used."
   )
   results[database] = fallback

Wenn die Live-Suche klappt, nutzt der Agent frische Snippets. Falls nicht, wird der Workflow mit eingebauten, deterministischen Recherche-Snippets abgeschlossen. Wichtig ist das Prinzip der „graceful degradation“: Der Agent darf nicht abstürzen, nur weil eine externe Abhängigkeit ausfällt.

Im nächsten Schritt geben wir diese Rechercheergebnisse an Qwen 3.7 Max, damit es eine Vergleichsmatrix synthetisiert.

Schritt 6: Synthese und Vergleichsmatrix erzeugen

Sobald der Agent Recherche-Snippets hat, folgt die Synthese. Dieser Schritt verwandelt verstreute Informationen in einen strukturierten Vergleich, der den Abschlussbericht stützt.

In diesem Schritt werden wir:

  • Den Recherchekontext an Qwen 3.7 Max zurückgeben.
  • Das Modell um eine strukturierte Gegenüberstellung bitten.
  • Diese später in der Streamlit-Oberfläche darstellen.
turn3 = self._run_turn(
   history=history,
   turn_index=3,
   phase="synthesis",
   user_prompt=_synthesis_prompt(),
   preserve_thinking=preserve_thinking,
)

Zu diesem Zeitpunkt enthält die Historie bereits die ursprüngliche Anfrage, die Planung, die Recherchezusammenfassungen und optional das bewahrte Reasoning aus früheren Turns.

Der Synthese-Prompt muss die Aufgabe daher nicht komplett wiederholen. Er konzentriert sich auf eine Aufgabe: Die Recherche in eine entscheidungsreife Vergleichsmatrix zu überführen.

Eine gute Synthese vergleicht Optionen entlang Dimensionen wie:

  • Bereitstellungsmodell
  • Skalierbarkeit
  • Developer Experience
  • Unterstützung hybrider Suche
  • Enterprise-Tauglichkeit
  • Passendstes Einsatzszenario

Auf dieser Struktur aufbauend schreiben wir anschließend den ersten Markdown-Bericht.

Schritt 7: Den Markdown-Bericht schreiben

Nach Planung, Recherche und Synthese hat der Agent genug Kontext für das erste vollständige Ergebnis. In dieser Demo ist das eine Markdown-Datei namens competitive_analysis.md.

In diesem Schritt werden wir:

  • Qwen 3.7 Max den ersten Entwurf schreiben lassen.
  • Überflüssige Markdown-Codezäune entfernen.
  • Den Entwurf auf die Festplatte schreiben.
  • Den Schreibvorgang als Tool-Event protokollieren.
turn4 = self._run_turn(
   history=history,
   turn_index=4,
   phase="draft",
   user_prompt=_draft_prompt(goal),
   preserve_thinking=preserve_thinking,
)

Der Entwurfs-Turn nutzt den gesamten bisherigen Kontext – Ziel der Nutzerin, Plan, Recherche und Synthesematrix.

Die Modellantwort wird bereinigt und geschrieben:

draft_markdown = _strip_markdown_fences(turn4.assistant_content)
report_path = run_output_dir / "competitive_analysis.md"
report_path.write_text(draft_markdown)

Der Helper _strip_markdown_fences() ist praktisch, da Modelle Markdown oft in drei Backticks einbetten. Das ist im Chat okay, aber nicht ideal für eine direkte .md-Datei.

Das Backend zeichnet den Schreibvorgang zudem auf:

turn4.tool_events.append(
   ToolEvent(
       name="write_file",
       status="completed",
       input_payload={"path": str(report_path)},
       output_payload={
           "description": "Initial draft written to disk.",
       },
   )
)

Dieses Tool-Event hilft der UI zu zeigen, dass wirklich eine Datei erstellt wurde – nicht nur eine weitere Textantwort. An diesem Punkt gibt es bereits einen nutzbaren Bericht. Wir fügen aber noch einen Modellturn hinzu, um die Qualität vor der finalen Anzeige zu erhöhen.

Im nächsten Schritt bitten wir Qwen 3.7 Max, den eigenen Entwurf zu überprüfen und zu patchen.

Schritt 8: Selbstreview und Patch des Berichts

Der letzte Modellturn ist ein Selbstreview. Statt den ersten Entwurf sofort zu übergeben, liest der Agent den Bericht erneut, prüft ihn gegen das ursprüngliche Ziel und schreibt eine verbesserte Version.

In diesem Schritt werden wir:

  • Den Entwurf an das Modell zurückgeben.
  • Schwachstellen identifizieren lassen.
  • Eine überarbeitete Version erzeugen.
  • Den Bericht mit der finalen Version überschreiben.
turn5 = self._run_turn(
   history=history,
   turn_index=5,
   phase="self_review",
   user_prompt=_self_review_prompt(draft_markdown),
   preserve_thinking=preserve_thinking,
)

Der Self-Review-Prompt prüft praktische Punkte: Ist die Empfehlung klar? Sind die Vergleichskriterien konsistent? Ist der Bericht für eine Teampräsentation hilfreich?

Die überarbeitete Fassung wird an gleicher Stelle gespeichert:

final_markdown = _strip_markdown_fences(turn5.assistant_content)
report_path.write_text(final_markdown)

Der Agent kann auch das finale Schreib-Event protokollieren:

turn5.tool_events.append(
   ToolEvent(
       name="write_file",
       status="completed",
       input_payload={"path": str(report_path)},
       output_payload={
           "description": "Self-reviewed final report written to disk.",
       },
   )
)

Damit wird aus einem einfachen Generator ein kleiner Redaktionsworkflow. Die Nutzerin sieht nicht den Erstentwurf, sondern die geprüfte und gepatchte Version.

Als Nächstes verbinden wir den Backend-Workflow mit der Streamlit-App.

Schritt 9: Streamlit-Fortschrittsoberfläche bauen

Jetzt wechseln wir von der Backend-Logik zur Benutzeroberfläche. Die Streamlit-App soll die Eingabe erlauben, den Workflow starten und den Fortschritt pro Phase sichtbar machen.

Hinweis: Dieser Code gehört in die Datei agent.py, da sie steuert, was Nutzer sehen und klicken.

In diesem Schritt werden wir:

  • Die Streamlit-Seite konfigurieren.

  • Die Prompt-Eingabe anlegen.

  • Einen Run-Button hinzufügen.

  • Die Funktion ThinkingAgent.run() aufrufen.

  • Die UI aktualisieren, sobald Turns fertig sind.

def render_streamlit_app() -> None:
   st.set_page_config(
       page_title="Qwen3.7-Max Demo Agent",
       page_icon=":material/psychology:",
       layout="wide",
       initial_sidebar_state="collapsed",
   )

Die App nutzt ein breites Layout, da die UI Schritt-Karten, Fortschrittsanzeigen und Ergebnis-Panels enthält.

Der Eingabebereich ist simpel:

goal = st.text_area(
   "Prompt",
   value=DEFAULT_GOAL,
   height=120,
   label_visibility="collapsed",
)

run_clicked = st.button("Run Demo", use_container_width=True)

Die Nutzerin muss nur die Aufgabe angeben. Die App fragt nicht nach Temperature, Suchmodus, Modell-ID oder Reasoning-Einstellungen. Diese Details übernimmt das Backend.

Beim Klick auf den Button erstellt agent.py den Backend-Agenten und startet ihn:

agent = ThinkingAgent(config=config)

result = agent.run(
   goal=goal,
   preserve_thinking=True,
   data_mode="live",
   on_turn=on_turn,
)

Hier treffen beide Dateien aufeinander. agent.py triggert den Workflow, aber thinking_agent.py steuert das Agentenverhalten. Der UI-Callback aktualisiert die Seite nach jedem Turn:

def on_turn(turn: TurnRecord) -> None:
   partial_turns.append(turn)

   progress_placeholder.progress(
       len(partial_turns) / len(phase_order),
       text=f"Completed {_phase_label(turn.phase)}",
   )

   with steps_placeholder.container():
       _render_step_cards(partial_turns, result_ready=False)

Der Callback erhält einen abgeschlossenen TurnRecord und aktualisiert Fortschrittsbalken und Schritt-Karten. Während der Ausführung dienen die Karten als Statusanzeigen. Danach werden sie zu klickbaren Ergebnisansichten.

Jetzt rendern wir den finalen Markdown-Bericht und bieten ihn zum Download an.

Schritt 10: Finalen Bericht ansehen und herunterladen

Nachdem das Backend fertig ist, zeigt die UI den finalen Bericht an. Da die Markdown-Datei bereits erstellt wurde, muss agent.py sie nur lesen, rendern und einen Download-Button anzeigen.

In diesem Schritt werden wir:

  • Prüfen, ob die Berichtsdatei existiert.
  • Den finalen Markdown-Inhalt lesen.
  • Einen Download-Button anzeigen.
  • Das Markdown in der Streamlit-App rendern.
def _render_file_preview(report_path: str) -> None:
   path = Path(report_path)

   if not path.exists():
       st.info("No file was written yet.")
       return
   content = path.read_text()
   st.caption(f"Created file: {path.name}")
   st.download_button(
       "Download competitive_analysis.md",
       data=content,
       file_name=path.name,
       use_container_width=True,
   )
   st.markdown(content)

Die Funktion prüft zuerst, ob die Datei existiert. So stürzt die App nicht ab, falls das Backend vor dem Schreiben fehlschlug. Dann liest sie den Inhalt, bietet den Download an und rendert das Markdown direkt in der Streamlit-Seite.

So trennen wir Verantwortlichkeiten sauber:

  • thinking_agent.py schreibt den Bericht

  • agent.py zeigt Vorschau und Download

Im nächsten Schritt ergänzen wir grundlegendes Fehlerhandling, damit die Demo bei Provider-Problemen oder Rate Limits robuster reagiert.

Schritt 11: Fehler- und Rate-Limit-Handling

Modellanbieter können Timeouts haben, temporär fehlschlagen oder Anfragen rate-limiten. Wenn wir solche Rohfehler ungefiltert zeigen, wirkt die App unfertig.

Dieser Schritt teilt sich auf beide Dateien auf. Die Retry-Logik gehört in thinking_agent.py, da sie Teil des Backend-Modellaufrufs ist. Die Fehlermeldung gehört in agent.py, da sie steuert, was Nutzer sehen.

In diesem Schritt werden wir:

  • Temporäre Providerfehler im Backend erneut versuchen.
  • Rate-Limit-ähnliche Fehler erkennen.
  • Eine verständliche Meldung in der Streamlit-UI anzeigen.
delays = (1.0, 2.0)

for attempt_index in range(len(delays) + 1):
   try:
       return self.client.chat.completions.create(...)
   except Exception as exc:
       if not _is_retryable_provider_error(exc):
           raise

       if attempt_index >= len(delays):
           raise

       time.sleep(delays[attempt_index])

Das Backend versucht den Modellaufruf, fängt wiederholbare Fehler ab, wartet kurz und probiert es erneut. Die kurzen Pausen glätten temporäre Instabilitäten, ohne die Wartezeit unnötig zu verlängern.

def _friendly_rate_limit_message(exc: Any) -> str:
   return (
       "Qwen 3.7 Max is temporarily rate-limited upstream. "
       "Please wait 30 to 60 seconds and try again."
   )

So bleiben rohe Provider-JSONs oder Stacktraces aus der UI raus. Nutzer erhalten eine klare Erklärung und eine konkrete Handlungsanweisung.

Mit diesem letzten Schritt können wir die vollständige App laufen lassen und den End-to-End-Workflow testen.

Schritt 12: Die Demo starten

Nachdem Backend-Workflow und Streamlit-Interface verbunden sind, starten wir die komplette App.

In diesem Schritt werden wir:

  • Die Streamlit-App starten.
  • Den Standard-Produktivitäts-Prompt eingeben.
  • Den Fünf-Phasen-Workflow ausführen.
  • Den finalen Markdown-Bericht ansehen und herunterladen.

App starten:

streamlit run agent.py

Standard-Prompt verwenden:

I need to prepare a competitive analysis of the top 3 vector databases
for a team presentation next week. I have no idea where to start.

Nach Klick auf Run Demo durchläuft die App den kompletten Workflow:

  • Planung: Erstellt einen strukturierten Plan.

  • Recherche: Sammelt Snippets zu Pinecone, Weaviate und Qdrant.

  • Synthese: Erstellt eine Vergleichsmatrix.

  • Entwurf: Schreibt den ersten Markdown-Bericht.

  • Selbstreview: Patches den Bericht.

  • Vorschau: Zeigt die finale competitive_analysis.md-Datei.

Der finale Bericht wird gespeichert unter:

output/showcase_runs/<timestamp>/with_preserve/competitive_analysis.md

Zum Schluss solltest du die Vorschau und einen Download-Button in der Streamlit-Oberfläche sehen.

Fazit

In diesem Tutorial haben wir mit Qwen 3.7 Max einen kompakten Produktivitätsagenten gebaut, der einen festen, nachvollziehbaren Workflow von Planung über Recherche und Synthese bis Schreiben und Selbstreview durchläuft. Dabei zeigt sich, warum bewahrtes Reasoning über mehrere Turns bei Langform-Agentenaufgaben hilfreich ist.

Die aktuelle Version setzt nur auf Streamlit, OpenAI-kompatible Modellaufrufe, eine schlanke Suche und Markdown-Output. Das macht sie leicht verständlich, anpassbar und wiederverwendbar für eigene Experimente.

Natürliche Erweiterungen sind zum Beispiel:

  • Das Modell die Vergleichsziele selbst wählen lassen statt einer festen Liste

  • Side-by-Side-Runs „mit preserve_thinking“ vs. „ohne preserve_thinking

  • Tokenverbrauch und Kostenschätzungen in der UI anzeigen

  • Zusätzlich zum Markdown-Bericht eine Folienskizze oder Grafik generieren

  • DuckDuckGo-Scraping durch eine robustere Such-API ersetzen

Wenn du über einen festen Workflow hinausgehen und lernen willst, wie du produktionsreife KI-Anwendungen von Prompt Engineering über RAG bis zu agentischen Systemen baust, ist unser AI Engineering with LangChain-Lernpfad ein guter nächster Schritt.

Qwen 3.7 Max API – Häufige Fragen (FAQ)

Wann sollte ich preserve_thinking=True mit Qwen 3.7 Max verwenden?

preserve_thinking=True hilft in mehrstufigen Workflows, spätere Turns an frühen Entscheidungen auszurichten. In unserem Beispiel können Synthese- und Selbstreview-Phase dieselben Kriterien weiterverwenden, die in der Planungsphase festgelegt wurden, statt davon abzuweichen.

Ist Qwen 3.7 Max nur für Coding-Agenten?

Nein. Coding ist eine seiner großen Stärken, aber das Modell ist ebenso für Produktivitätsagenten, Office-Automatisierung, MCP-basierte Workflows, mehrsprachige Aufgaben, Reasoning mit langem Kontext und langlaufende Toolnutzung ausgelegt.

Verwendet die Demo-App echte Websuche?

Ja, der aktuelle Standardpfad versucht Live-Scraping über DuckDuckGo. Falls das fehlschlägt, greift die App auf eingebaute Fixture-Recherche zurück.

Erstellt das Modell in unserer Demo-App Subagenten?

Nein. Die App nutzt eine einzige Modellsitzung. Die „parallele“ Komponente liegt in der Rechercheebene: Das Backend startet drei Websuchen gleichzeitig und speist die Ergebnisse in dieselbe Sitzung zurück.

Warum trennen wir agent.py und thinking_agent.py?

agent.py hält die Streamlit-UI übersichtlich. thinking_agent.py enthält den Backend-Workflow, Prompt-Konstruktion, Retries und Recherchelogik, sodass sich das Agentenverhalten unabhängig von der Oberfläche testen lässt.


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Ich bin Google Developers Expertin für ML (Gen AI), dreifache Kaggle-Expertin und Women-Techmakers-Botschafterin mit über drei Jahren Erfahrung in der Tech-Branche. 2020 habe ich ein Health-Tech-Startup mitgegründet und absolviere derzeit einen Master in Informatik an der Georgia Tech mit Schwerpunkt Machine Learning.

Themen
KI-Agenten
Künstliche Intelligenz

Lerne agentische KI mit DataCamp!

Lernpfad

KI-Agent-Grundlagen

6 Std.
Entdecke, wie KI-Agenten deine Arbeitsweise verändern und Mehrwert für dein Unternehmen schaffen können!
Details anzeigenRight Arrow
Kurs Starten
Mehr anzeigenRight Arrow