A few days ago I came across an arXiv preprint with a spicy title: Large-Language Models as a Cognitive Virus. It models our collective relationship with LLMs the way we’d model a disease. People move between not using them, using them casually, and being unable to function without them, complete with tipping points, runaway lock-in, and a prescribed “cognitive immunization.”

As luck would have it, version 0.2.0 of epidemik has just been released, so why not play around with some fun ideas?

A simplified model of dependence

The paper introduces a quadratic term to produce a hysteresis curve. Here, we explore a simpler way to achieve the same effect.

Let us define a small-ish variation of the usual SIR model, with the three compartments defined by the authors: Uncoupled (U, doesn’t use LLMs, corresponding to the usual Susceptible compartment), Coupled (C, casual/occasional use, equivalent to mildly Infectious), and Dependent (D, persistent dependence, equivalent to very Infectious). Transitions between compartments differ from the usual SIR model, as we include 4 different effects:

Graphically, we can represent the model as:

Which corresponds to a system of coupled ODEs:

\( \begin{aligned} \frac{du}{dt} &= -\beta u c + \gamma c \\ \frac{dc}{dt} &= \beta u c - \alpha c d - \gamma c + \delta d \\ \frac{dd}{dt} &= \alpha c d - \delta d \end{aligned}\)

Where lowercase letters correspond to population fractions. From these equations, we can already derive some interesting results.

Long-Term Equilibrium

Let us start by exploring the dd/dt=0 equilibrium. There are two solutions to this equation:

If we assume that there are no Dependents, so that d=0, then we have:

\(\begin{aligned} \frac{du}{dt} &= -\beta u c + \gamma c \\ \frac{dc}{dt} &= \beta u c - \gamma c \end{aligned}\)

which is just the usual SIS model.

\(\begin{aligned} \frac{dc}{dt} &= \beta \left(1-c\right) c - \gamma c \end{aligned}\)

From these equations, we find the first threshold in our model. For the “disease” to be able to spread, we must have

\( \frac{\beta}{\gamma}\ge 1\)

or, equivalently:

\( \beta>\gamma\equiv\beta_{SIS}\)

giving us the first threshold. In other words, with D=0, if γ > β, people recover faster than they can get infected, and the disease dies out. However, if β > γ, we end up with an endemic state with:

\(\begin{aligned} u_0&=\frac{\gamma}{\beta}\\ c_0&=1-\frac{\gamma}{\beta}\\ d_0&=0 \end{aligned}\)

Dependent seeding

Now consider the opposite case, and assume we start with some dependents in the system, d>0. We still need that dd/dt>0, and this only happens if:

\(c > \frac{\delta}{\alpha}\equiv c_0 \)

And we get, as the long term equilibrium state:

\(\begin{aligned} u^* &= \frac{\gamma}{\beta} \\ c^* &= \frac{ \delta}{\alpha} \\ d^* &= 1-\frac{\gamma}{\beta}-\frac{ \delta}{\alpha} \end{aligned}\)

meaning we expect c to overshoot c0 before coming back down.

Epidemik Implementation

We can implement this model in epidemik in just a few lines of Python:

GAMMA, ALPHA, DELTA = 0.3, 1.0, 0.2   # baseline; c0 = delta/alpha = 0.2

def build_model(beta, alpha=ALPHA, gamma=GAMMA, delta=DELTA, seed=None, 
    dependent_recruit=False):
    m = EpiModel(compartments=["U", "C", "D"], seed=seed)
    m.add_interaction("U", "C", "C", beta=beta)          # casual users recruit
    if dependent_recruit:
        m.add_interaction("U", "C", "D", rate="beta")    # dependent users recruit too
    m.add_interaction("C", "D", "D", alpha=alpha)        # collective reinforcement
    m.add_spontaneous("C", "U", gamma=gamma)             # casual recovery
    m.add_spontaneous("D", "C", delta=delta)             # slow de-escalation

    return m

Where we also include the dependent_recruit flag in our utility model definition function. dependent_recruit defines whether or not Dependent users recruit non-users. These two versions of the model will behave very differently. For now, let us focus on the case where dependents don’t recruit, dependent_recruit=False.

To run the model, we can just do:

GAMMA, ALPHA, DELTA = 0.3, 1.0, 0.2
N = 10_000

model=build_model(0.45, dependent_recruit=False)
print(model)

which outputs the structure of the model we just created:

# Epidemic Model with 3 compartments and 4 transitions:

Compartments: [U, C, D]

Parameters:
  beta: 0.45
  alpha: 1.0
  gamma: 0.3
  delta: 0.2

Transitions:
  - U + C = C beta
  - C + D = D alpha
  - C -> U gamma
  - D -> C delta

# R0=1.50

Now we can integrate the equations of this model with two different initial conditions:

m0 = build_model(beta, dependent_recruit=False)
m0.integrate(300, U=N - 20, C=10, D=0, )

m1 = build_model(beta, dependent_recruit=False)
m1.integrate(300, U=N - 20, C=10, D=10)

And compare the results. As expected, we see the impact that adding just a few dependents has on the course of the epidemic. While the population of u remains unaffected, the “infected” population is now split between the Coupled and the Dependent.

Infectious Dependents

Now let us turn to the flat that lets dependents recruit. With the flat turned on, the shape of our model changes. For simplicity, we make the dependents recruit at the same rate, β, as the coupled. Relaxing this would give us another way to explore the model.

Mathematically, our equations also change, with one extra term in the u and c ODEs

\( \begin{aligned} \frac{du}{dt} &= -\beta u c + \gamma c {\color{red}-\beta u d}\\ \frac{dc}{dt} &= \beta u c - \alpha c d - \gamma c + \delta d {\color{red}+ \beta u d}\\ \frac{dd}{dt} &= \alpha c d - \delta d \end{aligned}\)

This seemingly innocuous change makes a huge difference by adding a quadratic term. If you remember that 1=u+c+d , then we can write:

\(\frac{du}{dt} = -\beta u (c+d) + \gamma c = -\beta u (1-u) + \gamma c = -\beta u{\color{red}+\beta u^2}+ \gamma c \)

At the first equilibrium point, when c=c0 and dd/dt=0, we have, for the long term equilibrium:

\(0 = -\beta u+\beta u^2+ \gamma c_0 \)

Solving, we find:

\(x_{\pm}=\frac{1\pm\sqrt{1-\frac{4\gamma c_0}{\beta}}}{2}\)

which has two real solutions only when:

\(\beta > 4\gamma c_0\equiv\beta_{sn}\)

This quadratic equation is where the hysteresis comes from. We can observe it in epidemik by sweeping β up from zero and back down from the locked state. The first step is to define a function to calculate the equilibrium value for the various compartments:

def equilibrium(beta, U0, C0, D0, T=6000, **kw):
    m = build_model(beta, dependent_recruit=True, **kw)
    m.integrate(T, U=U0, C=C0, D=D0)
    eq = m.values_.iloc[-1]
    return eq

And then we can use it to compute the equilibrium values as we cycle over the values of β:

betas = np.linspace(0.16, 0.50, 35)

# Sweep up starting from the initial state
state = (N - 2, 1.0, 1.0)
forward = []
for b in betas:
    eq = equilibrium(b, *state)
    forward.append(eq["D"] / N)
    state = (max(eq["U"], 0.0), max(eq["C"], 1.0), max(eq["D"], 1.0))

# Sweep down starting from the locked state
state = (N * 0.1, N * 0.2, N * 0.7)
backward = []
for b in betas[::-1]:
    eq = equilibrium(b, *state)
    backward.append(eq["D"] / N)
    state = (max(eq["U"], 0.0), max(eq["C"], 1.0), max(eq["D"], 1.0))
backward = backward[::-1]

The hysteresis curve

Now we can plot the equilibrium-dependent fraction as a function of β, as β increases and then decreases, and compare it with our analytical solutions above.

In the figure above, we also plotted the threshold we calculated previously:

\( \begin{aligned} \beta_{sn}&= 4\gamma c_0\\ \beta_{SIS}&= \gamma \\ \beta_{inv}&= \frac{\gamma}{1-c_0} \end{aligned}\)

Look at the figure from left to right: nothing, nothing, nothing — then at βinv the dependent fraction jumps from zero to about 60% without any warning. Continuing to increase β, will keep us moving along the upper branch. However, if we now decide to turn back around and start decreasing β, we follow a different path. The system “ remembers ” that it was in the locked-in state all the way down to βsn, including a region where before we had seen no sustained casual use.

In other words: It’s easier to keep mass dependency than it is to create it. This memory effect is what produces the asymmetry in both paths, and is known as hysteresis.

Network effects

The ODE equations we have been exploring so far correspond to the idealized mean-field case. The mean field approximation assumes that everyone interacts with everyone equally. However, reality is a lot more complex. We live in societies where we interact with only a small number of the people around us. We can explore this effect by implementing this model on a network with the NetworkEpiModel module.

In addition to the number of contacts we have, who we interact with is also important. This becomes obvious when we compare the spread of the epidemic on two graphs with the same average degree: an Erdős–Rényi graph, with a narrow degree distribution, and a Barabási–Albert graph with a heavy-tailed, hub-dominated. When we sweeping the per-contact transmission probability, λ:

The BA network sustains locked-in dependence at transmission probabilities where the ER graph remains unaffected. The hubs that are the defining feature of a BA network act both as super-recruiters and reinforcement chambers. As soon as a hub is infected, it quickly infects its neighbors, which in turn infect their neighbors, and so on. The mean-field model is unable to account for this effect, as it treats every individual the same way.

We can also see that time spent dependent increases as degree increases.

The two levers aren’t equal

How can we immunize the population? The original paper proposes a “cognitive immunization” strategy that reduces to two levers: lower β (add friction to social transmission) or raise δ (make dependence easier to walk back from). Hysteresis show that these two approaches are very different. After we cross into the locked-in state the only way to drop back out is when δ > αβ/4γ, a boundary that’s linear in δ but requires reducing β by half to cross from the transmission side alone:

From a locked-in society, transmission control alone has to drag β below roughly 0.27 before the dependent state stops existing at all — a huge lift. Raising reversibility, on the other hand, moves the escape boundary toward you in a straight line. Cognitive immunization is ony possible by engineering an off-ramp: exportable workflows, retained skills, and the ability to still function when the tool no longer does.