DEV Community

Cover image for Biological AI: Building a Tool-Calling Cellular Simulation
Harish Kotra (he/him)
Harish Kotra (he/him)

Posted on

Biological AI: Building a Tool-Calling Cellular Simulation

Metabolic processes are messy. In biology, organelles like Mitochondria and Lysosomes don't follow a central "script"; they respond to chemical signals and negotiate resources. When building Cyto Agent, I wanted to mirror this decentralized intelligence using modern LLM agent patterns.

In this post, we’ll dive into how to build a real-time cellular simulation powered by a "LangGraph-style" tool-calling orchestrator.

The Problem: Scripted vs. Dynamic Intelligence

Most simulations use hard-coded if/else ladders.
if (pathogen) { defend(); }
While efficient, it lacks the nuance of biological adaptation. Cyto Agent replaces these ladders with a Nucleus Agentβ€”an LLM-powered orchestrator that perceives the cell state as unstructured data and decides on actions by reasoning through available tools.

High-Level Architecture

The system is split into three main components:

  1. The Engine (Simulation.ts): A reactive state machine that handles the "physics" of the cell (ATP decay, glucose consumption, pathogen damage).
  2. The Event Bus (EventBus.ts): A pub/sub system that allows agents to "hear" signals without being tightly coupled.
  3. The AI Orchestrator (LangChainService.ts): The bridge between simulation state and LLM reasoning.

The "Sensing Tools" Pattern

The most interesting part of this build is giving the LLM "eyes" and "hands." Instead of feeding the entire state into every prompt, I implemented Tool Calling:

const queryStatus = tool(
  async ({ id }) => {
    // Returns internal telemetry for specific organelles
    return `ATP Efficiency: Level ${state.mitoLevel}, Integrity: ${state.lysoLevel}`;
  },
  {
    name: "query_organelle_status",
    description: "Probe specific telemetry from an organelle",
    schema: z.object({ id: z.string() }),
  }
);
Enter fullscreen mode Exit fullscreen mode

When a crisis occurs, the Nucleus doesn't just panic. It calls check_genomic_database(pathogen_type) to retrieve the specific counter-measures for a Viral vs. Fungal strain. This separates "Domain Knowledge" (the database) from "Reasoning" (the LLM).

Real-Time Visualization

To make the simulation feel alive, we used Framer Motion to animate the cellular components. Pathogens aren't just static dots; their behavior changes based on their type:

  • Viral: Spiky, fast-vibrating fuchsia artifacts that reflect high-frequency replication.
  • Bacterial: Slow-moving emerald pill-shapes reflecting metabolic toxicity.
  • Fungal: Pulsing amber spores representing slow, steady growth.

The Result: Autonomous Evolution

One of the most rewarding features is "Autonomous Evolution." The Nucleus can decide to "evolve" the Mitochondria (upgrading it to Rank 2 or 3) using summarized ATP. This creates a feedback loop where the simulation optimizes itself over time without user intervention.

Want to explore the code?

Check out the full repository here: https://www.dailybuild.xyz/project/128-cyto-agent

Top comments (0)