Generated banner for Scvi Tools
Generated logo for Scvi Tools

Scvi Tools

AnthropicOfficialPublished by Anthropic

  • Skill
  • Tool integration
  • Data and AI
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Deep learning for single-cell analysis using scvi-tools. This skill should be used when users need (1) data integration and batch correction with scVI/scANVI, (2) ATAC-seq analysis with PeakVI, (3) CITE-seq multi-modal analysis with totalVI, (4) multiome RNA+ATAC analysis with MultiVI, (5) spatial transcriptomics deconvolution with DestVI, (6) label transfer and reference mapping with scANVI/scArches, (7) RNA velocity with veloVI, or (8) any deep learning-based single-cell method. Triggers include mentions of scVI, scANVI, totalVI, PeakVI, MultiVI, DestVI, veloVI, sysVI, scArches, variational autoencoder, VAE, batch correction, data integration, multi-modal, CITE-seq, multiome, reference mapping, latent space.
— the description by Anthropic

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

scvi-tools provides a suite of probabilistic models designed for the analysis of single-cell data, including scRNA-seq, scATAC-seq, and multi-modal datasets. It leverages variational autoencoders to handle batch correction, data integration, label transfer, and dimensionality reduction. This skill serves as a guide for utilizing specific models like scVI, scANVI, totalVI, PeakVI, MultiVI, DestVI, and veloVI, offering standardized workflows, CLI scripts for pipeline automation, and best practices for data preparation and model training.

What it does

  • Performs batch correction and data integration across different experimental conditions.
  • Supports multi-modal analysis for CITE-seq and multiome (RNA+ATAC) data.
  • Enables label transfer and reference mapping between query and reference datasets.
  • Facilitates spatial transcriptomics deconvolution and RNA velocity estimation.
  • Provides modular Python scripts for common analysis pipelines.
  • Offers guidance on model selection based on specific data types and research goals.

When to use it

  • When integrating multiple single-cell datasets with significant batch effects.
  • When analyzing multi-modal data such as CITE-seq or joint RNA+ATAC profiles.
  • When performing reference-based label transfer or query-to-reference mapping.
  • When conducting deep learning-based dimensionality reduction for clustering and visualization.
  • When working with spatial transcriptomics or RNA velocity data.

Advantages

  • Standardized approach to complex single-cell deep learning workflows.
  • Modular scripts allow for reproducible and scalable analysis pipelines.
  • Comprehensive model selection guide for diverse genomic data types.
  • Built-in support for advanced tasks like batch correction and multi-modal integration.
  • Clear documentation on data preparation requirements for probabilistic models.

Usage examples

“How do I integrate two scRNA-seq datasets using scVI?”
The agent provides the workflow for preparing the AnnData objects, selecting highly variable genes, setting up the model with batch keys, and training the scVI model.
“I have CITE-seq data, which model should I use?”
The agent identifies totalVI as the appropriate model and directs the user to the corresponding reference file for multi-modal integration.
“How can I map my new scRNA-seq query data to an existing reference?”
The agent explains the use of scArches for query-to-reference mapping and provides the necessary steps to configure the model.
“What are the requirements for input data before training a model?”
The agent outlines the necessity of raw integer count data, the importance of highly variable gene selection, and how to correctly set up the AnnData object.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/anthropics/scvi-tools/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip scvi-tools.zip -d .agents/skills

Documentation by Anthropic

scvi-tools Deep Learning Skill

This skill provides guidance for deep learning-based single-cell analysis using scvi-tools, the leading framework for probabilistic models in single-cell genomics.

How to Use This Skill

  1. Identify the appropriate workflow from the model/workflow tables below

  2. Read the corresponding reference file for detailed steps and code

  3. Use scripts in scripts/ to avoid rewriting common code

  4. For installation or GPU issues, consult references/environment_setup.md

  5. For debugging, consult references/troubleshooting.md

When to Use This Skill

  • When scvi-tools, scVI, scANVI, or related models are mentioned

  • When deep learning-based batch correction or integration is needed

  • When working with multi-modal data (CITE-seq, multiome)

  • When reference mapping or label transfer is required

  • When analyzing ATAC-seq or spatial transcriptomics data

  • When learning latent representations of single-cell data

Model Selection Guide

Data TypeModelPrimary Use Case
scRNA-seqscVIUnsupervised integration, DE, imputation
scRNA-seq + labelsscANVILabel transfer, semi-supervised integration
CITE-seq (RNA+protein)totalVIMulti-modal integration, protein denoising
scATAC-seqPeakVIChromatin accessibility analysis
Multiome (RNA+ATAC)MultiVIJoint modality analysis
Spatial + scRNA referenceDestVICell type deconvolution
RNA velocityveloVITranscriptional dynamics
Cross-technologysysVISystem-level batch correction

Workflow Reference Files

WorkflowReference FileDescription
Environment Setupreferences/environment_setup.mdInstallation, GPU, version info
Data Preparationreferences/data_preparation.mdFormatting data for any model
scRNA Integrationreferences/scrna_integration.mdscVI/scANVI batch correction
ATAC-seq Analysisreferences/atac_peakvi.mdPeakVI for accessibility
CITE-seq Analysisreferences/citeseq_totalvi.mdtotalVI for protein+RNA
Multiome Analysisreferences/multiome_multivi.mdMultiVI for RNA+ATAC
Spatial Deconvolutionreferences/spatial_deconvolution.mdDestVI spatial analysis
Label Transferreferences/label_transfer.mdscANVI reference mapping
scArches Mappingreferences/scarches_mapping.mdQuery-to-reference mapping
Batch Correctionreferences/batch_correction_sysvi.mdAdvanced batch methods
RNA Velocityreferences/rna_velocity_velovi.mdveloVI dynamics
Troubleshootingreferences/troubleshooting.mdCommon issues and solutions

CLI Scripts

Modular scripts for common workflows. Chain together or modify as needed.

Pipeline Scripts
ScriptPurposeUsage
prepare_data.pyQC, filter, HVG selectionpython scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch
train_model.pyTrain any scvi-tools modelpython scripts/train_model.py prepared.h5ad results/ --model scvi
cluster_embed.pyNeighbors, UMAP, Leidenpython scripts/cluster_embed.py adata.h5ad results/
differential_expression.pyDE analysispython scripts/differential_expression.py model/ adata.h5ad de.csv --groupby leiden
transfer_labels.pyLabel transfer with scANVIpython scripts/transfer_labels.py ref_model/ query.h5ad results/
integrate_datasets.pyMulti-dataset integrationpython scripts/integrate_datasets.py results/ data1.h5ad data2.h5ad
validate_adata.pyCheck data compatibilitypython scripts/validate_adata.py data.h5ad --batch-key batch
Example Workflow
# 1. Validate input data
python scripts/validate_adata.py raw.h5ad --batch-key batch --suggest

# 2. Prepare data (QC, HVG selection)
python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch --n-hvgs 2000

# 3. Train model
python scripts/train_model.py prepared.h5ad results/ --model scvi --batch-key batch

# 4. Cluster and visualize
python scripts/cluster_embed.py results/adata_trained.h5ad results/ --resolution 0.8

# 5. Differential expression
python scripts/differential_expression.py results/model results/adata_clustered.h5ad results/de.csv --groupby leiden
Python Utilities

The scripts/model_utils.py provides importable functions for custom workflows:

FunctionPurpose
prepare_adata()Data preparation (QC, HVG, layer setup)
train_scvi()Train scVI or scANVI
evaluate_integration()Compute integration metrics
get_marker_genes()Extract DE markers
save_results()Save model, data, plots
auto_select_model()Suggest best model
quick_clustering()Neighbors + UMAP + Leiden

Critical Requirements

  1. Raw counts required: scvi-tools models require integer count data

    adata.layers["counts"] = adata.X.copy()  # Before normalization
    scvi.model.SCVI.setup_anndata(adata, layer="counts")
  2. HVG selection: Use 2000-4000 highly variable genes

    sc.pp.highly_variable_genes(adata, n_top_genes=2000, batch_key="batch", layer="counts", flavor="seurat_v3")
    adata = adata[:, adata.var['highly_variable']].copy()
  3. Batch information: Specify batch_key for integration

    scvi.model.SCVI.setup_anndata(adata, layer="counts", batch_key="batch")

Quick Decision Tree

Need to integrate scRNA-seq data?
├── Have cell type labels? → scANVI (references/label_transfer.md)
└── No labels? → scVI (references/scrna_integration.md)

Have multi-modal data?
├── CITE-seq (RNA + protein)? → totalVI (references/citeseq_totalvi.md)
├── Multiome (RNA + ATAC)? → MultiVI (references/multiome_multivi.md)
└── scATAC-seq only? → PeakVI (references/atac_peakvi.md)

Have spatial data?
└── Need cell type deconvolution? → DestVI (references/spatial_deconvolution.md)

Have pre-trained reference model?
└── Map query to reference? → scArches (references/scarches_mapping.md)

Need RNA velocity?
└── veloVI (references/rna_velocity_velovi.md)

Strong cross-technology batch effects?
└── sysVI (references/batch_correction_sysvi.md)

Key Resources

Files

references/spatial_deconvolution.md

Spatial Transcriptomics Analysis

This reference covers spatial transcriptomics analysis using scvi-tools methods: DestVI for deconvolution and resolVI for building spatial models.

Overview

Spatial transcriptomics technologies like Visium capture gene expression at defined spatial locations, but many platforms have multi-cellular resolution. scvi-tools provides two main approaches:

  • DestVI: Deconvolution - estimates cell type proportions at each spot using a single-cell reference

  • resolVI: Builds a spatial model that learns gene expression patterns accounting for spatial context

Available Methods in scvi-tools

MethodDescriptionUse Case
DestVIVariational inference for deconvolutionEstimate cell type proportions per spot
resolVISpatial gene expression modelLearn spatially-aware representations
CondSCVIReference model for DestVIRequired for DestVI workflow

Prerequisites

import scvi
import scanpy as sc
import squidpy as sq
import numpy as np

print(f"scvi-tools version: {scvi.__version__}")

Part 1: DestVI Deconvolution

Step 1: Load Spatial Data
# Load Visium data
adata_spatial = sc.read_visium("spaceranger_output/")

# Check structure
print(f"Spots: {adata_spatial.n_obs}")
print(f"Genes: {adata_spatial.n_vars}")
print(f"Spatial coordinates: {adata_spatial.obsm['spatial'].shape}")

# Basic QC
sc.pp.calculate_qc_metrics(adata_spatial, inplace=True)
adata_spatial = adata_spatial[adata_spatial.obs['n_genes_by_counts'] > 200].copy()

# Store counts
adata_spatial.layers["counts"] = adata_spatial.X.copy()
Step 2: Load Single-Cell Reference
# Load reference single-cell data
adata_sc = sc.read_h5ad("reference_scrna.h5ad")

# Requirements:
# - Raw counts
# - Cell type annotations
print(f"Reference cells: {adata_sc.n_obs}")
print(f"Cell types: {adata_sc.obs['cell_type'].nunique()}")
print(adata_sc.obs['cell_type'].value_counts())

# Store counts
adata_sc.layers["counts"] = adata_sc.X.copy()
Step 3: Prepare Data
# DestVI requires gene overlap between reference and spatial
common_genes = adata_sc.var_names.intersection(adata_spatial.var_names)
print(f"Common genes: {len(common_genes)}")

adata_sc = adata_sc[:, common_genes].copy()
adata_spatial = adata_spatial[:, common_genes].copy()
Step 4: Train Reference Model (CondSCVI)
# Train conditional scVI on reference data
scvi.model.CondSCVI.setup_anndata(
    adata_sc,
    layer="counts",
    labels_key="cell_type"
)

sc_model = scvi.model.CondSCVI(
    adata_sc,
    n_latent=20
)

sc_model.train(max_epochs=200)
sc_model.history['elbo_train'].plot()
Step 5: Train DestVI
# Setup spatial data
scvi.model.DestVI.setup_anndata(
    adata_spatial,
    layer="counts"
)

# Train DestVI using reference model
spatial_model = scvi.model.DestVI.from_rna_model(
    adata_spatial,
    sc_model
)

spatial_model.train(max_epochs=500)
Step 6: Get Cell Type Proportions
# Infer cell type proportions at each spot
proportions = spatial_model.get_proportions()

# Add to adata
for ct in adata_sc.obs['cell_type'].unique():
    adata_spatial.obs[f'prop_{ct}'] = proportions[ct]

# Visualize
sq.pl.spatial_scatter(
    adata_spatial,
    color=[f'prop_{ct}' for ct in adata_sc.obs['cell_type'].unique()[:6]],
    ncols=3
)

Part 2: resolVI Spatial Model

resolVI is a semi-supervised method that learns cell type assignments and spatially-aware representations directly from spatial data, optionally using initial cell type predictions.

Note: resolVI is in scvi.external (not scvi.model).

Step 1: Prepare Spatial Data
# Load and preprocess
adata = sc.read_visium("spaceranger_output/")

# QC
sc.pp.calculate_qc_metrics(adata, inplace=True)
adata = adata[adata.obs['n_genes_by_counts'] > 200].copy()

# Store counts
adata.layers["counts"] = adata.X.copy()

# HVG selection
sc.pp.highly_variable_genes(
    adata,
    n_top_genes=4000,
    flavor="seurat_v3",
    layer="counts"
)
adata = adata[:, adata.var['highly_variable']].copy()

# Optional: Get initial cell type predictions (e.g., from a reference)
# adata.obs["predicted_celltype"] = ...
Step 2: Setup and Train resolVI
# Setup for resolVI (note: scvi.external, not scvi.model)
scvi.external.RESOLVI.setup_anndata(
    adata,
    labels_key="predicted_celltype",  # Initial cell type predictions
    layer="counts"
)

# Create model (semisupervised=True uses the labels)
model = scvi.external.RESOLVI(adata, semisupervised=True)

# Train
model.train(max_epochs=50)
Step 3: Get Cell Type Predictions
# Get refined cell type predictions
# soft=True returns probabilities, soft=False returns labels
cell_type_probs = model.predict(adata, num_samples=3, soft=True)
cell_type_labels = model.predict(adata, num_samples=3, soft=False)

adata.obs["resolvi_celltype"] = cell_type_labels

# Visualize
sq.pl.spatial_scatter(adata, color="resolvi_celltype")
Step 4: Get Latent Representation
# Get latent representation
adata.obsm["X_resolVI"] = model.get_latent_representation(adata)

# Cluster based on spatial representation
sc.pp.neighbors(adata, use_rep="X_resolVI")
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5)

# Visualize clusters spatially
sq.pl.spatial_scatter(adata, color="leiden")
Step 5: Differential Expression
# DE between cell types using resolVI
de_results = model.differential_expression(
    adata,
    groupby="resolvi_celltype",
    group1="T_cell",
    group2="Tumor"
)

print(de_results.head(20))
Step 6: Niche Abundance Analysis
# Analyze how cell type neighborhoods differ between conditions
# Requires spatial neighbor graph
sq.gr.spatial_neighbors(adata, coord_type="generic")

niche_results = model.differential_niche_abundance(
    groupby="resolvi_celltype",
    group1="T_cell",
    group2="Tumor",
    neighbor_key="spatial_neighbors"
)
Step 7: Query Mapping (Transfer to New Data)
# Map new spatial data to trained model
query_adata = sc.read_visium("new_sample/")
query_adata.layers["counts"] = query_adata.X.copy()

# Prepare and load query
model.prepare_query_anndata(query_adata, reference_model=model)
query_model = model.load_query_data(query_adata, reference_model=model)

# Fine-tune on query
query_model.train(max_epochs=20)

# Get predictions for query
query_labels = query_model.predict(query_adata, num_samples=3, soft=False)

Visualization

Spatial Proportions
import matplotlib.pyplot as plt

# Plot multiple cell type proportions
cell_types = ['T_cell', 'Tumor', 'Fibroblast', 'Macrophage']
fig, axes = plt.subplots(2, 2, figsize=(12, 12))

for ax, ct in zip(axes.flat, cell_types):
    sq.pl.spatial_scatter(
        adata_spatial,
        color=f'prop_{ct}',
        ax=ax,
        title=ct,
        show=False
    )

plt.tight_layout()
Enrichment by Region
# Cluster spatial data
sc.pp.neighbors(adata_spatial)
sc.tl.leiden(adata_spatial, resolution=0.5)

# Compare proportions across regions
import pandas as pd

cell_types = adata_sc.obs['cell_type'].unique()
prop_cols = [f'prop_{ct}' for ct in cell_types]
region_props = adata_spatial.obs.groupby('leiden')[prop_cols].mean()
print(region_props)

# Heatmap
import seaborn as sns
plt.figure(figsize=(10, 6))
sns.heatmap(region_props.T, annot=True, cmap='viridis')
plt.title('Cell Type Proportions by Region')
Spatial Cell Type Interactions
# Neighborhood enrichment using cell type assignments
sq.gr.spatial_neighbors(adata_spatial)

# Create "dominant cell type" annotation
prop_cols = [f'prop_{ct}' for ct in cell_types]
adata_spatial.obs['dominant_type'] = adata_spatial.obs[prop_cols].idxmax(axis=1)
adata_spatial.obs['dominant_type'] = adata_spatial.obs['dominant_type'].str.replace('prop_', '')

# Co-occurrence analysis
sq.gr.co_occurrence(adata_spatial, cluster_key='dominant_type')
sq.pl.co_occurrence(adata_spatial, cluster_key='dominant_type')

Complete DestVI Pipeline

def deconvolve_spatial(
    adata_spatial,
    adata_ref,
    cell_type_key="cell_type",
    n_latent=20,
    max_epochs_ref=200,
    max_epochs_spatial=500
):
    """
    Perform spatial deconvolution using DestVI.

    Parameters
    ----------
    adata_spatial : AnnData
        Spatial transcriptomics data
    adata_ref : AnnData
        Single-cell reference with cell type annotations
    cell_type_key : str
        Column in adata_ref.obs with cell type labels
    n_latent : int
        Latent dimensions
    max_epochs_ref : int
        Training epochs for reference model
    max_epochs_spatial : int
        Training epochs for spatial model

    Returns
    -------
    AnnData with cell type proportions in obs
    """
    import scvi

    # Get common genes
    common_genes = adata_ref.var_names.intersection(adata_spatial.var_names)
    adata_ref = adata_ref[:, common_genes].copy()
    adata_spatial = adata_spatial[:, common_genes].copy()

    # Ensure counts are stored
    if "counts" not in adata_ref.layers:
        adata_ref.layers["counts"] = adata_ref.X.copy()
    if "counts" not in adata_spatial.layers:
        adata_spatial.layers["counts"] = adata_spatial.X.copy()

    # Train reference model
    scvi.model.CondSCVI.setup_anndata(
        adata_ref,
        layer="counts",
        labels_key=cell_type_key
    )

    ref_model = scvi.model.CondSCVI(adata_ref, n_latent=n_latent)
    ref_model.train(max_epochs=max_epochs_ref)

    # Train spatial model
    scvi.model.DestVI.setup_anndata(adata_spatial, layer="counts")

    spatial_model = scvi.model.DestVI.from_rna_model(
        adata_spatial,
        ref_model
    )
    spatial_model.train(max_epochs=max_epochs_spatial)

    # Get proportions
    proportions = spatial_model.get_proportions()

    cell_types = adata_ref.obs[cell_type_key].unique()
    for ct in cell_types:
        adata_spatial.obs[f'prop_{ct}'] = proportions[ct]

    # Add dominant type
    prop_cols = [f'prop_{ct}' for ct in cell_types]
    adata_spatial.obs['dominant_type'] = adata_spatial.obs[prop_cols].idxmax(axis=1)
    adata_spatial.obs['dominant_type'] = adata_spatial.obs['dominant_type'].str.replace('prop_', '')

    return adata_spatial, ref_model, spatial_model

# Usage
adata_spatial, ref_model, spatial_model = deconvolve_spatial(
    adata_spatial,
    adata_sc,
    cell_type_key="cell_type"
)

# Visualize
sq.pl.spatial_scatter(
    adata_spatial,
    color=['dominant_type', 'prop_T_cell', 'prop_Tumor'],
    ncols=3
)

Troubleshooting

IssueCauseSolution
Few common genesDifferent gene namingConvert gene names (Ensembl ↔ Symbol)
Poor deconvolutionReference doesn't matchUse tissue-matched reference
All spots same typeOver-smoothingAdjust model parameters, check reference diversity
NaN proportionsMissing cell typesEnsure all expected types in reference
Training slowLarge spatial datasetReduce max_epochs, increase batch_size

Key References

Requirements and compatibility

Written for: Claude Code, Claude apps

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Python

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Anthropic
Publisher
Anthropic (Official)
Source
anthropics/knowledge-work-plugins · bio-research/skills/scvi-tools · commit e050c2e
Licence
Apache License 2.0 (redistribution allowed)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Anthropic or Anthropic.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download scvi-tools.zip