Spatial Omics Copilot

A chatbot that lets researchers ask spatial transcriptomics data questions in plain English. I own its agent layer.

Year
2026
Role
Agent layer owner, second largest contributor
Team
Research team of six engineers
Stack
Python, LangGraph, LangChain, DeepInfra, Enrichr, NCBI Gene, PubMed
Link
Repository on GitHub

How it works

Which pathways are enriched in this region?

Calls used 2 of 5

  • Pathway enrichmentfound
  • NCBI Genenot routed
  • PubMedfound
FoundFound nothingFailedRules pick the tools, five calls at most, and an empty result stays empty.

The system

How the copilot picks its evidence A rule-based router turns the question into a queue of evidence tools (NCBI Gene, Enrichr pathways, PubMed) or an image-only branch; a LangGraph loop runs one tool at a time up to five calls, records each result as found, empty or failed, names every gap, and the DeepInfra answer reports an empty result instead of inventing one. yes record, next tool no: queue empty or 5 calls image question empty or error named gaps _should_continue Question genes, ROI crop Rule-based router route · plan_tools() picks tools by intent Tools queued and calls < 5? Run one tool run_tool NCBI Gene Enrichr pathways PubMed, re-ranked Structured outcome ToolOutcome.status Found rows ok Ran, found nothing empty Tool unavailable error Attach ROI crop no tool lookup vision models only Assemble evidence synthesize evidence plus gaps Name the gap _evidence_gaps() empty is not failed Answer with DeepInfra call_deepinfra_chat reports an empty result, never invents one Legend Step Decision Optional branch Found-nothing path LangGraph state graph: route, run_tool, synthesize

Why location matters

Spatial transcriptomics reads which genes are switched on directly on an intact slice of tissue, so every measurement keeps its place on the tissue photo. Visium does it with about 5,000 dots per slide; Visium HD covers the slide edge to edge with squares smaller than a cell.

The result lands in an h5ad file: a table of every spot by every gene, plus the x and y of each spot and the tissue images. That is what the Copilot reads.

The job

A researcher draws a region on the slide and the app ranks its marker genes. On this breast cancer sample, a rectangle over a tumour region covers 328 spots, led by LIPF, FGFR4, CLCA2 and ABCA12.

Then they want to know what those genes mean. That used to mean switching between the viewer, pathway tools, gene databases and the literature. The Copilot puts them behind one question box next to the slide.

Ask, routed

Asked "What does LIPF do?", the router reads it as a gene function question and calls NCBI Gene only: no pathway lookup, no literature search, nothing spent that the question did not need. The workflow card beside every answer shows each step and how it ended.

These screens are the real app running locally on Ollama, answers unedited.

A router written by hand

The router picks which evidence tools a question needs: pathway enrichment, NCBI Gene annotation, PubMed. I made it rule based on purpose. Every tool does live network calls, the agent is capped at five calls per turn, and a misread instruction should not be able to spend that budget.

Rules are also the only way to assert routing decisions in tests without a live model.

Tools that fail honestly

Each tool returns a structured outcome that separates "the call failed" from "the call worked and found nothing". Asked which KEGG pathways LIPF belongs to, Enrichr came back empty and the answer says exactly that: no supported pathways in this region, instead of a plausible list.

I also built the multimodal payloads, the DeepInfra client, semantic re-ranking of abstracts, and the agent test suite, then fixed 10 findings from an adversarial review.

The bug worth keeping

An early router matched terms as prefixes, so "color" matched "colorectal". Questions about the project's own demo tissue went down the image branch and ran no evidence tools at all. Inflections are now listed one by one. More typing, far fewer surprises.

Next, Hilton College TMS →