Skip to main content

LangChain Financial Retriever

A production-ready hybrid retriever optimized for financial documents including SEC filings (10-K, 10-Q, 8-K) and earnings call transcripts.

Features

  • Hybrid Search: Combines dense (semantic) and sparse (keyword) retrieval with Reciprocal Rank Fusion
  • Financial Entity Extraction: Automatically extracts tickers, dates, quarters, and financial metrics
  • Number Normalization: Handles various financial number formats ($5.2M, $5,200,000)
  • Metadata Filtering: Filter by document type, company, fiscal year, quarter, section
  • Production Ready: Full async support, error handling, logging
  • LangChain Native: Fully compatible with LangChain ecosystem (chains, agents)

Installation

# From this directory
pip install -e .

# With optional dependencies for BM25
pip install -e ".[bm25]"

Quick Start

Basic Usage

from langchain_financial_retriever import HybridFinancialRetriever
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings

# Load financial embeddings
embeddings = HuggingFaceEmbeddings(model_name="ProsusAI/finbert")

# Create or load vector store with your financial documents
vectorstore = FAISS.load_local("path/to/financial/index", embeddings)

# Create retriever
retriever = HybridFinancialRetriever(
    vectorstore=vectorstore,
    k=10  # Return top 10 documents
)

# Use it!
docs = retriever.invoke("What are Apple's risk factors in 2024?")

for doc in docs:
    print(f"Source: {doc.metadata['source']}")
    print(f"Content: {doc.page_content[:200]}...")

With Metadata Filtering

retriever = HybridFinancialRetriever(
    vectorstore=vectorstore,
    k=10,
    # Metadata filters
    document_types=["10-K", "10-Q"],  # Only annual and quarterly reports
    companies=["Apple", "AAPL"],      # Apple documents only
    fiscal_years=[2024, 2023],        # Last 2 years
    sections=["Risk Factors", "MD&A"], # Specific sections
)

docs = retriever.invoke("revenue growth trends")

Advanced Configuration

retriever = HybridFinancialRetriever(
    vectorstore=vectorstore,
    documents=documents,  # Optional: for BM25 sparse retrieval

    # Retrieval parameters
    k=10,           # Final number of results
    dense_k=20,     # Retrieve 20 from dense search
    sparse_k=20,    # Retrieve 20 from sparse search

    # Fusion weights
    dense_weight=0.6,   # 60% weight to semantic search
    sparse_weight=0.4,  # 40% weight to keyword matching

    # Preprocessing
    normalize_numbers=True,  # $5.2M → 5200000
    extract_entities=True,   # Extract tickers, dates, etc.
    expand_synonyms=False,   # Query expansion

    # Metadata filters
    document_types=["10-K"],
    fiscal_years=[2024],
)

Async Usage

import asyncio

async def retrieve():
    # Single query
    docs = await retriever.ainvoke("What are the risk factors?")

    # Batch queries (parallel!)
    queries = [
        "What are Apple's risk factors?",
        "What is Microsoft's revenue?",
        "AWS performance metrics"
    ]
    results = await retriever.abatch(queries)

    for query, docs in zip(queries, results):
        print(f"{query} -> {len(docs)} documents")

asyncio.run(retrieve())

With LangChain Chains

from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI

# Create QA chain
llm = ChatOpenAI(model="gpt-4")
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    return_source_documents=True
)

# Ask questions
result = qa_chain.invoke({
    "query": "What are the main risks Apple faces in 2024?"
})

print("Answer:", result["result"])
print("\nSources:")
for doc in result["source_documents"]:
    print(f"- {doc.metadata['source']}")

With LangChain Agents

from langchain.agents import create_react_agent, AgentExecutor
from langchain.tools.retriever import create_retriever_tool

# Convert retriever to tool
retriever_tool = create_retriever_tool(
    retriever,
    name="financial_document_search",
    description="Search financial documents like 10-Ks, 10-Qs, and earnings calls"
)

# Create and use agent
agent = create_react_agent(llm, [retriever_tool], prompt)
agent_executor = AgentExecutor(agent=agent, tools=[retriever_tool])

result = agent_executor.invoke({
    "input": "Compare Apple and Microsoft's revenue growth in 2024"
})

Architecture

The retriever uses a multi-stage pipeline:

Query
  ↓
1. Query Preprocessing
   - Entity extraction (tickers, dates, quarters)
   - Number normalization ($5.2M → 5200000)
   - Query expansion (optional)
  ↓
2. Parallel Retrieval
   - Dense: Semantic search using embeddings
   - Sparse: Keyword search using BM25 (if enabled)
  ↓
3. Fusion Ranking
   - Reciprocal Rank Fusion (RRF) algorithm
   - Weighted combination of results
  ↓
4. Metadata Filtering
   - Filter by document type, company, year, etc.
  ↓
5. Return Top-K Results

Components

HybridFinancialRetriever

Main retriever class that orchestrates the pipeline.

Key Parameters:

  • vectorstore: Vector store for dense retrieval (required)
  • documents: Document list for sparse retrieval (optional)
  • k: Number of final results (default: 10)
  • dense_weight: Weight for semantic search (default: 0.6)
  • sparse_weight: Weight for keyword search (default: 0.4)

QueryPreprocessor

Handles query preprocessing including:

  • Entity extraction (tickers, dates, quarters, financial metrics)
  • Number normalization ($5.2M → 5200000)
  • Query expansion with financial synonyms

FusionRanker

Implements Reciprocal Rank Fusion (RRF) algorithm:

  • Combines results from multiple retrievers
  • No score normalization needed
  • Robust to different score scales

MetadataFilter

Filters documents by metadata:

  • Document type (10-K, 10-Q, 8-K, earnings_call)
  • Company name or ticker
  • Fiscal year and quarter
  • Section name
  • Custom filters

Metadata Schema

Expected metadata fields for financial documents:

{
    "source": "AAPL_10K_2024.pdf",           # Document source
    "document_type": "10-K",                  # 10-K, 10-Q, 8-K, earnings_call
    "company": "Apple Inc.",                  # Company name
    "ticker": "AAPL",                         # Stock ticker
    "fiscal_year": 2024,                      # Fiscal year (int)
    "quarter": "Q4",                          # Quarter (Q1, Q2, Q3, Q4)
    "section": "Risk Factors",                # Section name
    "page": 15,                               # Page number (optional)
}

Best Practices

1. Use Financial Embeddings

Use domain-specific embeddings for better accuracy:

# FinBERT (recommended)
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="ProsusAI/finbert")

# BGE-large (also good)
embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-large-en-v1.5")

2. Provide Documents for BM25

For best results, provide the document list for sparse retrieval:

retriever = HybridFinancialRetriever(
    vectorstore=vectorstore,
    documents=documents,  # Enable BM25 sparse retrieval
    k=10
)

3. Tune Weights for Your Use Case

  • More semantic understanding: Increase dense_weight (0.7-0.8)
  • More exact matching: Increase sparse_weight (0.5-0.6)
  • Balanced: Use defaults (0.6 dense, 0.4 sparse)

4. Use Metadata Filtering

Filter early to improve relevance:

retriever = HybridFinancialRetriever(
    vectorstore=vectorstore,
    fiscal_years=[2024, 2023],  # Recent filings only
    document_types=["10-K"],     # Annual reports only
)

5. Batch Queries When Possible

Use async batch processing for multiple queries:

queries = ["query1", "query2", "query3"]
results = await retriever.abatch(queries)

Performance

Typical performance on financial documents:

  • Latency: 200-500ms per query (single doc)
  • Throughput: 100+ queries/sec (with batching)
  • Accuracy: 85-90% recall@10 on financial QA tasks
  • Improvement over dense-only: +15-20% accuracy

Examples

See example_usage.py for complete examples:

python langchain_financial_retriever/example_usage.py

Requirements

  • Python 3.9+
  • langchain-core >= 0.3.0
  • pydantic >= 2.0.0
  • numpy (for BM25)
  • rank-bm25 (optional, for sparse retrieval)

Contributing

This retriever is designed to be contributed to LangChain. See CONTRIBUTION_GUIDE.md for details on:

  1. Forking the LangChain repository
  2. Adding the retriever to langchain-community
  3. Writing tests (unit + integration)
  4. Creating documentation
  5. Submitting a pull request

License

Apache License 2.0 (same as LangChain)

Support

For issues or questions:

  1. Check the examples in example_usage.py
  2. Review the architecture design in ARCHITECTURE_DESIGN.md
  3. See contribution guidelines in CONTRIBUTION_GUIDE.md

Metadata

Release files for langchain-financial 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-financial 0.1.1
File Size Uploaded
langchain_financial-0.1.1.tar.gz 23.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain-financial 0.1.1
File Interpreter ABI Platform
langchain_financial-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 45.4 kB

Release files / langchain_financial-0.1.1.tar.gz

Download URL langchain_financial-0.1.1.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9eaec5b3f1e29870496ee81c1350fc8e700739d60279ca9fcb799996c12e4aca
BLAKE2b-256 checksum
How to use checksums
d7c1f080a73d16b540211f81ba9db33708dbab05bd8fcff1c5e6ae5875ea646a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.0

Release files / langchain_financial-0.1.1-py3-none-any.whl

Download URL langchain_financial-0.1.1-py3-none-any.whl
Size 21.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e88ca9cc8a38971f5536c5466944d522db326fe1f1a9d43b7aafac2af728ea5b
BLAKE2b-256 checksum
How to use checksums
da90a4956d72308c595fa47de50c9240837412c270d4d0d29843bd116ab2fea9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.0

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page