1. Introduzione

La quantità di framework che sta nascendo per lo sviluppo di applicazioni di GenAI è incredibile e a mio avviso inizia ad essere pure eccessiva. Ogniqualvolta salta fuori un nuovo framework, mi sembra che faccia più o meno le stesse cose di quello precedente. Magari alcuni hanno una capacità di modularizzazione migliore, oppure un disegno più robusto contro l’obsolescenza nel lungo periodo, ma più o meno mi sembrano tutti gli stessi e, sebbene mi piaccia sperimentare, lo studio di nuovi mirabolanti e promettenti framework di GenAI comincia ad appassionarmi sempre meno.

Tanto per capirci, qualche giorno fa, mi sono imbattuto in AnyAgent: l’ennesimo framework che fa da wrapper verso altri framework! Nello specifico, non voglio essere frainteso, il lavoro che sta facendo il team di Mozilla in ambito AI è encomiabile e consiglio anche una lettura del loro blog, che pubblica articoli molto interessanti, ma questo genere di sovrastrutture Kafkiane mi sembra che introduca più problemi di quelli che risolva perché ogni stratificazione complica la manutenibilità del software nel lungo periodo, senza contare tutti i problemi di dipendenze, compatibilità e aggiornamenti.

Trovo inoltre inutilmente dispendioso specializzarmi sull’uno framework o sull’altro in maniera verticale, sia per una questione di lock-in, ma anche per non perdere quella capacità di astrazione che mi serve nel disegnare una soluzione end-to-end.

Un altro tema su cui quasi tutti i framework stanno dimostrando le loro limitazioni è nel supporto al multi-agent. I primissimi framework per lo sviluppo di GenAI si concentravano principalmente sul wrapping degli LLM, sul tracing e sul chaining, mentre ora la maggior parte dell’attenzione è rivolta alle funzionalità agentiche (odio questa parola), ma nella stragrande maggioranza dei casi, la progettazione originale dei framework è rimasta la stessa.

La maggior parte di questi framework è infatti ancora monolitica, il che rende difficile realizzare una vera applicazione multi-agente senza essere vincolati al framework specifico e al runtime sottostante.

Ed è qui che entra in gioco A2A (Agent-to-Agent). Il protocollo A2A mira a consentire una comunicazione e collaborazione fluida tra agenti, indipendentemente dal framework o runtime utilizzato, tramite formati di messaggistica e protocolli di trasporto standardizzati. Piuttosto che proseguire nello studio o approfondimento di questo o quell’altro framework, ho deciso di prendere sul serio il protocollo A2A e cercare di realizzare una soluzione applicativa end-to-end, compatibile con questo standard.

Il primo passo era quello di risolvere il problema della discovery e nel mio post precedente ho descritto come costruire un semplice Agent Registry che si adatta bene al protocollo A2A.

In seguito, volevo buttarmi su un caso d’uso concreto, quindi ho cercato qualche applicazione interessante da affrontare con la mia nuova architettura Multi-Agent A2A-compliant. Mi sono quindi imbattuto per caso nel paper AlphaAgents, pubblicato pochi giorni fa su arXiv dal team di BlackRock.

Il paper descrive un approccio di collaborazione multi-agente per supportare la stock selection e l’analisi finanziaria a partire da un set di titoli. Ho pensato che fosse un caso d’uso perfetto e mi ci sono buttato! Sfortunatamente, il team BlackRock non ha rilasciato il codice sorgente, quindi ho dovuto implementare l’intera soluzione AlphaAgent da solo, utilizzando il paper come specifica di alto livello. Ho comunque dovuto fare alcune assunzioni e semplificazioni, ad esempio i tool di estrazione e sintesi delle informazioni dell’agente che fa le analisi fondamentali non si basano realmente su RAG, ma piuttosto su tecniche molto banali di lookup tramite parole chiave o prefissi a partire dai dati restituiti da Yahoo Finance. Di conseguenza, l’implementazione non è conforme al 100% a quanto descritto nel paper, ma può essere un valido punto di partenza. In ogni caso, il mio focus è stato più sull’architettura che sull’affidabilità della risposta dei singoli agenti. Ho cercato inoltre di avere una visione agnostica rispetto al framework GenAI sottostante, dove l’agente orchestratore può ricercare e selezionare gli agenti specializzati a runtime, ignorando completamente i dettagli sottostanti in termini di modelli, linguaggi e librerie.

Nei capitoli che seguono, faccio un breve recap di cos’è AlphaAgents e come funziona in teoria, descrivo dunque l’architettura della mia implementazione A2A-compliant e alcuni dettagli tecnici e poi mostrerò cosa accade durante i singoli step di una esecuzione concreta.

Aggiungo anche un disclaimer probabilmente ovvio ma doveroso: l’output del sistema è da intendersi come puramente dimostrativo ai fini della soluzione multi-agent e non deve essere considerato in alcun modo come input per qualsiasi tipo di decisione finanziaria. Aggiungo inoltre che, sebbene abbia fatto qualche controllo puntuale di coerenza sui KPI calcolati, rilevando risultati più o meno in linea con le aspettatove, non è stato fatto un controllo approfondito e rigoroso della validità dei risultati. Non escludo dunque la possibilità di errori sistematici o ri-formulazioni delle risposte condizionate da allucinazioni dell’LLM.

2. Breve introduzione su AlphaAgents

Il paper AlphaAgents introduce un approccio innovativo al problema della selezione di titoli azionari attraverso un sistema multi-agente basato su Large Language Models (LLM).

2.1 Il problema e la soluzione

Le analisi di portafoglio tradizionali richiedono un notevole sforzo umano per processare enormi quantità di dati eterogenee: documenti SEC (10-K, 10-Q), trascrizioni di earnings call, target price, ratio finanziari, news di mercato e ricerche settoriali. Questo processo presenta inoltre significative sfide in termini di scalabilità e obiettività. Uno dei rischi citati più volte nel paper è infatti quello di propendere verso allocazioni sub-ottimali a causa di fattori soggettivi come l’avversione al rischio o l’eccessiva confidenza nelle proprie intuizioni.

Gli AlphaAgents affrontano questi problemi attraverso un framework multi-agente che incorpora alcune tecniche di adversarial reasoning e che suddivide l’analisi finanziaria in aree di specializzazione distinte, ciascuna gestita da un agente dedicato.

2.2 I tre agenti

Fundamental Agent: Si occupa dell’analisi fondamentale tradizionale, esaminando in profondità i bilanci, i flussi di cassa e le performance finanziarie attraverso l’analisi di documenti SEC e report finanziari.

Sentiment Agent: Analizza il sentiment di mercato attraverso l’elaborazione di news finanziarie, cambiamenti nei rating degli analisti e disclosure aziendali per valutare l’impatto potenziale sui prezzi delle azioni.

Valuation Agent: Si concentra sull’analisi tecnica e quantitativa, processando dati storici di prezzi e volumi per calcolare metriche di volatilità, rendimenti corretti per il rischio e indicatori di valutazione.

2.3 Il meccanismo di collaborazione e debate

Il framework implementa un meccanismo di coordinamento centralizzato attraverso un Group Chat Agent che gestisce l’interazione tra gli agenti specializzati. Questo agente coordinatore:

  1. Instrada le richieste verso gli agenti più appropriati in base al tipo di analisi richiesta usando un approccio basato sull’LLM
  2. Gestisce il processo di debate strutturato implementando un approccio di tipo “round-robin”
  3. Garantisce la partecipazione equa assicurando che ogni agente parli almeno due volte durante il debate
  4. Facilita la convergenza attraverso un sistema di consensus building che prevede la condivisione dei risultati intermedi con tutti gli agenti
  5. Sintetizza le analisi multiple in un report coerente che evidenzia il processo di debate
  6. Mitiga le allucinazioni attraverso il confronto cross-agent e la validazione collaborativa

Ricapitolando in poche parole: gli agenti si confrontano in turni sequenziali fino al raggiungimento del consenso, eliminando il rischio che alcuni agenti dominino la discussione.

graph TD A[Richiesta Utente] --> B[Group Chat Agent] B --> C{LLM-based Debate Detection} C -->|Investment Decision| D[Structured Debate Mode] C -->|Factual Query| E[Simple Coordination] D --> F[Round 1: Initial Positions] F --> G[Agent 1 Turn] G --> H[Agent 2 Turn] H --> I[Agent 3 Turn] I --> J[Round 2: Debate & Counter-arguments] J --> K[Agent 1 Response] K --> L[Agent 2 Response] L --> M[Agent 3 Response] M --> N{Consensus Check} N -->|No Consensus| O[Additional Rounds
Max 5 rounds] O --> J N -->|Consensus| P[Participation Check
Min 2 turns each] P -->|Insufficient| Q[Extra Turns] Q --> P P -->|Sufficient| R[Debate Consolidation] E --> S[Concurrent Agent Calls] S --> T[Simple Consolidation] R --> U[Final Report with Debate Metadata] T --> V[Final Report - Standard] style B fill:#e1f5fe style D fill:#fff3e0 style N fill:#ffecb3 style R fill:#e8f5e8 style C fill:#f3e5f5

2.4 Gestione Intelligente del Risk Tolerance

Un aspetto innovativo del framework è l’incorporamento di profili di tolleranza al rischio indicati dall’utente. Nel paper non è indicato precisamente in che modo il team di BlackRock ha implemetato l’introduzione di questi profili, ma ipotizzo che abbiano utilizzato dei meccanismi di prompting per inferire automaticamente il livello di rischio dalla query dell’utente. Partendo da questa analisi sulla query utente, viene dunque estrapolata una indicazione precisa del profilo di rischio desiderato, che poi viene utilizzata in tutte le interazioni con gli agenti.

Questo semplice accorgimento, consente dunque di aggiungere un livello di personalizzazione alle raccomandazioni fornite dagli agenti.

2.4.1 Classificazione dei Profili di Rischio

  • Risk-averse: Investitori conservativi che prioritizzano la conservazione del capitale, ricerca di rendimenti stabili, azioni dividend-paying, bassa volatilità, approccio safety-first
  • Risk-neutral: Investitori bilanciati che cercano crescita moderata con rischio ragionevole, portafogli diversificati, esposizione di mercato standard
  • Risk-seeking: Investitori aggressivi che perseguono rendimenti elevati, accettano alta volatilità, azioni growth, investimenti speculativi

2.4.2 Esempi di Classificazione Automatica

🟢 Risk-Averse (Conservativo):
"Sto cercando investimenti sicuri e stabili per la mia pensione"
"Cerco azioni sicure con dividendi regolari"
"Voglio preservare il mio capitale senza rischi"

🟡 Risk-Neutral (Bilanciato):  
"Dovrei investire in Tesla? Voglio un'analisi equilibrata"
"Devo investire in azioni Apple?"
"Analisi delle azioni Microsoft per il mio portafoglio"

🔴 Risk-Seeking (Aggressivo):
"Voglio azioni ad alta crescita anche se volatili"
"Voglio rendimenti massimi, posso gestire un rischio elevato"
"Cerco investimenti ad alto potenziale"

2.4.3 Integrazione nel Processo di Debate

Il profilo di rischio viene dunque:

  • Passato a tutti gli agenti specializzati tramite metadati nel messaggio JSON-RPC
  • Mantenuto durante tutto il debate per coerenza delle raccomandazioni
  • Registrato nei log per trasparenza del processo decisionale
  • Utilizzato per personalizzare le analisi di ciascun agente specialist

2.5 Vantaggi dell’approccio multi-agente con debate strutturato

Il sistema offre diversi benefici rispetto all’analisi tradizionale:

  • Mitigazione dei bias: Ogni agente opera in modo indipendente, riducendo l’impatto dei bias cognitivi umani
  • Partecipazione equa: Il meccanismo di turn-taking consente a tutti gli agenti di contribuire in modo equo
  • Validazione collaborativa: Le posizioni individuali vengono sottoposte a “challenge” e raffinate attraverso il confronto diretto
  • Convergenza guidata: Il sistema di consensus building porta a decisioni più robuste e ponderate
  • Personalizzazione automatica: Risk tolerance inferito automaticamente per analisi su misura
  • Adattamento multilingue: Sistema nativo per utenti di qualsiasi lingua senza configurazione
  • Scalabilità: Capacità di processare volumi molto maggiori di informazioni
  • Specializzazione: Ogni agente può sviluppare expertise approfondita nel proprio dominio
  • Flessibilità: Il framework può essere esteso con agenti aggiuntivi (es. Technical Analysis Agent, Macro Economist Agent)

3. Punto di partenza

Per realizzare il codice, ho fatto ampio uso di Claude Code, ma ho dedicato una quantità di tempo rilevante per la definizione delle specifiche tecniche di dettaglio rispetto a ciò che avevo in mente dopo aver letto il paper (es: struttura delle classi, gestione dei tool, etc), nonché per il testing e la modifica o la revisione di alcune classi e metodi.

Premesso che ciascun agente potrebbe essere implementato in modo indipendente, mi sono basato per semplicità sul seguente ecosistema:

  • Runtime: Python3.12
  • Package manager: uv
  • GenAI Framework: Langchain Agents (ma potrebbe essere sostituito con un altro framework tipo Autogen, CrewAI, Smolagents, etc)
  • Serving Layer: FastAPI
  • Protocollo di comunicazione: JSON-RPC
  • Test: semplici script python rilanciabili
  • Architettura basata sull’Agent Registry, con discovery dynamica dell’Agent Card per ciascun agente
  • LLM: per semplicità ho utilizzato GPT-4o, senza farmi troppi problemi sulla scelta del modello

Nei capitoli che seguono, illustro dettagliatamente l’architettura e l’implementazione. Ovviamente, uno degli step propedeutici è stato anche quello di corredare ciascun agente anche di un endpoint in cui esporre la Agent Card secondo il solito path “.well-known/agent-card” e registrare gli agenti all’interno dell’Agent Registry (Figura 1)

Figura 1 - Aggiunta del Valuation Agent
Figura 1 - Aggiunta del Valuation Agent

4. Design di alto livello

L’architettura è abbastanza semplice: si tratta di:

  • 1 Agent Registry che gestisce la registrazione e la discovery degli agenti (si tratta del modulo che ho discusso nel mio precedente articolo)
  • 3 agenti specializzati, ciascuno in esecuzione su un host e una porta specifica (nel mio caso, localhost e porte 3001-3003)
  • 1 agente di orchestrazione, che riceve gli input dell’utente, richiama gli altri agenti e produce la risposta finale.

4.1 Architettura Logica Complessiva

Ho lanciato tutti gli agenti in locale e configurato le Agent Card di conseguenza, ma ovviamente il sistema è progettato per supportare anche deployment distribuiti.

%%{init: {"themeVariables": { "fontSize": "16px", "nodeSpacing": 50, "rankSpacing": 70 }}}%% graph TD %% Client Layer subgraph "Client Layer" CLI[CLI Client] WEB[Web Interface] API[API Client] end %% A2A Protocol Layer subgraph "A2A Protocol Layer" JSONRPC[JSON-RPC Transport] A2AMSG[A2A Message Format] end %% Agent Registry subgraph "Agent Registry" REG[Agent Registry Service] REGDB[(Agent Cards DB)] end %% Orchestration Layer subgraph "Orchestration Layer" GCA[Group Chat Agent] ROUTER[Intelligent Routing] CONSOLIDATOR[Response Consolidator] end %% Specialized Agents subgraph "Specialized Agents" FA[Fundamental Agent
:3002] SA[Sentiment Agent
:3003] VA[Valuation Agent
:3001] end %% External Data Sources subgraph "External Data Sources" YF[Yahoo Finance API] SEC[SEC EDGAR API] NEWS["Financial News APIs"] end %% AI/LLM Layer subgraph "AI/LLM Layer" GPT[OpenAI GPT-4o] VADER[VADER Sentiment] TEXTBLOB[TextBlob Analysis] end %% Connessioni principali CLI --> JSONRPC WEB --> JSONRPC API --> JSONRPC JSONRPC --> A2AMSG A2AMSG --> GCA GCA --> REG REG --> REGDB GCA --> ROUTER ROUTER --> FA ROUTER --> SA ROUTER --> VA FA --> CONSOLIDATOR SA --> CONSOLIDATOR VA --> CONSOLIDATOR CONSOLIDATOR

4.2 Processo di registrazione

Nel mio caso, ho eseguito manualmente la registrazione sull’agent registry (Figura 1), tuttavia il processo potrebbe tranquillamente essere automatizzato. In sostanza, ogni Agent che vuole essere pubblicato all’interno dell’organizzazione potrebbe registrarsi autonomamente sull’Agent Registry.

Sia nel caso di registrazione manuale che automatica, il Group Chat Agent può in seguito interrogare l’Agent Registry e scoprire gli agenti specializzati necessari per rispondere a una richiesta dell’utente e decidere come orchestrare la comunicazione tra di essi.

sequenceDiagram participant GCA as Group Chat Agent participant REG as Agent Registry participant FA as Fundamental Agent participant SA as Sentiment Agent participant VA as Valuation Agent Note over FA,VA: Agent Startup & Registration FA->>REG: POST /agents/register
{agent_card, endpoints} REG-->>FA: 200 OK {agent_id} SA->>REG: POST /agents/register
{agent_card, endpoints} REG-->>SA: 200 OK {agent_id} VA->>REG: POST /agents/register
{agent_card, endpoints} REG-->>VA: 200 OK {agent_id} Note over GCA,REG: Agent Discovery GCA->>REG: GET /agents/search?skills=fundamental,sentiment,valuation REG-->>GCA: 200 OK {agents[]} Note over GCA,VA: Health Check & Validation GCA->>FA: GET /health FA-->>GCA: 200 OK {status: healthy} GCA->>SA: GET /health SA-->>GCA: 200 OK {status: healthy} GCA->>VA: GET /health VA-->>GCA: 200 OK {status: healthy}

4.3 Agent Card

Ogni agente espone le proprie capabilities attraverso un Agent Card conforme allo schema A2A. Per esempio, ecco come si presenta l’Agent Card per il Fundamental Agent:

{
  "name": "Fundamental Analysis Agent",
  "description": "Specialized agent for fundamental equity analysis. Analyzes 10-K and 10-Q financial reports, financial statements, and company fundamentals to assess stock value and projected trajectory. Provides qualitative and quantitative analysis of a company's financial performance, cash flow, operations, gross margins, and progress towards stated objectives.",
  "version": "1.0.0",
  "protocolVersion": "0.3.0",
  "url": "http://0.0.0.0:3003/",
  "preferredTransport": "JSONRPC",
  "provider": {
    "organization": "AlphaAgents Financial",
    "url": "https://AlphaAgents-dummy-corp.ai"
  },
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true
  },
  "defaultInputModes": [
    "text/plain",
    "application/json",
    "application/pdf"
  ],
  "defaultOutputModes": [
    "text/plain",
    "application/json"
  ],
  "skills": [
    {
      "id": "fundamental_analysis",
      "name": "Fundamental Financial Analysis",
      "description": "Performs comprehensive fundamental analysis of stocks using 10-K and 10-Q reports. Analyzes financial statements, cash flow, income statements, balance sheets, operations, gross margins, and company progress towards objectives. Provides buy/sell/hold recommendations based on fundamental metrics and risk tolerance.",
      "tags": [
        "financial-analysis",
        "10k-reports",
        "10q-reports",
        "financial-statements",
        "cash-flow-analysis",
        "fundamental-research",
        "equity-valuation"
      ],
      "examples": [
        "Analyze Apple's latest 10-K report and provide a fundamental analysis with recommendation",
        "Evaluate Microsoft's cash flow trends and operational efficiency from recent financial filings",
        "Compare Tesla's fundamental metrics against industry benchmarks and provide investment recommendation"
      ]
    },
    {
      "id": "financial_report_extraction",
      "name": "Financial Report Data Extraction",
      "description": "Extracts and processes key financial data from 10-K and 10-Q SEC filings. Uses RAG capabilities to retrieve relevant sections and perform targeted analysis on specific financial metrics, ratios, and disclosures.",
      "tags": [
        "data-extraction",
        "sec-filings",
        "financial-metrics",
        "rag-analysis",
        "document-processing"
      ],
      "examples": [
        "Extract revenue growth metrics from the latest quarterly report",
        "Pull debt-to-equity ratios and leverage analysis from annual filing",
        "Identify key risk factors mentioned in the 10-K management discussion"
      ]
    },
    {
      "id": "risk_assessment",
      "name": "Fundamental Risk Assessment",
      "description": "Assesses fundamental risks based on financial health indicators, debt levels, cash flow stability, competitive positioning, and management guidance. Tailors analysis to different risk tolerance profiles (risk-averse, risk-neutral).",
      "tags": [
        "risk-assessment",
        "financial-health",
        "debt-analysis",
        "competitive-analysis",
        "risk-tolerance"
      ],
      "examples": [
        "Assess the fundamental risk profile of Netflix given current debt levels and competitive pressures",
        "Evaluate Amazon's financial stability risks for risk-averse investors",
        "Analyze fundamental downside risks for Google's cloud business segment"
      ]
    }
  ],
  "additionalInterfaces": [
    {
      "url": "http://0.0.0.0:3003/",
      "transport": "JSONRPC"
    }
  ]
}

4.4 Flusso di Analisi End-to-End

Il processo di analisi prevede che l’orchestratore (il group chat) esegua un sistema di routing intelligente basato su LLM che:

  • Rileva automaticamente se la query richiede un debate strutturato (decisioni di investimento) o semplice coordinamento (query informative)
  • Determina quali agenti coinvolgere per svolgere l’analisi di dettaglio usando analisi semantica multilingue
  • Gestisce il processo di debate Round Robin quando necessario, garantendo come minimo 2 turni per agente

Per le domande che riguardano decisioni di investimento, il sistema attiva il meccanismo di debate strutturato:

  1. Round iniziale: Ogni agente presenta la sua posizione iniziale sequenzialmente
  2. Debate rounds: Gli agenti si confrontano in turni, presentando controargomentazioni
  3. Consensus check: Verifica del 75% di accordo dopo ogni round
  4. Participation enforcement: Garantisce minimo 2 turni per agente
  5. Synthesis finale: Consolida le posizioni finali evidenziando il processo di debate

Per le query informative, il sistema usa coordinamento parallelo tradizionale per massimizzare velocità e efficienza.

graph TD A[User Request] --> B[Group Chat Agent] B --> C{LLM-based Debate Detection
Multi-language Support} C -->|Investment Decision| D[Structured Debate Path] C -->|Information Query| E[Simple Coordination Path] subgraph "Structured Debate (Sequential)" D --> F[Initial Round - Sequential] F --> G[Agent 1: Initial Analysis] G --> H[Agent 2: Initial Analysis] H --> I[Agent 3: Initial Analysis] I --> J[Debate Round 2] J --> K[Agent 1: Counter-arguments] K --> L[Agent 2: Counter-arguments] L --> M[Agent 3: Counter-arguments] M --> N{Consensus Check
75% Threshold} N -->|No| O[Continue Debate
Max 5 Rounds] O --> J N -->|Yes| P{Participation Check
Min 2 turns each} P -->|No| Q[Extra Turns for Equity] Q --> P P -->|Yes| R[Debate Consolidation
with Metadata] end subgraph "Simple Coordination (Parallel)" E --> S[A2A Message/Send
to Required Agents] S --> T[Concurrent Processing] T --> U[Standard Consolidation] end R --> V[Final Report + Debate History] U --> W[Final Report - Standard] style B fill:#e1f5fe style C fill:#f3e5f5 style D fill:#fff3e0 style N fill:#ffecb3 style R fill:#e8f5e8

4.5 Transport Layer e Messaging Protocol

Tutto il traffico tra agenti utilizza il protocollo JSON-RPC conforme ad A2A:

Request Format:

{
  "jsonrpc": "2.0",
  "method": "message/send",
  "params": {
    "message": {
      "kind": "message",
      "messageId": "uuid",
      "role": "user",
      "parts": [{"kind": "text", "text": "Analyze AAPL"}],
      "contextId": "uuid",
      "taskId": "uuid"
    },
    "metadata": {}
  },
  "id": "uuid"
}

Response Format:

{
  "jsonrpc": "2.0",
  "result": {
    "kind": "message", 
    "messageId": "uuid",
    "role": "agent",
    "parts": [{"kind": "text", "text": "Analysis results..."}],
    "contextId": "uuid",
    "metadata": {
      "analysis_type": "fundamental",
      "confidence_score": 0.85
    }
  },
  "id": "uuid"
}

5. Implementazione

L’implementazione di AlphaAgents è stata realizzata con un focus sulla modularità, testabilità e conformità al protocollo A2A. Ogni agente è un’applicazione indipendente con le proprie dipendenze e può essere deployato separatamente.

Nota sull’implementazione: Come menzionato nell’introduzione, l’implementazione differisce dal paper originale in alcuni aspetti tecnici. In particolare:

  • Il Sentiment Agent utilizza le librerie VADER e TextBlob che dovrebbero rappresentare una soluzione semplice ma efficace poiché verosimilmente le news saranno esclusivamente in lingua inglese e non richiederanno una comprensione profonda del contesto. In futuro si potrebbero integrare modelli più sofisticati di sentiment analysis basati su LLM o modelli specifici come FinBERT.
  • Il Fundamental Agent impiega keyword matching sui dati di Yahoo Finance invece di vere tecniche RAG con vector databases
  • In generale, mi sono focalizzato sull’architettura piuttosto che sulle performance specifiche dei singoli agenti

Tutto il codice è disponibile su GitHub.

5.1 Stack Tecnologico e Dependencies

Il progetto utilizza Python 3.12 come runtime con uv come package manager per gestione rapida delle dependencies. Di seguito un estratto del file di configurazione per dare una idea delle dipendenze:

# pyproject.toml - Global Dependencies
[project]
name = "alpha_agents"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "langchain>=0.3.27",
    "langchain-openai>=0.3.32",
    "langchain-community>=0.3.28",
    "openai>=1.102.0",
    "yfinance>=0.2.65",
    "pandas>=2.3.2",
    "numpy>=2.3.2",
    "fastapi>=0.116.1",
    "uvicorn>=0.35.0",
    "pydantic>=2.11.7",
    "python-dotenv>=1.1.1",
    "httpx>=0.28.1",
    "aiohttp>=3.12.15",
    "requests>=2.32.5",
    "beautifulsoup4>=4.13.5",
    "feedparser>=6.0.11",
    "newspaper3k>=0.2.8",
    "textblob>=0.18.0",
    "vaderSentiment>=3.3.2",
    "python-dateutil>=2.9.0"
]

5.2 Struttura del Progetto

Di seguito una panoramica della struttura del progetto:

alpha-agents-implementation/
├── agents/
│   ├── groupchat-agent/          # Orchestratore principale
│   │   ├── src/groupchat_agent/
│   │   │   ├── a2a_agent.py      # Logica coordinamento
│   │   │   ├── registry_service.py # Client Agent Registry
│   │   │   └── server.py         # FastAPI server
│   │   └── pyproject.toml
│   ├── fundamental-agent/        # Analisi fondamentale
│   │   ├── src/fundamental_agent/
│   │   │   ├── agent.py          # Langchain agent
│   │   │   ├── tools.py          # SEC/Finance tools
│   │   │   └── server.py         # A2A endpoint
│   │   └── pyproject.toml
│   ├── sentiment-agent/          # Analisi sentiment
│   │   └── src/sentiment_agent/
│   │   │   ├── agent.py          # Langchain agent
│   │   │   ├── tools.py          # News collection / Sentiment Analysis
│   │   │   └── server.py         # A2A endpoint
│   │   └── pyproject.toml
│   └── valuation-agent/          # Analisi quantitativa
│       └── src/valuation_agent/
│   │   │   ├── agent.py          # Langchain agent
│   │   │   ├── tools.py          # Stock data collection / KPI calculation
│   │   │   └── server.py         # A2A endpoint
│   │   └── pyproject.toml

5.3 Implementazione del Group Chat Agent

Il Group Chat Agent è il cuore e l’entry point del sistema, implementato nella classe A2AGroupChatAgent. Le sue responsabilità principali includono:

  1. Rilevamento intelligente del debate: Usa LLM per determinare se la query richiede debate strutturato
  2. Inferenza automatica del risk tolerance: Analizza il messaggio utente per identificare il profilo di rischio
  3. Routing multilingue: Identifica agenti necessari indipendentemente dalla lingua della query
  4. Orchestrazione del debate: Gestisce la partecipazione equa tramite un sistema di turni round-robin
  5. Consensus monitoring: Verifica accordo e termina il debate quando appropriato
  6. Metadata enhancement: Arricchisce automaticamente i metadati con risk_tolerance per tutti gli agenti

5.3.1 Inferenza del Risk Tolerance

Il sistema utilizza un classificatore basato su LLM che analizza il messaggio utente per estrapolare il profilo di rischio. Le linee guida per la classificazione includono:

  1. Preferenze esplicite di rischio: Termini come “conservativo”, “aggressivo”, “alta crescita”, “sicuro”, “stabile”
  2. Timeframe di investimento: Menzioni di “pensionamento”, “lungo termine”, “guadagni rapidi”
  3. Analisi del vocabolario: Scelte linguistiche e tono (cauto vs confidente vs speculativo)
  4. Tipi di asset menzionati: Bond/dividendi = averse, growth stock = seeking
  5. Supporto multilingue: Funziona in qualsiasi lingua analizzando intento e segnali di rischio

Come ho anticipato in precedenza, non ho idea di come abbiano fatto i ricercatori di BlackRock per identificare il profilo di rischio. Tuttavia, è facile immaginare che abbiano fatto qualcosa di simile.

5.3.2 Estratto del codice

Di seguito un estratto della classe A2AGroupChatAgent che illustra alcuni dei metodi principali:

class A2AGroupChatAgent:
    def __init__(self, openai_api_key: str, registry_url: str, model_name: str = "gpt-4o"):
        self.llm = ChatOpenAI(
            model=model_name,
            openai_api_key=openai_api_key,
            temperature=0.1  # Bassa temperatura per analisi finanziarie
        )
        self.registry_service = AgentRegistryService(registry_url)
        self._agent_urls = {}
    
    def _requires_debate_analysis(self, user_message: str) -> bool:
        """Usa LLM per determinare intelligentemente se serve debate strutturato."""
        system_prompt = """You are a debate necessity classifier for a multi-agent financial analysis system.
        
        STRUCTURED DEBATE IS NEEDED when:
        1. The query asks for investment decisions or recommendations (buy/sell/hold advice)
        2. The query requires weighing conflicting factors or multiple perspectives
        3. The query asks for comprehensive analysis that would benefit from specialist disagreement/consensus
        4. The query involves risk assessment or strategic financial decisions
        5. The query asks for opinions, advice, or evaluations that could have multiple valid perspectives
        6. The query involves portfolio management decisions
        
        The query can be in ANY language. Focus on the intent and meaning, not specific keywords.
        Respond with ONLY "YES" if structured debate is needed, or "NO" if it's not needed."""
        
        response = self.llm.invoke([
            SystemMessage(content=system_prompt),
            HumanMessage(content=f"User query: {user_message}")
        ])
        
        return response.content.strip().upper() == "YES"
    
    def _enhance_metadata_with_risk_tolerance(
        self, user_message: str, metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Extract or infer risk tolerance and add it to metadata."""
        
        enhanced_metadata = metadata.copy() if metadata else {}
        
        # If risk_tolerance already provided in metadata, use it
        if "risk_tolerance" in enhanced_metadata:
            logger.info(f"Using provided risk_tolerance: {enhanced_metadata['risk_tolerance']}")
            return enhanced_metadata
        
        # Otherwise, infer using LLM
        risk_tolerance = self._infer_risk_tolerance_from_message(user_message)
        enhanced_metadata["risk_tolerance"] = risk_tolerance
        
        logger.info(f"Inferred risk_tolerance: {risk_tolerance} from user message")
        return enhanced_metadata

    def _infer_risk_tolerance_from_message(self, user_message: str) -> str:
        """Use LLM to infer risk tolerance from user message content."""
        
        system_prompt = """You are a financial risk tolerance classifier. 
        Analyze the user's message to determine their risk tolerance profile.

        RISK TOLERANCE LEVELS:
        - "averse": Conservative investors (capital preservation, stable returns, dividends)
        - "neutral": Balanced investors (moderate growth with reasonable risk)  
        - "seeking": Aggressive investors (high returns, accept high volatility)

        CLASSIFICATION GUIDELINES:
        1. Look for explicit risk preferences ("conservative", "aggressive", "safe")
        2. Consider investment timeframe ("retirement", "long-term", "quick gains")
        3. Analyze vocabulary and tone (cautious vs confident vs speculative)
        4. Consider asset mentions (bonds/dividends = averse, growth stocks = seeking)
        
        The message can be in any language. Focus on intent and risk signals.
        Respond with ONLY one word: "averse", "neutral", or "seeking"."""

        try:
            response = self.llm.invoke([
                SystemMessage(content=system_prompt),
                HumanMessage(content=f"User message: {user_message}")
            ])
            
            risk_level = response.content.strip().lower()
            return risk_level if risk_level in ["averse", "neutral", "seeking"] else "neutral"
            
        except Exception as e:
            logger.error(f"Error inferring risk tolerance: {e}")
            return "neutral"  # Safe default
    
    async def _conduct_structured_debate(
        self, user_message: str, context_id: str, task_id: str, 
        required_agents: List[str], metadata: Optional[Dict[str, Any]] = None
    ) -> List[Dict[str, Any]]:
        """Conduce debate strutturato con risk tolerance personalizzato."""
        
        risk_tolerance = metadata.get("risk_tolerance", "neutral") if metadata else "neutral"
        logger.info(f"Starting structured debate with agents: {required_agents} (risk_tolerance: {risk_tolerance})")
        
        # Gli agenti riceveranno il risk_tolerance nei metadati per personalizzare le analisi
        # ... resto dell'implementazione debate ...

5.4 Pattern di Comunicazione A2A

Ogni comunicazione tra agenti segue il protocollo A2A utilizzando JSON-RPC:

async def _send_message_to_agent(
    self, agent_name: str, agent_url: str, 
    message: Dict[str, Any], metadata: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """Invia messaggio A2A-compliant agli agenti specializzati."""
    
    request_payload = {
        "jsonrpc": "2.0",
        "method": "message/send",
        "params": {
            "message": {
                "kind": "message",
                "messageId": str(uuid.uuid4()),
                "role": "user", 
                "parts": [{"kind": "text", "text": user_message}],
                "contextId": context_id,
                "taskId": task_id
            },
            "metadata": metadata or {}
        },
        "id": str(uuid.uuid4())
    }
    
    async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=300.0)) as session:
        async with session.post(agent_url, json=request_payload, 
                              headers={"Content-Type": "application/json"}) as response:
            result = await response.json()
            
            # Estrai contenuto dalla risposta A2A
            a2a_result = result.get("result", {})
            if a2a_result.get("kind") == "message":
                parts = a2a_result.get("parts", [])
                analysis = " ".join([p.get("text", "") for p in parts 
                                   if p.get("kind") == "text"])

5.5 Implementazione degli Agenti Specializzati

5.5.1 Fundamental Agent

Il Fundamental Agent utilizza Langchain con pattern di tool calling per accedere a dati finanziari:

class FundamentalAgent:
    def __init__(self, openai_api_key: str, model_name: str = "gpt-4o"):
        self.llm = ChatOpenAI(
            api_key=openai_api_key,
            model=model_name,
            temperature=0.1,
            max_tokens=4000
        )
        
        # Tools specializzati per analisi fondamentale
        self.tools = get_fundamental_tools()  # Yahoo Finance API, keyword-based analysis
        
        # Prompt specializzato per analisi fondamentale
        self.system_prompt = """You are a specialized Fundamental Analysis Agent.
        Your core expertise includes:
        
        **Financial Statement Analysis:**
        - Deep analysis of income statements, balance sheets, and cash flow statements
        - Assessment of financial health, profitability, and operational efficiency
        
        **SEC Filing Analysis:**  
        - Comprehensive review of 10-K and 10-Q reports
        - Management Discussion & Analysis (MD&A) insights
        
        **Investment Decision Framework:**
        Your analysis should result in clear BUY/SELL/HOLD recommendations with:
        - Target price estimates with supporting rationale
        - Risk assessment (financial, operational, market risks)"""
        
        # Langchain Agent Executor
        self.agent_executor = AgentExecutor(
            agent=create_openai_tools_agent(self.llm, self.tools, prompt),
            tools=self.tools,
            verbose=True,
            handle_parsing_errors=True,
            max_iterations=10
        )

5.5.2 Sentiment Agent - Implementazione VADER

Il Sentiment Agent utilizza una combinazione di VADER (Valence Aware Dictionary and sEntiment Reasoner) e TextBlob per analizzare il sentiment delle news finanziarie:

class NewsSummarizationTool(BaseTool):
    name: str = "analyze_news_sentiment"
    description: str = "Analyzes financial news sentiment using VADER and TextBlob"
    
    def _analyze_vader_sentiment(self, text: str) -> Dict[str, Any]:
        """Analizza sentiment usando VADER - ottimizzato per social media e news."""
        vader_analyzer = SentimentIntensityAnalyzer()
        scores = vader_analyzer.polarity_scores(text)
        
        # Compound score da -1 a +1
        compound = scores['compound']
        if compound >= 0.05:
            label = "positive"
        elif compound <= -0.05:
            label = "negative"
        else:
            label = "neutral"
        
        return {
            "compound": float(compound),
            "pos": float(scores['pos']),
            "neg": float(scores['neg']),
            "neu": float(scores['neu']),
            "label": label
        }
    
    def _analyze_textblob_sentiment(self, text: str) -> Dict[str, Any]:
        """Analizza sentiment usando TextBlob."""
        blob = TextBlob(text)
        polarity = blob.sentiment.polarity  # -1 to 1
        subjectivity = blob.sentiment.subjectivity  # 0 to 1
        
        if polarity > 0.1:
            label = "positive"
        elif polarity < -0.1:
            label = "negative"
        else:
            label = "neutral"
        
        return {"polarity": float(polarity), "subjectivity": float(subjectivity), "label": label}
    
    def _combine_sentiments(self, textblob: Dict, vader: Dict) -> Dict[str, Any]:
        """Combina i risultati con peso maggiore per VADER (migliore per news)."""
        combined_score = (textblob["polarity"] * 0.4) + (vader["compound"] * 0.6)
        
        if combined_score > 0.1:
            label = "positive"
        elif combined_score < -0.1:
            label = "negative"
        else:
            label = "neutral"
        
        return {"score": float(combined_score), "label": label, "confidence": abs(combined_score)}

5.5.3 Fundamental Agent - Implementazione Keyword-Based

L’analisi fondamentale non utilizza tecniche RAG, ma impiega un approccio molto elementare basato su keyword matching partendo dai metadati restituiti da Yahoo Finance:

class RAGAnalysisTool(BaseTool):  # Nome mantenuto per compatibilità e futura evoluzione, ma NON è vero RAG
    name: str = "rag_fundamental_analysis"
    description: str = "Performs fundamental analysis using keyword-based data extraction"
    
    def _find_cash_flow_key(self, data: Dict[str, Any], possible_keys: List[str]) -> Optional[str]:
        """Trova la chiave corretta per i dati cash flow usando pattern matching."""
        for item_name, _ in data.items():
            for key in possible_keys:
                if key.lower() in item_name.lower():
                    return item_name
        return None
    
    def _analyze_cash_flow(self, financial_context: Dict[str, Any], guidance: Dict[str, Any]):
        """Analizza cash flow con ricerca per keyword, non RAG."""
        quarterly_data = financial_context.get("cash_flow", {}).get("quarterly", {}).get("data", {})
        
        if quarterly_data:
            # Cerca "Operating Cash Flow" usando keyword matching
            operating_cf_key = self._find_cash_flow_key(
                quarterly_data, 
                ["Operating Cash Flow", "Total Cash From Operating Activities"]
            )
            
            if operating_cf_key:
                # Estrai valori usando il pattern trovato
                cf_values = []
                for period, values in quarterly_data.items():
                    if operating_cf_key in values and values[operating_cf_key] is not None:
                        cf_values.append(values[operating_cf_key])

5.5.4 Valuation Agent Tools

Il Valuation Agent implementa calcoli finanziari specializzati utilizzando pandas e numpy:

class VolatilityCalculationTool(BaseTool):
    name: str = "calculate_volatility_metrics"
    description: str = "Calculates comprehensive volatility and risk metrics"
    
    def _run(self, symbol: str, risk_free_rate: float = 0.05) -> Dict[str, Any]:
        """Calculate volatility and risk metrics synchronously."""
        try:
            # First fetch the data
            stock_tool = StockDataTool()
            stock_data = stock_tool._run(symbol)
            
            if not stock_data["success"]:
                return stock_data
            
            # Convert to pandas DataFrame for calculations
            price_data = stock_data["price_data"]
            df = pd.DataFrame({
                'Date': pd.to_datetime(price_data["dates"]),
                'Close': price_data["close"],
                'Volume': price_data["volume"]
            })
            df.set_index('Date', inplace=True)
            
            # Calculate daily returns
            df['Daily_Return'] = df['Close'].pct_change()
            df = df.dropna()
            
            if len(df) < 2:
                return {
                    "success": False,
                    "error": "Insufficient data for calculations",
                    "symbol": symbol
                }
            
            # Basic metrics
            daily_returns = df['Daily_Return']
            
            # Daily metrics
            mean_daily_return = daily_returns.mean()
            daily_volatility = daily_returns.std()
            
            # Calculate cumulative return for proper annualized return
            start_price = df['Close'].iloc[0]
            end_price = df['Close'].iloc[-1]
            cumulative_return = (end_price / start_price) - 1
            trading_days = len(df)
            
            # Annualized metrics
            annualized_return = ((1 + cumulative_return) ** (TRADING_DAYS_PER_YEAR / trading_days)) - 1
            annualized_volatility = daily_volatility * np.sqrt(TRADING_DAYS_PER_YEAR)
            
            # Sharpe ratio
            sharpe_ratio = (annualized_return - risk_free_rate) / annualized_volatility if annualized_volatility > 0 else 0
            
            # Maximum drawdown calculation
            cumulative_returns = (1 + daily_returns).cumprod()
            rolling_max = cumulative_returns.expanding().max()
            drawdowns = (cumulative_returns - rolling_max) / rolling_max
            max_drawdown = drawdowns.min()
            
            # Value at Risk (VaR) - 5% and 1%
            var_5 = np.percentile(daily_returns, 5)
            var_1 = np.percentile(daily_returns, 1)
            
            # Additional statistics
            skewness = daily_returns.skew()
            kurtosis = daily_returns.kurtosis()
            
            # Price performance metrics
            total_return = (df['Close'].iloc[-1] - df['Close'].iloc[0]) / df['Close'].iloc[0]
            
            result = {
                "success": True,
                "symbol": symbol.upper(),
                "analysis_period": {
                    "start_date": df.index[0].strftime("%Y-%m-%d"),
                    "end_date": df.index[-1].strftime("%Y-%m-%d"),
                    "trading_days": len(df)
                },
                "price_metrics": {
                    "start_price": float(df['Close'].iloc[0]),
                    "end_price": float(df['Close'].iloc[-1]),
                    "total_return": float(total_return),
                    "annualized_return": float(annualized_return)
                },
                "volatility_metrics": {
                    "daily_volatility": float(daily_volatility),
                    "annualized_volatility": float(annualized_volatility),
                    "volatility_percentage": float(annualized_volatility * 100)
                },
                "risk_metrics": {
                    "sharpe_ratio": float(sharpe_ratio),
                    "max_drawdown": float(max_drawdown),
                    "max_drawdown_percentage": float(max_drawdown * 100),
                    "var_5_percent": float(var_5),
                    "var_1_percent": float(var_1),
                    "risk_free_rate": float(risk_free_rate)
                },
                "distribution_metrics": {
                    "mean_daily_return": float(mean_daily_return),
                    "skewness": float(skewness),
                    "kurtosis": float(kurtosis),
                    "positive_days": int((daily_returns > 0).sum()),
                    "negative_days": int((daily_returns < 0).sum())
                },
                "volume_metrics": {
                    "average_volume": float(df['Volume'].mean()),
                    "volume_volatility": float(df['Volume'].std()),
                    "latest_volume": float(df['Volume'].iloc[-1])
                }
            }
            
            logger.info(f"Successfully calculated metrics for {symbol}")
            return result
            
        except Exception as e:
            logger.error(f"Error calculating metrics for {symbol}: {str(e)}")
            return {
                "success": False,
                "error": f"Failed to calculate metrics for {symbol}: {str(e)}",
                "symbol": symbol
            }

5.6 Agent Registration e Discovery

Ogni agente espone un endpoint /.well-known/agent-card per la discovery automatica. Prima di avviare tutto lo stack, ho utilizzato questi endpoint per la registrazione all’interno dell’Agent Registry:

@app.get("/.well-known/agent-card")
async def get_agent_card():
    return {
        "name": "Valuation Analysis Agent",
        "description": "Specialized agent for stock valuation and technical analysis",
        "version": "1.0.0",
        "protocolVersion": "0.3.0",
        "url": "http://0.0.0.0:3001/",
        "preferredTransport": "JSONRPC",
        "skills": [
            {
                "id": "technical_valuation_analysis",
                "name": "Technical Valuation Analysis",
                "description": "Comprehensive technical analysis using historical data",
                "tags": ["technical-analysis", "volatility-analysis", "valuation-metrics"]
            }
        ]
    }

5.7 Consolidation Pattern con LLM

Il consolidamento delle analisi specialistiche utilizza un pattern di meta-prompt per sintetizzare le diverse prospettive.

def _consolidate_analyses(self, agent_responses: List[Dict], user_message: str) -> str:
    system_prompt = """You are a financial analysis consolidator. Your role is to 
    synthesize insights from multiple specialist agents into a coherent response.
    
    CONSOLIDATION GUIDELINES:
    1. Integrate insights from all successful agent responses
    2. Identify agreements and disagreements between agents
    3. Provide clear, actionable recommendations when possible
    4. If agents disagree, explain the different perspectives"""
    
    analyses_text = []
    for response in successful_responses:
        agent_name = response.get("agent", "unknown")
        analysis = response.get("analysis", "No analysis provided")
        analyses_text.append(f"**{agent_name.upper()} AGENT:**\n{analysis}")
    
    consolidation_prompt = f"""
    USER REQUEST: {user_message}
    
    AGENT ANALYSES:
    {chr(10).join(analyses_text)}
    
    Please provide a consolidated analysis that synthesizes these perspectives."""
    
    response = self.llm.invoke([
        SystemMessage(content=system_prompt),
        HumanMessage(content=consolidation_prompt)
    ])
    
    return response.content

Questa soluzione di consolidamento è complementare al sistema di debate strutturato implementato: quando il debate viene attivato, il consolidamento finale evidenzia il processo collaborativo seguito e i metadati del debate (rounds, turni, partecipazione), mentre per query informative usa il consolidamento standard per massimizzare velocità ed efficienza.

5.8 Semplificazioni dell’implementazione attuale

È importante evidenziare alcune semplificazioni che ho adottato rispetto alle specifiche del paper originale, per scendere a compromessi pratici:

Sentiment Analysis: L’uso di VADER e TextBlob è efficace per un prototipo, ma in un’implementazione produttiva sarebbe opportuno valutare:

  • Modelli transformer specializzati per testo finanziario (FinBERT)
  • Analisi multi-source più sofisticata
  • Gestione del contesto finanziario specifico

Fundamental Analysis: L’approccio keyword-based funziona sui dati strutturati di Yahoo Finance, ma un’implementazione produttiva richiederebbe:

  • Vero sistema RAG con vector embeddings per documenti SEC
  • Integrazione con database finanziari professionali (Bloomberg, Refinitiv)
  • Parsing semantico avanzato dei documenti 10-K/10-Q

Validazione: Il sistema manca di:

  • Backtesting rigoroso delle raccomandazioni
  • Metriche di performance validate su dataset storici
  • Confronto con benchmark di mercato

In ottica di un’evoluzione futura, possiamo facilmente sostituire questi componenti con implementazioni più sofisticate senza modificare l’architettura complessiva.

6. Scansione ai raggi X di una richiesta utente

Per capire bene come funziona il sistema AlphaAgents, vediamolo in azione! Ho eseguito un test end-to-end utilizzando una query utente significativa che richiede il coinvolgimento di tutti e tre gli agenti specializzati.

Query dell’utente: “Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato”

In questa sezione, documenterò passo passo tutto ciò che accade dietro le quinte dal momento in cui la richiesta viene ricevuta dal Group Chat Agent fino alla generazione del report finale di sintesi.

6.1 Fase 1: Inizializzazione e Setup dell’Ecosistema

Prima che la query utente possa essere elaborata, è necessario che tutto l’ecosistema AlphaAgents sia attivo e operativo:

6.1.1 Avvio dell’Agent Registry

L’Agent Registry è il primo componente che deve essere attivato, in quanto tutti gli agenti dipendono da esso per la discovery:

# Agent Registry attivo su porta 8000
curl -s http://localhost:8000/health
# Response: {"status":"ok","time":"2025-08-30T17:06:48.102057+00:00"}

6.1.2 Startup degli Agenti Specializzati

Ho lanciato gli agenti specializzati nella mia configurazione locale nelle porte [3001, 3002, 3003]:

Valuation Agent (porta 3001):

2025-08-30 19:06:50 - __main__ - INFO - Starting Valuation Agent...
2025-08-30 19:06:50 - valuation_agent.agent - INFO - Valuation Agent initialized successfully
2025-08-30 19:06:50 - valuation_agent.server - INFO - A2A Valuation Server initialized on 0.0.0.0:3001
INFO: Uvicorn running on http://0.0.0.0:3001

Sentiment Agent (porta 3002):

2025-08-30 19:06:50 - __main__ - INFO - Starting Sentiment Agent...
2025-08-30 19:06:50 - sentiment_agent.agent - INFO - Sentiment Agent initialized successfully
2025-08-30 19:06:50 - sentiment_agent.server - INFO - A2A Sentiment Server initialized on 0.0.0.0:3002
INFO: Uvicorn running on http://0.0.0.0:3002

Fundamental Agent (porta 3003):

2025-08-30 19:06:50 - __main__ - INFO - Starting Fundamental Agent...
2025-08-30 19:06:50 - fundamental_agent.agent - INFO - Fundamental Agent initialized successfully
2025-08-30 19:06:50 - fundamental_agent.server - INFO - A2A Fundamental Server initialized on 0.0.0.0:3003
INFO: Uvicorn running on http://0.0.0.0:3003

6.1.3 Avvio del Group Chat Agent

Il Group Chat Agent è l’ultimo a essere avviato ed agisce come orchestratore:

2025-08-30 19:07:31 - groupchat_agent.server - INFO - Starting GroupChat Agent server on 0.0.0.0:3000
2025-08-30 19:07:31 - groupchat_agent.a2a_agent - INFO - A2A GroupChat Agent initialized successfully
INFO: Uvicorn running on http://0.0.0.0:3000

6.2 Fase 2: Ricezione e Parsing della Query Utente

6.2.1 Richiesta JSON-RPC A2A

La query utente viene inviata al Group Chat Agent tramite protocollo JSON-RPC:

{
  "jsonrpc": "2.0",
  "method": "message/send",
  "params": {
    "message": "Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato",
    "metadata": {
      "user_id": "demo_user", 
      "session_id": "demo_session"
    }
  },
  "id": "1"
}

6.2.2 Conversione in Formato A2A Message

Il server converte automaticamente la query in formato A2A Message standard:

{
  "kind": "message",
  "messageId": "uuid-generated",
  "role": "user", 
  "parts": [
    {
      "kind": "text",
      "text": "Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato"
    }
  ],
  "contextId": "demo_session"
}

6.3 Fase 3: Inferenza Automatica del Risk Tolerance

6.3.1 Chiamata LLM per Risk Assessment

Il sistema analizza semanticamente la query dell’utente per inferire automaticamente il profilo di rischio:

2025-08-30 19:09:40 - groupchat_agent.a2a_agent - INFO - Inferred risk_tolerance: seeking from user message

Prompt LLM utilizzato:

"""
You are a financial risk tolerance classifier. 
Analyze the user's message to determine their risk tolerance profile.

RISK TOLERANCE LEVELS:
- "averse": Conservative investors (capital preservation, stable returns, dividends)
- "neutral": Balanced investors (moderate growth with reasonable risk)  
- "seeking": Aggressive investors (high returns, accept high volatility)

User message: "Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato"
"""

Risultato: risk_tolerance: "seeking"

Come da attese, il sistema ha identificato un profilo aggressivo basandosi su “rendimenti massimi” e “posso gestire un rischio elevato”.

6.4 Fase 4: Agent Discovery e Routing Intelligente

6.4.1 Recupero Agent Card dall’Agent Registry

Il Group Chat Agent interroga l’Agent Registry per ottenere l’Agent Card e gli endpoint degli agenti richiesti:

2025-08-30 19:09:40 - groupchat_agent.registry_service - INFO - Fetching specialist agent URLs from registry...

HTTP Request: GET http://localhost:8000/agents?name=valuation
HTTP Request: GET http://localhost:8000/agents?name=sentiment  
HTTP Request: GET http://localhost:8000/agents?name=fundamental

2025-08-30 19:09:40 - groupchat_agent.registry_service - INFO - Found agent 'valuation' at http://0.0.0.0:3001/
2025-08-30 19:09:40 - groupchat_agent.registry_service - INFO - Found agent 'sentiment' at http://0.0.0.0:3002
2025-08-30 19:09:40 - groupchat_agent.registry_service - INFO - Found agent 'fundamental' at http://0.0.0.0:3003/

6.4.2 Routing LLM per Selezione Agenti

Il sistema usa un prompt per determinare quali agenti coinvolgere:

Prompt LLM Routing:

"""
You are a routing coordinator for financial analysis agents. 
Analyze the user's request and determine which specialist agents should be consulted:

AVAILABLE AGENTS:
- valuation: Technical analysis, price charts, volatility, quantitative metrics
- sentiment: News analysis, market sentiment, social media trends  
- fundamental: Financial reports, earnings, company fundamentals, SEC filings

User request: Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato
"""

Risultato:

2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - 🤖 LLM ROUTING RESPONSE: ["valuation", "sentiment", "fundamental"]
2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - Determined required agents: ['valuation', 'sentiment', 'fundamental']

6.4.3 Decisione per Debate Strutturato

Un altro prompt determina se la query richiede debate strutturato o coordinamento semplice:

2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - 🤔 LLM DEBATE DECISION: YES for query: 'Sono indeciso se investire in Tesla oppure in Pala...'
2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - Multi-agent analysis detected - initiating structured debate

6.5 Fase 5: Round 1 - Analisi Iniziali

Viene attivato il meccanismo di debate strutturato con round-robin. Ogni agente presenta la sua analisi iniziale sequenzialmente.

2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - Starting structured debate with agents: ['valuation', 'sentiment', 'fundamental']
2025-08-30 19:09:41 - groupchat_agent.a2a_agent - INFO - === INITIAL ANALYSIS ROUND ===

6.5.1 Valuation Agent - Round 1

Ticker Resolution: Il Valuation Agent inizia risolvendo i nomi delle compagnie in ticker di borsa, poi recupera i dati finanziari, calcola le metriche di valutazione ed infine genera un breve report di sintesi in cui consiglia di investire in Palantir:

> Entering new AgentExecutor chain...

Invoking: `resolve_company_ticker` with `{'query': 'Tesla'}`
{'success': True, 'query': 'Tesla', 'ticker': 'TSLA', 'company_name': 'Tesla, Inc.', 'resolution_method': 'company_mapping'}

Invoking: `resolve_company_ticker` with `{'query': 'Palantir'}`  
{'success': False, 'query': 'Palantir', 'error': "Could not resolve 'Palantir' to a valid stock ticker"}

Invoking: `resolve_company_ticker` with `{'query': 'PLTR'}`
{'success': True, 'query': 'PLTR', 'ticker': 'PLTR', 'company_name': 'Palantir Technologies Inc.', 'resolution_method': 'direct_ticker'}

Recupero Dati Finanziari:

Invoking: `fetch_stock_data` with `{'symbol': 'TSLA', 'period_days': 365}`
→ Successfully fetched 250 data points for TSLA

Invoking: `fetch_stock_data` with `{'symbol': 'PLTR', 'period_days': 365}`  
→ Successfully fetched 250 data points for PLTR

Calcoli di Volatilità e Metriche:

Invoking: `calculate_volatility_metrics` with `{'symbol': 'TSLA'}`
Invoking: `calculate_volatility_metrics` with `{'symbol': 'PLTR'}`

Analisi Comparativa del Valuation Agent:

Tesla (TSLA):

  • Prezzo attuale: $333.87
  • Rendimento totale (1 anno): 58.53%
  • Rendimento annualizzato: 59.42%
  • Volatilità annualizzata: 71.44%
  • Sharpe Ratio: 0.76
  • Max Drawdown: -53.77%

Palantir (PLTR):

  • Prezzo attuale: $156.71
  • Rendimento totale (1 anno): 413.63%
  • Rendimento annualizzato: 423.86%
  • Volatilità annualizzata: 72.53%
  • Sharpe Ratio: 5.77
  • Max Drawdown: -40.61%

Raccomandazione Valuation Agent:

STRONG BUY Palantir Palantir’s superior risk-adjusted returns and extraordinary growth potential make it a more attractive option for maximizing returns.

6.5.2 Sentiment Agent - Round 1

Il Sentiment Agent effettua una ricerca di news in merito a Tesla e Palantir su Yahoo Finance e Google News, recupera il testo degli articoli e calcola i punteggi di sentiment utilizzando VADER e TextBlob.

Raccolta News Finanziarie:

2025-08-30 19:10:08 - sentiment_agent.tools - INFO - Collecting news for TSLA (Tesla, Inc.)
2025-08-30 19:10:08 - sentiment_agent.tools - INFO - Collecting news for PLTR (Palantir Technologies Inc.)

HTTP Request: GET https://feeds.finance.yahoo.com/rss/2.0/headline?s=TSLA&region=US&lang=en-US
HTTP Request: GET https://feeds.finance.yahoo.com/rss/2.0/headline?s=PLTR&region=US&lang=en-US
HTTP Request: GET https://news.google.com/rss/search?q="Tesla,+Inc."+OR+"TSLA"+stock+finance

2025-08-30 19:10:09 - sentiment_agent.tools - INFO - Successfully collected 9 articles for TSLA
2025-08-30 19:10:09 - sentiment_agent.tools - INFO - Successfully collected 6 articles for PLTR

Analisi Sentiment con VADER + TextBlob:

Tesla (TSLA):

  • Sentiment complessivo: Neutrale
  • TextBlob Average: 0.0024
  • VADER Average: -0.0651
  • Combined Average: -0.0381 (leggera tendenza negativa)
  • Distribuzione: 22% positive, 33% negative, 44% neutral

Palantir (PLTR):

  • Sentiment complessivo: Positivo
  • TextBlob Average: 0.0235
  • VADER Average: 0.4288
  • Combined Average: 0.2667 (moderatamente positivo)
  • Distribuzione: 83% positive, 17% negative

Key News Analysis Tesla:

  • Negative: “Nearly Half Of Americans Say Tesla FSD Should Be Illegal”
  • Negative: “Tesla’s sales down 40% in EU while Chinese EV maker BYD is up 200%”
  • Positive: “Tesla Stock is Going Up Today? TSLA Shares Jump to June Highs on Elon Musk’s FSD Optimism”

Key News Analysis Palantir:

  • Positive: “Palantir Technologies Inc. (PLTR)’s New Name Is ‘Karpe Diem,’ Says Jim Cramer”
  • Positive: “Moody’s Just Upgraded The Top S&P 500 Stock Not Named Palantir”

Raccomandazione Sentiment Agent:

BUY Palantir Strong positive sentiment and market performance vs Tesla’s neutral sentiment with regulatory challenges.

6.5.3 Fundamental Agent - Round 1

L’output dell’agente Fundamental è molto più articolato e dettagliato. In particolare, non ha indicato una preferenza specifica di investimento, ma ha invece suggerito una strategia bivalente (SELL su Tesla e BUY su Palantir)

Analisi Finanziaria Approfondita:

In un primo momento, l’agente recupera ed esamina i rapporti finanziari di entrambe le aziende, evidenziando le loro performance e metriche chiave. I dati vengono recuperati tramite le API di Yahoo Finance.

2025-08-30 19:10:38 - fundamental_agent.tools - INFO - Pulling financial reports for TSLA (Tesla, Inc.)
2025-08-30 19:10:40 - fundamental_agent.tools - INFO - Successfully retrieved financial reports for TSLA

2025-08-30 19:10:40 - fundamental_agent.tools - INFO - Pulling financial reports for PLTR (Palantir Technologies Inc.) 
2025-08-30 19:10:42 - fundamental_agent.tools - INFO - Successfully retrieved financial reports for PLTR

RAG-based Analysis Results:

Come anticipato in precedenza, non si tratta di una vera analisi RAG, ma piuttosto di una ricerca delle informazioni rilevanti a partire dall’output delle API di Yahoo finance. Partendo dai dati finanziari recuperati, l’agente calcola i KPI di interesse e produce un parere da “esperto”.

Tesla (TSLA):

  • Settore: Consumer Cyclical - Auto Manufacturers
  • Gross Margin: 17.48%
  • Operating Margin: 4.10%
  • Revenue Growth: -11.80% (negativo)
  • Earnings Growth: -17.50% (negativo)
  • Fundamental Score: 0/100
  • Investment Recommendation: SELL

Concerns: “Low operating margin indicates operational challenges, negative revenue growth indicates declining business

Palantir (PLTR):

  • Settore: Technology - Software Infrastructure
  • Gross Margin: 80.03% (eccellente)
  • Operating Margin: 26.83% (forte)
  • Revenue Growth: 48.00% (robusto)
  • Earnings Growth: 116.70% (straordinario)
  • Fundamental Score: 100/100
  • Investment Recommendation: BUY

Strengths: Strong gross margin indicates good pricing power, Strong operating margin indicates efficient operations, Strong revenue growth indicates market expansion

6.6 Round 2 del Debate

Il sistema procede con il Round 2 del debate strutturato, dove ogni agente ha l’opportunità di rispondere alle analisi degli altri:

2025-08-30 19:11:12 - groupchat_agent.a2a_agent - INFO - === DEBATE ROUND 2 ===
2025-08-30 19:11:12 - groupchat_agent.a2a_agent - INFO - Round 2: valuation's turn (turn #2)

6.6.1 Dibattito

Gli agenti, nel Round 2, hanno accesso alle analisi degli altri agenti e possono presentare controargomentazioni o rafforzare le proprie posizioni. Questo processo permette di:

  • Identificare disaccordi: Tesla vs Palantir come investimento ottimale
  • Confrontare metodologie: Analisi tecnica vs fondamentale vs sentiment
  • Raffinare raccomandazioni: Basandosi su feedback peer-to-peer
  • Validazione incrociata: Cross-reference tra diverse prospettive analitiche

6.6.2 Processo di Consensus Building

Il Group Agent ha una soglia per il consenso tra gli agenti che è configurata tramite una variabile di ambiente. Nello specifico, ho lasciato il valore di default del 75%, ma potrebbe essere regolato in base alle esigenze del dibattito. In ogni caso, per il test eseguito non ci sono state differenze significative nella risposta, per cui è stato molto facile raggiungere un consenso.

Ciononostante, prima di procedere alla fase di consolidamento, il Group Agent ha comunque evidenziato alcuni elementi distintivi delle risposte dei 3 agenti, e poi ha fornito un commento di sintesi:

  1. Valuation vs Fundamental divergence su Tesla:

    • Valuation Agent: Tesla ha mostrato 59.42% rendimento annualizzato → Potenziale BUY
    • Fundamental Agent: Tesla ha -11.80% crescita ricavi, margini operativi 4.10% → SELL
  2. Consensus su Palantir:

    • Valuation: 423.86% rendimento annualizzato, Sharpe 5.77 → STRONG BUY
    • Fundamental: Score 100/100, margini 80.03% → BUY
    • Sentiment: 83% sentiment positivo → BUY
  3. Risk-adjusted perspective:

    • Tutti concordano: Per investitore risk-seeking con orizzonte 5-7 anni, Palantir è superiore a Tesla

6.7 Fase 7: Consolidamento Finale e Report Generation

6.7.1 LLM-based Synthesis

Il Group Chat Agent utilizza un LLM con prompt ad-hoc per consolidare le analisi multiple. Per dare una idea di come funziona il processo, riporto un esempio di prompt utilizzato, con alcune variabili che fanno riferimento al contesto:

Consolidation Prompt:

"""
You are a financial analysis consolidator. Your role is to synthesize insights from multiple specialist agents into a coherent response.

USER REQUEST: Sono indeciso se investire in Tesla oppure in Palantir. Il mio orizzonte di investimento è di 5-7 anni e voglio rendimenti massimi, posso gestire un rischio elevato

AGENT ANALYSES:
**VALUATION AGENT:**
[Analisi completa con metriche quantitative...]

**SENTIMENT AGENT:** 
[Analisi sentiment con distribuzione news...]

**FUNDAMENTAL AGENT:**
[Analisi fondamentale con score...]
"""

6.7.2 Report Finale

Il sistema genera un report finale completo che integra tutte le analisi specialistiche. Ecco il report nella sua interezza:


📊 ALPHAAGENTS INVESTMENT ANALYSIS REPORT

The analysis of whether to invest in Tesla (TSLA) or Palantir (PLTR) over a 5-7 year horizon, with a focus on maximizing returns and a willingness to manage high risk, was conducted through a structured multi-agent debate process. This comprehensive approach involved valuation, sentiment, and fundamental analyses, ensuring a well-rounded perspective.

🎯 CONSENSUS AND KEY FINDINGS:

1. Palantir Technologies Inc. (PLTR)

  • Valuation: Palantir has demonstrated an extraordinary annualized return of 423.86% with a high Sharpe ratio of 5.77, indicating exceptional risk-adjusted returns. The volatility is high, but the risk-reward profile is favorable.
  • Sentiment: The sentiment analysis shows a strong positive outlook, with 83% of articles reflecting positive sentiment. This aligns with the valuation analysis, reinforcing Palantir’s growth potential.
  • Fundamentals: Palantir’s strong growth metrics and operational efficiency support the positive sentiment and valuation findings.

Recommendation: STRONG BUY. Palantir is recommended for risk-seeking investors due to its exceptional growth potential and positive sentiment, making it an attractive option for maximizing returns.

2. Tesla, Inc. (TSLA):

  • Valuation: Tesla has a strong annualized return of 59.42% with high volatility. The Sharpe ratio of 0.76 suggests moderate risk-adjusted returns. The potential for significant returns exists, but with substantial risk.
  • Sentiment: The sentiment analysis is neutral with a slight negative tilt, reflecting concerns about automotive sector challenges and regulatory issues with Tesla’s Full Self-Driving technology.
  • Fundamentals: Operational challenges and strategic uncertainties contribute to a more cautious outlook.

Recommendation: HOLD. While Tesla has potential upside, the current sentiment and operational challenges suggest a more cautious approach. Investors should wait for more positive sentiment or strategic clarity before increasing exposure.

🏆 FINAL RECOMMENDATION:

Based on the collective reasoning from the multi-agent debate, Palantir (PLTR) is the preferred choice for a risk-seeking investor aiming for maximum returns over a 5-7 year horizon. Its strong positive sentiment, exceptional risk-adjusted returns, and growth potential make it a compelling investment.

Tesla (TSLA), while still a strong contender, is recommended as a hold due to its current neutral sentiment and operational challenges. Investors should monitor Tesla for strategic developments that could enhance its investment appeal.

This analysis benefits from the collaborative insights of multiple expert perspectives, providing increased confidence in the recommendations provided.


6.7.3 Metadata del Processo di Debate

Il report finale include anche alcuni metadati sul processo seguito, che possono essere utilizzati per analisi di explainability:

{
  "debate_metadata": {
    "total_rounds": 2,
    "agents_participated": ["valuation", "sentiment", "fundamental"],  
    "consensus_achieved": true,
    "consensus_percentage": 100,
    "risk_tolerance_inferred": "seeking",
    "debate_duration": "3m 32s",
    "llm_calls": {
      "risk_inference": 1,
      "agent_routing": 1, 
      "debate_detection": 1,
      "consolidation": 1
    }
  }
}

6.8 Performance e Tempi di Esecuzione

Un aspetto importante da documentare è il tempo necessario per completare l’intero processo di analisi. Basandomi sui timestamp registrati durante l’esecuzione, ecco il breakdown temporale dettagliato:

6.8.1 Durata Complessiva

Tempo totale di esecuzione: 3 minuti e 32 secondi (dalle 19:09:40 alle 19:13:12)

6.8.2 Breakdown Temporale per Fasi

FaseDurataTimestamp InizioTimestamp FineDescrizione
Setup Iniziale~41s19:06:5019:07:31Avvio di tutti gli agenti, Agent Registry, Healthcheck e verifiche di base
Query Processing~1s19:09:4019:09:41Ricezione e parsing della query utente
Risk Tolerance Inference<1s19:09:4019:09:40Analisi LLM per inferire profilo di rischio
Agent Discovery<1s19:09:4019:09:40Recupero endpoint dall’Agent Registry
Agent Routing~1s19:09:4119:09:41Decisione LLM su agenti da coinvolgere
Debate Detection<1s19:09:4119:09:41Decisione LLM per debate strutturato
Round 1 Analysis~91s19:09:4119:11:12Analisi iniziali sequenziali dei 3 agenti
Round 2 Debate~120s19:11:1219:13:12Secondo round e consolidamento finale

6.8.3 Analisi delle Componenti più Costose

Le fasi più time-intensive sono:

  1. Round 1 Analysis (91 secondi):

    • Valuation Agent: ~30s per recupero dati Yahoo Finance + calcoli volatilità
    • Sentiment Agent: ~30s per raccolta news da fonti multiple + analisi VADER/TextBlob
    • Fundamental Agent: ~31s per processing dati finanziari + keyword matching
  2. Round 2 Debate (120 secondi):

    • Debate structured: ~60s per secondo round di analisi cross-agent
    • LLM Consolidation: ~60s per sintesi finale e report generation

6.8.4 Bottlenecks e Ottimizzazioni Possibili

Colli di bottiglia identificati:

  • API Latency: Chiamate a Yahoo Finance (~2-3s per request)
  • LLM Processing: Analisi complesse richiedono 10-15s per agente
  • Sequential Execution: Turni sequenziali non parallelizzabili per design

Ottimizzazioni future:

  • Parallelizzazione Round 1: Possibile riduzione da 91s a ~35-40s
  • Caching dati finanziari: Evitare retrieve multipli degli stessi ticker
  • Model optimization: Prompt più efficienti o modelli più veloci

7. Conclusioni

7.1 Motivazioni e Obiettivi del Progetto

Questo progetto è nato dall’esigenza di testare concretamente il protocollo A2A e l’Agent Registry in uno scenario applicativo reale, per sperimentare un applicativo multi-agente distribuito.

Come ho evidenziato nell’introduzione, la proliferazione di framework GenAI monolitici e le loro limitazioni nel supporto multi-agente mi hanno spinto a investire un po’ di tempo per alzare il livello di astrazione e provare a disegnare un’architettura ad agenti basata su A2A in modo da garantire:

  • Standardizzazione della comunicazione tra agenti eterogenei
  • Eliminazione del lock-in verso framework specifici
  • Scalabilità orizzontale attraverso deployment distribuiti
  • Interoperabilità tra agenti implementati con stack tecnologici diversi

Questo piccolo progetto mi ha tenuto sveglio qualche notte ma mi ha dato modo di mettere le mani in pasta con un sistema multi-agente REALE diverso dal caso di studio monolitico che spesso viene presentato nella sezione “Getting Started” di questo o di quel framework di GenAI.

Sono sempre più convinto che per le soluzioni Enterprise, valga la pena iniziare a pensare seriamente all’architettura degli agenti e ai protocolli di collaborazione piuttosto che allo specifico stack tecnologico per implementare questo o quello Use Case.

7.2 La Scelta di AlphaAgents

La selezione del paper AlphaAgents di BlackRock come caso d’uso si è rivelata particolarmente azzeccata perché, a fronte di una complessità non troppo elevata, mi ha consentito di realizzare una soluzione end-to-end, con risultati tangili e misurabili

Rispetto al paper originale ho dovuto accettare qualche compromesso per semplificare l’implementazione, ma ciò non ha pregiudicato il raggiungimento del mio obiettivo.

7.3 Sviluppi Futuri

Il test end-to-end ha confermato la validità dell’approccio e mi ha anche fornito alcuni spunti per miglioramenti futuri.

7.4.1 Miglioramenti Tecnici

Performance Optimization:

  • Parallelizzazione Round 1: Riduzione potenziale da 91s a ~35s
  • Data caching: Evitare retrieve multipli degli stessi ticker
  • LLM optimization: Prompt engineering per ridurre latenza

Affidabilità degli agenti:

  • Sentiment Agent: Integrazione FinBERT per analisi più accurate
  • Fundamental Agent: Implementazione vera RAG con vector embeddings
  • Risk Assessment: Modelli più sofisticati per portfolio risk management

Miglioramenti sul Registry:

  • Agent versioning e gestione delle compatibilità
  • Load balancing per agenti con istanze multiple
  • Health monitoring e automatic failover

7.4.2 Espansioni Funzionali

Nuovi Agenti Specializzati:

  • Technical Analysis Agent: Pattern recognition, supporti/resistenze
  • Macro Economic Agent: Analisi macroeconomica e settoriale
  • ESG Agent: Environmental, Social, Governance scoring
  • Options Agent: Analisi derivati e strategie hedging

Verifica accurata dei risultati:

  • Double check delle metriche calcolate dal Valuation Agent su ampi campioni di dati
  • Cross-validation con altri modelli di valutazione

7.5 Considerazioni sui Risultati Finanziari

7.5.1 Limitazioni e Rischi

Limitazioni Tecniche:

  • Dati limitati: Buona parte dell’analisi è basata sui dati di Yahoo Finance, non su fonti professionali
  • Mancanza di backtesting: Come ho più volte sottolineato, non ho effettuato nessuna validazione sistematica su dati storici
  • Scope ristretto: Il campione di analisi su cui ho fatto i test end-to-end è limitato a poche azioni e poche tipologie di richieste utente

Rischi:

  • Allucinazioni LLM: Possibili analisi errate o contraddittorie
  • Data quality: Accuratezza non garantita dei dati di input
  • Model bias: Bias nei modelli di linguaggio utilizzati
  • Market conditions: Non considera condizioni macroeconomiche correnti

7.5.2 ⚠️ Disclaimer Importante

Anche alla luce delle limitazioni indicate sopra, tutti i risultati, le raccomandazioni e le analisi presentate in questo articolo sono esclusivamente a scopo esemplificativo per illustrare il funzionamento del sistema multi-agente.

I risultati qui riportati ed il software rilasciato su GitHub NON devono essere utilizzati in alcun modo come:

  • Base per decisioni di investimento reali
  • Consigli finanziari o raccomandazioni di trading
  • Input per strategie di portfolio management