DEV Community

shashank ms
shashank ms

Posted on

Using LLMs for Social Network Analysis: A Beginner's Guide

Social network analysis usually requires specialized graph libraries and manual data labeling, but an LLM can extract entities and relationships from raw text in a single pass. In this guide, we will build a Python agent that reads a conversation transcript, builds a directed graph of interactions, and scores influence using degree centrality, all powered by Oxlo.ai. The finished script fits in one file and runs against any long-form text you provide.

What you'll need

  • Python 3.10 or newer
  • An Oxlo.ai API key from https://portal.oxlo.ai
  • The OpenAI SDK: pip install openai
  • NetworkX and Matplotlib: pip install networkx matplotlib

Step 1: Configure the Oxlo.ai client

I initialize the OpenAI-compatible client pointing at Oxlo.ai. I picked llama-3.3-70b because it follows structured instructions reliably, and Oxlo.ai's flat per-request pricing keeps the cost predictable even when I feed it much longer transcripts later.

from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key="YOUR_OXLO_API_KEY"  # get yours at https://portal.oxlo.ai
)

MODEL = "llama-3.3-70b"

Step 2: Define the agent's system prompt

The system prompt forces the model to behave like a strict extraction engine. It returns only normalized JSON with nodes and edges, which keeps downstream parsing simple and deterministic.

SYSTEM_PROMPT = """You are a social network analysis extractor.
Read the provided conversation transcript and identify every person or organization mentioned.
Return a single JSON object with no markdown formatting.
The JSON must contain:
- "nodes": a list of unique entities, each with "id" and "type" (person or organization).
- "edges": a list of directed interactions, each with "source", "target", and "relationship" (e.g., replies_to, mentions, reports_to).
If the same name appears with variations, normalize it to one id.
Do not include any text outside the JSON object."""

Step 3: Extract the graph from raw text

I wrote a small sample transcript that mimics a cross-team thread. The extract_graph function sends the text to Oxlo.ai and sanitizes the response so we get clean JSON back.

TRANSCRIPT = """
Alice (Product): Hey team, the new API docs are live. Bob, can you review the authentication section?
Bob (Engineering): Sure Alice, I will look at it today. Charlie, you wrote the OAuth flow, can you double-check the examples?
Charlie (Engineering): On it. Alice, do we need to notify the marketing team?
Alice (Product): Yes. Dana, can you handle the announcement?
Dana (Marketing): Already drafting it. I will loop in Evan from PR.
Evan (PR): Thanks Dana. I will reach out to Alice for final approval.
"""

def extract_graph(text: str):
    response = client.chat.completions.create(
        model=MODEL,
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": text},
        ],
        temperature=0.1,
    )
    raw = response.choices[0].message.content.strip()
    # Strip accidental markdown fences if the model emits them
    if raw.startswith("

```json"):
        raw = raw.split("```

json")[1]
    if raw.endswith("

```"):
        raw = raw.rsplit("```

", 1)[0]
    return json.loads(raw.strip())

Step 4: Build the graph and compute centrality

With the extracted nodes and edges, we load a directed graph in NetworkX and calculate in-degree centrality. This surfaces the people who receive the most attention in the network.

import networkx as nx

def analyze_graph(graph_data: dict):
    G = nx.DiGraph()

    for node in graph_data["nodes"]:
        G.add_node(node["id"], type=node["type"])

    for edge in graph_data["edges"]:
        G.add_edge(edge["source"], edge["target"], relationship=edge["relationship"])

    centrality = nx.in_degree_centrality(G)
    return G, centrality

Step 5: Render the network

A quick matplotlib plot gives an immediate sanity check. We color nodes by type and annotate each edge with its relationship label.

import matplotlib.pyplot as plt

def draw_graph(G):
    color_map = []
    for n in G.nodes():
        t = G.nodes[n].get("type", "person")
        color_map.append("skyblue" if t == "person" else "lightgreen")

    pos = nx.spring_layout(G, seed=42, k=1.5)
    plt.figure(figsize=(8, 6))
    nx.draw_networkx_nodes(G, pos, node_color=color_map, node_size=1200, alpha=0.9)
    nx.draw_networkx_labels(G, pos, font_size=10)
    nx.draw_networkx_edges(G, pos, arrowstyle="->", arrowsize=20, edge_color="gray")
    edge_labels = nx.get_edge_attributes(G, "relationship")
    nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size=8)

    plt.title("Social Network Extracted from Transcript")
    plt.axis("off")
    plt.tight_layout()
    plt.show()

Run it

Tie the pieces together in a single entrypoint. When I run this, the agent extracts the graph, prints centrality scores, and opens the visualization.

if __name__ == "__main__":
    graph_data = extract_graph(TRANSCRIPT)
    G, centrality = analyze_graph(graph_data)

    print("Extracted graph JSON:")
    print(json.dumps(graph_data, indent=2))

    print("\nIn-degree centrality:")
    for node, score in sorted(centrality.items(), key=lambda x: x[1], reverse=True):
        print(f"  {node}: {score:.2f}")

    print(f"\nTotal nodes: {G.number_of_nodes()}, Total edges: {G.number_of_edges()}")
    draw_graph(G)

Example output:

Extracted graph JSON:
{
  "nodes": [
    {"id": "Alice", "type": "person"},
    {"id": "Bob", "type": "person"},
    {"id": "Charlie", "type": "person"},
    {"id": "Dana", "type": "person"},
    {"id": "Evan", "type": "person"}
  ],
  "edges": [
    {"source": "Alice", "target": "Bob", "relationship": "requests_review"},
    {"source": "Bob", "target": "Charlie", "relationship": "requests_review"},
    {"source": "Charlie", "target": "Alice", "relationship": "asks"},
    {"source": "Alice", "target": "Dana", "relationship": "requests"},
    {"source": "Dana", "target": "Evan", "relationship": "loops_in"},
    {"source": "Evan", "target": "Alice", "relationship": "requests_approval"}
  ]
}

In-degree centrality:
  Alice: 0.50
  Bob: 0.25
  Charlie: 0.25
  Dana: 0.25
  Evan: 0.25

Total nodes: 5, Total edges: 6

Wrap-up and next steps

Replace the hard-coded transcript with a Slack export or email mbox file to analyze real organizational communication. If you want to experiment before scaling, swap llama-3.3-70b for deepseek-v3.2 on Oxlo.ai's free tier to compare extraction quality on your own data.

Top comments (0)