AI-Powered Multi-Agent Research System
Data Harbor is an advanced, autonomous AI-powered platform for data analysis and research. It employs a multi-agent system built with LangChain, LangGraph, and OpenAI to orchestrate a complete research workflow, from hypothesis generation to final report compilation, with strategic human oversight.
Table of Contents
- System Architecture
- Core Concepts
- Key Features
- Directory Structure
- Codebase Deep Dive
- Setup and Usage
System Architecture
The multi agent system operates as a stateful graph where each node represents an agent or a human interaction point. The system is designed to iteratively process research tasks, ensuring quality at each step through review cycles and maintaining context via a dedicated note-taking agent.
Workflow Diagram
This diagram illustrates the flow of control and data between the different agents and human review stages.
graph TD
subgraph "Phase 1: Hypothesis Generation"
Start[START] --> Hypothesis;
Hypothesis --> HumanChoice{"Human Choice"};
HumanChoice -- "Regenerate" --> Hypothesis;
end
HumanChoice -- "Continue" --> Process;
subgraph "Phase 2: Iterative Research Cycle"
Process -- "Assign Task" --> Code;
Process -- "Assign Task" --> Search;
Process -- "Assign Task" --> Visualization;
Process -- "Assign Task" --> Report;
Code --> QualityReview;
Search --> QualityReview;
Visualization --> QualityReview;
Report --> QualityReview;
QualityReview -- "Rejection (to specific agent)" --> Code;
QualityReview -- "Rejection (to specific agent)" --> Search;
QualityReview -- "Rejection (to specific agent)" --> Visualization;
QualityReview -- "Rejection (to specific agent)" --> Report;
QualityReview -- "Approval" --> NoteTaker;
NoteTaker --> Process;
end
subgraph "Phase 3: Finalization"
Process -- "FINISH" --> Refiner;
Refiner --> HumanReview{"Human Review"};
HumanReview -- "Needs Revision" --> Process;
HumanReview -- "Approve & End" --> End[END];
end
%% Styling optimized for dark mode visibility
style Start fill:#4ade80,stroke:#e5e7eb,stroke-width:2px,color:#000000
style End fill:#f87171,stroke:#e5e7eb,stroke-width:2px,color:#000000
classDef humanNode fill:#a78bfa,stroke:#e5e7eb,stroke-width:2px,color:#ffffff
class HumanChoice,HumanReview humanNode
classDef specialAgent fill:#38bdf8,stroke:#e5e7eb,stroke-width:2px,color:#000000
class Hypothesis,Code,Search,Visualization,Report,QualityReview,Refiner specialAgent
classDef normalAgent fill:#facc15,stroke:#e5e7eb,stroke-width:2px,color:#000000
class Process,NoteTaker normalAgent
Architectural Concepts
- Workflow START/END Nodes: Represent the entry and exit points of the entire process.
- Human Nodes: Points where the system pauses for human input and validation (
HumanChoice,HumanReview). This ensures control over the research direction and final approval. - Special Agents: Agents designed to perform specific, isolated tasks like coding, searching, or generating visualizations.
- Normal Agents: Core agents that manage the workflow.
-
Process: The supervisor or project manager. It analyzes the overall state and delegates tasks to the appropriate special agents. -
NoteTaker: The state historian. It observes the outputs of other agents, summarizes the progress, and maintains a coherent, structured representation of the entire research state. This prevents context loss in long-running tasks.
-
- Edges: The connections between nodes.
- Definite Edge: A direct, unconditional path (e.g., after
Hypothesisgeneration, the system always proceeds toHumanChoice). - Conditional Edge: A branching path where the next step is determined by the output of the current node (e.g.,
QualityReviewcan either approve and move toNoteTakeror reject and loop back to a special agent).
- Definite Edge: A direct, unconditional path (e.g., after
Core Concepts
Multi-Agent Collaboration
The system is built on the principle of "divide and conquer." Instead of a single monolithic AI, it uses a team of specialized agents. Each agent has a distinct role, a specific set of tools, and a unique prompt defining its expertise. This modular design makes the system more robust, easier to debug, and allows for the use of different LLMs optimized for different tasks (e.g., a powerful model for coding, a JSON-enforced model for state management).
State-Driven Workflow
The entire research process is managed as a state machine using LangGraph. A central State object is passed between nodes, and each agent's execution updates this state.
The State object (defined in core/state.py) contains fields that track every aspect of the research:
-
messages: The history of conversation and agent outputs. -
hypothesis: The current research hypothesis. -
process_decision: The next action decided by theProcessagent. -
visualization_state,searcher_state,code_state,report_section: Content generated by the respective agents. -
quality_review: Feedback from theQualityReviewagent. -
needs_revision: A boolean flag that controls the revision loop.
The NoteTaker agent plays a critical role by reading the entire state and generating a clean, summarized JSON representation of it, ensuring consistency as the workflow progresses.
Human-in-the-Loop
The tool is a human-AI collaboration tool, not a fully autonomous system. There are two key points for human intervention:
- Hypothesis Review (
HumanChoice): After the initial hypothesis is generated, a human must approve it or request modifications before the main analysis begins. - Final Review (
HumanReview): Once theProcessagent determines the research is complete, it passes the final report to a human for review. The human can either approve and end the process or send it back for further revisions.
Key Features
Rate Limit Resilience
The system includes sophisticated rate limit handling to ensure continuous operation even with API restrictions:
- Exponential Backoff: Automatic retry with increasing wait times
- Model Fallback: Automatically switches to
gpt-4o-miniwhengpt-4ohits rate limits - Request Tracking: Monitors usage per model to proactively switch to fallback models
- Jitter: Adds randomization to retry timing to avoid thundering herd effects
Workflow Persistence
Built-in checkpointing ensures no work is lost during interruptions:
- SQLite Checkpointing: Persistent storage of workflow state across sessions
- Thread Management: Support for multiple concurrent research workflows
- Resume Capability: Restart from any checkpoint after interruptions or errors
- State Recovery: Full state restoration including agent outputs and decisions
Quality Control
Rigorous quality assurance throughout the research process:
- Structured Review Process: Quality review agent with standardized APPROVE/REJECT responses
- Idempotency Protection: Prevents duplicate task execution
- Output Validation: Ensures agent outputs meet quality standards before proceeding
- Revision Loops: Automatic routing back to specific agents for improvements
Enhanced Logging
Comprehensive logging and observability for debugging and monitoring:
- Structured Logging: Separate log files for different severity levels
- Workflow Tracking: Detailed logs of agent transitions and state changes
- Error Context: Full stack traces with contextual information
- Rate Limit Monitoring: Tracking of API usage and fallback events
- Colored Console Output: Easy-to-read console logs with color coding
Directory Structure
.
├── agent/ # Definitions for all specialized agents
│ ├── code_agent.py
│ ├── hypothesis_agent.py
│ ├── note_agent.py
│ ├── process_agent.py
│ ├── quality_review_agent.py
│ ├── refiner_agent.py
│ ├── report_agent.py
│ ├── search_agent.py
│ └── visualization_agent.py
├── core/ # Core logic for the workflow, state, and routing
│ ├── language_models.py
│ ├── node.py
│ ├── router.py
│ ├── state.py
│ └── workflow.py
├── tools/ # Tools available to the agents (file I/O, code execution, web search)
│ ├── basetool.py
│ ├── FileEdit.py
│ └── internet.py
├── vue-frontend/ # (Placeholder for Vue.js frontend)
├── .env.example # Template for environment variables
├── .gitignore
├── create_agent.py # Factory functions for creating agents
├── load_cfg.py # Loads environment variables from .env file
├── logger.py # Logging configuration
├── main.py # Main script for command-line execution
├── README.md
└── requirements.txt
Codebase Deep Dive
The System's Core (core/)
This directory contains the essential machinery that drives the multi-agent system.
-
workflow.py: The central orchestrator. TheWorkflowManagerclass initializes all agents and assembles theStateGraph. It defines all the nodes and edges shown in the architecture diagram, effectively building the application's logic flow. -
node.py: Defines the functions that are executed at each node in the graph.-
agent_node: A generic wrapper that invokes an agent with the current state and updates the state with the agent's output. -
note_agent_node: A special node for theNoteTakeragent. It processes the agent's JSON output to update the entire state object, ensuring consistency. -
human_choice_node/human_review_node: Functions that pause the graph and prompt for user input from the console. -
refiner_node: A node that gathers all generated artifacts (markdown files, images) and passes them to theRefineragent for final polishing.
-
-
router.py: Contains the logic for conditional branching in the graph. These functions inspect the current state and decide which node to visit next.-
hypothesis_router: Directs the flow afterHumanChoice—either back toHypothesisor forward toProcess. -
process_router: The main router that interprets theProcessagent's decision (e.g., 'Coder', 'Search', 'FINISH') and routes to the corresponding node. -
QualityReview_router: Routes based on theQualityReviewagent's output, either toNoteTaker(approval) or back to the original agent (rejection).
-
-
state.py: Defines the data structure for the shared state (StateTypedDict) that circulates through the graph. This is the single source of truth for the research project at any given time. -
language_models.py: TheLanguageModelManagercentralizes the configuration and initialization of the differentChatOpenAImodels used throughout the system (e.g.,gpt-4ofor complex tasks,gpt-4o-minifor simpler ones, and a JSON-mode model for theNoteTaker).
The Agent Workforce (agent/)
Each file in this directory defines a specialized agent by providing a system prompt and a set of tools.
| Agent | Responsibilities | Key Tools |
|---|---|---|
hypothesis_agent.py |
Generates an initial research hypothesis based on the user's prompt and initial data. | collect_data, google_search, wikipedia |
process_agent.py |
Supervisor. Oversees the entire research cycle, assigns tasks to other agents, and decides when to finish. | (None - It's a routing agent) |
code_agent.py |
Writes, debugs, and executes Python code for data processing and analysis. | execute_code, read_document |
visualization_agent.py |
Generates Python code to create data visualizations (e.g., charts, plots) and saves them as files. | execute_code, read_document |
search_agent.py |
Conducts literature reviews and web searches to gather supporting information and references. | google_search, scrape_webpages, arxiv |
report_agent.py |
Drafts and structures the final research report, integrating text, findings, and visualizations. | create_document, read_document, edit_document |
quality_review_agent.py |
Reviews the outputs of other agents for accuracy, clarity, and adherence to standards. | read_document, edit_document |
note_agent.py |
State Manager. Observes the workflow, summarizes progress, and outputs the entire state as a clean JSON. | read_document |
refiner_agent.py |
Polishes the final compiled report, improving readability, flow, and coherence before final human review. | read_document, edit_document, web tools |
The Agent Factory (create_agent.py)
This module provides helper functions to standardize agent creation.
-
create_agent: A generic function that builds a standard agent. It combines a system prompt, a list of tools, and placeholders for the shared state into a prompt template compatible with LangChain'screate_openai_functions_agent. -
create_supervisor: A specialized function for creating theProcessagent. It configures the LLM with aroutefunction definition, compelling it to output its decision in a structured format that theprocess_routercan parse. -
create_note_agent: A specialized function for theNoteTakeragent. It injects Pydantic-based JSON formatting instructions into the prompt to ensure the agent's output is always a validNoteStateobject.
The Agent's Toolkit (tools/)
This directory contains the functions that agents can invoke to interact with the outside world.
-
basetool.py:-
execute_code: Executes Python code in a sandboxed Conda environment. -
execute_command: Executes shell commands in the same environment, primarily used for installing dependencies.
-
-
FileEdit.py:- Provides a suite of tools for file system operations within the
WORKING_DIRECTORY:collect_data(from CSV),create_document,read_document,write_document, andedit_document.
- Provides a suite of tools for file system operations within the
-
internet.py:- Provides tools for web access:
google_search,scrape_webpages(usingWebBaseLoader), andFireCrawl_scrape_webpages. It includes a fallback mechanism to ensure robustness.
- Provides tools for web access:
Entrypoints & Configuration
-
main.py: The primary script for running the application. It initializes theMultiAgentSystemclass and starts the workflow stream. -
load_cfg.py&.env.example: Manage the loading of secrets and configuration from a.envfile.
Setup and Usage
Prerequisites
- Python 3.10+
- Conda package manager
Installation
Clone the repository:
Create and activate a Conda environment:
conda create -n hack_env python=3.10 conda activate hack_envInstall dependencies:
pip install -r requirements.txt
Configuration
Create
.envfile: Create a.envfile in the project root with your configuration:# Copy the example file (if it exists) cp .env.example .env # Or create a new one touch .envFill in the required environment variables: Open the
.envfile and provide the following values:# REQUIRED: Your data storage path WORKING_DIRECTORY=./data_storage/ # REQUIRED: Anaconda installation path # Windows: C:\Users\YourUsername\anaconda3 or C:\Users\YourUsername\miniconda3 # macOS/Linux: /home/yourusername/anaconda3 or /opt/anaconda3 CONDA_PATH=/path/to/your/anaconda3 # REQUIRED: Conda environment name (must match the one you created) CONDA_ENV=hack_env # REQUIRED: OpenAI API key (get from https://platform.openai.com/account/api-keys) OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # OPTIONAL: ChromeDriver executable path (for web search functionality) # Download from https://chromedriver.chromium.org/ # Windows: ./chromedriver/chromedriver.exe # macOS/Linux: ./chromedriver/chromedriver CHROMEDRIVER_PATH=./chromedriver/chromedriver # OPTIONAL: Firecrawl API key (for enhanced web scraping) FIRECRAWL_API_KEY=fc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # OPTIONAL: LangChain API key (for LangSmith tracing and debugging) LANGCHAIN_API_KEY=ls__xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # OPTIONAL: User agent for web requests USER_AGENT=AI-Research-System/1.0Verify your configuration: The system will validate your configuration on startup and provide helpful error messages if anything is missing.
Running the System
Place your data: Put your data file (e.g.,
MyData.csv) inside thedata_storagedirectory specified in your.envfile.Choose an execution method:
A) Using the Python Script (Recommended for runs)
Modify the
user_inputvariable in themain()function ofmain.py:# in main.py def main(): system = MultiAgentSystem() user_input = ''' datapath:MyData.csv Please analyze this data to find sales trends and create a report with visualizations. ''' system.run(user_input)Then, run the script from your terminal:
python main.py
Built With
- langchain
- langgraph
- python
Log in or sign up for Devpost to join the conversation.