Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

41 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Medea

uv agentlite openrouter

bioRxiv Website HuggingFace figshare


Medea, an AI agent for therapeutic reasoning across biological contexts. Built on the AgentLite framework, Medea addresses a fundamental challenge in biomedical research: how to effectively integrate diverse data modalities, computational resources, and scientific knowledge to identify therapeutic targets and predict drug responses.

Medea consists of four specialized modules that collaborate with each other:

  1. ResearchPlanning module - Formulates experimental plans, verifies biological context (diseases, cell types, genes), and audits plan integrity/feasibility
  2. Analysis module - Executes biological tools and generated code across single-cell, cell-line, and patient-level data, with pre-run checks and post-run verification
  3. LiteratureReasoning module - Retrieves, filters, and synthesizes scientific papers with LLM-based relevance and evidence-strength assessment
  4. MultiRoundDiscussion module β€” A multi-LLM deliberation panel that reconciles evidence across the other modules and abstains when support is insufficient

Medea System Overview
Overview of Medea

🧬 S. cerevisiae E-MAP Synthetic Lethality Benchmark

We release a previously unpublished high-density Epistatic MiniArray Profile (E-MAP) screen that systematically maps genetic interactions in S. cerevisiae β€” a major new contribution accompanying Medea. Each 6,144-colony plate profiles a query gene against the full yeast single-deletion library, yielding a 5,806 Γ— 41 matrix across 41 query genes. Comparing the fitness of double-mutant strains against the expected fitness of single mutants reveals functional relationships, where strongly negative scores indicate synthetic lethality. By screening with and without DNA-damaging treatments, the benchmark distinguishes constitutive functional relationships from those that emerge specifically under DNA damage stress.

Benchmark detail (labeled gene pairs per condition):

Condition Synthetic lethal (SL) Non-synthetic lethal Total
Bleomycin (BLEO) β€” DNA-damaging 86 172 258
Dimethyl sulfate (DMS) 114 228 342

What's included. Each labeled gene pair is provided as a row with the genetic-interaction score (pi), false discovery rate (fdr), Z-score (z), standard deviation (sd), a binary label (SL / non_SL), the experimental condition, and negative-sampling metadata.

array_gene, query_gene, pi, fdr, z, sd, label, condition, neg_sample_type, related_sl_pair

Run Medea on the yeast benchmark:

# Bleomycin (DNA-damaging) condition
python main.py --task sl --sl-source yeast --condition BLEO --sample-seed 42

# Dimethyl sulfate condition
python main.py --task sl --sl-source yeast --condition DMS --sample-seed 42

πŸ”— Download the dataset: Yeast E-MAP Screen on figshare

πŸ“„ Benchmark construction details: docs/yeast_sl_benchmark.md

πŸ“‹ Table of Contents

Installation

Quick Install

# Clone the repository
git clone https://github.com/mims-harvard/Medea.git
cd Medea

# Create virtual environment with uv (recommended)
pip install uv
uv venv medea --python 3.10
source medea/bin/activate  # On Windows: medea\Scripts\activate

# Install Medea
uv pip install -e .
uv pip install openai==1.82.1  # Ensure correct OpenAI version

Download MedeaDB

Download required datasets from Hugging Face:

uv pip install -U huggingface_hub
huggingface-cli login  # Enter your token
brew install git-lfs  # macOS, or: sudo apt-get install git-lfs (Linux)
git lfs install
git clone https://huggingface.co/datasets/mims-harvard/MedeaDB

# OPTIONAL: For machine learning tools (COMPASS, etc.)
# Clone and configure the tool in the Medea directory
git clone https://github.com/mims-harvard/COMPASS.git MedeaDB/compass/COMPASS

πŸ“š Detailed guide: See docs/QUICKSTART.md

Configuration

Create a .env file in the project root:

cp env_template.txt .env

Required Settings

# Database path
MEDEADB_PATH=/path/to/MedeaDB

# Model configuration
BACKBONE_LLM=gpt-4o
SEED=42

# API Key (recommended: OpenRouter for access to 100+ models)
OPENROUTER_API_KEY=your-key-here
USE_OPENROUTER=true

Alternative API Configurations

Azure OpenAI:

AZURE_OPENAI_API_KEY=your-key
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_API_VERSION=2024-10-21
USE_OPENROUTER=false

Google Gemini:

GEMINI_API_KEY=your-key
GEMINI_MODEL=gemini-2.0-flash-exp

Anthropic Claude:

ANTHROPIC_API_KEY=your-key
ANTHROPIC_MODEL=claude-3-7-sonnet-20250219

NVIDIA DeepSeek:

NVIDIA_DEEPSEEK_ENDPOINT=https://your-endpoint.com/v1
NVIDIA_DEEPSEEK_API_KEY=your-key

πŸ“‹ Full configuration reference: See env_template.txt

Using Medea as a Library

Once installed, you can use Medea in your own Python scripts. Here are three simple ways to get started:

πŸš€ Option 1: Full Medea Agent (Recommended)

Run the complete Medea agent with all four modules β€” ResearchPlanning, Analysis, LiteratureReasoning, and the MultiRoundDiscussion panel:

import os
from medea import medea, AgentLLM, LLMConfig
from medea import ResearchPlanning, Analysis, LiteratureReasoning
from medea import (
    ResearchPlanDraft, ContextVerification, IntegrityVerification,
    CodeGenerator, AnalysisExecution, CodeDebug, AnalysisQualityChecker,
    LiteratureSearch, PaperJudge, OpenScholarReasoning
)

# Step 1: Initialize LLMs
backbone_llm = "gpt-4o"
llm_config = LLMConfig({"temperature": 0.4})
research_llm = AgentLLM(llm_config, llm_name=backbone_llm)
analysis_llm = AgentLLM(llm_config, llm_name=backbone_llm)
literature_llm = AgentLLM(llm_config, llm_name=backbone_llm)

# Step 2: Configure module specific actions
research_actions = [
    ResearchPlanDraft(tmp=0.4, llm_provider=backbone_llm),
    ContextVerification(tmp=0.4, llm_provider=backbone_llm),
    IntegrityVerification(tmp=0.4, llm_provider=backbone_llm, max_iter=2)
]

analysis_actions = [
    CodeGenerator(tmp=0.4, llm_provider=backbone_llm),
    AnalysisExecution(),
    CodeDebug(tmp=0.4, llm_provider=backbone_llm),
    AnalysisQualityChecker(tmp=0.4, llm_provider=backbone_llm, max_iter=2)
]

literature_actions = [
    LiteratureSearch(model_name=backbone_llm, verbose=True),
    PaperJudge(model_name=backbone_llm, verbose=True),
    OpenScholarReasoning(tmp=0.4, llm_provider=backbone_llm, verbose=True)
]

# Step 3: Create module
research_planning_module = ResearchPlanning(llm=research_llm, actions=research_actions)
analysis_module = Analysis(llm=analysis_llm, actions=analysis_actions)
literature_module = LiteratureReasoning(llm=literature_llm, actions=literature_actions)

# Step 4: Run Medea
result = medea(
    user_instruction="Which gene is the best therapeutic target for RA in CD4+ T cells?",
    experiment_instruction=None,  # Optional: additional experiment context
    research_planning_module=research_planning_module,
    analysis_module=analysis_module,
    literature_module=literature_module,
    debate_rounds=2,  # Number of panel discussion rounds
    timeout=800  # Timeout in seconds per process
)

# Step 5: Get your answer
print(result['final'])  # Medea (full agent) output
print(result['P'])     # Research plan from ResearchPlanning module
print(result['PA'])    # ResearchPlanning + Analysis module output
print(result['R'])     # LiteratureReasoning output

πŸ”¬ Option 2: Research Planning + In-Silico Experiment Only

Run computational experiments without literature search:

from medea import experiment_analysis, AgentLLM, LLMConfig
from medea import ResearchPlanning, Analysis
from medea import (
    ResearchPlanDraft, ContextVerification, IntegrityVerification,
    CodeGenerator, AnalysisExecution, CodeDebug, AnalysisQualityChecker
)

# Step 1: Initialize LLMs
backbone_llm = "gpt-4o"
llm_config = LLMConfig({"temperature": 0.4})
research_llm = AgentLLM(llm_config, llm_name=backbone_llm)
analysis_llm = AgentLLM(llm_config, llm_name=backbone_llm)

# Step 2: Configure actions
research_actions = [
    ResearchPlanDraft(tmp=0.4, llm_provider=backbone_llm),
    ContextVerification(tmp=0.4, llm_provider=backbone_llm),
    IntegrityVerification(tmp=0.4, llm_provider=backbone_llm, max_iter=2)
]

analysis_actions = [
    CodeGenerator(tmp=0.4, llm_provider=backbone_llm),
    AnalysisExecution(),
    CodeDebug(tmp=0.4, llm_provider=backbone_llm),
    AnalysisQualityChecker(tmp=0.4, llm_provider=backbone_llm, max_iter=2)
]

# Step 3: Create modules
research_planning_module = ResearchPlanning(llm=research_llm, actions=research_actions)
analysis_module = Analysis(llm=analysis_llm, actions=analysis_actions)

# Step 4: Run experiment
plan, result = experiment_analysis(
    query="Identify therapeutic targets for rheumatoid arthritis in CD4+ T cells",
    research_planning_module=research_planning_module,
    analysis_module=analysis_module
)

print(f"Research Plan:\n{plan}\n")
print(f"Experiment Result:\n{result}")

πŸ“š Option 3: Literature Reasoning Only

Search papers and synthesize insights without computational experiments:

from medea import literature_reasoning, AgentLLM, LLMConfig
from medea import LiteratureReasoning
from medea import LiteratureSearch, PaperJudge, OpenScholarReasoning

# Step 1: Initialize LLM
backbone_llm = "gpt-4o"
llm_config = LLMConfig({"temperature": 0.4})
literature_llm = AgentLLM(llm_config, llm_name=backbone_llm)

# Step 2: Configure actions
literature_actions = [
    LiteratureSearch(model_name=backbone_llm, verbose=True),
    PaperJudge(model_name=backbone_llm, verbose=True),
    OpenScholarReasoning(tmp=0.4, llm_provider=backbone_llm, verbose=True)
]

# Step 3: Create modules
literature_module = LiteratureReasoning(llm=literature_llm, actions=literature_actions)

# Step 4: Search and reason
result = literature_reasoning(
    query="What are validated therapeutic targets for rheumatoid arthritis?",
    literature_module=literature_module
)

print(result)

πŸ“– More Examples

See the examples/ directory for detailed examples including:

  • Custom temperature settings for different modules
  • Using different LLMs for different tasks
  • Advanced module configuration
  • Panel discussion customization

πŸ”§ Using Medea Tools with ToolUniverse

Medea's tools are compatible with ToolUniverse framework. This allows you to use Medea's specialized tools in agent systems and tool management frameworks.

Use Medea tools with ToolUniverse:

from tooluniverse.tool_registry import get_tool_registry
from medea.tool_space import tooluniverse_tools

# Register Medea tools (13 tools available)
all_tools = get_tool_registry()
medea_tools = tooluniverse_tools.list_medea_tools()
print(f"Available Medea tools: {medea_tools}")

# Use a tool
tool_class = all_tools['load_disease_targets']
tool = tool_class({})

result = tool.run({
    'disease_name': 'rheumatoid arthritis',
    'use_api': True,
    'attributes': ['otGeneticsPortal', 'chembl']
})

print(f"Found {result['count']} therapeutic targets")

Detailed guide: See examples/tooluniverse_integration.py

Command-Line Interface (CLI) Usage

Medea provides a comprehensive command-line interface for running different evaluation tasks and configurations. The CLI allows you to easily configure all aspects of the system without modifying code.

Quick Start for Benchmark Evaluation

# Run with defaults (Medea evaluation on targetID task on rheumatoid arthritis)
python main.py

# View all options
python main.py --help

Task-Specific Evaluation

TargetID Task
# Default TargetID (disease: ra, scfm: PINNACLE)
python main.py --task targetID

# Custom disease
python main.py --task targetID --disease t1dm

# Different single-cell model
python main.py --task targetID --scfm TranscriptFormer --disease ss

# Combined
python main.py --task targetID --disease blastoma --scfm PINNACLE --sample-seed 44

TargetID evaluation files are loaded from:

evaluation/
  targetID/
    source/targetid-<disease>-<seed>.csv
    evaluation_samples/targetid-<disease>-query-<seed>.csv

The source CSVs include disease, celltype, candidate_genes, and y. The query CSVs add user_question and full_query prompts generated from those inputs. Disease-specific embeddings and processed single-cell resources are expected to come from MedeaDB and the selected single-cell foundation model configuration, such as PINNACLE or TranscriptFormer.

Synthetic Lethality Task
# Human cell line SL (source: samson)
python main.py --task sl --sl-source samson --cell-line CAL27

# Custom seed
python main.py --task sl --sl-source samson --cell-line CAL27 --sample-seed 44

# Yeast E-MAP SL (source: yeast) β€” see the E-MAP benchmark section above
python main.py --task sl --sl-source yeast --condition BLEO --sample-seed 42
Immune Therapy Response Task
# Default immune response
python main.py --task immune_response --patient-tpm-root /path/to/tpm/data

# Custom dataset
python main.py --task immune_response --immune-dataset IMVigor210 --patient-tpm-root /path/to/tpm/data

For a custom immune therapy cohort, place the task files under the evaluation folder using the dataset name passed to --immune-dataset:

evaluation/
  immune_response/
    source/<dataset-name>-patient.csv
    evaluation_samples/<dataset-name>-<prompt-setting>-query-<seed>.csv

The source CSV should follow the IMvigor210 patient-table style and include patient metadata columns such as Sample_id, response_label, cohort, cancer_type, ICI, ICI_target, and the patient identifier used to locate the transcriptomic TPM file. Query CSVs should include user_question and full_query; the bundled examples also include clinical context columns such as cancer_type, TMB (FMOne mutation burden per MB), Neoantigen burden per MB, Immune phenotype, and response_label.

--patient-tpm-root should point to the directory containing the per-patient TPM files referenced by the generated query text.

Agent Configuration

# Custom temperature (LLM temperature for all modules)
python main.py --temperature 0.7

# Custom quality iterations (3 max iteration for IntegrityVerification, 3 max iteration for AnalysisQualityChecker)
python main.py --quality-max-iter 3 --code-quality-max-iter 3

# Custom debate rounds
python main.py --debate-rounds 3

# Custom panelists
python main.py --panelists gemini-2.5-flash gpt-4o claude

Advanced Examples

# Complete custom configuration
python main.py \
  --setting gpt-4o \
  --task targetID \
  --disease ra \
  --scfm PINNACLE \
  --sample-seed 42 \
  --temperature 0.5 \
  --quality-max-iter 3 \
  --evaluation-folder ./custom_evaluation

# Resume from checkpoint (human cell line SL)
python main.py --task sl --sl-source samson --cell-line CAL27 --sample-seed 42 \
  --checkpoint "PARP6,NOTCH1,CAL27,non-sl"

# Multi-round discussion with custom panelists
python main.py \
  --task sl \
  --debate-rounds 3 \
  --panelists gemini-2.5-flash o3-mini-0131 gpt-4o claude

All Available Arguments

General Settings

Argument Type Default Description
--setting str medea Evaluation setting (medea, gpt-4o, o3-mini-0131, etc.)
--task str targetID Task type (targetID, sl, immune_response)
--sample-seed int 42 Dataset sampling seed
--evaluation-folder str ./evaluation Path to evaluation data folder
--checkpoint str None Checkpoint to resume from (comma-separated)

TargetID Task

Argument Type Default Description
--disease str ra Disease context (ra, t1dm, ss, blastoma [hepatoblastoma], fl)
--scfm str PINNACLE Single-cell foundation model (PINNACLE, TranscriptFormer)

Synthetic Lethality Task

Argument Type Default Description
--cell-line str MCF7 Cell line for samson source (MCF7, MCF10A, MDAMB231, CAL27, CAL33, A549, A427)
--sl-source str samson SL data source (samson, yeast)
--condition str BLEO Experimental condition for yeast SL data (BLEO, DMS); used only when --sl-source yeast

Immune Therapy Task

Argument Type Default Description
--immune-dataset str IMVigor210 Immune therapy dataset
--patient-tpm-root str None Path to patient TPM data

Agent Configuration

Argument Type Default Description
--temperature float 0.4 LLM temperature for all modules
--quality-max-iter int 2 Max iterations for proposal quality checks
--code-quality-max-iter int 2 Max iterations for code quality checks
--reasoning-mode str strict Literature reasoning mode (strict, decomposition)
--debate-rounds int 2 Number of panel discussion rounds
--panelists str[] [gemini-2.5-flash, o3-mini-0131, BACKBONE_LLM] LLM models for panel

Example Output

Each run displays your configuration. Example (running with defaults):

python main.py

Shows:

================================================================================
 MEDEA EVALUATION CONFIGURATION
================================================================================
Setting:           medea
Task:              targetID
Dataset Seed:      42
LLM Backbone Seed: 42
Temperature:       0.4
Evaluation Folder: ./evaluation
--------------------------------------------------------------------------------
Disease:           ra
SCFM:              PINNACLE
--------------------------------------------------------------------------------
LLM Backbone:      gpt-4o
LLM Paraphraser:   gpt-4o
LLM Judge:         gpt-4o
Quality Max Iter:  2
Debate Rounds:     2
Panelists:         ['gemini-2.5-flash', 'o3-mini-0131', 'gpt-4o']
================================================================================

Output changes based on your task and arguments.

Tips

  1. View help anytime:

    python main.py --help
  2. Task-specific args only needed for that task:

    # These are ignored when task != targetID
    python main.py --task sl --disease ra --scfm PINNACLE
  3. Environment variables still work:

    • BACKBONE_LLM, SEED, MEDEADB_PATH, etc. are still used
    • Command-line args override defaults but respect env vars where appropriate
  4. Checkpoint format (resume from where you left off):

    # For samson (human cell line) SL:
    --checkpoint "GENE1,GENE2,CELLLINE,INTERACTION"
    # Values must match the last completed row in the CSV log

Documentation

Cite

@article {Sui2026.01.16.696667,
	author = {Sui, Pengwei and Li, Michelle and Munson, Brenton P. and Gao, Shanghua and Shen, Wanxiang and Giunchiglia, Valentina and Shen, Andrew and Huang, Yepeng and Kong, Zhenglun and Licon, Katherine and Ideker, Trey and Zitnik, Marinka},
	title = {Medea: An AI agent for therapeutic reasoning across biological contexts},
	year = {2026},
	doi = {10.64898/2026.01.16.696667},
	URL = {https://www.biorxiv.org/content/early/2026/07/16/2026.01.16.696667},
	journal = {bioRxiv}
}