Category Archives: Antibodies

SAbDab2: The structural antibody database in the age of machine learning 

Henriette L. Capel, Odysseas Vavourakis, Benjamin H. Williams, Christopher R. Taylor, and Charlotte M. Deane

The Structural Antibody Database 

The Structural Antibody Database (SAbDab) [1] is a publicly available repository of experimentally determined antibody structures, first released in 2013. Explicit support for single-domain antibodies was added in 2021, with SAbDab-nano [2]. Detailed annotations and consistent maintenance have made SAbDab a central resource supporting important advances in the field. SAbDab has been used to study antibody-antigen interactions, including SARS-CoV-2; to predict antibody structure; to design antibodies de-novo; and to investigate antibody flexibility. 

Continue reading

Building an Agent – Practical Notes for Beginners

For the last few months, I’ve been building an agent around OPIG’s antibody analysis and design tools, and I thought I’d share some practical notes from the process.

An agent is a language model that doesn’t just answer questions but can also decide what to do, call tools, and follow workflows. I’m using Claude in these notes, but most of the ideas apply equally well to other agent frameworks.

Rather than building an agent from scratch, we’re starting with one that already comes with useful capabilities out of the box. For example, Claude Code can search files, edit code, execute commands, and run scripts. Everything below is really about adapting that behaviour to a specific domain and workflow.

How to start?

Start with the `CLAUDE.md` file. It’s a special file Claude reads at the start of every conversation, and it’s where you define the behaviour of the agent (other agents have their own equivalent — for example `AGENTS.md`). In this file, include things like bash commands, code style preferences, and workflow rules. This gives Claude a persistent context that it can’t infer from the codebase alone. Since it’s loaded every session, it sets the baseline for how the agent behaves.

Start simple – especially if it’s your first time. Define clear tools, write lightweight instructions in the markdown (md) file, and create realistic evaluations before adding complexity.

Then run a loop where the agent gathers context, takes actions, and verifies the outputs. Think about how you’ll verify them first: if you can’t tell whether a run was good, you can’t tell whether your changes helped.

In research, you don’t always know how a project will evolve, so you’ll often end up making many changes along the way. But for projects that are relatively well-defined, I’ve found it’s worth spending some time upfront with pen and paper, specifying what you want the agent to do before writing it all out.

From there, most development becomes an iterative process of improving the md files and adjusting tools when needed.

What is a tool?

A tool gives the agent a capability. It executes an action and returns a result — calling an API, running code, querying a database, and so on.

The key idea is that tools are deterministic: given the same input, they produce the same output. So if I ask, “Can you check whether this is an antibody?”, the agent will always reach for the same tool — `execute_run_anarci()` — and get the same result.

A tool can be an MCP server or simply a Python function; what matters is that it gives the agent a reliable way to perform a specific action. Both work.

For example, I implemented execute_anarci_number() as a Python function — a thin wrapper around ANARCI — and it returns a structured JSON output with the results and the execution status. All the tools follow the same general structure, which makes them easier for the agent to use consistently.

The signature and docstring are really all the agent needs to decide when to reach for it:

def execute_anarci_number(sequence: str, chain_name: str = "Chain") -> dict:
"""Identify and number an antibody/TCR sequence using ANARCI.

Returns chain type, species, numbering, and whether it's a valid antibody.
Chain types: H=Heavy, K=Kappa light, L=Lambda light, A=TCR-alpha, B=TCR-beta
"""


The function itself is simple: it runs ANARCI, parses the numbering, extracts the CDRs, and checks whether the input looks like a real, complete variable domain. Instead of returning a bare error when numbering fails, the tool returns a structured verdict the agent can reason about:

# numbering failed → the sequence just isn't an antibody (not a tool error)
return {
"success": True,
"chain_name": chain_name,
"is_antibody": False,
"is_tcr": False,
"chain_type": None,
"species": None,
"message": "ANARCI could not number this sequence. "
"It is likely not an antibody or TCR variable domain.",
"sequence_length": len(sequence),
}

One thing I found useful is having tools return an explicit verdict, not just output, so the agent knows whether it received an answer, encountered an error, or was given an invalid input.

A few things that helped:

  • Use the agent itself to help write the tools. It’s good at it, especially if you give Claude documentation for any software libraries, APIs, or SDKs you’re wrapping.
  • Don’t forget to document the tool in the markdown workflow file so the agent knows it exists and when to use it.
  • Open a fresh session and check the agent can actually call the tools correctly before building on top of them.

What is a skill?

Skills extend Claude with procedural knowledge. They teach the agent how to perform a task, not just what tools are available.

I think of tools as capabilities and skills as workflows. Tools let the agent do something; skills tell it how to approach a task. A tool might tell Claude how to number an antibody sequence. A skill tells it how to carry out an antibody analysis workflow: which tools to use, in what order, what outputs to expect, and how to interpret the results.

Without skills, the model has to rediscover that workflow from scratch each time. Skills package it once and make it reusable.

A skill is just a folder containing a SKILL.md file (instructions plus metadata) and optional scripts or reference material. One nice advantage is portability: because a skill is just a folder of markdown and scripts, you can write it once and reuse it across different projects, environments, and even different agent frameworks.

To make it concrete, here’s one of mine: ab-diversity-select. After an optimization run, I’m left with dozens of candidate antibodies and need to select a small, maximally diverse subset where the retained mutations remain structurally safe. Rather than re-explaining that workflow every time, I captured it as a skill:

ab-diversity-select/
├── SKILL.md # when to use it + the procedure
├── structural_pipeline.py
├── pipeline.py
└── config_template.py

The SKILL.md header tells Claude when the skill is relevant:


name: ab-diversity-select
description: >-
Select a structurally-validated, maximally-diverse subset of antibody candidates from a results CSV…

The rest of the file describes the procedure, while the accompanying scripts do the heavy lifting. When Claude encounters a task like “pick 20 diverse antibody candidates,” it can automatically apply my workflow instead of inventing a new selection strategy from scratch.

Practices that worked for me

There’s already a lot of useful information out there, for example:

anthropic.com/engineering

Claude Code best practices

A few things I’d highlight:

Keep the markdown files organized. `CLAUDE.md` is loaded every session, so only put things in it that apply broadly. For domain-specific knowledge or workflows that are only relevant sometimes, use skills instead. There’s no required format for `CLAUDE.md`; just keep it short and human-readable. Mine roughly covers: setup & environment, architecture & code map, and failure handling.

Use subagents to protect the context. Once the basic agent is working, most improvements come from managing context effectively. Subagents run in their own context with their own set of allowed tools. They’re useful for subtasks that require a lot of context. For example, summarizing a paper. In practice, though, I mostly used them for tools that generate large outputs, where it becomes difficult for a single agent to process everything cleanly within one context window.

I defined small operator agents that return only compact summaries. The main agent stays focused on planning and interpretation, large tool outputs stay outside its context, and cheaper, faster models handle parsing and batch work.

Prompts matter — a lot. Performance changes significantly depending on the prompt. From my experience, when building longer workflows, improving the prompt often helps more than editing the markdown files.

For example, explicitly defining the expected output format and level of detail can reduce lazy behaviour and make the agent more consistent across runs.

One approach I like is building a skill that interviews the user up front about the information you care about using the built-in `AskUserQuestion` tool, and then generates the prompt from the user’s answers in a structured way.

Use the agent to explain its own failures. The agent is actually pretty good at explaining where it failed and why. Use it to help debug and improve itself. Ask it what went wrong, have it suggest edits to the markdown files, or ask what it learned during the session. Some of my best improvements came from just asking the agent why a run failed.

A few bio-specific lessons

First, watch the jargon and define your terms. “Diverse” might mean sequence distance, V-gene spread, or structural diversity. Say exactly what you mean, or define it explicitly in your workflow files.

Second, the agent will always give you an answer, so make sure it is grounded in tools rather than invented. A language model can easily produce a confident, plausible-looking sequence or numbering out of thin air. If you do not explicitly tell the agent to use the available tools, it may continue without them, even when they exist.

Finally, keep a human in the loop. Read the logs yourself, understand what happened, and do not trust a clean-looking summary on its own. Ask the agent to explain each step and justify its decisions — that is often the fastest way to catch a wrong assumption before it ends up in your results.

Agents are surprisingly capable, but I still found it challenging to get them to reliably execute long workflows without intervention. In practice, I had the most success when treating the agent as a collaborator rather than a fully autonomous system, giving it clear tools, workflows, and checkpoints along the way.

Building agents is still a fast-moving area, and there are many ways to approach it. It can feel confusing at first, but once you start experimenting and building real projects, things become much clearer. My advice would be to start simple, build something useful, and learn by doing.

References:
1. https://code.claude.com/
2. https://code.claude.com/docs/en/agent-sdk/modifying-system-prompts
3. https://youtu.be/TqC1qOfiVcQ?si=K24t3oxuHgYWs375
4. https://www.aiwithamitay.com/p/skills

Biologic Summit 2026

This year we (Fabian and Henriette) were invited to speak at the Biologic Summit. The conference took place January 20-22 in San Diego. Fabian presented his work on conformational ensembles of antibodies [1] in the “Data Strategies and the Future of AI Models” track. Henriette presented her work on LICHEN [2], a tool to generate an antibody light sequence for a specific heavy sequence, in the “ML/AI for Biologics Developability, Optimization and de novo Design” track. Below we give some general highlights of the conference, and some talks we enjoyed. We would like to thank the organisers for the opportunity to discuss our research and hear about the latest developments in harnessing ML for design and optimisation of antibodies.  

General feedback

  • Industry focused conference. Biologic Summit is strongly attended by industry, making this conference an excellent opportunity to promote your tools/databases, and to connect with companies. The conference is attended by both start-ups as big pharma companies. 
  • Medium size conference. With approximately 250 attendees, the Biologic Summit provides a good opportunity to connect with researchers from a wide range of disciplines. Held concurrently with Protein Science and Production Week (PepTalk) and sharing the same venue, the event further benefited from a diverse mix of scientific backgrounds and expertise. 
  • Panel and table discussions. Throughout the three days there where various table discussions and panel discussions organised. These are good places to learn about general interest and challenges in the field. 
  • Well-organised conference. The conference is well-organised with a clear schedule and enough breaks to recharge and connect. Most talks are scheduled for 30 minutes with around 4 talks per block.
Continue reading

New DPhil/PhD Programme in Pharmaceutical Science Joint with GSK!

Many OPIGlets found their way into a DPhil in Protein Informatics through our Systems Approaches to Biomedical Sciences Industrial Doctoral Landscape Award, which was open to applicants 2009-2024. This innovative course, based at the MPLS Doctoral Training Centre (DTC), offered six months of intensive taught modules prior to starting PhD-level research, allowing students to upskill across a diverse range of subjects (coding, mathematics, structural biology, etc.) and to go on to do research in areas significantly distinct from their formal Undergraduate training. All projects also benefited from direct co-supervision from researchers working in the Pharmaceutical industry, ensuring DPhil projects in areas with drug discovery translation potential. Regrettably, having twice successfully applied for renewal of funding, we were unsuccessful in our bid to refund SABS in 2024.

Happily though, we can now formally announce that our bid for a direct successor to SABS, the Transformative Technologies in Pharmaceutical Sciences IDLA, has been backed by the BBSRC, and we will shortly be opening for applications for entry this October [2026]. As someone who benefited from the interdisciplinary training and industry-adjacency of SABS, I’m thrilled to be a co-director of this new Programme and to help deliver this course to a new generation of talented students.

Continue reading

The Experimentally Relevant Future of Molecular Dynamics: Lessons from the Annual Danish Workshop on Advanced Molecular Simulations

I recently had the opportunity to present part of my PhD work on molecular dynamics (MD) studies of engineered T Cell Receptors at the Annual Danish Conference on Advanced Molecular Simulations in Aarhus, Denmark. The meeting had an emphasis on membrane biophysics, multi- & mesoscale simulations, with keynotes focusing on connecting MD to experimental relevance.

What I mainly got from the keynotes, Weria Pezeshkian, Mohsen Sadeghi, Matteo Degiacomi, Lucie Delemotte, and Ilpo Vattulainen is that the community is shifting from from exploratory, proof-of-concept simulations towards more quantitative, decision-ready modelling. i.e., multiscale workflows that admit their limits, report uncertainties, and actually talk to experiments. There was a shared way of thinking about multiscale simulations by first getting the chemistry and thermodynamics right with atomistic or coarse-grained MD, be honest about kinetics at the mesoscale, and only then claim mechanisms for membranes and proteins in ways that can be checked against data.

Here are the main things I took away:

Continue reading

Dispatches from Lisbon

Tiles, tiles, as far as the eye can see. Conquerors on horseback storming into the breach; proud merchant ships cresting ocean waves; pious monks and shepherds tending to their flocks; Christ bearing the cross to Calvary—in intricate tones of blue and white on tin-glazed ceramic tilework. Vedi Napoli e poi muori the Sage of Weimar once wrote—to see Naples and die. But had he been to Lisbon?

The azulejos of the city’s numerous magnificent monasteries are far from the only thing for the weary PhD student to admire. Lisbon has no shortage of imposing bridges and striking towers, historically fraught monuments and charming art galleries. Crumbling old castles and revitalised industrial quarters butt up against the Airbnbs-and-expats district, somewhere between property speculation and the sea. An endearing flock of magellanic penguins paddles away an afternoon in their enclosure at the local aquarium (which is excellent), and an alarming proliferation of custard-based pastries invites one to indulge.

Continue reading

Nanobodies® galore in Utrecht

At the end of September, I had the opportunity to present at the 4th Single-Domain Antibody (sdAb/VHH) Conference hosted in the city of Utrecht. The sdAb conference is a biennial event, and was held for the first time in Bonn (2019), then in Brussels (2021) and Paris (2023), before coming to the Netherlands this year.

This was the first time I’d attended a VHH-focused conference, and I was taken aback at just how large the community is; the Jaarbeurs ‘Supernova’ event hall was completely sold out, with over 400 researchers in attendance (pictures below courtesy of the organisers). The buzz reflects the ever growing interest in sdAbs as tools to discover new fundamental biology, vectors for diagnosing disease, and as prophylactic or curative therapeutics. Most every disease indication was represented at the conference, from anticancer and antiviral sdAbs to antivenom sdAbs (both for use in lateral flow tests to diagnose the snake that bit you, and as quick ‘epipen’-like therapeutics accessible even in the most remote parts of the world).

Continue reading

Handling OAS Scale Datasets Without The Drama

Working with Observed Antibody Space (OAS) dataset sometimes feels a bit like trying to cook dinner with the contents of the whole fridge emptied into the pan. There are countless CSVs, all of different sizes (some might not even fit onto your RAM), and you just want a clean, fast pipeline so you can get back to modelling. The trick is to stop treating the data like a giant spreadsheet you fully load into memory and start treating it like a columnar, on-disk database you stream through. That’s exactly what the 🤗 Datasets library gives you.

At the heart of 🤗 Datasets is Apache Arrow, which stores columns in a memory-mapped format (if you are curious about what that means there is a great explanation in another blog post here. In plain terms: the data mostly lives on disk, and you pull in just the slices you need. It feels interactive even when the dataset is huge. Instead of a single monolithic script that does everything (and takes forever), you layer small, composable steps—standardize a few columns, filter out junk, compute a couple of derived fields—and each step is cached automatically. Change one piece, and only that piece recomputes. Sounds great, right? But of course, the key question now is how to get OAS data into Datasets to begin with.

Continue reading

Antibody developability datasets

Next to binding the antigen with high affinity, antibodies for therapeutic purposes need to be developable. These developability properties includes high expression, high stability, low aggregation, low immunogenicity, and low non-specificity [1]. These properties are often linked and therefore optimising for one property might be at the expense of another. Machine learning methods have been build to guide the optimistation process of one or multiple developability properties.

Performance of these methods is often limited by the amount and type of data available for training. These dataset contain experimental determined scores of biophysical assays related to developability. Some common experimental assays are described in a previous blog post by Matthew Raybould [2]. Here I will discuss some (commonly) used and new dataset related to antibody developability. This list is not exhaustive but might help you start understanding more about antibody developability.

Continue reading