FinAgent is a sophisticated Multi-Agent AI system designed to provide personalized investment advice. By orchestrating specialized agentsβfrom profile analysis to fierce debates between opposing viewpointsβit delivers comprehensive, data-driven financial reports tailored to the user's specific risk tolerance and goals.
The system follows a graph-based workflow powered by LangGraph, ensuring modularity and context retention throughout the user interaction.
- Input Guardrail: Every user input is first checked for safety and domain relevance. Non-financial queries are filtered out immediately.
- Context-Aware Routing: The
Condition Nodeanalyzes the user's intent and conversation history to decide the next step:- New User / Profile Update β
User Chat(Onboarding) - Simple Data Query β
Retriever(Search) - Complex Investment Advice β
Debate(Analysis) - Report Generation β
Finance(Synthesis)
- New User / Profile Update β
- Multi-Agent Collaboration:
- User Chat: Conducts a natural interview to fill missing KYC data (Risk level, Income, etc.) and syncs with Supabase.
- Debate: Bull, Bear, and Balanced experts engage in a multi-round debate using real-time data (Yahoo Finance, Tavily) to analyze risks and opportunities.
- Retriever: Fetches specific product data via SQL or general knowledge via RAG.
- Final Output: The
Finance Nodesynthesizes all gathered insights and debate conclusions into a structured Markdown report.
- Guardrail: Ensures safety and domain relevance, filtering out non-financial queries.
- Condition: The intelligent router that analyzes user intent and context to direct the flow (e.g., to Debate, Retriever, or Profile setup).
- User Chat: Conducts a natural interview to collect and manage user profiles (KYC) and synchronizes data with the database.
- Retriever: Handles data fetching via SQL (for products), RAG (for regulations), and APIs (for market prices).
- Debate: Simulates a fierce debate between Bull (Aggressive), Bear (Conservative), and Balanced experts, concluded by a Judge (CIO).
FinAgent_Investment_Agent/
βββ assets/ # Static assets (images, diagrams)
βββ condtition/ # Router & Safety Layer
β βββ condition.py # Context-aware routing logic
β βββ guardrail.py # Input validation & safety checks
βββ debate/ # Debate Engine
β βββ node.py # 5-Round Debate Logic (Bull vs Bear vs Judge)
β βββ tools.py # Tools for debate (News, Market Data)
βββ finance/ # Reporting Engine
β βββ node.py # Final Report Generation
β βββ tools.py # SQL-based Product Recommendation Tools
βββ retriever/ # Information Retrieval
β βββ node.py # ReAct Agent for Search
β βββ tools.py # Hybrid Search (SQL + Vector + Web)
βββ user_chat/ # User Onboarding
β βββ models.py # Pydantic Data Models for Profile
β βββ node.py # Interview & DB Sync Logic
βββ utils/ # Core Utilities
β βββ const.py # Constants & Prompts
β βββ db.py # Supabase Connection
β βββ embedding.py # BGE-M3 Embedding Loader
β βββ llm.py # OpenRouter/HTTPX Client
β βββ state.py # Shared Agent State (Memory)
βββ .env # API Keys and Config
βββ .gitignore
βββ api.py # FastAPI REST API Server
βββ main.py # Application Entry Point (Graph Compiler)
βββ README.md # Project Documentation
Clone the repository and install the required dependencies
# Clone repository
git clone https://github.com/your-repo/FinAgent_Investment_Agent.git
cd FinAgent
# Install dependencies
pip install -r requirements.txtCreate a .env file in the root directory and add your API keys:
OPENROUTER_API_KEY="your-api-key"
SUPABASE_URL="your-supbase-url"
SUPABASE_SERVICE_KEY="your-api-key"
TAVILY_API_KEY="your-api-key"
Run the main script to start the interactive CLI session.
python main.pyStart the FastAPI server for programmatic access:
python api.pyThe server will start on http://localhost:8000
POST /chat - Send messages and receive AI responses
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{
"user_id": "test_user",
"message": "Should I invest in Nvidia?",
"session_id": "optional-session-id"
}'Response:
{
"session_id": "abc123",
"user_id": "test_user",
"message": "Should I invest in Nvidia?",
"response": "Let me analyze Nvidia for you...",
"node_executed": "debate",
"debate_history": [...],
"timestamp": "2024-01-03T12:00:00"
}GET /profile/{user_id} - Retrieve user profile
curl http://localhost:8000/profile/test_userPOST /profile/{user_id} - Create/Update user profile
curl -X POST http://localhost:8000/profile/test_user \
-H "Content-Type: application/json" \
-d '{
"name_display": "John Doe",
"age_range": "30λ",
"risk_tolerance_level": "aggressive",
"goal_type": "long_term"
}'GET /health - Health check endpoint
curl http://localhost:8000/healthScenario: A user asks about investing in Nvidia.
User: Should I buy Nvidia right now?
Guardrail: [finance] -> Allowed: True
Routing to [debate] (Reason: User is asking for investment advice.)
[Debate Arena] Topic: Should I buy Nvidia right now? (5 Rounds)
--- Round 1: Opening Statement ---
Turn: Conservative Expert
Arg: Nvidia's valuation is too high (PER > 70). Regulatory risks in China are concerning...
Turn: Aggressive Expert
Arg: AI demand is just starting. Nvidia has a monopoly on H100 chips...
... (Rounds 2, 3, 4...) ...
Judge's Verdict:
"While growth potential is undeniable, short-term volatility is expected.
I recommend a split-buying strategy."
AI Suggestion: "Shall we analyze the exchange rate risk before writing the report?"
User: Yes, please check that.
... (Additional Debate on Exchange Rates) ...
[Finance Node] Generating Final Report...
Report Saved to DB.
Agent (finance):
# π Investment Advisory Report: Nvidia Analysis
## 1. Market Analysis...
## 2. Investment Strategy...
## 3. Recommended Portfolio (Product: TIGER US Tech Top 10)...
Hybrid Market Data Tools (utils/tools.py)
Our agent uses a hybrid approach to fetch real-time stock data:
- Korean Stocks: Uses FinanceDataReader (Naver Finance based).
- Global Stocks/Indices: Uses Yahoo Finance (with auto-ticker mapping).
Context-Aware Router (condition/condition.py)
The router doesn't just look at the last message. It analyzes the entire conversation history to determine if the user is answering a profile question, agreeing to a suggestion, or asking a new question, preventing infinite loops.
Database Synchronization (user_chat/node.py)
- Load: Fetches existing user profiles on startup.
- Upsert: Automatically updates the profile in Supabase whenever new information is extracted during the chat.
- Strict Schema: Enforces strict data types (e.g., risk_tolerance_level Enum) to ensure data integrity.
- Conversation History: Stored in-memory using MemorySaver for context retention.
- User Profile: Persisted in the user_profile table in Supabase.
- Advisory Report: Final reports are saved in the advisory_reports table and presented to the user in Markdown format.
