Communities in Graphiti are automatically detected clusters of related entities discovered through graph analysis. Think of them as topics or themes that emerge organically from your knowledge graph without manual categorization.For example, in a graph containing information about California politics, Graphiti might detect:
A community of “California State Government Officials”
Graphiti uses label propagation, a graph clustering algorithm that groups entities based on their connectivity:
Initialize: Each entity starts in its own community
Propagate: Each entity adopts the most common community label among its neighbors
Iterate: Repeat until community assignments stabilize
Summarize: Generate natural language descriptions for each community
# From graphiti_core/utils/maintenance/community_operations.py:92def label_propagation(projection: dict[str, list[Neighbor]]) -> list[list[str]]: """Implement the label propagation community detection algorithm. 1. Start with each node being assigned its own community 2. Each node will take on the community of the plurality of its neighbors 3. Ties are broken by going to the largest community 4. Continue until no communities change during propagation """
CommunityNode( uuid="community-uuid-123", name="California State Government Leadership", summary="This community includes political figures who have held senior positions in California state government, including Governor, Attorney General, and Lieutenant Governor. Key members have worked together in various capacities and many have connections to San Francisco politics.", group_id="default", created_at=datetime(2024, 3, 15, tzinfo=timezone.utc))
Generate communities for all entities in your graph:
from graphiti_core.utils.maintenance.community_operations import build_communities# Build communities for all groupscommunity_nodes, community_edges = await build_communities( driver=graphiti.driver, llm_client=graphiti.llm_client, group_ids=None # Process all groups)# Build communities for specific groupscommunity_nodes, community_edges = await build_communities( driver=graphiti.driver, llm_client=graphiti.llm_client, group_ids=["user_123", "user_456"])print(f"Detected {len(community_nodes)} communities")
Community building is a compute-intensive operation. For large graphs, consider running it as a background job or on a schedule rather than after every episode.
# Add episode with community updates enabledresult = await graphiti.add_episode( name="New Information", episode_body="Alice Chen joined the Platform Engineering team.", source=EpisodeType.text, reference_time=datetime.now(timezone.utc), update_communities=True # Incrementally update communities)# Access updated communitiescommunities = result.communitiescommunity_edges = result.community_edges
Setting update_communities=True adds latency to add_episode(). Use it when you need real-time community updates, otherwise run build_communities() periodically.
# For each entity, get connected entities and edge countsprojection: dict[str, list[Neighbor]] = {}for node in nodes: # Find neighbors and count connections neighbors = await get_neighbors(node) projection[node.uuid] = neighbors
summaries = [entity.summary for entity in community_cluster]
Hierarchically merges summaries using LLM:
# Pair-wise summarizationwhile len(summaries) > 1: summary_pairs = [(summaries[i], summaries[i+1]) for i in range(0, len(summaries)-1, 2)] summaries = [await summarize_pair(llm_client, pair) for pair in summary_pairs]
Generates community name:
name = await generate_summary_description(llm_client, final_summary)# Returns: "California State Government Leadership"
# Query members of a specific communityrecords, _, _ = await graphiti.driver.execute_query(""" MATCH (c:Community {uuid: $community_uuid})-[:HAS_MEMBER]->(e:Entity) RETURN e.uuid AS uuid, e.name AS name, e.summary AS summary""", community_uuid=community.uuid)members = [record['name'] for record in records]print(f"Community '{community.name}' has {len(members)} members: {members}")
# Find which community an entity belongs torecords, _, _ = await graphiti.driver.execute_query(""" MATCH (c:Community)-[:HAS_MEMBER]->(e:Entity {uuid: $entity_uuid}) RETURN c.uuid AS uuid, c.name AS name, c.summary AS summary""", entity_uuid=alice.uuid)if records: community_name = records[0]['name'] print(f"Alice belongs to: {community_name}")
from graphiti_core.utils.maintenance.community_operations import update_community# Update community to include new entitycommunities, edges = await update_community( driver=graphiti.driver, llm_client=graphiti.llm_client, embedder=graphiti.embedder, entity=new_entity_node)
This:
Determines which community the entity belongs to (based on neighbors)
Merges the entity’s summary with the community summary
# Search for communities (not individual entities)results = await graphiti.search( query="California political leadership", # Search will match against community names and summaries)# Results may include CommunityNodesfor result in results: if isinstance(result, CommunityNode): print(f"Found community: {result.name}") print(f"Summary: {result.summary}")
# Find a relevant communitycommunity_results = await graphiti.search("tech industry leaders")community_uuid = community_results[0].uuid# Get all membersmembers = await graphiti.driver.execute_query(""" MATCH (c:Community {uuid: $uuid})-[:HAS_MEMBER]->(e:Entity) RETURN e""", uuid=community_uuid)
communities = await CommunityNode.get_by_group_ids( driver=graphiti.driver, group_ids=["research_papers"])print("Discovered research topics:")for community in communities: print(f"- {community.name}")
User asks: "What do you know about California politics?"→ Show communities: "California State Government Leadership", "San Francisco Political Figures"→ User selects: "California State Government Leadership"→ Show members: Kamala Harris, Gavin Newsom, Jerry Brown→ User selects: Kamala Harris→ Show relationships: worked with Gavin Newsom, succeeded Jerry Brown
# Find the "Engineering" communityeng_community = await CommunityNode.get_by_uuid(driver, uuid="eng-comm-uuid")# Get all entities in that communitymember_uuids = [edge.target_node_uuid for edge in await CommunityEdge.get_by_uuids( driver, [e.uuid for e in eng_community_edges] )]# Search only within those entities' relationshipsresults = await graphiti.search( query="who is working on the platform?", # Filter to only edges connected to engineering community members)
communities = await CommunityNode.get_by_group_ids( driver=graphiti.driver, group_ids=["customer_data"])print(f"Your graph contains {len(communities)} main topics:")for community in communities[:5]: # Top 5 print(f"\n{community.name}") print(f"{community.summary}")
communities = await CommunityNode.get_by_group_ids(driver, ["default"])# Check for overly large communities (may need rebalancing)large_communities = [c for c in communities if len(await get_members(c)) > 100]# Check for singleton communities (may be noise)singleton_communities = [c for c in communities if len(await get_members(c)) == 1]
# Use community membership as a search signalresults = await graphiti.search( "software engineers", # Boost results that belong to "Engineering" community)
from graphiti_core.utils.maintenance.community_operations import remove_communitiesawait remove_communities(driver=graphiti.driver)# Deletes all CommunityNodes and CommunityEdges# EntityNodes and EntityEdges are preserved