Programma
I large language model diventano più utili quando assegniamo loro ruoli specializzati, strumenti e accesso a dati in tempo reale. Invece di affidarci a un unico modello, possiamo creare un piccolo team di ricerca in cui ogni agente si concentra su una parte diversa dell’analisi.
È esattamente ciò che faremo in questo tutorial: costruiremo un-analista multi-agent per le azioni usando GLM-5.3-Flash e CrewAI. Tre agenti analizzano fondamentali, indicatori tecnici e notizie recenti, mentre un portfolio manager combina i loro risultati in un segnale di ricerca finale BUY, HOLD o SELL.
Per prima cosa testeremo il workflow in un Jupyter Notebook, poi lo trasformeremo in una semplice interfaccia da terminale in grado di analizzare azioni e rispondere a domande di follow-up.
Il progetto usa:
- GLM-5.3-Flash per il reasoning
- CrewAI per il coordinamento degli agenti
- Finnhub per dati di mercato e fondamentali
- Yahoo Finance per i prezzi storici
- Tavily per le notizie recenti
- Pandas e NumPy per gli indicatori tecnici
Nuovo al framework? Il nostro corso Building AI Agents with CrewAI copre a partire da zero agenti, crew e flow.
Perché usare GLM-5.3-Flash per applicazioni multi-agent
GLM-5.3-Flash offre un equilibrio notevole tra prestazioni, efficienza e prezzo. Per una panoramica completa, leggi la nostra guida a GLM-5.3-Flash e il nostro confronto con Qwen3.8-Flash-Next.
Prestazioni ed efficienza competitive
Sull’Artificial Analysis Intelligence Index ottiene un punteggio di 57, collocandosi tra i modelli leader e risultando competitivo con diversi modelli di frontiera molto più costosi. Per esempio:
-
GPT-5.6 Sol ottiene anch’esso 57 (con sforzo di reasoning
high) ma costa oltre 25 volte di più per i token in input e 40 volte di più per quelli in output. -
Claude Sonnet 5 ottiene persino un po’ meno, 55 al suo sforzo di reasoning
max. È 20x/30x più costoso per input/output token rispetto a GLM-5.3-Flash.
Ha 320B parametri totali, ma solo circa 18B parametri sono attivi per token, consentendogli di offrire buone prestazioni restando relativamente efficiente dal punto di vista computazionale.

Fonte: AI Model & API Providers Analysis | Artificial Analysis
Prezzi interessanti
Come già accennato, queste prestazioni arrivano con un prezzo API relativamente basso. Al momento della stesura, OpenRouter offre GLM-5.3-Flash con uno sconto del 50%, a 0,075 $ per milione di token in input e 0,25 $ per milione di token in output.
Anche al prezzo regolare di 0,15 $/0,50 $, rimane più economico di modelli come GPT-5.6 Luna di OpenAI, che costa 0,20 $/1,20 $ (52 sull’AA Intelligence Index con reasoning max). Questo lo rende interessante non solo per esperimenti, ma anche per applicazioni agentiche più grandi e di produzione.

Fonte: GLM 5.3 Flash - API Pricing & Benchmarks | OpenRouter
Questo conta ancora di più quando costruisci un sistema multi-agent, perché una richiesta utente può attivare molte chiamate LLM dietro le quinte. Un singolo agente LLM potrebbe chiamare il modello più volte per il reasoning, la selezione degli strumenti, l’elaborazione degli output degli strumenti e la generazione della risposta finale. Se un agente effettua circa sette chiamate LLM e il tuo workflow usa cinque agenti, una singola richiesta potrebbe facilmente comportare 35 o più chiamate LLM.
Il numero esatto dipende da come è progettato il tuo sistema, ma il punto è semplice: i workflow agentici possono diventare costosi molto in fretta. Usare un modello capace con un prezzo per token basso, come GLM-5.3-Flash, può fare una grande differenza quando si passa da una piccola demo a una vera applicazione in produzione.
1. Configura l’ambiente per GLM-5.3-Flash
Prima di costruire il workflow multi-agent, crea le chiavi API per Z.ai, Finnhub e Tavily.
Crea le chiavi API
Per Z.ai, assicurati di usare la normale API, non il GLM Coding Plan. Il Coding Plan è pensato per i tool di coding AI supportati e non dovrebbe essere usato come API generica per la tua applicazione multi-agent.
Genera una chiave API Z.ai standard e aggiungi un piccolo credito al tuo account. Dato che GLM-5.3-Flash è economico, basta un piccolo saldo per iniziare i test.

Fonte: Z.ai API Platform — Start building with GLM-5.3
Puoi anche creare account gratuiti su Finnhub e Tavily e generare chiavi API. I loro piani free sono sufficienti per testare questo progetto.
Configura i file del progetto
Poi, crea un file .env nella cartella del progetto e aggiungi le chiavi API:
ZAI_API_KEY="your_zai_api_key"
FINNHUB_API_KEY="your_finnhub_api_key"
TAVILY_API_KEY="your_tavily_api_key"
Ora crea un nuovo Jupyter Notebook. Qui costruiremo e testeremo l’intero workflow multi-agent, ispezioneremo l’output di ciascun agente e risolveremo eventuali problemi prima di trasformarlo in un’applicazione vera e propria.
Installa le librerie necessarie
Useremo CrewAI per creare e coordinare gli agenti, Finnhub per i dati di borsa e Tavily per la ricerca web in tempo reale. Installa i pacchetti Python richiesti:
!pip install -q crewai crewai-tools finnhub-python tavily-python pandas numpy requests python-dotenv openai
Importa librerie e chiavi API
Poi importa le librerie necessarie e carica le chiavi API:
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")
Infine, scegli l’azione che vuoi far analizzare agli agenti:
TICKER = "NVDA"
Userò NVIDIA (NVDA) per tutto il notebook, ma sentiti libero di sostituirla con un altro ticker di tuo interesse, come AAPL, MSFT o TSLA.
2. Configura GLM-5.3-Flash e le API dati
Ora che le chiavi API sono pronte, possiamo collegare i servizi che i nostri agenti useranno in tutto il progetto.
Inizia inizializzando Finnhub per i dati di mercato e Tavily per la ricerca sul web:
finnhub_client = finnhub.Client(
api_key=os.environ["FINNHUB_API_KEY"]
)
tavily_client = TavilyClient(
api_key=os.environ["TAVILY_API_KEY"]
)
Se vuoi costruire agenti finanziari e non sai quale fonte dati usare, ti consiglio di leggere la nostra guida su come scegliere la giusta API di dati di mercato.
Poi configura GLM-5.3-Flash come LLM principale per i nostri agenti CrewAI. Z.ai fornisce un’API compatibile con OpenAI, quindi possiamo collegarla direttamente tramite la classe LLM di CrewAI:
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,
)
Manteniamo la temperatura bassa perché questa applicazione è incentrata su ricerca e analisi finanziaria, dove vogliamo che gli agenti producano risposte più coerenti e focalizzate.
Connessi il modello, i dati di mercato e le API di ricerca web, possiamo iniziare a creare gli strumenti che useranno i nostri agenti.
3. Raccogli i dati di mercato storici
Ci servono i dati sui prezzi storici affinché i nostri agenti possano capire come si è comportata l’azione nel tempo.
Per questo useremo l’endpoint pubblico dei grafici di Yahoo Finance per raccogliere dati giornalieri di open, high, low, close e volume.
Scarica la cronologia dei prezzi
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)
Raccoglieremo circa 450 giorni di storia, che ci danno abbastanza dati per calcolare indicatori di più lungo periodo come la media mobile a 200 giorni.
Calcola gli indicatori tecnici
Ora calcoliamo alcuni indicatori comunemente usati:
- Medie mobili: media sugli ultimi 20, 50 e 200 giorni
- Relative Strength Index (RSI): scala tra 0 e 100 usata per indicare se un titolo è ipercomprato (>70) o ipervenduto (<30)
- Moving Average Convergence/Divergence (MACD): differenza tra le EMA di breve e lungo periodo
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
Questi indicatori saranno utili perché offrono all’agente di analisi tecnica una vista rapida di trend e momentum senza dover chiedere all’LLM di calcolare tutto da solo.
Rivedi gli ultimi valori
Ora raccogli i dati, calcola gli indicatori e mostra le ultime righe:
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",
]
]

Dovresti vedere l’ultimo prezzo dell’azione insieme alle sue medie mobili, RSI e MACD, simile all’output qui sopra.
Più avanti passeremo questi dati all’agente di analisi tecnica così che possa identificare trend di prezzo, momentum e segnali rialzisti o ribassisti.
4. Trasforma le fonti dati in strumenti CrewAI
Ora che le nostre fonti dati funzionano, dobbiamo trasformarle in strumenti CrewAI. Questo consente agli agenti di chiamarle direttamente quando hanno bisogno di informazioni finanziarie, tecniche o di news.
Crea gli strumenti sui dati azionari
Per prima cosa, crea una piccola funzione helper per mantenere i valori numerici puliti e coerenti:
def _number(value, decimals: int = 2) -> str:
if value is None or pd.isna(value):
return "N/A"
return f"{float(value):,.{decimals}f}"
Poi crea lo strumento per i fondamentali. Usa Finnhub per recuperare l’ultimo prezzo, le metriche di valutazione, crescita, redditività e altri fondamentali dell’azienda.
@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'))}"""
Creeremo anche uno strumento di analisi tecnica usando i dati storici e gli indicatori della sezione precedente.
@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)}%"""
La parte importante qui è il decoratore @tool. Trasforma una normale funzione Python in uno strumento che un agente CrewAI può decidere di chiamare durante un task.
Aggiungi lo strumento di ricerca web
Per notizie aziendali e sviluppi recenti, useremo lo strumento di ricerca Tavily di CrewAI:
web_search = TavilySearchTool(
api_key=os.environ["TAVILY_API_KEY"],
topic="news",
search_depth="advanced",
days=30,
max_results=5,
)
Limitiamo la ricerca agli ultimi 30 giorni e restituiamo fino a cinque risultati, sufficienti a fornire ai nostri agenti di ricerca informazioni recenti senza sommergerli di contenuti superflui.
Testa gli strumenti sulle azioni
Prima di creare gli agenti, esegui direttamente i due strumenti personalizzati:
print(get_fundamentals.run(ticker=TICKER))
print()
print(get_technicals.run(ticker=TICKER))

Ora dovresti vedere le ultime metriche fondamentali seguite dagli indicatori tecnici per l’azione selezionata.
5. Costruisci il team di ricerca multi-agent
Ora che gli strumenti sono pronti, possiamo creare il nostro team di ricerca multi-agent.
Useremo tre agenti specialisti, uno per l’analisi fondamentale, uno per l’analisi tecnica e uno per le notizie recenti, più un portfolio manager che combina i loro risultati nella valutazione finale.
Crea gli agenti specialisti
Per prima cosa, crea l’analista fondamentale:
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,
)
Poi crea l’analista tecnico:
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,
)
Poi crea l’analista delle notizie finanziarie:
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,
)
Ogni specialista riceve solo lo strumento di cui ha davvero bisogno. Questo mantiene il workflow focalizzato ed evita che gli agenti chiamino strumenti non pertinenti.
Crea il portfolio manager
Infine, crea l’agente manager che rivedrà i tre report degli specialisti:
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,
)
Il portfolio manager non ha bisogno di accesso diretto ai nostri strumenti dati. Lavorerà invece con i report prodotti dai tre agenti specialisti.
Impostare allow_delegation=False mantiene anche il workflow prevedibile, mentre max_iter limita il numero di cicli di reasoning e uso strumenti che ogni agente può eseguire.
6. Assegna task di ricerca specializzati
Creare gli agenti definisce chi sono. Ora dobbiamo dire a ciascuno esattamente cosa deve fare e cosa deve contenere il suo output finale.
Definisci i task di ricerca
Inizia con il task di analisi fondamentale:
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,
)
Poi definisci il task di analisi tecnica:
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,
)
Per gli sviluppi recenti, crea il task sulle news:
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,
)
Dare a ogni agente un task chiaro e un formato di output è importante. Rende i loro report più facili da confrontare per il portfolio manager, invece di ricevere risposte completamente diverse da ogni agente.
Crea il task decisionale finale
Il task finale riunisce i tre report:
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,
],
)
La parte chiave è context. Fornisce al portfolio manager l’accesso agli output dei tre task specialistici, consentendogli di confrontare i segnali da fondamentali, tecnici e news prima di produrre la valutazione finale BUY, HOLD o SELL.
A questo punto, i nostri agenti, strumenti e task sono pronti. Ora possiamo collegare tutto in un workflow CrewAI ed eseguire l’intero team di ricerca.
7. Esegui la research crew multi-agent
Ora possiamo mettere tutto insieme ed eseguire il workflow completo di ricerca azionaria.
Crea la crew
Crea una crew di CrewAI contenente i nostri tre agenti specialisti e il portfolio manager:
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,
)
Usiamo Process.sequential, quindi i task di ricerca vengono eseguiti in ordine. Gli agenti fondamentali, tecnici e news completano prima la loro analisi, e poi il portfolio manager riceve quei report per produrre la valutazione finale.
Esegui il team di ricerca
Avvia il workflow in modo asincrono:
result = await crew.kickoff_async()
Questo passaggio può richiedere tempo perché gli agenti effettuano più chiamate LLM e agli strumenti. Nei miei test, il workflow completo di ricerca ha impiegato circa 4–5 minuti per concludersi.
Una volta completato, mostra il report finale del portfolio manager:
print(result.raw)

Dovresti ottenere un report dettagliato simile all’output sopra, che include:
- Segnale BUY, HOLD o SELL
- Punteggio complessivo
- Livello di confidenza
- Punteggi degli specialisti
- Bull case
- Bear case
- Catalyst
- Rischi
- Fonti a supporto
In questo esempio, gli agenti hanno analizzato NVIDIA in modo indipendente e poi hanno combinato i risultati in un unico report di ricerca basato sulle evidenze. Qui possiamo finalmente vedere il vantaggio dell’approccio multi-agent: invece di chiedere a un solo modello di fare tutto insieme, ogni agente si concentra sulla propria area prima che il portfolio manager riunisca tutta la ricerca.
Se riscontri problemi nell’esecuzione del codice sopra, ho incluso anche il Jupyter Notebook completo con tutto il codice e gli output, che puoi consultare o eseguire: glm-stock-swarm/stock_analyst_crew.ipynb
8. Crea ed esegui la UI da terminale
Dopo aver testato tutto nel Jupyter Notebook, ho convertito l’intero workflow in un’interfaccia utente da terminale (TUI). Invece di eseguire manualmente ogni cella, ora puoi lanciare l’intero analista multi-agent con un singolo comando.
Il progetto completo, inclusi codice e istruzioni di setup, è disponibile su GitHub: repository GitHub glm-stock-swarm.
Installa ed esegui l’app
Inizia clonando il repository:
git clone https://github.com/kingabzpro/glm-stock-swarm.git
cd glm-stock-swarm
Aggiungi le tue chiavi API Z.ai, Finnhub e Tavily al file .env, quindi installa tutte le dipendenze con uv:
uv sync
Infine, avvia la TUI:
uv run glm-stock-swarm
Analizza un’azione
L’interfaccia offre un semplice box di input in cui puoi inserire qualsiasi ticker supportato per avviare l’analisi.

Una volta inviato il ticker, puoi osservare gli agenti lavorare uno alla volta. L’analista fondamentale parte per primo, seguito dall’analista tecnico, dall’analista news e infine dal portfolio manager, che combina tutto nella decisione finale.

Al termine, la TUI genera un report completo direttamente nel terminale, incluso punteggio fondamentali, punteggio tecnico, punteggio news, punteggio complessivo, confidenza, bull case, bear case, rischi, catalyst e il segnale finale BUY, HOLD o SELL.
Fai domande di follow-up
Ho aggiunto anche una chat di follow-up, così non devi rilanciare l’intera pipeline multi-agent ogni volta che hai un’altra domanda.

Per esempio, dopo aver ricevuto una raccomandazione SELL, ho chiesto se dovrei vendere l’intera posizione o solo una parte.

Invece di lanciare di nuovo tutti e quattro gli agenti, l’app usa il contesto del report di ricerca generato e invia una risposta di follow-up molto più rapida.
Questo rende l’applicazione più pratica perché la costosa ricerca multi-agent gira una volta, mentre le domande successive possono riutilizzare l’analisi esistente.
Considerazioni finali
La cosa degna di nota dai miei test è l’affidabilità nelle chiamate agli strumenti. Tutti e tre gli specialisti hanno scelto lo strumento giusto, rispettato la convenzione N/A invece di trattare i dati mancanti come zero, e restituito il formato punteggio+evidenze di cui il portfolio manager aveva bisogno. Di solito è lì che i modelli economici inciampano.
La velocità è il compromesso. Artificial Analysis misura GLM-5.3-Flash a circa 45 token di output al secondo sull’API di Z.ai, che è nella fascia bassa per modelli open-weight di queste dimensioni, e lo si percepisce nei 4–5 minuti che richiede un’esecuzione completa della crew. Inoltre, ottiene 57 sul loro indice d’intelligenza contro 60 per GLM-5.3, quindi si rinuncia a un po’ di qualità del reasoning, ma è un buon compromesso considerando che paghi circa un decimo del prezzo.
Nulla di tutto questo ti vincola. Passare a OpenRouter, Hugging Face Inference o a un modello locale tramite Ollama di solito significa cambiare tre cose: la chiave API, il nome del modello e la base URL. Lo stesso per gli strumenti, dove yfinance potrebbe svolgere il lavoro che qui si sono divisi Finnhub e Yahoo.
Il prossimo passo che farei è collegare questo a una API di paper trading e programmare un’esecuzione mattutina. Tienilo però su un account demo. Questo è stato costruito per insegnare il design degli agenti, non per fare trading.
Se vuoi imparare tutto sull’agentic AI dalle basi, ti consiglio il nostro skill track AI Agent Fundamentals come ottimo punto di partenza.
In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.
