A biological reasoning agent developed for the MLGenX BioReasoning Challenge — Track B.
The challenge asks participants to predict how knocking out one gene affects the expression of another gene in LPS-stimulated mouse macrophages. For every perturbation–target pair, the system must estimate the probabilities of:
up: target gene upregulation;down: target gene downregulation;none: no statistically significant expression change.
This project combines GPT-OSS-120B, LangGraph, biological annotation retrieval, structured outputs, checkpointed batch inference, and submission validation.
Track B fixed the language model to openai/gpt-oss-120b while allowing participants to design their own prompts, tools, retrieval systems, and agent workflows.
The solution developed in this repository can:
- reason about gene perturbations in an inflammatory macrophage context;
- produce structured and validated probability estimates;
- retrieve mouse gene annotations;
- search for relevant patterns in the competition training data;
- track tool calls, reasoning steps, tokens, and execution errors;
- process the complete test set with concurrent and resumable inference;
- automatically generate and validate the final submission package.
Official resources:
Each record contains:
pert: gene disrupted through CRISPR knockout;gene: target gene whose response must be predicted;label:up,down, ornonein the training set.
The experiments were performed in mouse bone marrow-derived macrophages stimulated with lipopolysaccharide. Gene expression was measured nine hours after stimulation.
| Split | Rows | Perturbations | Target genes |
|---|---|---|---|
| Train | 7,705 | 386 | 1,570 |
| Test | 1,813 | 96 | 636 |
The test set represents a strong double cold-start problem: test perturbations and targets do not appear in the same roles in the training set. The system must therefore generalize through biological knowledge rather than simple pair memorization.
Competition data is not included in this repository.
The model predicts two components:
P(DE)
P(up | DE)
These are converted into the final class probabilities:
prediction_up = P(DE) × P(up | DE)
prediction_down = P(DE) × (1 − P(up | DE))
prediction_none = 1 − P(DE)
This decomposition separates two questions:
- Is the target likely to be differentially expressed?
- If it changes, is it more likely to increase or decrease?
The complete agent was built with LangGraph and supports two tools:
Retrieves mouse gene annotations from MyGene.info, including gene names, functional summaries, Gene Ontology processes, pathways, aliases, and ortholog information.
Retrieves related observations and structural priors from the competition training data.
The main workflow is:
prepare_case
↓
reasoner
↓
optional tools
↓
reasoner
↓
validate and finalize prediction
The repository also includes a simpler single-call baseline without tools.
Because of API rate limits close to the competition deadline, most final test predictions were generated with the single-call configuration. The complete tool-enabled architecture remains available for experimentation and future improvement.
mlgenx-bioreasoning-agent/
├── docs/ # Architecture notes
├── notebooks/
│ ├── 01_eda.ipynb
│ ├── 02_agent_baseline.ipynb
│ └── 03_tool_agent.ipynb
├── prompts/ # Versioned system prompts
├── scripts/
│ └── run_track_b_submission.py
├── src/mlgenx_agent/
│ ├── agent/ # Graph, nodes, state and schemas
│ ├── evaluation/ # Metric and validation splits
│ ├── llm/ # OpenAI-compatible API client
│ ├── tools/ # Biological and training-data tools
│ └── config.py
├── tests/
├── .env.example
├── pyproject.toml
└── uv.lock
- Python 3.11
uv- access to an OpenAI-compatible API serving
openai/gpt-oss-120b - competition
train.csvandtest.csv
git clone https://github.com/<your-username>/mlgenx-bioreasoning-agent.git
cd mlgenx-bioreasoning-agent
uv sync --extra dev
cp .env.example .envAdd the API configuration to .env:
LLM_API_BASE=https://your-provider-api.com/openai
LLM_API_KEY=your_private_api_key
LLM_MODEL=openai/gpt-oss-120bPlace the competition files in:
data/raw/train.csv
data/raw/test.csv
Run the tests:
uv run pytestRun batch inference:
uv run python scripts/run_track_b_submission.py \
--workers 6 \
--case-attempts 1The runner saves each completed prediction to a JSONL checkpoint. Running the same command again skips completed IDs and resumes failed or pending rows.
Rebuild the submission without API calls:
uv run python scripts/run_track_b_submission.py --build-onlyGenerated files are stored under:
outputs/track_b/
- Python
- LangGraph
- GPT-OSS-120B
- OpenAI-compatible APIs
- Pydantic
- pandas and NumPy
- MyGene.info
- Jupyter
uv- Git and GitHub
The BioReasoning Challenge was organized for the MLGenX Workshop at ICLR 2026.
Organizers listed on the official challenge website:
Carl Edwards, Ehsan Hajiramezanali, Takamasa Kudo, Jack Kamm, Hugues Van Assel, Xiner Li, Edward De Brouwer, Jan-Christian Hütter, Gabriele Scalia, Romain Lopez, Sara Mostafavi, and Aviv Regev.
See the official challenge website for affiliations and complete organizer information.
Carl Edwards. MLGenX Bioreasoning Challenge — Track B. Kaggle, 2026. https://kaggle.com/competitions/ml-gen-x-bioreasoning-challenge-track-b
This repository is an independent participant solution and is not an official implementation from Genentech or the competition organizers.
The source code is released under the MIT License.
Competition data is subject to the Kaggle competition rules and is not redistributed in this repository.