Plot.plot({
grid: false,
color: {
legend: true,
type: "utc",
scheme: "Viridis",
label: "Edit time"},
x: {axis:null},
y: {axis:null},
marks: [
Plot.dot(vertices,
{
x: "x",
y: "y",
symbol: "Label",
r: 2
}
),
Plot.arrow(edgesFiltered,
{
x1: "x",
x2: "xend",
y1: "y",
y2: "yend",
stroke: "Timestamp",
insetEnd: 5
}
)
]
})OpenAI Swarm
SNA
AI
Another “AI Swarm” was recently found abusing an old German wiki. The unsupervised OpenAI Agents generated text which left notes that became inputs for other OpenAI Agents. I do not understand the technical details of it, and really do not know how to feel about what these “swarms” mean;1 but after several years of teaching a Social Network Analysis course I do know new and interesting network data when I see it.
I decided to see what interesting things might come out of this data. Below I backbone the network and cluster it, discovering that most of the nodes can be placed in a relatively few nodes.
Network Construction
For whatever reasons, the agents often, but not always, generated “names” as part of their edits. It is impossible to know if these names are a 1-to-1 match with the Agent that generated the edit text. For the purpose of this exercise I am going to treat each Name2 as one part of a bipartite network, the other side is the Page that was edited. In addition, I exclude the few human edits3 that were made and identified by Von Arx et al along with the edits lacking names. This leaves 3,084 Names and 4,000 Pages. You can divide a network into components (where each node can reach every other node). In this case, there are 563 total components. But of the total 7,084 nodes (Pages and Names), 5,691 are in a single component. The majority of the rest of the components represent a single Name making an edit on a single Page.
Figure 1 shows the bipartite network of the largest component, with the colors of the edges indicative of when the edit was made to the Page4. In addition Figure 2 shows the edits over time. You can use the Start and End fields to show edges during just certain periods as well. As with many networks of this size, it is hard to identify much signal from the noise here.
In order to improve upon this we can focus on what we are most interested in, the “Agents,” or in this case the Names that are being used. What we are interested, in particular, is if they are acting in some sort of systematic way. This is a common problem in social network analysis: We have a bipartite network where we have two types of nodes (Names and Pages), and interactions only go between the types. Names might be used to edit the same Page at random (simply because the Name is being used a lot) or there might be “purposeful” (non-random) edits of the same Page using the same Names. What we want to extract are connections between Names that are non-random, this is called the backbone of the network.
Extracting the backbone of a bipartite network is difficult, and there is open research on the best way to do it. This particular network also poses some challenges, it is relatively large (thousands of nodes), and we have information not just on whether a Page has been edited by a Name but also the number of times. From my understanding the most advanced methods to do this do not directly account for the number of interactions, just whether they have interacted. Because of this, and because I spent a long time implementing something similar for my dissertation, I opt for a slightly older backboning process.
CautionExpand To Learn Unnecessary Details
Briefly, I adapt Neal (2014) by developing a null distribution of the number of interactions expected, and then testing whether the observed interactions are at a certain threshold above the expectations. To do this I estimate a Hurdle (a type of zero inflated model) Poisson model. Formally, let \(y_{ij}\) be the number of times Name \(i\) edits Page \(j\), I predict this using the sum of the number of edits made by Name \(i\) (\(\log(\sum_{j=1\ldots J} y_{ij})\)), the log number of edits made on Page \(j\) (\(\log(\sum_{i=1\ldots I} y_{ij})\)) and their interaction.
I use this model to simulate the number of interactions (\(\widehat{y_{ij}}\)). This creates a simulated bipartite network. Taking the cross product of the adjacency matrix projects this into a single mode network where the cells represent the strength of co-edits between each Name. Finally, we can compare the simulated strength of co-edits against the observed co-edits from the actual data. We retain the edges where the observed co-edits are greater than 99% of the simulated, or null distribution.
The logic in all this is, what would happen if each Name was editing at random just based on their overall propensity to make edits. Is the observed similarity of edits between two Names greater than what would happen in this random scenario? If so, we assume that similarity is not driven solely by randomness.
Figure 3 displays the largest component of the backbone, along with clusters identified using the Leiden method. There are 29 clusters in total but many of these are small. There are only 8 clusters with more than 50 members in them, and they make up the majority of the network. Cluster A is the largest, with NA members, making up the large red blob in Figure 3.
Table 1 displays the most unique Pages edited in each cluster along with the first and last time a Page was edited. I identify uniqueness by multiplying the number of edits on a Page from Names in each cluster by the inverse cluster frequency of that Page. This process down-weights Pages that were commonly edited by Names in each cluster.
You can view the specific edits here. If you pick a cluster and a Page that is unique to it, you’ll notice that most (but not necessarily all) edits on that Page are from Names in the same cluster. This is unsurprising given that this is directly what the algorithm is designed to find. The question is, what does this reflect?
There are a few different possibilities, and none of what I’ve done can distinguish between the two. First, it is possible these clusters are identifying separate AI agents that were “passing” information between each other. These clusters are Agents that were working more closely with each other. Second, it is possible that these clusters are actually each only one (or maybe a small number of Agents). In this case, the Names are not a 1-to-1 match with an Agent, but are being randomly created during the text generation process. And, of course, it could be a mixture of options one and two.
Finally, in Table 2 I display each Name along with the identified Cluster from this whole process.
Note
I used an LLM to help with coding some of this and to “proofread” at the end. I use OpenRouter’s auto router through Positron to do this.
Footnotes
On the one hand I don’t think it is useful to anthropomorphize text generation models. On the other hand, I’m not sure it matters if these models were “communicating” or not. At a basic level, the models generated text that could store part of that text on a website which other models used as inputs in their text generation. The fact this happens as the result of probabilistic models is wild to me.↩︎
I capitalize Name and Page to signify that these are types of nodes.↩︎
These appear to be the ones with
[..]Names, so they were removed. This looks to be more than they initially said in their post, but still only a handful of human edits in total.↩︎This is technically a multigraph where each node can have multiple edges between a graph.↩︎