--- title: Instant SWOT Agent emoji: πŸ“Š colorFrom: blue colorTo: purple sdk: docker pinned: false short_description: Instant SWOT Agent with self-correcting feedback --- # Instant SWOT Agent **Multi-agent workflow with self-correcting quality control for strategic analysis.** [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) | Resource | Link | |----------|------| | Live Demo | [huggingface.co/spaces/vn6295337/Instant-SWOT-Agent](https://huggingface.co/spaces/vn6295337/Instant-SWOT-Agent) | | Product Demo Video | [Pre-recorded Demo](https://github.com/vn6295337/Instant-SWOT-Agent/issues/1) | | Business Guide | [BUSINESS_README.md](BUSINESS_README.md) | --- ## The Problem Strategic analysis is time-consuming and quality varies widely. Analysts spend hours gathering data and drafting reports, with no systematic quality checks until peer reviewβ€”often too late in the process. ## The Solution This demo implements an **agentic AI pattern** where specialized agents collaborate autonomously: one gathers data, another drafts analysis, a third evaluates quality, and a fourth revises until standards are met. The self-correcting loop eliminates the "first draft = final draft" problem common in LLM applications. ## Why This Matters Most enterprise AI deployments fail not from bad models, but from lack of quality gates. This architecture demonstrates how to build reliability into AI workflowsβ€”a pattern applicable to any domain requiring consistent output quality. --- ## Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ USER INTERFACE β”‚ β”‚ (React + Vite) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ORCHESTRATION (LangGraph) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Researcher │─▢│ Analyst │─▢│ Critic │─▢│ Editor β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ (SWOT Gen) β”‚ β”‚ (Scoring) β”‚ β”‚ (Revision) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ score < 7 β”‚ β”‚ β”‚ β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β–Ό β”‚ β”‚ score β‰₯ 7 or 3 revisions β†’ [END] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 1. FINANCIALS BASKET β”‚ β”‚ 2. VOLATILITY BASKET β”‚ β”‚ 3. MACRO BASKET β”‚ β”‚ (MCP Server) βœ“ β”‚ β”‚ (MCP Server) βœ“ β”‚ β”‚ (MCP Server) βœ“ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β€’ get_financials β”‚ β”‚ β€’ get_vix β”‚ β”‚ β€’ get_gdp β”‚ β”‚ β€’ get_debt_metrics β”‚ β”‚ β€’ get_beta β”‚ β”‚ β€’ get_interest_rates β”‚ β”‚ β€’ get_cash_flow β”‚ β”‚ β€’ get_historical_vol β”‚ β”‚ β€’ get_cpi β”‚ β”‚ β€’ get_material_events β”‚ β”‚ β€’ get_implied_vol β”‚ β”‚ β€’ get_unemployment β”‚ β”‚ β€’ get_ownership_filings β”‚ β”‚ β€’ get_volatility_basket β”‚ β”‚ β€’ get_macro_basket β”‚ β”‚ β€’ get_going_concern β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ get_sec_fundamentals β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SEC EDGAR API β”‚ β”‚ FRED API + Yahoo Finance β”‚ β”‚ FRED API β”‚ β”‚ (Free, Public) β”‚ β”‚ (Free with API Key) β”‚ β”‚ (Free with Key) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 4. VALUATION BASKET β”‚ β”‚ 5. NEWS BASKET β”‚ β”‚ 6. SENTIMENT BASKET β”‚ β”‚ (MCP Server) βœ“ β”‚ β”‚ (MCP Server) βœ“ β”‚ β”‚ (MCP Server) βœ“ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β€’ get_pe_ratio β”‚ β”‚ β€’ search_company_news β”‚ β”‚ β€’ get_social_sentiment β”‚ β”‚ β€’ get_ps_ratio β”‚ β”‚ β€’ search_going_concern β”‚ β”‚ β€’ get_analyst_ratings β”‚ β”‚ β€’ get_pb_ratio β”‚ β”‚ β€’ search_industry_trends β”‚ β”‚ β”‚ β”‚ β€’ get_ev_ebitda β”‚ β”‚ β€’ search_competitor_news β”‚ β”‚ β”‚ β”‚ β€’ get_valuation_basket β”‚ β”‚ β€’ tavily_search β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Yahoo + SEC EDGAR β”‚ β”‚ Tavily API β”‚ β”‚ Finnhub API β”‚ β”‚ (Free/Public) β”‚ β”‚ (Free 1,000/month) β”‚ β”‚ (Free with API Key) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### MCP Baskets Summary | # | Basket | Status | Source | Key Metrics | |---|--------|--------|--------|-------------| | 1 | Financials | βœ“ Done | SEC EDGAR | Revenue, Margins, Debt, Cash Flow, 8-K, Ownership | | 2 | Volatility | βœ“ Done | FRED + Yahoo | VIX, Beta, Historical Vol, Implied Vol | | 3 | Macro | βœ“ Done | FRED | GDP, CPI, Interest Rates, Unemployment | | 4 | Valuation | βœ“ Done | Yahoo + SEC | P/E, P/S, P/B, EV/EBITDA, PEG | | 5 | News | βœ“ Done | Tavily | Company News, Industry Trends, Competitors | | 6 | Sentiment | βœ“ Done | Finnhub | Social Sentiment, Analyst Ratings | ### Data Flow ``` User Input (Company) β†’ Researcher β†’ [MCP Servers] β†’ Raw Data ↓ Raw Data β†’ Analyst β†’ SWOT Draft β†’ Critic β†’ Score ↓ Score < 7 β†’ Editor β†’ Revised Draft β†’ Critic Score β‰₯ 7 β†’ Final Output β†’ User ``` ## Features | Agent | Role | Implementation | |-------|------|----------------| | **Researcher** | Gathers real-time company data | 6 MCP servers (financials, volatility, macro, valuation, news, sentiment) | | **Analyst** | Drafts SWOT based on selected strategy | Prompt-engineered generation | | **Critic** | Scores output 1-10 with reasoning | Rubric-based evaluation | | **Editor** | Revises based on critique | Targeted improvement | **Supported Strategies:** Cost Leadership, Differentiation, Focus/Niche ## MCP Data Servers Model Context Protocol (MCP) servers provide structured data access for AI agents. See [BUSINESS_README.md](BUSINESS_README.md) for detailed explanation. ### Financials Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/financials-basket/` | Revenue, Net Income, Margins | `get_financials` | | | Debt, Debt-to-Equity | `get_debt_metrics` | | | Operating CF, CapEx, FCF, R&D | `get_cash_flow` | | | 8-K Material Events | `get_material_events` | | | 13D/13G, Form 4 (Ownership) | `get_ownership_filings` | | | Going Concern Warnings | `get_going_concern` | | | All Metrics + SWOT | `get_sec_fundamentals` | ### Volatility Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/volatility-basket/` | VIX Index | `get_vix` | | | Beta (vs S&P 500) | `get_beta` | | | Historical Volatility | `get_historical_volatility` | | | Implied Volatility | `get_implied_volatility` | | | All Metrics + SWOT | `get_volatility_basket` | ### Macro Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/macro-basket/` | GDP Growth Rate | `get_gdp` | | | Federal Funds Rate | `get_interest_rates` | | | CPI / Inflation | `get_cpi` | | | Unemployment Rate | `get_unemployment` | | | All Metrics + SWOT | `get_macro_basket` | ### Valuation Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/valuation-basket/` | P/E Ratio | `get_pe_ratio` | | | P/S Ratio | `get_ps_ratio` | | | P/B Ratio | `get_pb_ratio` | | | EV/EBITDA | `get_ev_ebitda` | | | PEG Ratio | `get_peg_ratio` | | | All Metrics + SWOT | `get_valuation_basket` | ### News Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/news-basket/` | General Web Search | `tavily_search` | | | Company News | `search_company_news` | | | Going Concern News | `search_going_concern_news` | | | Industry Trends | `search_industry_trends` | | | Competitor News | `search_competitor_news` | ### Sentiment Basket | Location | Metric | Tool | |----------|--------|------| | `mcp-servers/sentiment-basket/` | Social Sentiment | `get_social_sentiment` | | | Analyst Ratings | `get_analyst_ratings` | ### API Endpoints | MCP Server | API | Endpoint | Auth | |------------|-----|----------|------| | **Financials Basket** | SEC EDGAR | `https://data.sec.gov/api/xbrl/companyfacts/CIK{cik}.json` | None (free) | | | | `https://data.sec.gov/submissions/CIK{cik}.json` | | | **Volatility Basket** | FRED | `https://api.stlouisfed.org/fred/series/observations` | API Key | | | Yahoo Finance | `https://query1.finance.yahoo.com/v8/finance/chart/{ticker}` | None | | **Macro Basket** | FRED | `https://api.stlouisfed.org/fred/series/observations` | API Key | | **Valuation Basket** | Yahoo Finance | `https://query1.finance.yahoo.com/v10/finance/quoteSummary/{ticker}` | None | | **News Basket** | Tavily | `https://api.tavily.com/search` | API Key | | **Sentiment Basket** | Finnhub | `https://finnhub.io/api/v1/` | API Key | ### API Keys | Key | Environment Variable | Get From | |-----|---------------------|----------| | FRED | `FRED_VIX_API_KEY` | https://fred.stlouisfed.org/docs/api/api_key.html | | Tavily | `TAVILY_API_KEY` | https://tavily.com | | Finnhub | `FINNHUB_API_KEY` | https://finnhub.io | Store in `.env`: ``` FRED_VIX_API_KEY=your_key TAVILY_API_KEY=tvly-your_key FINNHUB_API_KEY=your_key ``` ## Installation & Setup ### Local Development ```bash # Clone the repository git clone https://github.com/vn6295337/Instant-SWOT-Agent.git cd Instant-SWOT-Agent # Create and activate virtual environment python3 -m venv .venv source .venv/bin/activate # Install dependencies pip install -r requirements.txt # Set up environment variables cp .env.example .env # Edit .env with your API keys # Run the application (FastAPI + React UI) python -m src.main api # Or use make make api ``` ### Hugging Face Spaces Deployment 1. **Create a new Space** (Docker SDK) 2. **Add this repository** as the source 3. **Set up Secrets** (at least one LLM provider required): - `GROQ_API_KEY` (primary, recommended) - `GEMINI_API_KEY` (fallback) - `OPENROUTER_API_KEY` (fallback) - `TAVILY_API_KEY` (for live search data) 4. The system automatically falls back through providers if one fails ## Requirements - Python 3.11+ - At least one LLM API key (Groq, Gemini, or OpenRouter) - Tavily API key (optional, for live search data) ## Usage Examples ### Web UI ```bash # Start the FastAPI server with React frontend python -m src.main api ``` Open http://localhost:7860, enter a company name (e.g., "Tesla", "NVIDIA", "Microsoft") and click "Generate SWOT". ### CLI Usage ```bash # Analyze a company from command line python -m src.main analyze --company "Apple" --strategy "Differentiation" ``` ### Programmatic Usage ```python from src.workflow.runner import run_self_correcting_workflow # Generate SWOT analysis with specific strategy result = run_self_correcting_workflow(company_name="Apple", strategy_focus="Differentiation") print(f"Score: {result['score']}/10") print(f"Revisions: {result['revision_count']}") print(f"SWOT Analysis:\n{result['draft_report']}") ``` ## Testing ```bash # Run tests make test # Or directly python3 tests/test_self_correcting_loop.py ``` ## Technical Characteristics - **Analysis Time**: Typically under 10 seconds (depends on API latency) - **Quality Loop**: Iterates until score β‰₯ 7/10 or max 3 revisions - **LLM Providers**: Groq (primary) β†’ Gemini β†’ OpenRouter (cascading fallback) - **Data Sources**: 6 MCP servers aggregating SEC EDGAR, FRED, Yahoo Finance, Tavily, and Finnhub APIs - **Frontend**: React + TypeScript + Vite + Tailwind CSS - **Backend**: FastAPI with async workflow execution ## Design Decisions | Decision | Choice | Rationale | |----------|--------|-----------| | **Orchestration** | LangGraph | Native support for cyclic workflows; cleaner than raw LangChain for multi-agent patterns | | **LLM Provider** | Groq (Llama 3.1 8B) | Sub-second inference enables tight feedback loops; cost-effective for demos | | **Quality Threshold** | 7/10 | Balances quality vs. latency; lower values cause excessive loops, higher values rarely achievable | | **Max Revisions** | 3 | Empirically, quality plateaus after 2-3 iterations; prevents infinite loops | | **Same Model for Critic** | Intentional tradeoff | Production would use a stronger model for evaluation; kept simple for demo cost management | | **Web Search** | Tavily API | Purpose-built for LLM applications; returns clean, structured content | ### Known Limitations - **Self-evaluation bias**: The critic uses the same model family as the analyst. A production system would use a more capable evaluator model or human-in-the-loop for high-stakes decisions. - **Mock data visibility**: When Tavily API is unavailable, the UI clearly indicates cached data is being used. ## Contributing Contributions are welcome! Please follow these steps: 1. Fork the repository 2. Create a feature branch 3. Implement your changes 4. Add tests for new functionality 5. Submit a pull request ## License This project is licensed under the MIT License. ---