Wednesday, September 9, 2026

Demystifying AI Agents

Introduction: Why Agents Matter Now

AI agents have quickly become one of the most talked-about ideas in the current AI wave. If you work in biology or drug discovery, the term can sound both exciting and slightly suspicious: is an “agent” truly a new capability, or is it just automation with a shinier name tag? The answer is somewhere in between. Agents build on ideas we already know -- workflows, scripts, search, databases, and decision logic -- but add a flexible LLM-based decision layer that can interpret goals, choose the next step, use tools, and recover when the path is not perfectly predefined. In other words, an agent is less like a single script and more like a digital colleague who can read instructions, check the lab notebook, use selected instruments, and report back. The key difference is that agents can reason through what to do next, while traditional automation scripts simply follow predefined instructions.

In this tutorial, we will start with intuition: what makes an AI agent different from a normal workflow? We will then unpack the core parts of an agent -- LLM, memory, tools, and control loop -- using analogies that should feel familiar to scientists. Finally, we will connect the concepts to practical examples such as literature triage, gene annotation, protein-design support, and document classification. By the end, the goal is not to memorize buzzwords, but to develop judgment: when is a simple script enough, when is one LLM step useful, and when do we really need an agent?

Part I. AI Agents from Ground Zero

What Is an AI Agent?

A useful working definition is: a form of automation in which Large Language Models (LLM) assume human roles. An agent consists of an LLM and wrapper scripts. The LLM acts as the decision engine; the surrounding application provides memory, tools, permissions, execution, and stopping rules. A simple biology analogy is this: a fixed script is like a printed lab protocol that always follows the same steps. An agent is more like a scientist who follows the protocol, checks the result, and decides what to do next if something looks wrong. Under a broad definition, systems such as AlphaGo can be described as agents because they pursue a goal and choose actions. However, AlphaGo is highly specialized and is not the type of AI agent emphasized in this tutorial, as it does not rely on LLMs. The recent excitement about AI agents comes from the fact that large language models can generalize across many tasks, understand natural-language goals, call tools, and recover from partial failures in ways that were very difficult to encode manually. What LLMs now enable is the creation of AI agents for many different decision-making workflows without tedious task-specific neural network training. A recommended upcoming resource to understand how AI agents work is "An Illustrated Guide to AI Agents: Concepts and Code for Building Agents with LLMs, Tools, and Memory" by Maarten Grootendorst and Jay Alammar, scheduled for release in October 2026.

Workflow Automation vs AI Agent

Traditional automation works best when the path is known. Data engineers encode decision logic into software, so applications such as lab information management systems (LIMS) behave predictably and repeatedly. Even when these systems could use machine-learning models such as CNNs or SVMs for automatic data analyses, the overall control flow is usually fixed: the system receives input, runs predefined steps, produces output, and reports errors when something unexpected happens. At that point, humans usually need to step in. 

An AI agent becomes useful when part of the workflow previously required human judgment. Imagine an application that receives an error message, forms hypotheses, checks server health, tests input formats, verifies permissions, retries safely, and proposes a source-code fix all by itself. A traditional application can theoretically be programmed to do this, but the logic quickly becomes brittle and expensive to implement and maintain. An agent can delegate the judgment-heavy part to an LLM, while the surrounding software constrains what the LLM is allowed to do. In short: use code when the path is known; use an agent when the path must be discovered.

Agentic Systems Exist on a Spectrum

  • Deterministic workflow: every step is predefined; this is often the safest and cheapest solution. But an application that is capable of troubleshooting, self-upgrade, and redeploy itself is no longer a workflow, as it used to require human intervention.

  • Workflow plus one LLM step: the LLM summarizes, extracts, classifies, or rewrites inside an otherwise fixed pipeline. (Gene annotation is an example, where the application reads content from the Internet and writes a 100-word summary of a gene's functions and disease implications. Such a task used to require a well-educated biologist.)

  • Controlled agent loop: the LLM can choose from a small set of tools and iterate until a clear stopping condition is met. (Chatbot such as MS Copilot or ChatGPT is an example)

  • Dynamic tool-using agent: the LLM plans, calls multiple tools, updates strategy, and handles partial failures. (Github Copilot or Claude Code for debugging your Python script is an example. Such a task used to be a programmer's job.)

  • Multi-agent system: multiple agents specialize or critique each other, which can help complex tasks but also adds orchestration overhead. (Improving the quality of gene annotation through a generator, evaluator, and a is an optimizer is an example)


A practical caution: not every workflow needs an agent. If a simple script solves the problem reliably, let the script enjoy its quiet retirement. This is like using a standard protocol when it already works: we do not need to redesign the experiment every time. Agents are most valuable when the task involves ambiguity, changing context, multiple information sources, or judgment that would otherwise require a human.

The Anatomy of an AI Agent

An AI agent has four essential parts: the LLM brain, which interprets goals and reasons about next steps; memory or context, which acts like the current lab notebook page; tools, which are the instruments the agent is allowed to use; and the control loop, which is the repeated cycle of deciding, acting, observing, and deciding again. In simple terms, the agent reads the notebook, chooses the right instrument, checks the output, and then decides the next step. Its “hands” are software tools rather than pipettes.


LLM is agent's brain, context is what agent sees (chat history, documents, databases, long-term memory), and tools allow the agent to observe the world and act to change the world.


The LLM as the Decision Engine

Large language models are transformer-based neural networks trained to predict text. Earlier word-embedding methods such as Word2Vec represented each word as a vector, so words with similar meanings occupied nearby regions in a high-dimensional space. However, static word vectors cannot fully capture context. In the sentence “she deposited money at the bank before sitting on the bank of the river,” the two uses of “bank” should not have the same representation. Transformers solve this by representing each token in relation to the surrounding context.

During pretraining, an LLM sees enormous amounts of text and learns statistical patterns that encode facts, styles, procedures, and reasoning traces into its model weights. This is why an LLM can answer many questions from internal knowledge. However, this knowledge is frozen at training time, may be incomplete, and can be sometimes wrong. Hallucination slowed early adoption because fluent language can sound authoritative even when the underlying evidence is weak.

Reasoning improved when researchers realized that models often had useful reasoning paths available, but did not always select them by default. For example, given the prompt “I have 3 apples. My dad has 2 more apples than me. How many apples do we have in total?”, a model may incorrectly answer “5” because the tokens 2, 3, and total strongly suggest simple addition. If prompted to reason step by step, the model is more likely to produce: “I have 3 apples. My dad has 2 more than me, so he has 5. Together we have 3 + 5 = 8.”

Modern reasoning models make these useful paths more likely through a combination of prompting, decoding strategies, supervised examples, reinforcement learning, and preference-based feedback. As a result, LLMs are better at following longer, more structured problem-solving paths. This improvement is a major reason agents have become more capable: an agent needs a decision engine that can decide what to try next, not just complete the next sentence. If you are interested in how LLMs learn reasoning ability, watch this video.

Memory, Context, and RAG

Unlike a human brain, a deployed LLM is usually read-only during conversation. The model does not update its weights each time we ask a question. Instead, the application supplies memory through context. The simplest memory is conversation history: the previous messages are concatenated with the new user request and sent back to the model. This allows the model to answer follow-up questions, but it also increases token usage and can clutter the context window.

A more scalable approach is retrieval-augmented generation, or RAG. Instead of loading all possible information into the prompt, the agent searches relevant documents, databases, or previous notes and inserts only the most useful pieces into the current context. Long-term memory can also store user preferences, project facts, or reusable knowledge, but that memory should be selectively reintroduced rather than blindly appended.

This is the motivation for context engineering: decide what to include, what to compress, what to retrieve, and what to discard. If we summarize a BoltzGen paper and then ask about a Germinal paper, resending the entire BoltzGen paper may waste context and distract the model. A simple analogy is preparing for an experiment: bring the relevant protocol, sample information, and controls -- not everything in the lab notebook. Good context engineering means giving the model the right information at the right time.

Tools and Tool Calling

LLMs can recall many common facts from training. For example, they may know that sin(1) is approximately 0.84147 because this value appears frequently in mathematical text. However, the model should not rely on internal memory for current, private, exact, large-scale, or high-stakes information. It should use tools. A calculator does not make the mathematician less intelligent; it makes arithmetic less distracting.

Tools may include web search, web-page extraction, Python execution, shell commands, database queries, internal document search, file operations, or domain-specific scientific systems. Tool calling is the bridge from “talking about work” to “doing work.” A simple lab analogy is that the LLM can decide what measurement is needed, but the tool is the instrument that actually makes the measurement. The LLM proposes a tool call, the agent runtime validates and executes it, the tool returns an observation, and the LLM uses that observation to continue or answer.

For example, if the user asks for today’s weather, the model should use a web or weather tool. If the user asks for sin(1.23456789), the model should use Python or a calculator app. Even if an LLM could approximate the value using a Taylor expansion, calling Python is faster, cheaper, and less error-prone. In agent design, the best tool is often the boring reliable one.

The ReAct Loop

A typical agent follows a Reason-Act-Observe pattern: 

  • The user provides a goal, such as: “If sin(1.2) is greater than 0.9, tell me the weather in San Diego today; otherwise, tell me the weather in Boston today.”
  • The LLM reasons that it must first calculate sin(1.2).
  • The agent runtime executes a Python tool and returns the observation that the condition is true.
  • The LLM updates its plan and decides to retrieve San Diego weather.
  • The agent runtime executes the weather or search tool and returns the result.
  • The LLM decides it has enough information and produces the final answer.

The same loop can be described in more human terms. The agent first realizes, “I should not answer the weather question yet, because the math condition decides which city matters.” It then uses Python to calculate the sine value, observes that the condition is true, and only then looks up San Diego weather. This is like checking a sample first before choosing the next experimental step.

Clarifying Four Common Terms

LLM vs Agent. The LLM is the reasoning engine, but it is not the whole agent. Models such as GPT, Claude, DeepSeek, Kimi, and Qwen can generate text and reason over context. An agent wraps such a model with memory, tools, permissions, and a control loop. A simple analogy: the LLM is like the reasoning brain of a scientist, while the full agent is that brain connected to a lab notebook, approved tools, and a workflow for deciding what to do next.

Prompt vs Skill. A prompt is the instruction we give the model for the current task. A skill is reusable know-how that can be loaded only when relevant. For example, we might have separate skills for protein design, sequence analysis, PyMOL visualization, antibody optimization, and literature summarization. Loading every skill into every request is like putting every lab protocol on the bench for one simple task. A skill is therefore “prompt on demand”: the agent first sees a short description of each skill, then opens the detailed skill only when the task requires it.

Tool vs MCP. A tool is a capability the agent can call, such as searching an internal database, querying NCBI, reading a PDF, running Python, or retrieving information from a protein-structure system. MCP, or Model Context Protocol, is a standard way to expose tools, resources, and prompt templates so that agents can discover and use them in a consistent format. A simple analogy: tools are instruments, and MCP is the catalog that tells the agent what instruments are available and how to use them.

Part II. Example AI Agents

AI Agent Base Class

At a high level, the implementation is surprisingly simple. The agent keeps a conversation memory, advertises a set of available tools to the LLM, asks the LLM what to do next, executes a selected tool if needed, and then feeds the result back into the conversation. The important idea is not the exact Python syntax, but the repeated design-test-learn loop. A simple analogy is assay optimization: look at the previous result, choose the next condition, test it, and update the plan.

# Agent State

memory = ConversationHistory()

tools = [web_search, read_webpage, python, run_bash]

user_msg = get_user_input() 
# 1. Store user message in memory 
memory.add("user", user_msg)

while True:

    # 2. Build context from conversation history 
    context = memory.retrieve() 
    # 3. Send context + tool definitions to LLM 
    response = LLM.generate(context, tools=tools) 

    # 4. Does the LLM want to use a tool? 
    if response.tool_call: 
        # 5. Execute requested tool 
        observation = execute_tool(response.tool_call)

        # 6. Add tool result to memory 
        memory.add("tool", observation)

        # 7. Re-query LLM with new information 
        continue

    # 8. Final answer produced 
    memory.add("assistant", response.content) 
    display(response.content)

In practice, this outline can be turned into a reusable “Agent class. That class can register common tools such as web search, web-page extraction, Python execution, shell execution, and PDF summarization.

With this base class, it becomes much easier to build specialized agents. The agent does not need to be rewritten from scratch each time; instead, we change the system prompt, available tools, and task-specific instructions.

The same basic agent architecture can support many scientific use cases. Below are three examples. They are intentionally simple, because the goal is to show the pattern rather than to build a production system on the first try. In real projects, we would add authentication, input validation, logging, safety limits, and human review for important actions.

Depending on model access, the same framework can run with different LLM backends. For interactive development, a local or lower-cost model may be sufficient. For more demanding scientific reasoning, literature synthesis, or coding tasks, a stronger hosted model may be preferable. The key design principle is to separate the agent framework from the model choice, so the “brain” can be swapped without rebuilding the entire body. We will not share our agent class code here, as this is done in a much better way in frameworks such as LangChain. In fact, for most agent applications we write for simple cases, simply instruct Claude Code or Github Copilot to code without using LangChain.

Example 1: Chatbot

The simplest agent is a chatbot. At this stage, we are not asking it to perform a specialized scientific workflow. We simply give it access to useful tools and allow it to converse with the user. This is the “hello world” of agents, like running a simple positive control before using a new assay.

#!/usr/bin/env python

"""Interactive chatbot using the agent framework."""

from agent import create_default_agent


if __name__ == "__main__":

    agent = create_default_agent(

        system_prompt="You are a helpful assistant with access to tools for running code, searching the web, and reading web pages.",

    )

    agent.chat()


Example 2: Gene Annotation Agent

A gene annotation agent is more interesting because it needs domain-specific instructions. We can give it a skill document that defines the expected annotation style, preferred databases, evidence hierarchy, and output format. These instructions can mostly be written in plain English in a SKILL.md file. The agent can then retrieve information, reason over biological function, and write a structured annotation. This is like asking a scientist to prepare a gene brief: check trusted sources, separate known function from speculation, and write the result in a consistent format.

class GeneAnnotationAgent(Agent):

    """Agent that annotates genes according to the SKILL document."""


    def __init__(self, llm: LLM | None = None, verbose: bool = True):

        self.skill_text = _read_skill()

        system_prompt = (

            "You are a gene annotation assistant. Follow the instructions below EXACTLY.\n\n"

            f"{self.skill_text}"

        )

        super().__init__(llm=llm, system_prompt=system_prompt, verbose=verbose)

        self.register_tool(make_fetch_url_tool())

        self.register_tool(make_web_search_tool())

        self.register_tool(make_write_file_tool())


    def reset_keep_skill(self) -> None:

        """Clear conversation history but keep the SKILL system prompt."""

        self.reset()


    def annotate(self, gene_input: str) -> str:

        """Annotate a single gene. Returns the agent's response."""

        self.reset_keep_skill()

        return self.run(gene_input)


if __name__ == "__main__":

    agent = GeneAnnotationAgent()

    result = agent.annotate(user_input)

 

Example 3: Document Classification Agent

A document classification agent is useful when a folder contains many PDFs, reports, or papers and the categories are not known in advance. A deterministic script can move files if the folder names and rules already exist. An agent is helpful when it must read summaries, infer themes, propose categories, and organize documents accordingly. This is like sorting a stack of papers into a few useful piles, such as “methods,” “benchmarking,” “biology background,” and “follow-up later.”

#!/usr/bin/env python

"""

Document classification agent — crawls a folder of PDFs, summarizes each,

extracts keywords, then groups them into categories and moves files into

category folders.

"""


def classify_documents(input_folder: str, output_folder: str | None = None, word_count: int = 300, verbose: bool = True):

    """

    Crawl input_folder for PDFs, summarize each, classify into categories,

    and move files into category sub-folders under output_folder.

    """

    # Step 1: Find all PDF files

    pdf_files = []

    for root, _, files in os.walk(input_folder):

        for fname in files:

            if fname.lower().endswith(".pdf"):

                pdf_files.append(os.path.join(root, fname))


    # Step 2: Summarize each PDF using the PDF agent (with caching)

    summaries: dict[str, dict] = {}

    pdf_agent = PDFSummarizerAgent(word_count=word_count, verbose=verbose)


    for pdf_path in pbar:

         result = pdf_agent.summarize(pdf_path)

         summaries[pdf_path] = result


    # Step 3: Use a classification agent to group documents


    classifier = Agent(

        system_prompt=(

            "You are a document classifier. You will receive summaries and keywords for multiple PDF documents. "

            "Group them into logical categories (3-8 categories). Use short, descriptive category names as folder names "

            "(lowercase, underscores instead of spaces, no special characters).\n\n"

            "Respond ONLY with valid JSON in this format:\n"

            '{"categories": {"category_name": ["filename1.pdf", "filename2.pdf"], ...}}'

        ),

    )


    # Build the classification prompt

    doc_descriptions = []

    for pdf_path, info in summaries.items():

        fname = os.path.basename(pdf_path)

        summary = info.get("summary", "")

        keywords = ", ".join(info.get("keywords", []))

        suggested_name = info.get("filename", "")

        doc_descriptions.append(

            f"File: {fname}\n"

            f"Suggested name: {suggested_name}\n"

            f"Keywords: {keywords}\n"

            f"Summary: {summary}"

        )


    classification_prompt = (

        "Classify the following documents into categories:\n\n"

        + "\n\n---\n\n".join(doc_descriptions)

    )


    result = classifier.run(classification_prompt)


    # Step 4: Parse the classification result and move files

    # Step 5: Move files into category folders (with renaming)

Example 4: Agent for de novo protein design

Latent-Y is an example of a domain-specific autonomous scientific agent. Unlike general-purpose copilots that answer questions or automate office workflows, Latent-Y demonstrates how an agent could execute an end-to-end research campaign in a highly specialized domain: biologics drug discovery. According to the authors, the agent accepts a natural-language design goal, performs literature review, analyzes targets, identifies candidate epitopes, designs antibodies, validates them computationally, and produces lab-ready sequences. This moves beyond simple information retrieval or tool orchestration; the agent acts as an AI research assistant that can coordinate a complex multi-stage workflow.

What makes Latent-Y particularly interesting from an AI-agent perspective is its architecture. The system combines a large language model–style planning layer with access to scientific literature, biological databases, bioinformatics tools, and a specialized generative protein-design model called Latent-X2. Rather than generating antibody sequences directly from a prompt, the agent decomposes the problem into a series of scientific reasoning tasks. For example, it may first determine which region of a target protein is most relevant to a desired mechanism of action, evaluate structural evidence from published studies, generate candidate binders, and then iterate through computational quality checks before selecting molecules for experimental testing. In agent terminology, Latent-Y acts as an orchestrator that coordinates reasoning, planning, memory, tool usage, and specialized foundation models to achieve a complex objective.


Refer to captionLatent-Y autonomously designs binders to IL-6 with the goal of disrupting IL-6/IL-6R complex formation. Figure is from the Latent-Y preprint: https://arxiv.org/html/2603.29727v2.

No comments: