Skip to main content

Hermes Financial

An open-source framework for building AI investment research systems.

Hermes is the reusable Python framework a developer reaches for when building professional AI investment-research applications. It ships pre-built financial data tools, document ingestion pipelines, output generation (Excel models, Word/PDF reports, charts), composable agents, and the infrastructure you need to make those agents reliable, observable, and extensible.

Hermes does not answer "what should I buy?" — that question belongs to your application, your strategy, and your judgment. What it answers:

"How do I give AI agents the tools, data, workflows, provenance, and output infrastructure needed to perform serious investment research?"

A downstream application can use Hermes as its research substrate without modifying Hermes itself — registering custom agents, workflows, tools, storage adapters, and event sinks.


Quick Start

pip install hermes-financial
import asyncio
from hermes import Hermes, configure

configure(
    llm_provider="anthropic",
    sec_user_agent="MyApp/1.0 (me@company.com)",  # required by SEC
)

h = Hermes()
result = h.invoke("Research Apple's latest quarter")
print(result["response"])

The default invoke() returns a dict; for richer output use await h.run_structured(...) to receive a ResearchResult (see Structured outputs).


What's Included

Data Tools (free, no proprietary keys required for the basics)

Module What you get Source
SEC EDGAR Company facts (XBRL), filing search, submissions, filing URLs, structured financial tables, labeled text sections (MD&A, Risk Factors, …), insider transactions, institutional holdings edgartools + efts.sec.gov
FRED Economic time series, series search, metadata api.stlouisfed.org (free key)
Market Data Quotes, historical OHLCV, batch quotes Yahoo Finance
News Company news, general financial news RSS feeds
Excel Create, write, read, format, formulas, charts, save .xlsx openpyxl
Documents Create, headings, paragraphs, tables, images, save .docx, export PDF python-docx
Charts Line, bar, waterfall, scatter, heatmap → PNG matplotlib

Specialist Agents (7 built-in)

Agent Type Role
SecFilingsAgent FunctionAgent SEC filing retrieval & analysis
MacroAgent FunctionAgent FRED macroeconomic data
MarketDataAgent FunctionAgent Quotes and historical prices
NewsAgent FunctionAgent News/sentiment
ModelingAgent ReActAgent Excel financial model construction
ReportAgent ReActAgent Word/PDF report generation
ResearchOrchestrator FunctionAgent Multi-agent coordination

Architecture (since 0.2.0)

hermes/
├── agents/        # Specialist agents (built-in + custom HermesAgent subclasses)
├── workflows/     # ResearchWorkflow / EquityResearchWorkflow + HermesWorkflow protocol
├── tools/         # Data + output tools, each exposes create_tools()
├── schemas/       # Source, Evidence, ResearchArtifact, ResearchRun, ResearchResult,
│                  # CompanyProfile, FinancialAnalysis, ValuationAnalysis, CompanyResearch
├── provenance/    # ProvenanceCollector + current_collector() contextvar
├── storage/       # ResearchStore / ArtifactStore protocols + in-memory + local impls
├── ingestion/     # Optional: filing / transcript parsers + ChromaDB RAG (rag extra)
├── infra/         # Cache, rate limiter, retry, streaming events
├── config.py      # Pydantic HermesConfig (HERMES_ env prefix)
├── llm_providers.py   # Provider registry (10 built-in + openai_compatible + openrouter)
├── registry.py    # Tool/agent/workflow registry (per Hermes instance)
└── core.py        # The Hermes facade

Configuration

All settings are accepted as kwargs to configure() or via environment variables with the HERMES_ prefix:

from hermes import Hermes, configure

configure(
    llm_provider="anthropic",                  # or openai, google, ollama, ...
    llm_model="claude-sonnet-4-6",
    sec_user_agent="MyApp/1.0 (me@company.com)",
    fred_api_key="...",
    verbose=True,
)

OpenAI-compatible endpoints (OpenRouter, vLLM, self-hosted)

Hermes ships a generic openai_compatible provider and a preconfigured openrouter convenience. Set the base URL and key via config:

configure(
    llm_provider="openai_compatible",
    llm_model="my-model",
    llm_api_base="https://internal.example.com/v1",
    llm_api_key="...",
    llm_context_window=32000,                # optional
    llm_is_function_calling_model=True,      # optional
)

Or for OpenRouter:

configure(
    llm_provider="openrouter",
    llm_model="anthropic/claude-sonnet-4-5",
    llm_api_key="...",                        # OpenRouter API key
)

See examples/openrouter.py.

Add your own providers at runtime:

from hermes.llm_providers import ProviderSpec, register_provider

register_provider(
    ProviderSpec(
        name="my_internal",
        import_module="llama_index.llms.openai_like",
        class_name="OpenAILike",
        extra_kwargs={"api_base": "https://internal.example/v1"},
    )
)

Extending Hermes

Custom agent

from hermes.agents.base import HermesAgent
from hermes import Hermes

class SupplyChainAgent(HermesAgent):
    name = "supply_chain"
    description = "Analyzes supplier concentration and logistics risks."
    system_prompt = "You are a supply chain analyst..."
    agent_type = "function"

    def get_tools(self):
        return [...]

h = Hermes()
h.register_agent("supply_chain", SupplyChainAgent)

See examples/custom_agent.py.

Custom workflow

A workflow composes a root agent with a set of specialists and decides how they hand off. Built-in EquityResearchWorkflow is the default; you can compose your own with ResearchWorkflow (or any class implementing the HermesWorkflow protocol):

from hermes import Hermes
from hermes.workflows import ResearchWorkflow

workflow = ResearchWorkflow(
    root_agent="orchestrator",
    agents=[
        "sec_filings",
        "market_data",
        SupplyChainAgent(),
    ],
)

h = Hermes()
result = await h.run("Research NVDA", workflow=workflow)

See examples/custom_workflow.py.

Per-agent LLM overrides (cost / latency / quality)

from hermes.workflows import ResearchWorkflow

workflow = ResearchWorkflow(
    agent_llms={
        "sec_filings": cheap_llm,    # fast/cheap model for data extraction
        "modeling": strong_llm,      # strongest model for the model agent
        "report": writing_llm,       # different model for prose
    },
)

Structured outputs

run_structured() returns a ResearchResult with a full ResearchRun record: participating agents, provider/model, status, timestamps, sources, and artifacts. Failures don't raise — they return ResearchResult with run.status = failed and run.error set.

result = await h.run_structured("Research AMBA")
print(result.response)
print(result.run.agents)
print(result.run.sources)

See examples/structured_results.py.

Event sinks

Hermes(event_sinks=[...]) fans every event (workflow started, agent output, tool call, artifact created, …) out to every callable sink. Async sinks are scheduled; sync sinks block. Sink exceptions are logged but don't abort the run.

def my_sink(event):
    print(f"[{event.run_id}] {event.type}: {event.text or event.metadata}")

h = Hermes(event_sinks=[my_sink])

Storage

By default runs live in memory. Replace with a local-disk or remote implementation:

from hermes import Hermes
from hermes.storage import LocalResearchStore

h = Hermes(research_store=LocalResearchStore("~/.hermes/runs"))

Implement the ResearchStore / ArtifactStore protocols to plug in your own backend (D1, R2, S3, Postgres, …).

See examples/storage_adapter.py.

Custom tools (registry-based)

from llama_index.core.tools import FunctionTool
from hermes import Hermes

tool = FunctionTool.from_defaults(fn=my_lookup, name="my_lookup")
h = Hermes()
h.register_tool("my_lookup", tool, tags=["custom"])

Custom agents can pull registered tools by name via the HermesAgent.tool_names class attribute — no need to import the module that created them.


Using Tools Directly

You don't need agents to use the tools. Every tool module exposes async functions that work standalone:

from hermes.tools.sec_edgar import (
    get_company_facts,
    get_filing_urls,
    get_filing_financial_tables,
    get_filing_text,
)
from hermes.tools.fred import get_series
from hermes.tools.excel import excel_create_workbook, excel_write_cells, excel_save

facts = await get_company_facts("AAPL")
filings = await get_filing_urls("AAPL", filing_types="10-K,10-Q", limit=10)
tables = await get_filing_financial_tables("AAPL", filings[0]["accessionNumber"])
text = await get_filing_text(filings[0]["url"])
gdp = await get_series("GDP", start_date="2020-01-01")

Optional Extras

Extra What it adds Install
rag ChromaDB-backed semantic search over filings/transcripts/user documents pip install hermes-financial[rag]
google, mistral, groq, ollama, huggingface, cohere, deepseek, xai Corresponding LLM provider pip install hermes-financial[google] (etc.)
llamaparse LlamaParse for parsing PDFs pip install hermes-financial[llamaparse]
web Web page readers pip install hermes-financial[web]
pandas Pandas-shaped returns pip install hermes-financial[pandas]
dev Test/lint/type tooling pip install hermes-financial[dev]
all Everything above pip install hermes-financial[all]

Documentation


Development

git clone https://github.com/hermes-financial/hermes-financial.git
cd hermes-financial
uv sync --all-extras

uv run pytest          # 340+ tests
uv run ruff check hermes/ tests/
uv run mypy hermes/

Requirements

  • Python >= 3.10
  • An LLM API key (Anthropic, OpenAI, OpenRouter, …) for agent functionality
  • SEC EDGAR requires a User-Agent string identifying your application
  • FRED requires a free API key from fred.stlouisfed.org

License

MIT — see LICENSE.


Hermes is the research framework. Downstream applications are the investors.

Metadata

Release files for hermes-financial 0.2.0

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

Source distribution (sdist)

Source distribution for hermes-financial 0.2.0
File Size Uploaded
hermes_financial-0.2.0.tar.gz 585.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermes-financial 0.2.0
File Interpreter ABI Platform
hermes_financial-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 708.1 kB

Release files / hermes_financial-0.2.0.tar.gz

Download URL hermes_financial-0.2.0.tar.gz
Size 585.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1a3d8cd7a93fa178207b0dca53a77be2241d1c29c28a9ddbf0073f79c3e36836
BLAKE2b-256 checksum
How to use checksums
3f6aacd655b8c40bd9aeb877f92ab4d1ee7ce0d045a71f219839569d54addd89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / hermes_financial-0.2.0-py3-none-any.whl

Download URL hermes_financial-0.2.0-py3-none-any.whl
Size 122.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
71e1292f61105aeb7ebf8155ef21a4e42962acc72b3d1e192732d67260152ed9
BLAKE2b-256 checksum
How to use checksums
3d2d0947b560d482a3fec2a30182fdcd37550d6156dd0384b095f243f0a82395
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
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