[ blog · use-case ]9 min read

Come costruire un agente di due diligence sui filing della SEC (10-K, 10-Q, 8-K, risultati)

Sarah ChoyPubblicato il 3 maggio 20269 min di lettura
Come costruire un agente di due diligence sui filing della SEC (10-K, 10-Q, 8-K, risultati)

Leggere un 10-K è praticamente Ctrl+F. Farlo per cinquanta aziende è un lavoro. Sostituisci l'80% noioso con un agente di ricerca-ed-estrazione contro SEC EDGAR — e conserva il 20% che conta per l'analista umano.

In breve

  • Architettura: lookup del ticker → SEC Filings Search (filing + risultati + statistiche di equity) → URL Extract per i passaggi lunghi → risposta dell'LLM con citazioni a livello di sezione.
  • Tetto di costo: SEC Filings Search costa 120 crediti per chiamata (≈0,12 $); una tipica revisione aziendale da 3 domande costa ~0,40 $ in crediti + ~0,05 $ in token di LLM.
  • In cosa l'agente azzecca: lookup fattuali (ricavi per segmento, trend del capex, governance, variazioni anno su anno dei fattori di rischio), riepiloghi della retribuzione dei dirigenti, eventi recenti degli 8-K.
  • Cosa serve ancora a un umano: i giudizi sulla qualità del management, il posizionamento di mercato, le questioni specifiche dell'operazione, qualsiasi cosa al di fuori del linguaggio del filing.

Perché vale la pena automatizzarlo

Una prima lettura di due diligence su una società quotata è in gran parte meccanica: recuperare l'ultimo 10-K, scorrere i fattori di rischio e l'MD&A, controllare gli 8-K recenti, dare un'occhiata all'earnings call più recente. Un analista di livello associate ci dedica 2–4 ore per azienda. Il risultato è raramente un'intuizione profonda — è un pattern strutturato di fatti su cui poi ragiona un'altra persona, più senior.

Quel passaggio del "pattern di fatti" è esattamente ciò di cui un piccolo agente può farsi carico. Cerca nella SEC, estrai i passaggi rilevanti, riassumi con citazioni. La persona senior continua a fare il ragionamento — ma parte da una lettura di 5 minuti invece che da una di 4 ore.

Tre cose lo rendono pratico oggi:

  • La ricerca semantica sui filing permette di chiedere 'come sono cambiati i ricavi per segmento' e ricevere il paragrafo giusto dal modulo giusto, invece di leggere 200 pagine.
  • Gli LLM a contesto lungo possono tenere un 10-K completo più qualche 8-K nella memoria di lavoro e rispondere a domande che attraversano più documenti.
  • La disciplina di citazione nel prompt rende l'output verificabile in pochi secondi — esattamente ciò che richiedono i flussi di compliance e revisione.

Architettura

question + ticker
       ├─ /api/company/facts (2 credits)
       │  ↳ confirm ticker, get CIK and sector
       ├─ /api/search/sec (120 credits)
       │  ↳ semantic search across 10-K/10-Q/8-K/earnings/equity stats
       ├─ /api/extract (2 credits per URL)
       │  ↳ pull full text of the top 3-5 most relevant filings
       └─ Claude / GPT-4 with citation-required prompt
          ↳ "answer + [Form, Fiscal Period, Section]"

Costo di una singola domanda: ~130 crediti (~0,13 $) di API + ~0,03 $ di LLM. Una revisione aziendale da tre domande (trend finanziario, diff dei fattori di rischio, eventi rilevanti recenti) si attesta su ~0,45–0,60 $. Rispetto a un'ora di analista a qualsiasi tariffa di fatturazione ragionevole, i conti sono ovvi.

Il system prompt che si guadagna lo stipendio

Il fattore che più di ogni altro determina la qualità dell'output nel RAG finanziario è, di gran lunga, il system prompt. Quello che usiamo:

You are a financial research assistant for an investment team. You answer
questions about US public companies using SEC filings, earnings call
transcripts, and equity statistics retrieved by your tools.

Rules — non-negotiable:

1. Cite every numeric claim with: [Form, Fiscal Period, Section]. Example:
   "Operating income rose 12% YoY to $4.1B [10-K FY2025, Item 7 MD&A]."

2. Quote numbers verbatim. Do not round, paraphrase, or convert. If a
   filing says "$4,127M", do not say "$4.1B" unless the filing itself does.

3. If the answer requires content you have not extracted, say so:
   "I could not retrieve the FY2024 10-K for the segment-level breakdown.
   Please re-run with that filing in scope."

4. Do not infer from training-data knowledge. If your tools didn't return
   it, you don't know it.

5. Default to the most recent fiscal period available. State the period
   you used.

6. Format multi-figure answers as a small markdown table with one column
   per fiscal period. Always end with a one-line "How I read this" summary.

Tone: precise, terse, no marketing language.

Le regole 1, 2 e 4 insieme eliminano ~90% dei problemi di invenzione che abbiamo misurato. La regola 3 (il "non lo so" elegante) è ciò che separa questo da un chatbot che inventa numeri con sicumera.

Query di esempio che l'agente gestisce in modo pulito

  • 'Confronta il trend dei ricavi dei servizi di Apple negli ultimi 5 esercizi fiscali.' → attinge ai 10-K rilevanti, restituisce una tabella con citazioni all'MD&A.
  • 'Cosa è cambiato nei fattori di rischio di NVIDIA tra il FY2023 e il FY2025?' → diff tra documenti, citando l'Item 1A in ciascun modulo.
  • 'Riassumi gli ultimi 4 8-K di $TICKER.' → ricerca semantica filtrata sugli 8-K, ordinata per data di filing.
  • 'Cosa ha detto il CFO di Microsoft sul capex per l'IA nell'ultima earnings call?' → cerca nelle trascrizioni, estrae il passaggio di Q&A rilevante, lo cita alla lettera.

Dove fa cilecca — e il giusto passaggio di consegne all'umano

L'agente inciampa in tre punti prevedibili:

  • Giudizi sulla qualità del management. Il filing ti dice cosa hanno fatto, non se sono capaci. Non chiederlo all'agente.
  • Comparabili di settore al di fuori del filing. Se la domanda è 'come si confronta questo margine lordo con quello dei peer', l'agente conosce solo ciò che c'è nei filing cercati. Per il confronto con i peer servono o un dataset a parte o far girare l'agente una volta per azienda e aggregare.
  • Commenti prospettici. I filing contengono forward-looking statements, ma il modello li prende alla lettera salvo indicazione contraria. Aggiungi al prompt: 'Segnala esplicitamente i forward-looking statements. Non presentare la guidance come un fatto.'

Il build minimo praticabile

Si applica lo stesso pattern di loop di tool-use di Claude del tutorial dell'agente di research — cambiano solo gli strumenti e il system prompt:

from anthropic import Anthropic
import requests

KEY = "pk_yourkey"
client = Anthropic()

def fetch_tool(path: str) -> dict:
    return requests.get(f"https://www.apipick.com{path}/tool-schema").json()["claude"]

TOOLS = [
    fetch_tool("/api/search/sec"),
    fetch_tool("/api/extract"),
    fetch_tool("/api/company/facts"),
]

def call_tool(block):
    name_to_path = {
        "sec_search": "/api/search/sec",
        "extract_urls": "/api/extract",
        "company_facts": "/api/company/facts",
    }
    path = name_to_path[block.name]
    method = "GET" if block.name == "company_facts" else "POST"
    if method == "GET":
        resp = requests.get(
            f"https://www.apipick.com{path}",
            params=block.input,
            headers={"x-api-key": KEY},
            timeout=30,
        )
    else:
        resp = requests.post(
            f"https://www.apipick.com{path}",
            json=block.input,
            headers={"x-api-key": KEY},
            timeout=30,
        )
    return {
        "type": "tool_result",
        "tool_use_id": block.id,
        "content": resp.text,
        "is_error": resp.status_code != 200,
    }

def due_dil(question: str) -> str:
    messages = [{"role": "user", "content": question}]
    while True:
        r = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=2048,
            system=SYSTEM_PROMPT,  # the one above
            tools=TOOLS,
            messages=messages,
        )
        messages.append({"role": "assistant", "content": r.content})
        if r.stop_reason == "end_turn":
            return "\n".join(b.text for b in r.content if b.type == "text")
        if r.stop_reason == "tool_use":
            results = [call_tool(b) for b in r.content if b.type == "tool_use"]
            messages.append({"role": "user", "content": results})

print(due_dil("Compare Snowflake's product revenue YoY for the last 4 quarters."))

Dove portarlo poi

  • Template per revisioni ripetibili. Avvolgi l'agente in una piccola CLI che riceve un ticker ed emette un brief in markdown a formato fisso: 'Ultimi 8-K', 'Trend dei ricavi per segmento', 'Delta dei fattori di rischio'. Stesso agente, prompt scriptati.
  • Modalità watchlist. Fai girare l'agente su un ticker ogni mattina e confronta con un diff la risposta di oggi con quella di ieri. Fai emergere solo i delta. Si sposa bene con il pattern di briefing mattutino.
  • Combinalo con brevetti e mercati di previsione. Per i nomi tech / biotech, aggiungi Patent Search per i cambiamenti di IP e Prediction Markets per gli esiti impliciti dalla folla (per es. la probabilità di approvazione di un farmaco).

Il pattern si generalizza. La SEC è il corpus più denso e schema-friendly che serviamo — ma il loop ('ricerca semantica → estrazione di URL → risposta con citazioni') si applica a qualsiasi corpus di documenti strutturati a cui tieni: filing legali, abstract scientifici, rivendicazioni di brevetto. Costruisci prima l'agente di diligence, poi porta l'architettura di lato.

Domande frequenti

Quanto è aggiornato l'indice della SEC?

I filing vengono indicizzati entro poche ore dall'accettazione da parte di EDGAR. Per gli 8-K (quelli sensibili al tempo — eventi rilevanti, cambi di leadership, acquisizioni), di solito è abbastanza rapido per i flussi di fine giornata. Se ti serve una notifica dei nuovi 8-K in meno di un'ora, abbina la ricerca a un feed RSS della SEC a parte e usa l'agente solo per l'analisi dei contenuti, non per il rilevamento.

Copre le trascrizioni delle earnings call?

Sì — l'indice di SEC Filings Search include le trascrizioni delle earnings call statunitensi e le statistiche di equity (prezzo/volume, storico della capitalizzazione di mercato) insieme ai filing veri e propri. Una singola query semantica può attingere da una qualsiasi di queste fonti.

Quali sono le leve di costo se lo faccio su scala?

Tre. (1) Pre-filtra con Company Facts (2 crediti) per confermare che un ticker sia una vera società quotata prima di spendere 120 crediti in una ricerca SEC. (2) Metti in cache i risultati di ricerca per (ticker, trimestre) — i filing si aggiornano solo secondo il loro calendario. (3) Usa una ricerca ampia per domanda anziché molte ristrette; l'agente è bravo a sintetizzare tra i risultati.

L'agente gestisce i filing non statunitensi?

SEC Filings Search copre le società quotate negli USA (10-K, 10-Q, 8-K). Per le aziende del Regno Unito, abbina UK Legal Search e Web Search. Per altre giurisdizioni, ripiega su Web Search + URL Extract sul sito del regolatore nazionale di riferimento (Companies House, SEDAR, ecc.).

Come evito numeri allucinati?

Tre regole nel system prompt sono quelle che spostano di più l'ago. (1) 'Cita i numeri alla lettera dal testo estratto — non parafrasare né arrotondare mai.' (2) 'Includi sempre il modulo del filing, il periodo fiscale e un riferimento di sezione.' (3) 'Se il filing rilevante non è stato estratto, dillo esplicitamente — non dedurre dai dati di addestramento.' Queste tre insieme eliminano la maggior parte delle invenzioni.

API usate in questo articolo

Sarah Choy
Scritto da
Sarah Choy
CEO, API Pick

Sarah Choy è la CEO di API Pick. Scrive sulla creazione di API pronte per la produzione per agenti IA e flussi di lavoro con LLM.