Weiter zum Inhalt

GLM-5.3-Flash Tutorial: Baue einen Multi-Agenten-Aktienanalysten

Nutze GLM-5.3-Flash und CrewAI, um 3 spezialisierte LLM-Agenten für Fundamentaldaten, Technik und News zu bauen – und ihre Ergebnisse zu einem BUY/SELL-Signal zusammenzuführen.
Aktualisiert 31. Aug. 2026  · 12 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Große Sprachmodelle werden hilfreicher, wenn wir ihnen spezialisierte Rollen, Tools und Zugriff auf Live-Daten geben. Anstatt uns auf ein einzelnes Modell zu verlassen, können wir ein kleines Research-Team aufsetzen, in dem jeder Agent einen anderen Teil der Analyse übernimmt.

Genau das bauen wir in diesem Tutorial: einen Multi-Agenten-Aktienanalysten mit GLM-5.3-Flash und CrewAI. Drei Agenten analysieren Fundamentaldaten, technische Indikatoren und aktuelle Nachrichten, während ein Portfoliomanager ihre Ergebnisse zu einem finalen BUY-, HOLD- oder SELL-Signal zusammenführt.

Wir testen den Workflow zunächst in einem Jupyter-Notebook und verwandeln ihn dann in eine einfache Terminal-UI, die Aktien analysiert und Rückfragen beantwortet.

Das Projekt nutzt:

  • GLM-5.3-Flash für Reasoning
  • CrewAI für die Agentenkoordination
  • Finnhub für Markt- und Fundamentaldaten
  • Yahoo Finance für historische Preise
  • Tavily für aktuelle News
  • Pandas und NumPy für technische Indikatoren

Neu im Framework? Unser Kurs Building AI Agents with CrewAI führt dich von Grund auf in Agents, Crews und Flows ein.

Einführung in KI-Agenten

Lerne die Grundlagen von KI-Agenten, ihre Komponenten und ihre Anwendung in der Praxis - ohne Programmierkenntnisse.
Kurs Erkunden

Warum GLM-5.3-Flash für Multi-Agenten-Anwendungen?

GLM-5.3-Flash bietet ein starkes Verhältnis aus Performance, Effizienz und Preis. Für den kompletten Überblick lies unseren GLM-5.3-Flash-Guide und den Vergleich mit Qwen3.8-Flash-Next.

Wettbewerbsfähige Performance und Effizienz

Im Artificial Analysis Intelligence Index erzielt es 57 Punkte, rangiert damit unter den führenden Modellen und konkurriert mit deutlich teureren Frontier-Modellen. Zum Beispiel:

  • GPT-5.6 Sol erzielt ebenfalls 57 (bei high Reasoning-Effort), kostet aber über 25-mal mehr für Input- und 40-mal mehr für Output-Tokens.

  • Claude Sonnet 5 liegt sogar etwas darunter mit 55 bei max Reasoning-Effort. Es ist 20x/30x teurer für Input/Output-Tokens als GLM-5.3-Flash.

Es hat 320B Gesamtparameter, aber nur etwa 18B Parameter sind pro Token aktiv. So liefert es starke Leistung bei gleichzeitig hoher Recheneffizienz. 

GLM-5.3-Flash auf Rang 8 im Artificial Analysis Intelligence Index

Quelle: AI Model & API Providers Analysis | Artificial Analysis 

Attraktive Preise

Wie erwähnt, kommt diese Performance zu einem vergleichsweise niedrigen API-Preis. Zum Zeitpunkt des Schreibens bietet OpenRouter GLM-5.3-Flash mit 50% Rabatt an: $0,075 pro Million Input-Tokens und $0,25 pro Million Output-Tokens. 

Auch zum regulären Preis von $0,15/$0,50 bleibt es günstiger als Modelle wie OpenAI's GPT-5.6 Luna mit $0,20/$1,20 (52 im AA Intelligence Index bei max Reasoning). Damit eignet es sich nicht nur für Experimente, sondern auch für größere, produktionsreife Agentenanwendungen. 

GLM-5.3-Flash-Anbieter auf OpenRouter

Quelle: GLM 5.3 Flash - API Pricing & Benchmarks | OpenRouter 

Das zählt umso mehr bei Multi-Agenten-Systemen, weil eine Nutzeranfrage im Hintergrund viele LLM-Calls auslösen kann. Ein einzelner LLM-Agent ruft das Modell womöglich mehrfach auf: für Reasoning, Toolauswahl, Verarbeitung der Tool-Ausgaben und die finale Antwort. Wenn ein Agent etwa sieben LLM-Calls macht und dein Workflow fünf Agenten hat, kann eine einzige Anfrage leicht 35 oder mehr LLM-Calls erzeugen. 

Die genaue Zahl hängt vom Systemdesign ab. Der Punkt ist: Agentische Workflows werden schnell teuer. Ein fähiges Modell mit niedrigen Tokenpreisen wie GLM-5.3-Flash macht beim Schritt vom kleinen Demo zur echten Produktionsanwendung einen großen Unterschied. 

1. Umgebung für GLM-5.3-Flash einrichten

Bevor wir den Multi-Agenten-Workflow bauen, lege API-Schlüssel für Z.ai, Finnhub und Tavily an.

API-Schlüssel erstellen

Achte bei Z.ai darauf, die reguläre API zu verwenden, nicht den GLM Coding Plan. Der Coding Plan ist für unterstützte KI-Coding-Tools gedacht und nicht als generische API für eigene Multi-Agenten-Apps.

Erzeuge einen regulären Z.ai-API-Schlüssel und lade ein kleines Guthaben auf. Da GLM-5.3-Flash günstig ist, reicht ein kleiner Betrag für die ersten Tests.

Z.ai Abrechnungsmenü

Quelle: Z.ai API Platform — Start building with GLM-5.3 

Du kannst auch kostenlose Accounts bei Finnhub und Tavily anlegen und API-Schlüssel generieren. Deren Free-Tiers reichen zum Testen dieses Projekts.

Projektdateien vorbereiten

Lege anschließend eine .env-Datei im Projektordner an und füge die API-Schlüssel hinzu:

ZAI_API_KEY="your_zai_api_key"
FINNHUB_API_KEY="your_finnhub_api_key"
TAVILY_API_KEY="your_tavily_api_key"

Erstelle jetzt ein neues Jupyter-Notebook. Wir bauen und testen hier zuerst den kompletten Multi-Agenten-Workflow, prüfen die Ausgaben der Agenten und beheben Probleme, bevor wir daraus eine Anwendung machen.

Benötigte Bibliotheken installieren

Wir verwenden CrewAI für Aufbau und Koordination der Agenten, Finnhub für Marktdaten und Tavily für Websuche in Echtzeit. Installiere die erforderlichen Python-Pakete:

!pip install -q crewai crewai-tools finnhub-python tavily-python pandas numpy requests python-dotenv openai

Bibliotheken und API-Schlüssel importieren

Importiere als Nächstes die benötigten Bibliotheken und lade die API-Schlüssel:

import os
import re
import time

import finnhub
import numpy as np
import pandas as pd
import requests

from dotenv import load_dotenv
from openai import OpenAI
from tavily import TavilyClient

from crewai import Agent, Crew, LLM, Process, Task
from crewai.tools import tool
from crewai_tools import TavilySearchTool

# Load environment variables
load_dotenv()

# Disable CrewAI tracing
os.environ.setdefault("CREWAI_TRACING_ENABLED", "false")
os.environ.setdefault("OTEL_SDK_DISABLED", "true")

Lege zuletzt fest, welche Aktie die Agenten analysieren sollen:

TICKER = "NVDA"

Ich verwende im Notebook NVIDIA (NVDA). Du kannst den Ticker aber jederzeit austauschen, z. B. gegen AAPL, MSFT oder TSLA.

2. GLM-5.3-Flash und Daten-APIs konfigurieren

Mit fertigen API-Schlüsseln verbinden wir nun die Services, die unsere Agenten im Projekt nutzen.

Starte mit Finnhub für Marktdaten und Tavily für die Websuche:

finnhub_client = finnhub.Client(
    api_key=os.environ["FINNHUB_API_KEY"]
)

tavily_client = TavilyClient(
    api_key=os.environ["TAVILY_API_KEY"]
)

Wenn du Finanzagenten bauen möchtest und unsicher bist, welche Datenquelle du nehmen solltest, lies unseren Guide zum Auswählen der passenden Stock-Market-Data-API.

Als Nächstes konfigurieren wir GLM-5.3-Flash als Haupt-LLM für unsere CrewAI-Agenten. Z.ai bietet eine OpenAI-kompatible API, daher können wir sie direkt über CrewAIs LLM-Klasse anbinden:

llm = LLM(
    model="openai/glm-5.3-flash",
    api_key=os.environ["ZAI_API_KEY"],
    base_url="https://api.z.ai/api/paas/v4/",
    temperature=0.1,
)

Wir halten die Temperatur niedrig, da es hier um Finanzresearch und Analyse geht. Wir wollen konsistente, fokussierte Antworten.

Mit Modell, Marktdaten und Websuche verbunden, können wir nun die Tools bauen, die unsere Agenten nutzen.

3. Historische Marktdaten sammeln

Wir benötigen historische Preisdaten, damit die Agenten die Kursentwicklung über die Zeit verstehen.

Dafür nutzen wir den öffentlichen Chart-Endpunkt von Yahoo Finance, um tägliche Open-, High-, Low-, Close- und Volumen-Daten zu laden.

Kursverlauf herunterladen

HTTP = requests.Session()
HTTP.headers.update({"User-Agent": "glm-stock-swarm/1.0"})


def _yahoo_history(ticker: str, days: int) -> pd.DataFrame:
    end = int(time.time())
    start = end - days * 24 * 60 * 60

    response = HTTP.get(
        f"https://query1.finance.yahoo.com/v8/finance/chart/{ticker}",
        params={
            "period1": start,
            "period2": end,
            "interval": "1d",
            "events": "history",
        },
        timeout=30,
    )
    response.raise_for_status()

    result = response.json()["chart"]["result"][0]
    values = result["indicators"]["quote"][0]

    frame = pd.DataFrame({
        "date": pd.to_datetime(
            result["timestamp"], unit="s", utc=True
        ).tz_localize(None),
        "open": values["open"],
        "high": values["high"],
        "low": values["low"],
        "close": values["close"],
        "volume": values["volume"],
    })

    frame = (
        frame.dropna(subset=["close"])
        .sort_values("date")
        .reset_index(drop=True)
    )

    frame.attrs["source"] = "Yahoo public chart"
    return frame


def get_price_history(ticker: str, days: int = 450) -> pd.DataFrame:
    return _yahoo_history(ticker.strip().upper(), days)

Wir sammeln rund 450 Tage Historie. Das reicht für langfristige Indikatoren wie den 200-Tage-Durchschnitt.

Technische Indikatoren berechnen

Berechnen wir nun ein paar gängige Indikatoren: 

  • Gleitende Durchschnitte: Mittelwerte über 20, 50 und 200 Tage
  • Relative Strength Index (RSI): Skala von 0 bis 100, zeigt überkaufte (>70) bzw. überverkaufte (<30) Zonen
  • Moving Average Convergence/Divergence (MACD): Differenz der langfristigen und kurzfristigen exponentiellen Durchschnitte (EMAs)
def add_indicators(frame: pd.DataFrame) -> pd.DataFrame:
    if frame.empty:
        return frame.copy()

    result = frame.copy()
    result.attrs.update(frame.attrs)

    # Moving averages
    result["SMA20"] = result["close"].rolling(20).mean()
    result["SMA50"] = result["close"].rolling(50).mean()
    result["SMA200"] = result["close"].rolling(200).mean()

    # RSI
    delta = result["close"].diff()
    gain = delta.clip(lower=0)
    loss = -delta.clip(upper=0)

    avg_gain = gain.ewm(
        alpha=1 / 14, min_periods=14, adjust=False
    ).mean()

    avg_loss = loss.ewm(
        alpha=1 / 14, min_periods=14, adjust=False
    ).mean()

    result["RSI14"] = 100 - (
        100 / (1 + avg_gain / avg_loss.replace(0, np.nan))
    )

    # MACD
    result["EMA12"] = result["close"].ewm(
        span=12, adjust=False
    ).mean()

    result["EMA26"] = result["close"].ewm(
        span=26, adjust=False
    ).mean()

    result["MACD"] = result["EMA12"] - result["EMA26"]

    return result

Diese Indikatoren helfen dem Technical-Agenten, Trends und Momentum schnell zu erkennen, ohne dass das LLM alles selbst berechnen muss.

Neueste Werte prüfen

Sammle nun die Daten, berechne die Indikatoren und zeige die letzten Zeilen an:

history = add_indicators(
    get_price_history(TICKER)
)

if len(history) < 200:
    raise RuntimeError(
        f"Need at least 200 daily observations; received {len(history)}."
    )

print(
    f"Loaded {len(history)} rows "
    f"from {history.attrs['source']}."
)

history.tail(3)[
    [
        "date",
        "close",
        "SMA20",
        "SMA50",
        "SMA200",
        "RSI14",
        "MACD",
    ]
]

Kursverlauf und technische Indikatoren der Nvidia-Aktie

Du solltest den aktuellen Kurs zusammen mit gleitenden Durchschnitten, RSI und MACD sehen – ähnlich wie oben.

Diese Daten geben wir später an den Technical-Agenten, damit er Trends, Momentum sowie bullische oder bärische Signale identifizieren kann.

4. Datenquellen als CrewAI-Tools bereitstellen

Da unsere Datenquellen funktionieren, verwandeln wir sie in CrewAI-Tools. So können die Agenten bei Bedarf direkt auf Fundamentaldaten, Technik oder News zugreifen.

Tools für Kurs- und Fundamentaldaten erstellen

Zuerst eine kleine Hilfsfunktion, um Zahlen einheitlich zu formatieren:

def _number(value, decimals: int = 2) -> str:
    if value is None or pd.isna(value):
        return "N/A"

    return f"{float(value):,.{decimals}f}"

Als Nächstes das Fundamentals-Tool. Es nutzt Finnhub für aktuellen Kurs, Bewertung, Wachstum, Profitabilität und weitere Unternehmenskennzahlen.

@tool("Get Stock Fundamentals")
def get_fundamentals(ticker: str) -> str:
    """Get current price and company fundamentals from Finnhub for one ticker."""

    ticker = ticker.strip().upper()

    quote = finnhub_client.quote(ticker)
    metrics = finnhub_client.company_basic_financials(ticker, "all")
    m = metrics.get("metric", {})

    return f"""Ticker: {ticker}
Source: Finnhub
Current price: {_number(quote.get('c'))}
Previous close: {_number(quote.get('pc'))}
Daily change %: {_number(quote.get('dp'))}
Day high / low: {_number(quote.get('h'))} / {_number(quote.get('l'))}
Market cap (USD millions): {_number(m.get('marketCapitalization'))}
52-week high / low: {_number(m.get('52WeekHigh'))} / {_number(m.get('52WeekLow'))}
Normalized annual P/E: {_number(m.get('peNormalizedAnnual'))}
Annual P/B: {_number(m.get('pbAnnual'))}
Annual P/S: {_number(m.get('psAnnual'))}
ROE TTM: {_number(m.get('roeTTM'))}
Net margin TTM: {_number(m.get('netProfitMarginTTM'))}
Revenue growth TTM YoY: {_number(m.get('revenueGrowthTTMYoy'))}
EPS growth TTM YoY: {_number(m.get('epsGrowthTTMYoy'))}
Annual debt/equity: {_number(m.get('totalDebt/totalEquityAnnual'))}"""

Außerdem erstellen wir ein Tool für die technische Analyse auf Basis der historischen Daten und Indikatoren aus dem vorherigen Abschnitt.

@tool("Analyze Stock Technicals")
def get_technicals(ticker: str) -> str:
    """Calculate price trends, returns, moving averages, RSI, and MACD."""

    ticker = ticker.strip().upper()
    frame = add_indicators(get_price_history(ticker))

    if len(frame) < 200:
        return (
            f"Technical data unavailable for {ticker}: "
            "fewer than 200 observations."
        )

    latest = frame.iloc[-1]

    return f"""Ticker: {ticker}
Source: {frame.attrs.get('source', 'unknown')}
Last market date: {latest['date'].date()}
Close: {_number(latest['close'])}
SMA20 / SMA50 / SMA200: {_number(latest['SMA20'])} / {_number(latest['SMA50'])} / {_number(latest['SMA200'])}
RSI14: {_number(latest['RSI14'])}
MACD: {_number(latest['MACD'])}
20-day return: {_number((latest['close'] / frame['close'].iloc[-21] - 1) * 100)}%
50-day return: {_number((latest['close'] / frame['close'].iloc[-51] - 1) * 100)}%
Price vs SMA20: {_number((latest['close'] / latest['SMA20'] - 1) * 100)}%
Price vs SMA50: {_number((latest['close'] / latest['SMA50'] - 1) * 100)}%
Price vs SMA200: {_number((latest['close'] / latest['SMA200'] - 1) * 100)}%"""

Wichtig ist hier der @tool-Decorator. Er macht aus einer normalen Python-Funktion ein Tool, das ein CrewAI-Agent während einer Aufgabe gezielt aufrufen kann.

Websuche hinzufügen

Für Unternehmensnews und aktuelle Entwicklungen verwenden wir das Tavily-Suchtool von CrewAI:

web_search = TavilySearchTool(
    api_key=os.environ["TAVILY_API_KEY"],
    topic="news",
    search_depth="advanced",
    days=30,
    max_results=5,
)

Wir begrenzen die Suche auf die letzten 30 Tage und maximal fünf Treffer. So bekommen die Research-Agenten genug aktuelle Informationen, ohne in unnötigen Details zu versinken.

Aktien-Tools testen

Bevor wir die Agenten erstellen, rufe die beiden Custom-Tools direkt auf:

print(get_fundamentals.run(ticker=TICKER))
print()
print(get_technicals.run(ticker=TICKER))

Fundamentaldaten und technische Infos zur Nvidia-Aktie

Du solltest nun zuerst die neuesten Fundamentalkennzahlen und anschließend die technischen Indikatoren der ausgewählten Aktie sehen.

5. Das Multi-Agenten-Research-Team bauen

Jetzt, da die Tools bereitstehen, erstellen wir unser Multi-Agenten-Research-Team.

Wir nutzen drei Spezialisten – für Fundamentalanalyse, technische Analyse und aktuelle Nachrichten – plus einen Portfoliomanager, der daraus die finale Bewertung ableitet.

Spezialisten anlegen

Zuerst der Fundamental-Analyst:

fundamental_agent = Agent(
    role="Fundamental Analyst",
    goal=(
        "Evaluate financial health, growth, profitability, "
        "valuation, and balance-sheet risk."
    ),
    backstory=(
        "You are a careful long-term equity analyst. "
        "Use the fundamentals tool and never invent a figure. "
        "Treat N/A as missing, not as zero."
    ),
    tools=[get_fundamentals],
    llm=llm,
    allow_delegation=False,
    max_iter=4,
    verbose=False,
)

Als Nächstes der Technical-Analyst:

technical_agent = Agent(
    role="Technical Analyst",
    goal=(
        "Determine whether the current price setup is "
        "bullish, bearish, or neutral."
    ),
    backstory=(
        "You interpret indicators calculated by Python. "
        "Never guess market prices or indicator values."
    ),
    tools=[get_technicals],
    llm=llm,
    allow_delegation=False,
    max_iter=4,
    verbose=False,
)

Dann der News-Analyst:

news_agent = Agent(
    role="Financial News Analyst",
    goal=(
        "Find material recent developments and distinguish "
        "confirmed reporting from speculation."
    ),
    backstory=(
        "You are a skeptical financial-news researcher. "
        "Prioritize primary and reputable sources, dates, and links."
    ),
    tools=[web_search],
    llm=llm,
    allow_delegation=False,
    max_iter=5,
    verbose=False,
)

Jeder Spezialist bekommt nur das Tool, das er wirklich braucht. So bleibt der Workflow fokussiert und Agenten rufen keine irrelevanten Tools auf.

Portfoliomanager erstellen

Zum Schluss der Manager, der alle drei Spezialistenberichte prüft:

manager_agent = Agent(
    role="Portfolio Manager",
    goal=(
        "Combine the specialist reports into a balanced, "
        "evidence-based research signal."
    ),
    backstory=(
        "You lead an equity research team. "
        "Weigh bullish and bearish evidence, use HOLD when evidence "
        "is mixed, and never add unsupported facts."
    ),
    llm=llm,
    allow_delegation=False,
    max_iter=4,
    verbose=False,
)

Der Portfoliomanager braucht keinen direkten Zugriff auf die Datentools. Er arbeitet mit den Berichten der drei Spezialisten.

Mit allow_delegation=False bleibt der Ablauf vorhersagbar. max_iter begrenzt die Zyklen aus Reasoning und Toolnutzung je Agent.

6. Spezialisierte Research-Aufgaben definieren

Mit den Agenten ist definiert, wer sie sind. Jetzt sagen wir jedem Agenten genau, was er tun und was sein Endergebnis enthalten soll.

Research-Tasks festlegen

Beginne mit der Fundamentalanalyse:

fundamental_task = Task(
    description=(
        f"Analyze {TICKER}'s growth, profitability, valuation, "
        "balance sheet, and business quality. "
        "Use Get Stock Fundamentals. "
        "Return a Fundamental Score from 0-100, strongest positive, "
        "biggest risk, and note all material missing data."
    ),
    expected_output=(
        "A concise fundamental assessment with a 0-100 score, "
        "evidence, strongest positive, biggest risk, "
        "and missing-data note."
    ),
    agent=fundamental_agent,
)

Als Nächstes die technische Analyse:

technical_task = Task(
    description=(
        f"Analyze {TICKER}'s technical setup. "
        "Use Analyze Stock Technicals. "
        "Consider SMA20/50/200, RSI14, MACD, recent returns, and trend. "
        "Return Technical Score 0-100, Bullish/Neutral/Bearish signal, "
        "trend, momentum, and main technical risk."
    ),
    expected_output=(
        "A concise technical assessment with score, signal, trend, "
        "momentum, data source, and main risk."
    ),
    agent=technical_agent,
)

Für aktuelle Entwicklungen der News-Task:

news_task = Task(
    description=(
        f"Research the most important recent news for {TICKER}, "
        "focusing on the last 30 days: earnings, guidance, analyst "
        "revisions, products, partnerships, M&A, regulation, lawsuits, "
        "management, and industry developments. "
        "Use Tavily Search. "
        "Return News Score 0-100, sentiment, positive and negative "
        "catalysts, publication dates, and source URLs. "
        "Ignore low-quality speculation."
    ),
    expected_output=(
        "A sourced recent-news assessment with score, sentiment, "
        "catalysts, dates, and clickable URLs."
    ),
    agent=news_agent,
)

Klare Aufgaben und Output-Formate sind entscheidend. So kann der Portfoliomanager die Reports besser vergleichen, statt völlig unterschiedliche Antworten zu erhalten.

Finale Entscheidungsaufgabe erstellen

Die letzte Aufgabe führt alle drei Berichte zusammen:

decision_task = Task(
    description=(
        f"Review all three specialist reports and make the final "
        f"educational research assessment for {TICKER}. "
        "Return exactly one signal: BUY, HOLD, or SELL. "
        "Use HOLD when evidence is mixed or confidence is insufficient. "
        "Base every claim only on the supplied reports."
    ),
    expected_output=(
        "Ticker; Signal; Overall Score /100; Confidence %; "
        "Fundamental, Technical, and News scores; Bull Case; "
        "Bear Case; Main Catalyst; Main Risk; Final Explanation; "
        "Sources; and an educational-not-financial-advice disclaimer."
    ),
    agent=manager_agent,
    context=[
        fundamental_task,
        technical_task,
        news_task,
    ],
)

Der wichtige Teil ist context. So erhält der Portfoliomanager Zugriff auf die Ausgaben aller drei Spezialisten und kann Fundamentals, Technik und News abwägen, bevor er das finale BUY-, HOLD- oder SELL-Urteil fällt.

Damit sind Agenten, Tools und Tasks bereit. Jetzt verbinden wir alles in einem CrewAI-Workflow und lassen das komplette Research-Team laufen.

7. Die Multi-Agenten-Crew ausführen

Bringen wir nun alles zusammen und starten den vollständigen Aktienresearch-Workflow.

Die Crew erstellen

Erstelle eine CrewAI-Crew mit unseren drei Spezialisten und dem Portfoliomanager:

crew = Crew(
    agents=[
        fundamental_agent,
        technical_agent,
        news_agent,
        manager_agent,
    ],
    tasks=[
        fundamental_task,
        technical_task,
        news_task,
        decision_task,
    ],
    process=Process.sequential,
    verbose=False,
    tracing=False,
)

Wir verwenden Process.sequential, sodass die Research-Aufgaben nacheinander laufen. Fundamental-, Technical- und News-Agent schließen zuerst ab, dann erstellt der Portfoliomanager die finale Einschätzung.

Research-Team starten

Starte den Workflow asynchron:

result = await crew.kickoff_async()

Dieser Schritt dauert etwas, da die Agenten mehrere LLM- und Tool-Calls durchführen. In meinem Test brauchte der komplette Workflow etwa 4 bis 5 Minuten.

Ist er fertig, gib den finalen Report des Portfoliomanagers aus:

print(result.raw)

Finale Bewertung des Portfoliomanagers für die Nvidia-Aktie

Du solltest einen ausführlichen Report ähnlich dem obigen sehen, inklusive:

  • BUY-, HOLD- oder SELL-Signal
  • Gesamtscore
  • Konfidenzniveau
  • Scores der Spezialisten
  • Bull Case
  • Bear Case
  • Katalysatoren
  • Risiken
  • Quellen

In diesem Beispiel analysierten die Agenten NVIDIA unabhängig und kombinierten ihre Ergebnisse in einem evidenzbasierten Research-Report. Hier zeigt sich der Vorteil des Multi-Agenten-Ansatzes: Anstatt ein Modell alles auf einmal machen zu lassen, fokussiert sich jeder Agent auf sein Gebiet, bevor der Portfoliomanager alles zusammenführt.

Falls es Probleme mit dem Code gibt: Das vollständige Jupyter-Notebook mit allen Snippets und Ausgaben ist ebenfalls verlinkt. Du kannst es ansehen oder selbst ausführen: glm-stock-swarm/stock_analyst_crew.ipynb

8. Terminal-UI bauen und ausführen

Nach den Tests im Jupyter-Notebook habe ich den kompletten Workflow in eine Terminal-User-Interface (TUI) übertragen. Statt einzelne Notebook-Zellen manuell zu starten, kannst du den gesamten Multi-Agenten-Aktienanalysten mit einem einzigen Befehl ausführen.

Das komplette Projekt inklusive Code und Setup-Anleitung findest du auf GitHub: glm-stock-swarm GitHub-Repository.

App installieren und starten

Starte mit dem Klonen des Repositories:

git clone https://github.com/kingabzpro/glm-stock-swarm.git
cd glm-stock-swarm

Füge deine Z.ai-, Finnhub- und Tavily-API-Schlüssel in die .env-Datei ein und installiere dann alle Abhängigkeiten mit uv:

uv sync

Starte anschließend die TUI:

uv run glm-stock-swarm

Eine Aktie analysieren

Die Oberfläche bietet ein simples Eingabefeld. Gib dort einen unterstützten Ticker ein, um die Analyse zu starten.

Multi-Agenten-Aktienanalyst TUI

Nach dem Absenden siehst du, wie die Agenten nacheinander arbeiten. Zuerst der Fundamental-Analyst, gefolgt vom Technical-Analyst, dann der News-Analyst und schließlich der Portfoliomanager, der alles zur finalen Entscheidung zusammenführt.

Ergebnisse des Multi-Agenten-Aktienanalysten für SpaceX

Am Ende erzeugt die TUI direkt im Terminal einen vollständigen Report mit Fundamental-, Technical- und News-Score, Gesamtscore, Konfidenz, Bull Case, Bear Case, Risiken, Katalysatoren und dem finalen BUY-, HOLD- oder SELL-Signal.

Rückfragen stellen

Ich habe außerdem einen Follow-up-Chat ergänzt, damit du nicht für jede Rückfrage die gesamte Multi-Agenten-Pipeline neu starten musst.

Rückfrage stellen in der Multi-Agenten-Aktienanalyst TUI

Beispiel: Nach einer SELL-Empfehlung fragte ich, ob ich die gesamte Position oder nur einen Teil verkaufen sollte.

Ergebnisse der Rückfrage in der Multi-Agenten-Aktienanalyst TUI

Statt erneut alle vier Agenten zu starten, nutzt die Anwendung den Kontext aus dem erzeugten Research-Report und liefert eine deutlich schnellere Folgeantwort.

So wird die App praktischer: Der teure Multi-Agenten-Research läuft einmal, Rückfragen nutzen die bestehende Analyse.

Abschließende Gedanken

Bemerkenswert in meinen Testruns war die Zuverlässigkeit beim Tool-Aufruf. Alle drei Spezialisten wählten das richtige Tool, hielten sich an die N/A-Konvention statt fehlende Daten als Null zu deuten, und lieferten das Score-und-Evidence-Format, das der Portfoliomanager brauchte. Genau hier stolpern günstige Modelle oft.

Der Trade-off ist Geschwindigkeit. Artificial Analysis misst GLM-5.3-Flash auf Z.ai's API mit rund 45 Output-Tokens pro Sekunde – am unteren Ende für Open-Weight-Modelle dieser Größe. Das merkt man an den 4 bis 5 Minuten für einen kompletten Crew-Run. Auf ihrem Index erzielt es 57 vs. 60 für GLM-5.3. Du gibst also ein wenig Reasoning-Qualität ab, bekommst dafür aber ungefähr ein Zehntel des Preises. Ein guter Tausch.

Nichts davon bindet dich fest. Ein Wechsel zu OpenRouter, Hugging Face Inference oder einem lokalen Modell über Ollama bedeutet meist nur drei Änderungen: API-Schlüssel, Modellname, Base-URL. Ähnlich bei den Tools, wo yfinance hier die Aufgaben von Finnhub und Yahoo übernehmen könnte.

Als nächsten Schritt würde ich das an eine Paper-Trading-API anbinden und morgens automatisch laufen lassen. Aber bitte nur mit Demokonto. Dieses Projekt soll Agentendesign vermitteln, nicht zum Traden anregen.

Wenn du agentische KI von Grund auf lernen willst, empfehle ich unseren AI Agent Fundamentals Lernpfad als idealen Einstieg.


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Als zertifizierter Data Scientist ist es meine Leidenschaft, modernste Technologien zu nutzen, um innovative Machine Learning-Anwendungen zu entwickeln. Mit meinem fundierten Hintergrund in den Bereichen Spracherkennung, Datenanalyse und Reporting, MLOps, KI und NLP habe ich meine Fähigkeiten bei der Entwicklung intelligenter Systeme verfeinert, die wirklich etwas bewirken können. Neben meinem technischen Fachwissen bin ich auch ein geschickter Kommunikator mit dem Talent, komplexe Konzepte in eine klare und prägnante Sprache zu fassen. Das hat dazu geführt, dass ich ein gefragter Blogger zum Thema Datenwissenschaft geworden bin und meine Erkenntnisse und Erfahrungen mit einer wachsenden Gemeinschaft von Datenexperten teile. Zurzeit konzentriere ich mich auf die Erstellung und Bearbeitung von Inhalten und arbeite mit großen Sprachmodellen, um aussagekräftige und ansprechende Inhalte zu entwickeln, die sowohl Unternehmen als auch Privatpersonen helfen, das Beste aus ihren Daten zu machen.

Themen

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