Een due-diligence-agent bouwen op SEC-filings (10-K, 10-Q, 8-K, kwartaalcijfers)

Een 10-K lezen is vooral Ctrl+F. Dat doen voor vijftig bedrijven is een baan op zich. Vervang de saaie 80% door een zoek-en-extractie-agent tegen SEC EDGAR — en houd de 20% over die ertoe doet voor de menselijke analist.
TL;DR
- •Architectuur: ticker opzoeken → SEC Filings Search (filings + kwartaalcijfers + equity-statistieken) → URL Extract voor de lange passages → LLM-antwoord met bronvermelding op sectieniveau.
- •Kostenplafond: SEC Filings Search kost 120 credits per aanroep (≈$0,12); een typische bedrijfsreview met 3 vragen kost ~$0,40 aan credits + ~$0,05 aan LLM-tokens.
- •Waar de agent goed in is: feitelijke opzoekingen (segmentomzet, capex-trend, governance, jaar-op-jaar wijzigingen in risicofactoren), samenvattingen van bestuurdersbeloningen, recente 8-K-gebeurtenissen.
- •Wat nog een mens nodig heeft: oordeelsvorming over de kwaliteit van het management, marktpositionering, deal-specifieke kwesties, alles buiten de tekst van de filing.
Waarom dit de moeite waard is om te automatiseren
Een eerste due-diligence-lezing van een beursgenoteerd bedrijf is grotendeels mechanisch: haal de laatste 10-K op, scan de risicofactoren en de MD&A, controleer de recente 8-K's, werp een blik op de meest recente earnings call. Een analist op associate-niveau besteedt hier 2–4 uur per bedrijf aan. De uitkomst is zelden een diep inzicht — het is een gestructureerd feitenpatroon waar vervolgens een andere, senior persoon over redeneert.
Precies die feitenpatroon-stap kan een kleine agent overnemen. Doorzoek de SEC, extraheer de relevante passages, vat samen met bronvermelding. De senior persoon doet nog steeds het redeneren — maar begint bij een lezing van 5 minuten in plaats van een van 4 uur.
Drie dingen maken dit nu praktisch haalbaar:
- Semantisch zoeken over filings betekent dat je kunt vragen 'hoe veranderde de segmentomzet' en de juiste alinea uit het juiste formulier terugkrijgt, in plaats van 200 pagina's te lezen.
- LLM's met lange context kunnen een volledige 10-K plus een paar 8-K's in hun werkgeheugen houden en vragen beantwoorden die documenten overstijgen.
- Discipline in bronvermelding in de prompt maakt de output in seconden verifieerbaar — precies wat compliance- en reviewworkflows vereisen.
Architectuur
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]"Kosten voor één vraag: ~130 credits (~$0,13) aan API + ~$0,03 aan LLM. Een bedrijfsreview met drie vragen (financiële trend, diff van risicofactoren, recente materiële gebeurtenissen) komt uit op ~$0,45–$0,60. Vergeleken met een analistuur tegen elk redelijk uurtarief is de rekensom overduidelijk.
De system prompt die zijn geld waard is
De grootste bepalende factor voor de kwaliteit van de output bij financiële RAG is met afstand de system prompt. Degene die wij gebruiken:
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.De regels 1, 2 en 4 samen elimineren ~90% van de verzinselproblemen die we hebben gemeten. Regel 3 (het elegante 'ik weet het niet') is wat dit onderscheidt van een chatbot die met veel zelfvertrouwen cijfers verzint.
Voorbeeldvragen die de agent netjes afhandelt
- 'Vergelijk de trend in Apple's services-omzet over de laatste 5 boekjaren.' → put uit de relevante 10-K's, geeft een tabel terug met bronvermeldingen naar de MD&A.
- 'Wat veranderde er in de risicofactoren van NVIDIA tussen FY2023 en FY2025?' → diff tussen documenten, met verwijzing naar Item 1A in elk formulier.
- 'Vat de laatste 4 8-K's voor $TICKER samen.' → semantisch zoeken gefilterd op 8-K, gesorteerd op filing-datum.
- 'Wat zei de CFO van Microsoft over AI-capex tijdens de meest recente earnings call?' → doorzoekt de transcripten, extraheert de relevante Q&A-passage, citeert woordelijk.
Waar het tekortschiet — en de juiste overdracht aan de mens
De agent struikelt op drie voorspelbare plekken:
- Oordeelsvorming over de kwaliteit van het management. De filing vertelt je wat ze deden, niet of ze capabel zijn. Vraag het de agent niet.
- Branchevergelijkingen buiten de filing. Als de vraag is 'hoe verhoudt deze brutomarge zich tot die van peers', dan kent de agent alleen wat er in de doorzochte filings staat. Voor peervergelijking heb je ofwel een aparte dataset nodig, ofwel moet je de agent één keer per bedrijf draaien en aggregeren.
- Toekomstgerichte commentaren. Filings bevatten forward-looking statements, maar het model neemt ze voor waar aan tenzij anders geïnstrueerd. Voeg toe aan de prompt: 'Markeer forward-looking statements expliciet. Presenteer guidance niet als feit.'
De minimale werkbare build
Hetzelfde tool-use-lus-patroon van Claude uit de walkthrough van de research-agent is van toepassing — alleen de tools en de system prompt veranderen:
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."))Waar je het verder mee kunt brengen
- Sjablonen voor herhaalbare reviews. Verpak de agent in een kleine CLI die een ticker aanneemt en een markdown-brief met vast formaat uitspuugt: 'Recente 8-K's', 'Trend in segmentomzet', 'Delta in risicofactoren'. Dezelfde agent, gescripte prompts.
- Watchlist-modus. Draai de agent elke ochtend tegen een ticker en maak een diff van het antwoord van vandaag met dat van gisteren. Breng alleen de delta's naar boven. Sluit goed aan bij het morning-briefing-patroon.
- Combineer met patenten en voorspellingsmarkten. Voor tech-/biotechnamen voeg je Patent Search toe voor IP-wijzigingen en Prediction Markets voor door de menigte impliciet ingeschatte uitkomsten (bijv. de kans op goedkeuring van een medicijn).
Het patroon laat zich veralgemenen. De SEC is het dichtste, meest schema-vriendelijke corpus dat we leveren — maar de lus ('semantisch zoeken → URL-extractie → antwoord met bronvermelding') geldt voor elk corpus van gestructureerde documenten dat er voor jou toe doet: juridische filings, wetenschappelijke abstracts, patentclaims. Bouw eerst de diligence-agent, port daarna de architectuur zijwaarts.
Veelgestelde vragen
Hoe actueel is de SEC-index?
Filings worden binnen enkele uren na acceptatie door EDGAR geïndexeerd. Voor 8-K's (de tijdsgevoelige — materiële gebeurtenissen, wisselingen in het leiderschap, overnames) is dat doorgaans snel genoeg voor workflows aan het einde van de dag. Heb je binnen een uur melding nodig van nieuwe 8-K's, combineer de zoekfunctie dan met een aparte SEC RSS-feed en gebruik de agent alleen voor contentanalyse, niet voor detectie.
Bevat het ook earnings-call-transcripten?
Ja — de SEC Filings Search-index bevat Amerikaanse earnings-call-transcripten en equity-statistieken (koers/volume, historie van de marktkapitalisatie) naast de filings zelf. Eén enkele semantische query kan uit al deze bronnen putten.
Wat zijn de kostenhefbomen als ik dit op schaal doe?
Drie. (1) Voorfilter via Company Facts (2 credits) om te bevestigen dat een ticker een echt beursgenoteerd bedrijf is voordat je 120 credits aan een SEC-zoekopdracht uitgeeft. (2) Cache zoekresultaten op (ticker, kwartaal) — filings worden alleen volgens hun eigen schema bijgewerkt. (3) Gebruik één brede zoekopdracht per vraag in plaats van veel smalle; de agent is goed in het synthetiseren van meerdere resultaten.
Kan de agent overweg met niet-Amerikaanse filings?
SEC Filings Search dekt beursgenoteerde bedrijven in de VS (10-K, 10-Q, 8-K). Voor Britse bedrijven combineer je UK Legal Search en Web Search. Voor andere jurisdicties val je terug op Web Search + URL Extract over de site van de betreffende nationale toezichthouder (Companies House, SEDAR, enzovoort).
Hoe voorkom ik gehallucineerde cijfers?
Drie regels in de system prompt maken het grootste verschil. (1) 'Citeer cijfers woordelijk uit de geëxtraheerde tekst — nooit parafraseren of afronden.' (2) 'Vermeld altijd het filing-formulier, de fiscale periode en een sectieverwijzing.' (3) 'Als de relevante filing niet is geëxtraheerd, zeg dat dan expliciet — leid niets af uit trainingsdata.' Deze drie samen halen het merendeel van de verzinsels weg.
API's gebruikt in dit artikel
Sarah Choy is de CEO van API Pick. Ze schrijft over het bouwen van productieklare API's voor AI-agents en LLM-workflows.