[ blog · use-case ]9 min read

Budowa agenta due diligence na dokumentach SEC (10-K, 10-Q, 8-K, wyniki kwartalne)

Sarah ChoyOpublikowano 3 maja 20269 min czytania
Budowa agenta due diligence na dokumentach SEC (10-K, 10-Q, 8-K, wyniki kwartalne)

Czytanie 10-K to głównie Ctrl+F. Robienie tego dla pięćdziesięciu spółek to już praca na etat. Zastąp nudne 80% agentem wyszukująco-ekstrahującym działającym na SEC EDGAR — i zostaw te 20%, które naprawdę liczą się dla analityka-człowieka.

TL;DR

  • Architektura: wyszukanie tickera → SEC Filings Search (dokumenty + wyniki + statystyki akcji) → URL Extract dla długich fragmentów → odpowiedź LLM z przypisami na poziomie sekcji.
  • Pułap kosztów: SEC Filings Search to 120 kredytów za wywołanie (≈$0,12); typowy przegląd spółki z 3 pytaniami kosztuje ~$0,40 w kredytach + ~$0,05 w tokenach LLM.
  • W czym agent jest dobry: fakty do sprawdzenia (przychody segmentów, trend nakładów inwestycyjnych, ład korporacyjny, zmiany czynników ryzyka rok do roku), podsumowania wynagrodzeń zarządu, ostatnie zdarzenia 8-K.
  • Co nadal wymaga człowieka: oceny jakości zarządu, pozycjonowania rynkowego, kwestii specyficznych dla transakcji, wszystkiego, co wykracza poza treść dokumentu.

Dlaczego warto to zautomatyzować

Pierwsze podejście do due diligence spółki giełdowej jest w większości mechaniczne: pobierz najnowszy 10-K, przejrzyj czynniki ryzyka i MD&A, sprawdź ostatnie 8-K, rzuć okiem na najświeższą konferencję wynikową. Analityk na poziomie associate poświęca na to 2–4 godziny na spółkę. Wynik rzadko jest głębokim spostrzeżeniem — to ustrukturyzowany wzorzec faktów, nad którym potem rozumuje inna, bardziej doświadczona osoba.

To właśnie ten krok „wzorca faktów” może przejąć niewielki agent. Przeszukaj SEC, wyekstrahuj odpowiednie fragmenty, podsumuj z przypisami. Osoba senior nadal wykonuje rozumowanie — ale zaczyna od 5-minutowej lektury zamiast 4-godzinnej.

Trzy rzeczy sprawiają, że jest to teraz praktyczne:

  • Wyszukiwanie semantyczne po dokumentach oznacza, że możesz zapytać „jak zmieniły się przychody segmentu” i otrzymać właściwy akapit z właściwego formularza, zamiast czytać 200 stron.
  • LLM-y o długim kontekście potrafią utrzymać w pamięci roboczej cały 10-K plus kilka 8-K i odpowiadać na pytania obejmujące wiele dokumentów.
  • Dyscyplina cytowania w promptcie sprawia, że wynik da się zweryfikować w kilka sekund — dokładnie tego wymagają procesy compliance i przeglądu.

Architektura

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]"

Koszt pojedynczego pytania: ~130 kredytów (~$0,13) za API + ~$0,03 za LLM. Przegląd spółki z trzema pytaniami (trend finansowy, diff czynników ryzyka, ostatnie zdarzenia istotne) wypada na ~$0,45–$0,60. W porównaniu z godziną pracy analityka przy jakiejkolwiek rozsądnej stawce, rachunek jest oczywisty.

System prompt, który zarabia na siebie

Najważniejszym czynnikiem decydującym o jakości wyniku w finansowym RAG jest zdecydowanie system prompt. Ten, którego używamy:

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.

Zasady 1, 2 i 4 razem eliminują ~90% problemów z konfabulacją, które zmierzyliśmy. Zasada 3 (eleganckie „nie wiem”) jest tym, co odróżnia to rozwiązanie od chatbota, który z pewnością siebie zmyśla liczby.

Przykładowe zapytania, z którymi agent radzi sobie czysto

  • „Porównaj trend przychodów z usług Apple w ciągu ostatnich 5 lat obrotowych.” → sięga do odpowiednich 10-K, zwraca tabelę z przypisami do MD&A.
  • „Co zmieniło się w czynnikach ryzyka NVIDIA między FY2023 a FY2025?” → diff między dokumentami, z odniesieniem do Item 1A w każdym formularzu.
  • „Podsumuj ostatnie 4 dokumenty 8-K dla $TICKER.” → wyszukiwanie semantyczne filtrowane do 8-K, uporządkowane według daty złożenia.
  • „Co CFO Microsoftu powiedział o nakładach inwestycyjnych na AI podczas ostatniej konferencji wynikowej?” → przeszukuje transkrypcje, ekstrahuje odpowiedni fragment Q&A, cytuje dosłownie.

Gdzie zawodzi — i właściwe przekazanie człowiekowi

Agent potyka się w trzech przewidywalnych miejscach:

  • Oceny jakości zarządu. Dokument mówi ci, co zrobili, a nie czy są kompetentni. Nie pytaj o to agenta.
  • Porównania branżowe spoza dokumentu. Jeśli pytanie brzmi „jak ta marża brutto wypada na tle konkurentów”, agent zna tylko to, co jest w przeszukanych dokumentach. Do porównania z konkurentami potrzebujesz albo osobnego zbioru danych, albo uruchomienia agenta raz na spółkę i agregacji.
  • Komentarze dotyczące przyszłości. Dokumenty zawierają forward-looking statements, ale model traktuje je dosłownie, o ile nie zostanie poinstruowany inaczej. Dodaj do promptu: „Oznaczaj forward-looking statements wprost. Nie przedstawiaj prognoz jako faktów.”

Minimalna działająca wersja

Obowiązuje ten sam wzorzec pętli tool-use Claude z przewodnika po agencie badawczym — zmieniają się tylko narzędzia i 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."))

Jak to rozwinąć dalej

  • Szablony do powtarzalnych przeglądów. Opakuj agenta w niewielki CLI, który przyjmuje ticker i emituje brief w markdown o stałym formacie: „Ostatnie 8-K”, „Trend przychodów segmentu”, „Delta czynników ryzyka”. Ten sam agent, oskryptowane prompty.
  • Tryb watchlist. Uruchamiaj agenta na tickerze każdego ranka i porównuj dzisiejszą odpowiedź z wczorajszą. Wyciągaj na wierzch wyłącznie różnice. Dobrze łączy się ze wzorcem porannego briefingu.
  • Połącz z patentami i rynkami predykcyjnymi. Dla nazw z branży tech/biotech dołóż Patent Search dla zmian w IP oraz Prediction Markets dla wyników implikowanych przez tłum (np. prawdopodobieństwo dopuszczenia leku).

Wzorzec daje się uogólnić. SEC to najgęstszy, najbardziej przyjazny schematom korpus, jaki dostarczamy — ale pętla („wyszukiwanie semantyczne → ekstrakcja URL → odpowiedź z przypisami”) stosuje się do każdego korpusu dokumentów ustrukturyzowanych, który cię interesuje: dokumentów prawnych, abstraktów naukowych, zastrzeżeń patentowych. Zbuduj najpierw agenta due diligence, a potem przenieś architekturę w bok.

Najczęściej zadawane pytania

Jak świeży jest indeks SEC?

Dokumenty są indeksowane w ciągu kilku godzin od zaakceptowania przez EDGAR. W przypadku 8-K (tych wrażliwych czasowo — zdarzenia istotne, zmiany w kierownictwie, przejęcia) jest to zwykle wystarczająco szybko dla procesów kończonych na koniec dnia. Jeśli potrzebujesz powiadomienia o nowych 8-K w czasie poniżej godziny, połącz wyszukiwanie z osobnym kanałem RSS SEC i używaj agenta wyłącznie do analizy treści, nie do wykrywania.

Czy obejmuje transkrypcje z konferencji wynikowych?

Tak — indeks SEC Filings Search zawiera amerykańskie transkrypcje earnings calls oraz statystyki akcji (cena/wolumen, historia kapitalizacji rynkowej) obok samych dokumentów. Pojedyncze zapytanie semantyczne może sięgnąć do dowolnego z tych źródeł.

Jakie są dźwignie kosztów, gdy robię to na dużą skalę?

Trzy. (1) Wstępne filtrowanie przez Company Facts (2 kredyty), aby potwierdzić, że ticker to realna spółka giełdowa, zanim wydasz 120 kredytów na wyszukiwanie w SEC. (2) Buforuj wyniki wyszukiwania według (ticker, kwartał) — dokumenty aktualizują się tylko według harmonogramu. (3) Używaj jednego szerokiego wyszukiwania na pytanie zamiast wielu wąskich; agent dobrze syntetyzuje wyniki.

Czy agent poradzi sobie z dokumentami spoza USA?

SEC Filings Search obejmuje spółki notowane w USA (10-K, 10-Q, 8-K). Dla spółek brytyjskich połącz UK Legal Search i Web Search. Dla innych jurysdykcji sięgnij po Web Search + URL Extract na stronie odpowiedniego krajowego regulatora (Companies House, SEDAR itp.).

Jak uniknąć zmyślonych liczb?

Trzy zasady w system prompt robią największą różnicę. (1) 'Cytuj liczby dosłownie z wyekstrahowanego tekstu — nigdy nie parafrazuj ani nie zaokrąglaj.' (2) 'Zawsze podawaj rodzaj dokumentu, okres fiskalny i odniesienie do sekcji.' (3) 'Jeśli odpowiedni dokument nie został wyekstrahowany, powiedz to wprost — nie wnioskuj z danych treningowych.' Te trzy razem eliminują większość konfabulacji.

API użyte w tym artykule

Sarah Choy
Autor
Sarah Choy
CEO, API Pick

Sarah Choy jest CEO API Pick. Pisze o budowaniu produkcyjnych API dla agentów AI i przepływów pracy z LLM.