Agentic Financial Document Intelligence & Risk Analyst
FinSight is a multi-agent AI system that analyzes SEC filings (10-K, 10-Q, 8-K) using a LangGraph-orchestrated pipeline of specialized agents. It combines document intelligence, quantitative analysis, risk classification, and cross-document reasoning to generate investment-grade research reports β all powered by local Ollama inference with no cloud LLM dependencies.
- Multi-Agent LangGraph Workflow β Four specialized agents (Document Intelligence, Quantitative Analysis, Risk Classification, Synthesis) orchestrated via LangGraph StateGraph with conditional routing
- PageIndex Tree Navigation β Hierarchical document structure maps for precise section-level extraction with citations
- Docling Document AI β IBM's AI-powered document conversion with layout analysis, table extraction, and structured Markdown output as the default PDF processor
- Local Ollama Inference β Runs entirely offline using Qwen3.5 via Ollama β no API keys required for core analysis. Supports multiple models (Qwen3.5:9b, Qwen3:8b, Qwen3.5:4b, or any Ollama-compatible model)
- Groq Cloud Fallback β When Ollama times out on large documents (100+ pages), automatically falls back to Groq's fast cloud inference (free tier: 14,400 requests/day)
- Market Data Integration β Real-time financial data from Yahoo Finance, FRED, Finnhub, Financial Modeling Prep, Alpha Vantage, and StockData via MCP-style data servers
- MITRE F3 Risk Framework β Risk classification using a financial threat taxonomy inspired by MITRE ATT&CK
- Cross-Document Reasoning (RLM) β Recursive Language Model integration for multi-filing comparative analysis. When multiple filings are loaded, the router activates RLM synthesis for cross-document reasoning with iterative refinement (up to 15 iterations)
- Local Tree Generation β Heuristic heading detection + LLM refinement (Ollama β Groq fallback) for generating document structure trees from raw PDFs
- Streamlit Web UI β Interactive chat interface, document manager, analysis dashboard with findings/risk scores/export
- iPhone Export β
.finsightbundle export for companion iOS app
FinSight Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Streamlit Web UI β
β ββββββββββββ ββββββββββββββββ βββββββββββββββββββββ β
β β Chat β β Documents β β Analysis Board β β
β ββββββ¬ββββββ ββββββββ¬ββββββββ βββββββββββ¬ββββββββββ β
ββββββββββΌβββββββββββββββββΌββββββββββββββββββββββΌββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LangGraph StateGraph β
β β
β ββββββββββββ ββββββββββββββ ββββββββββββ β
β β Router ββββ>β Doc Intel ββββ>β Quant β (conditional) β
β β Node β β Agent β β Agent β β
β ββββββββββββ ββββββββββββββ ββββββ¬ββββββ β
β β β
β βΌ β
β ββββββββββββ β
β β Risk β (conditional) β
β β Agent β β
β ββββββ¬ββββββ β
β β β
β ββββββ΄βββββ β
β βΌ βΌ β
β βββββββββββββ ββββββββββββββ β
β β Synthesis β β RLM β β
β β Agent β β Synthesis β β
β βββββββββββββ ββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββββββββ βββββββββββββββ ββββββββββββββββββββββββββββββββββββββββ
β Ollama LLM β β PageIndex β β MCP Data Servers β
β (Qwen3.5:9b) β β Trees β β βββββββββββββββββββββββββββββ β
β localhost:11434β β (JSON) β β β FRED ββFinnhubββ yFinββFMPβ β
ββββββββββββββββββ βββββββββββββββ β βββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββ β
β βAlphaVantageββStockDataβ β
β βββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββ
Query Processing Flow
User Query: "What are Apple's main risk factors?"
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. ROUTER β
β classify_query(query, num_filings) β
β βββ Detects: risk signals β route = "risk_focused" β
β βββ agents_to_run = ["doc_intel", "risk", "synthesis"] β
β βββ needs_rlm = False (single document) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. DOC INTEL AGENT β
β For each loaded filing: β
β βββ Present PageIndex tree outline to LLM β
β βββ LLM selects relevant node IDs (e.g., Risk Factors) β
β βββ Extract page text for selected sections β
β βββ Analyze each section with LLM β
β βββ Output: Findings[] with precise Citations β
β (filing, section, page range, excerpt) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. RISK AGENT (conditional β risk_focused route) β
β βββ Classify findings using MITRE F3 taxonomy β
β β βββ Disclosure Risk (DR-T001..T006) β
β β βββ Financial Health (FH-T001..T008) β
β β βββ Governance (GV-T001..T005) β
β β βββ Market Risk (MR-T001..T004) β
β βββ Output: RiskScore[] with severity (0.0-1.0) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. SYNTHESIS AGENT β
β βββ Aggregate all upstream findings + risk scores β
β βββ If RLM: incorporate cross-document reasoning β
β βββ Generate investment-grade report (markdown) β
β βββ Generate executive summary (one paragraph) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. OUTPUT β
β βββ report: Full synthesis report β
β βββ executive_summary: One-paragraph summary β
β βββ findings: [{content, agent, confidence, citations}] β
β βββ risk_scores: [{tactic, technique, severity, evidence}] β
β βββ agent_summaries: [{agent, summary, duration}] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
FinSight/
βββ shared/ # Shared core library (finsight_core)
β βββ src/finsight_core/
β βββ models/
β β βββ state.py # FinSightState β LangGraph state schema
β β βββ analysis.py # Finding, RiskScore, Citation, AgentOutput
β β βββ document.py # Filing, PageIndexTree, TreeNode
β β βββ export.py # ExportBundle for iPhone
β βββ prompts/ # All LLM prompt templates
β βββ pageindex/ # PageIndex tree parser & navigator
β βββ taxonomy/ # MITRE F3 risk taxonomy
β βββ finance/ # Financial ratio calculations
β
βββ mac/ # Mac application (finsight_mac)
β βββ src/finsight_mac/
β βββ agents/ # Four specialized agents
β β βββ doc_intel.py # Document Intelligence Agent
β β βββ quant.py # Quantitative Analysis Agent
β β βββ risk.py # Risk Classification Agent
β β βββ synthesis.py # Synthesis & Report Agent
β βββ graph/
β β βββ workflow.py # LangGraph StateGraph definition
β β βββ router.py # Query classification & routing
β βββ document/
β β βββ pipeline.py # PDF β PageIndex tree pipeline
β β βββ local_tree_generator.py # Offline tree generation
β βββ mcp/ # Market data servers
β β βββ market_data.py # Aggregator (all data sources)
β β βββ fred.py # Federal Reserve data
β β βββ finnhub_client.py # Market quotes & fundamentals
β β βββ yfinance_client.py # Yahoo Finance (no API key)
β β βββ fmp_client.py # Financial Modeling Prep (statements, ratios)
β β βββ alpha_vantage_client.py # Historical data & technical indicators
β β βββ stockdata_client.py # Market news & sentiment
β βββ llm/
β β βββ ollama_client.py # Async Ollama wrapper
β β βββ groq_client.py # Groq cloud fallback client
β β βββ rlm_client.py # Recursive Language Model client
β βββ ui/ # Streamlit web interface
β β βββ app.py # Main entry point
β β βββ pages/
β β β βββ chat.py # Chat Q&A interface
β β β βββ documents.py # PDF/tree management
β β β βββ analysis.py # Analysis dashboard
β β βββ components/
β β βββ tree_viewer.py # PageIndex tree renderer
β β βββ findings_viewer.py
β β βββ risk_viewer.py
β βββ config.py # Settings (Pydantic BaseSettings)
β
βββ tests/
β βββ shared/ # Core library unit tests
β βββ mac/ # Agent & workflow unit tests
β βββ e2e/ # End-to-end tests (requires Ollama)
β
βββ scripts/ # CLI utilities
β βββ setup_sample_data.py # One-command sample data setup
β βββ test_e2e.py # Manual E2E test runner
β βββ generate_tree.py # Tree generation CLI
β βββ export_for_iphone.py # .finsight bundle exporter
β
βββ data/
β βββ filings/ # SEC filing PDFs (gitignored)
β βββ trees/ # Generated PageIndex trees (gitignored)
β
βββ references/ # Design specs & documentation
# Clone the repo
git clone https://github.com/ayansk11/FinSight.git
cd FinSight
# Install dependencies with uv
uv sync
# Pull the Ollama model
ollama pull qwen3.5:9b
# Copy environment config
cp .env.example .env
# Edit .env to add optional API keys (FRED, Finnhub, PageIndex)# Download a sample 10-K from SEC EDGAR and generate a PageIndex tree
# (requires Ollama running with a model pulled)
uv run python scripts/setup_sample_data.py
# Or for a different company:
uv run python scripts/setup_sample_data.py --ticker MSFTSupported tickers: AAPL, MSFT, GOOGL, AMZN, TSLA, META, NVDA, JPM, V, JNJ.
# Start Ollama (if not already running)
ollama serve
# Launch Streamlit
uv run streamlit run mac/src/finsight_mac/ui/app.py# Unit tests (no Ollama required)
uv run python -m pytest tests/ -q -m "not e2e"
# E2E tests (requires Ollama + qwen3.5:9b)
uv run python -m pytest tests/e2e/ -v
# Lint
uv run ruff check .# Run the full pipeline from command line
uv run python scripts/test_e2e.py --query "What are Apple's main risk factors?"| Variable | Required | Description |
|---|---|---|
OLLAMA_MODEL |
No | Ollama model name (default: qwen3.5:9b) |
OLLAMA_BASE_URL |
No | Ollama endpoint (default: http://localhost:11434) |
FRED_API_KEY |
No | FRED macroeconomic data (free at fred.stlouisfed.org) |
FINNHUB_API_KEY |
No | Finnhub market data (free at finnhub.io) |
ALPHA_VANTAGE_API_KEY |
No | Alpha Vantage historical data & technical indicators (free at alphavantage.co) |
STOCKDATA_API_KEY |
No | StockData.org market news & sentiment (free at stockdata.org) |
GROQ_API_KEY |
No | Groq cloud fallback when Ollama times out (free at console.groq.com) |
PAGEINDEX_API_KEY |
No | PageIndex cloud tree generation |
OPENAI_API_KEY |
No | OpenAI for cloud tree generation fallback |
Core analysis works with zero API keys β only Ollama is required. Market data APIs are optional and enhance the Quantitative Agent. Groq is strongly recommended for generating trees from large (100+ page) filings β it prevents timeout issues on consumer hardware.
FinSight uses hierarchical PageIndex trees to navigate SEC filings efficiently. Instead of processing entire 100+ page documents, the system:
- Generates a structural tree (PART I β Item 1 β Business β ...) with page ranges
- Presents the tree outline to the LLM for intelligent section selection
- Extracts only relevant pages, maintaining precise citations
Trees can be generated via:
- Local Ollama β Groq fallback β Heuristic heading detection + LLM refinement. Tries local Ollama first; auto-falls back to Groq cloud when Ollama times out on large documents
- PageIndex Cloud API β High-quality cloud-based generation
- Pre-generated β Load from
data/trees/directory
The Router analyzes query intent and selects the appropriate agent combination:
| Route | Agents | Trigger |
|---|---|---|
single_doc |
doc_intel β synthesis | Default for single-filing queries |
quantitative |
doc_intel β quant β synthesis | Revenue, ratios, margins, P/E |
risk_focused |
doc_intel β risk β synthesis | Risk factors, governance, fraud |
multi_doc |
doc_intel β quant/risk β RLM synthesis | Cross-filing comparison queries |
FinSight uses Ollama for local inference and supports any Ollama-compatible model. Configure via the OLLAMA_MODEL environment variable:
| Model | Ollama ID | Size | Notes |
|---|---|---|---|
| Qwen3.5-9B | qwen3.5:9b |
~6GB | Default β best balance of quality and speed |
| Qwen3-8B (RLM) | qwen3:8b-q4_K_M |
~5GB | Optimized for cross-document reasoning |
| Qwen3.5-4B | qwen3.5:4b |
~3GB | Lightweight, good for quick queries |
| Qwen3.5-2B | qwen3.5:2b |
~1.5GB | Minimal memory footprint |
| Qwen3.5-0.8B | qwen3.5:0.8b |
~0.5GB | Ultra-light, fastest inference |
Select your model from the dropdown in the Streamlit sidebar. The default (OLLAMA_MODEL env var) can be overridden at runtime.
When multiple filings are loaded (e.g., comparing AAPL 10-K 2023 vs 2024), the Router automatically activates RLM synthesis instead of standard synthesis. RLM performs iterative cross-document reasoning:
- Generates initial comparative analysis from all upstream findings
- Iteratively refines the analysis (up to
MAX_RLM_ITERATIONS, default 15) - Produces a unified cross-filing report with comparative insights
RLM is triggered automatically β no configuration needed beyond loading multiple documents.
FinSight uses Docling (IBM) as its default PDF processor for:
- Layout analysis β Correct reading order for multi-column layouts
- Table extraction β Structured table data from financial statements
- Page-level Markdown β Clean formatted text preserving document structure
Docling results are cached to disk for fast reprocessing. Falls back to PyMuPDF if Docling processing fails on a specific document.
The Risk Agent uses a financial threat taxonomy inspired by MITRE ATT&CK:
- Disclosure Risk β Material omissions, vague language, delayed reporting
- Financial Health β Revenue concentration, debt levels, cash flow issues
- Governance β Related party transactions, executive compensation, board independence
- Market Risk β Concentration risk, regulatory exposure, competitive threats
Each risk receives a severity score (0.0β1.0) with supporting evidence and citations.
- 129 unit tests β Models, agents, workflow routing, tree generation, MCP clients
- 10 E2E tests β Full pipeline, live market data, real PDF processing
- All tests auto-skip when Ollama/network unavailable
| Component | Technology |
|---|---|
| Orchestration | LangGraph (StateGraph) |
| LLM | Ollama (Qwen3.5:9b default, multi-model) + Groq cloud fallback |
| Document AI | Docling (IBM) β layout analysis, tables |
| Document Parsing | PyMuPDF, PageIndex |
| Cross-Doc Reasoning | RLM (Recursive Language Model) |
| Market Data | yfinance, FRED API, Finnhub, FMP, Alpha Vantage, StockData |
| Data Models | Pydantic v2 |
| Web UI | Streamlit |
| Package Manager | uv (workspace) |
| Testing | pytest, pytest-asyncio |
| Linting | Ruff |
MIT