[ blog · use-case ]9 min read

SEC 공시(10-K, 10-Q, 8-K, 실적)로 실사 에이전트 만들기

Sarah Choy2026년 5월 3일 게시9분 분량
SEC 공시(10-K, 10-Q, 8-K, 실적)로 실사 에이전트 만들기

10-K를 읽는 일은 대부분 Ctrl+F다. 그걸 50개 회사에 대해 하는 건 직업이다. 지루한 80%를 SEC EDGAR 대상 검색·추출 에이전트로 대체하고, 인간 애널리스트에게 중요한 20%는 남겨라.

한눈에

  • 아키텍처: 티커 조회 → SEC Filings Search(공시 + 실적 + 주식 통계) → 긴 구절을 위한 URL Extract → 섹션 단위 인용이 달린 LLM 답변.
  • 비용 상한: SEC Filings Search는 호출당 120 크레딧(≈$0.12)이며, 전형적인 3개 질문짜리 기업 리뷰는 크레딧 ~$0.40 + LLM 토큰 ~$0.05.
  • 에이전트가 잘하는 것: 사실 조회(세그먼트 매출, capex 추이, 거버넌스, 전년 대비 리스크 요인 변화), 임원 보수 요약, 최근 8-K 이벤트.
  • 여전히 사람이 필요한 것: 경영진 자질에 대한 판단, 시장 포지셔닝, 거래별 특수 이슈, 공시 문언 바깥의 모든 것.

왜 자동화할 가치가 있나

상장사에 대한 1차 실사 읽기는 대부분 기계적이다: 최신 10-K를 가져오고, 리스크 요인과 MD&A를 훑고, 최근 8-K를 확인하고, 가장 최근 실적 발표를 슬쩍 본다. 어소시에이트급 애널리스트는 회사당 이 작업에 2~4시간을 쓴다. 산출물이 깊은 통찰인 경우는 드물다 — 그것은 더 시니어한 누군가가 추론할 정형화된 사실 패턴이다.

그 사실 패턴 단계가 바로 작은 에이전트가 넘겨받을 수 있는 부분이다. SEC를 검색하고, 관련 구절을 추출하고, 인용과 함께 요약한다. 추론은 여전히 시니어가 하지만 — 4시간짜리가 아니라 5분짜리 읽기에서 출발한다.

지금 이것이 현실적인 이유는 세 가지다:

  • 공시에 대한 시맨틱 검색 덕분에 '세그먼트 매출이 어떻게 변했나'를 물으면 200페이지를 읽는 대신 올바른 양식의 올바른 문단을 돌려받는다.
  • 롱컨텍스트 LLM은 10-K 전체에 8-K 몇 개를 작업 메모리에 담고 문서 간 질문에 답할 수 있다.
  • 프롬프트의 인용 규율은 산출물을 몇 초 안에 검증 가능하게 만든다 — 컴플라이언스와 리뷰 워크플로가 정확히 요구하는 것이다.

아키텍처

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

단일 질문 비용: API ~130 크레딧(~$0.13) + LLM ~$0.03. 3개 질문짜리 기업 리뷰(재무 추이, 리스크 요인 차이, 최근 중대 사건)는 ~$0.45~$0.60에 안착한다. 어지간한 청구 단가의 애널리스트 한 시간과 비교하면 계산은 명백하다.

제값을 하는 시스템 프롬프트

금융 RAG에서 산출물 품질을 가장 크게 좌우하는 단일 요인은 시스템 프롬프트다. 우리가 쓰는 것:

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.

규칙 1, 2, 4가 함께 우리가 측정한 날조 이슈의 ~90%를 제거한다. 규칙 3(우아한 "모르겠다")이 이것을 자신만만하게 숫자를 지어내는 챗봇과 구별짓는다.

에이전트가 깔끔하게 처리하는 샘플 쿼리

  • 'Apple의 서비스 매출 추이를 최근 5개 회계연도에 걸쳐 비교하라.' → 해당 10-K들에서 끌어와 MD&A에 대한 인용이 달린 표를 반환한다.
  • 'NVIDIA의 리스크 요인이 FY2023과 FY2025 사이에 무엇이 바뀌었나?' → 문서 간 차이 비교, 각 양식의 Item 1A를 인용.
  • '$TICKER의 최근 8-K 4건을 요약하라.' → 8-K로 필터링한 시맨틱 검색, 공시일 순 정렬.
  • 'Microsoft의 CFO가 가장 최근 실적 발표에서 AI capex에 관해 뭐라고 말했나?' → 트랜스크립트를 검색하고, 관련 Q&A 구절을 추출해, 그대로 인용한다.

한계 지점 — 그리고 올바른 인간 인계

에이전트는 예측 가능한 세 곳에서 비틀거린다:

  • 경영진 자질에 대한 판단. 공시는 그들이 무엇을 했는지는 알려주지만, 그들이 유능한지는 알려주지 않는다. 에이전트에게 묻지 말라.
  • 공시 바깥의 동종업계 비교. 질문이 '이 총이익률이 동종업계와 어떻게 비교되나'라면, 에이전트는 검색된 공시에 있는 것만 안다. 동종업계 비교를 하려면 별도 데이터셋이 있거나, 회사별로 에이전트를 한 번씩 돌려 집계해야 한다.
  • 미래 전망성 코멘터리. 공시에는 미래 전망 진술이 들어 있지만, 따로 지시하지 않으면 모델은 그것을 액면 그대로 다룬다. 프롬프트에 추가하라: '미래 전망 진술을 명시적으로 표시하라. 가이던스를 사실로 제시하지 말라.'

최소 동작 빌드

리서치 에이전트 워크스루와 동일한 Claude tool-use 루프 패턴이 적용된다 — 도구와 시스템 프롬프트만 바뀐다:

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."))

다음으로 가져갈 방향

  • 반복 가능한 리뷰용 템플릿. 에이전트를 작은 CLI로 감싸 티커를 받으면 고정 형식의 마크다운 브리프를 내놓게 하라: '최근 8-K', '세그먼트 매출 추이', '리스크 요인 델타'. 같은 에이전트, 스크립트화된 프롬프트.
  • 워치리스트 모드. 매일 아침 티커에 대해 에이전트를 돌리고 오늘의 답을 어제 것과 비교하라. 델타만 노출하라. 모닝 브리핑 패턴과 잘 어울린다.
  • 특허·예측 시장과 결합하라. 테크 / 바이오테크 종목이라면 IP 변화를 위한 Patent Search와 군중이 함의하는 결과(예: 약물 승인 확률)를 위한 Prediction Markets를 한 겹 더하라.

이 패턴은 일반화된다. SEC는 우리가 제공하는 가장 밀도 높고 스키마 친화적인 코퍼스지만 — 그 루프('시맨틱 검색 → URL 추출 → 인용과 함께 답변')는 당신이 신경 쓰는 어떤 정형 문서 코퍼스에도 적용된다: 법률 공시, 과학 초록, 특허 청구항. 실사 에이전트를 먼저 만들고, 그다음 아키텍처를 옆으로 이식하라.

자주 묻는 질문

SEC 인덱스는 얼마나 최신인가?

공시는 EDGAR가 접수한 지 몇 시간 안에 인덱싱된다. 8-K(시급한 것 — 중대 사건, 경영진 교체, 인수)의 경우 보통 장 마감 워크플로에는 충분히 빠르다. 새 8-K를 한 시간 안에 알림받아야 한다면, 검색을 별도의 SEC RSS 피드와 짝짓고 에이전트는 탐지가 아니라 내용 분석에만 쓰라.

실적 발표 트랜스크립트도 포함하나?

그렇다 — SEC Filings Search 인덱스는 공시 자체와 함께 미국 실적 발표 트랜스크립트와 주식 통계(가격/거래량, 시가총액 이력)를 포함한다. 단일 시맨틱 쿼리로 이 소스들 어디서든 끌어올 수 있다.

대규모로 돌릴 때 비용 레버는 무엇인가?

셋이다. (1) Company Facts(2 크레딧)로 사전 필터링해, SEC 검색에 120 크레딧을 쓰기 전에 티커가 실제 상장사인지 확인하라. (2) 검색 결과를 (티커, 분기)로 캐싱하라 — 공시는 정해진 일정에만 갱신된다. (3) 좁은 검색을 여러 번 하지 말고 질문당 넓은 검색 하나를 써라. 에이전트는 여러 결과를 가로질러 종합하는 데 능하다.

에이전트가 미국 외 공시도 다룰 수 있나?

SEC Filings Search는 미국 상장사(10-K, 10-Q, 8-K)를 다룬다. 영국 기업은 UK Legal Search와 Web Search를 짝지어라. 다른 관할권은 해당 국가 규제기관 사이트(Companies House, SEDAR 등)에 Web Search + URL Extract로 우회하라.

숫자 환각은 어떻게 피하나?

시스템 프롬프트의 세 가지 규칙이 가장 큰 차이를 만든다. (1) '추출된 텍스트에서 숫자를 그대로 인용하라 — 절대 의역하거나 반올림하지 말라.' (2) '항상 공시 양식, 회계 기간, 섹션 참조를 포함하라.' (3) '관련 공시가 추출되지 않았다면 명시적으로 그렇다고 말하라 — 학습 데이터로 추론하지 말라.' 이 셋이 함께 대부분의 날조를 없앤다.

이 글에서 사용한 API

Sarah Choy
작성
Sarah Choy
CEO, API Pick

Sarah Choy는 API Pick의 CEO입니다. AI 에이전트와 LLM 워크플로를 위한 프로덕션 등급 API에 대해 씁니다.