This repository contains the technical assessment for the Engineering Intern (AI & Fintech) position. It is not just a collection of scripts, but a modular, CLI-driven agentic framework designed around a "Decision Spine" philosophy. The system leverages a clear separation of concerns to orchestrate deterministic financial calculations with probabilistic, agent-based reasoning for comprehensive portfolio analysis.
The application's architecture is designed for modularity and scalability, separating core logic, data models, and configuration into distinct, manageable components. This promotes a clean "separation of concerns" where deterministic logic (e.g., risk calculation) is isolated from probabilistic AI reasoning, and constants or prompts are decoupled from business logic.
src/
├── __init__.py
├── config.py
├── models.py
├── constants/
│ ├── __init__.py
│ ├── defaults.py
│ ├── market_catalog.py
│ └── prompts.py
├── services/
│ ├── __init__.py
│ ├── committee_simulator.py
│ ├── llm_advisor.py
│ ├── market_data.py
│ └── risk_engine.py
└── utils/
├── __init__.py
└── cli_formatter.py
constants/: Isolates static data, including default portfolios, market data simulation parameters, and structured AI prompts. This allows for easy updates without altering core application logic.services/: Contains the core business logic for each of the application's main features, from deterministic risk calculations to agentic simulations.utils/: Provides shared utilities, such as the CLI formatter for presenting data to the user.
The terminal provides four primary tasks, each demonstrating a different facet of a "Finance as Code" architecture.
-
Portfolio Risk Calculator: A deterministic service that calculates the risk metrics for a given portfolio, including Value at Risk (VaR) and portfolio volatility.
-
Live Market Data Pipeline: An asynchronous task that simulates a live market data feed.
- Innovative Extension: This service runs in a separate thread, fetching and processing data concurrently without blocking the main application thread. It includes latency tracking to monitor the performance of the data pipeline.
-
Agentic AI Portfolio Explainer: An AI-powered agent that provides a qualitative analysis of the portfolio.
- Innovative Extension: This feature uses a dual-prompt "Maker/Checker" architecture. An 'Advisor' agent first generates a qualitative analysis, which is then passed to a 'Chief Risk Officer' (CRO) agent for a critical review. This adversarial process, combined with a JSON schema extraction engine, ensures a higher degree of accuracy and reduces the risk of AI hallucination.
-
Adversarial Investment Committee Simulation: A multi-agent simulation that models an investment committee debate.
- Innovative Extension: Built using LangGraph, this service orchestrates a multi-pass debate loop between several AI agents with different personas (e.g., Bull, Bear, Quant). The simulation culminates in a final "Decision Spine" output, which summarizes the key arguments and the committee's final consensus.
-
Environment Setup:
- Create a
.envfile in the root directory. You can copy the.env.examplefile as a template. - Set the
GOOGLE_API_KEYvariable to your Gemini API key. The application is also compatible with OpenAI models by setting theOPENAI_API_KEYand appropriate model name.
GOOGLE_API_KEY="your_api_key_here" - Create a
-
Install Dependencies:
- It is recommended to use a virtual environment.
- Install the required packages using
pip:
pip install -r requirements.txt
-
Run the Application:
- Execute the main script from the root directory:
python main.py
- You will be prompted to enter your portfolio or load a default sample.
This section addresses key aspects of the AI engineering and prompt design methodology for the grading team.
-
Prompt Approach: The project deliberately moved away from simple zero-shot prompts towards a more robust and structured System/User Template architecture. Initial prompts were brittle and prone to hallucination. The final implementation uses detailed system messages to define the agent's persona and task, and user messages to provide context and data. We enforce a strict output format using JSON schema extraction and a secondary critique loop (as seen in the Advisor/CRO service) to validate the AI's output, effectively eliminating hallucinations and ensuring reliable, structured data.
-
AI Tool Usage: Generative AI was used extensively as a pair-programming partner throughout the development process. GitHub Copilot and Anthropic's Claude were instrumental in rapidly scaffolding the initial architecture, refactoring monolithic proof-of-concept scripts into the final modular service pattern, and debugging the state management logic within the LangGraph implementation. These tools acted as a force multiplier, allowing for a greater focus on architectural design and feature innovation.
-
The Hardest Part: The most challenging aspect of the project was managing the state and conversational flow within the multi-agent LangGraph simulation. Orchestrating a coherent, multi-pass debate between agents, ensuring that state was correctly passed, updated, and routed between nodes, required a deep dive into LangGraph's conditional routing and state management mechanisms. Solving this involved designing a custom graph state object and carefully mapping the conditional edges to guide the conversation, culminating in the final "Decision Spine" output.