Skip to content

Latest commit

 

History

25 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FinancialGraphRag

A minimal, explainable financial intelligence system that enhances user queries using vector similarity search (Qdrant) and graph traversal (Neo4j). It now also supports text-based ingestion from the UI to upsert both stores.


Architecture

User Query
  │
  ▼
embeddings.py          — embed query with SentenceTransformers (all-MiniLM-L6-v2)
  │
  ▼
vector_store.py        — Qdrant cosine similarity search → top-k similar events
  │
  ▼  extract entity names from vector result payloads
  │
  ▼
graph_store.py         — Neo4j multi-hop traversal starting from seed entities
  │
  ▼
main.py                — merge vector + graph results into structured output
  │
  ▼
app.py                 — Streamlit dashboard for analysts

Pipeline (step by step)

Step File What happens
1 embeddings.py Query text → 384-dim dense vector via SentenceTransformers
2 vector_store.py Qdrant finds the k most semantically similar historical events
3 main.py Entity lists are extracted from the Qdrant payload metadata
4 graph_store.py Neo4j follows supply-chain edges up to N hops from seed entities
5 main.py Results are merged into a single structured dict
6 app.py Streamlit renders the result as an interactive dashboard

File Overview

File Purpose
config.py All constants — DB connection details, entity/relationship lists, sample data
embeddings.py SentenceTransformers model loading and get_embedding() helper
vector_store.py Qdrant collection management and similarity search
graph_store.py Neo4j driver, graph seeding, and multi-hop traversal query
ingestion_agent.py Agent prompt + parsing logic to convert plain text into ingestion payload JSON
main.py Orchestration pipeline and CLI entry point
app.py Streamlit frontend
requirements.txt Python dependencies

Quick Start

Prerequisites

Service Default address
Qdrant localhost:6333
Neo4j bolt://localhost:7687 (user: neo4j, password: password)

Install dependencies

pip install -r requirements.txt

Run the Streamlit app

streamlit run app.py

Ingest new data from text

The Ingest tab now supports two modes:

  1. Structured JSON mode for direct payload entry.
  2. Agent from article text mode that parses plain text into payload JSON.

For AI Analyst Brief generation and Agent ingestion mode, set your API key before starting Streamlit.

Option 1 (recommended): create a .env file from .env.example and set GOOGLE_API_KEY.

Option 2: export it in shell:

export GOOGLE_API_KEY="your_key_here"

Structured JSON example:

Example payload:

{
  "event": {
    "text": "Lithium refinery shutdown in Chile raises EV battery risk",
    "entities": ["Lithium", "Chile", "Tesla"],
    "entity": "Lithium",
    "region": "Chile",
    "sentiment": "negative",
    "industry": "battery"
  },
  "graph_edges": [
    {
      "from_label": "Country",
      "from_name": "Chile",
      "rel": "SUPPLIES",
      "to_label": "Commodity",
      "to_name": "Lithium"
    },
    {
      "from_label": "Company",
      "from_name": "Tesla",
      "rel": "USES_RESOURCE",
      "to_label": "Commodity",
      "to_name": "Lithium"
    }
  ]
}

You can also send events (array) instead of event (single object). Neo4j constraints are verified before every graph ingestion write.

Run the pipeline from the command line

python main.py "lithium supply disruption"

Example Output

{
  "query": "lithium supply disruption",
  "similar_events": [
    {
      "score": 0.92,
      "text": "Chile lithium strike disrupts battery supply chain",
      "entity": "Lithium",
      "region": "Chile",
      "sentiment": "negative",
      "industry": "battery"
    }
  ],
  "related_entities": ["Battery Manufacturing", "Chile", "EV Companies", "Lithium", "Tesla"],
  "relationships": [
    "Chile --[SUPPLIES]--> Lithium",
    "Lithium --[SUPPLIES]--> Battery Manufacturing",
    "Battery Manufacturing --[SUPPLIES]--> Electric Vehicles",
    "Tesla --[USES_RESOURCE]--> Lithium"
  ],
  "supporting_news": [
    "Chile lithium strike disrupts battery supply chain",
    "Battery makers seek alternative suppliers amid lithium shortage"
  ]
}

Neo4j Graph Model

Node labels: Company · Commodity · Country · Industry

Relationship types:

Relationship Meaning
SUPPLIES Entity A provides goods/services to Entity B
USES_RESOURCE Company consumes a commodity
COMPETES_WITH Two companies compete in the same market
SUBSTITUTE_FOR Commodity A can replace Commodity B
SUBSIDIARY_OF Company A is owned by Company B

Configuration

All tuneable parameters live in config.py:

QDRANT_HOST = "localhost"
QDRANT_PORT = 6333
NEO4J_URI   = "bolt://localhost:7687"
GRAPH_TRAVERSAL_DEPTH = 2   # increase for deeper supply-chain discovery
EMBEDDING_MODEL = "all-MiniLM-L6-v2"
LLM_MODEL = "gemini-2.5-flash"  # single Gemini model used across the project

Design Principles

  • Small — fewer than 7 source files, each under 120 lines
  • Explainable — every function has a docstring describing its role in the pipeline
  • Readable — functions over classes, plain dicts over ORM objects
  • Self-contained — sample data is loaded automatically so the system works without a live data feed

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages