# How RAG-Anything Handles Weighted Relationship Scoring in Its Multimodal Knowledge Graph

> Discover how RAGAnything's multimodal knowledge graph uses weighted relationship scoring to rank results. Learn about default weights and vector similarity integration.

- Repository: [✨Data Intelligence Lab@HKU✨/RAG-Anything](https://github.com/HKUDS/RAG-Anything)
- Tags: deep-dive
- Published: 2026-04-22

---

**RAG-Anything assigns a default weight of 10.0 to hierarchical "belongs_to" edges during graph construction, then multiplies these weights against vector similarity scores during retrieval to rank multimodal results.**

Building multimodal RAG systems requires more than chunked text and vector search.**weighted relationship scoring** in knowledge graphs bridges the gap between unstructured data and structured reasoning. RAG-Anything, an open-source multimodal RAG framework built on LightRAG, implements this through explicit edge weights that influence retrieval ranking. This article examines how the system calculates, stores, and applies these weights using actual source code from the HKUDS/RAG-Anything repository.

---

## How the Multimodal Knowledge Graph Stores Relationship Weights

RAG-Anything extends LightRAG's graph backend to handle multimodal entities—text snippets, image regions, table cells, and other extracted elements. Every relationship between these entities carries a **`weight`** field in its edge metadata.

### Edge Structure with Weight Field

When the pipeline creates a relationship, it constructs a dictionary with these fields:

```json
{
    "src_id": "<child_entity>",
    "tgt_id": "<parent_modal_entity>",
    "description": "Entity belongs to parent modal",
    "keywords": "belongs_to,part_of,contained_in",
    "source_id": "<chunk_id>",
    "weight": 10.0,
    "file_path": "<origin>"
}

```

The `weight` field is a floating-point value persisted through LightRAG's `upsert_edge()` method. This weight remains accessible during retrieval queries where the scoring layer combines it with semantic similarity scores.

---

## How "Belongs_To" Edges Receive Their Default Weight

The most common relationship type in RAG-Anything's multimodal graph is **"belongs_to"**—a hierarchical edge connecting child entities to their parent modal container. The system assigns these edges a fixed weight of **10.0** during construction.

### Weight Assignment in processor.py

The core implementation resides in [`raganything/processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/processor.py) at line 1315. Here the pipeline iterates through extracted entities and creates parent-child relationships:

```python
belongs_to_relation = {
    "src_id": entity_name,
    "tgt_id": modal_entity_name,
    "description": f"Entity {entity_name} belongs to {modal_entity_name}",
    "keywords": "belongs_to,part_of,contained_in",
    "source_id": chunk_id,
    "weight": 10.0,                     # ← fixed default weight

    "file_path": file_path,
}
await self.knowledge_graph_inst.upsert_edge(
    entity_name, modal_entity_name, belongs_to_relation
)

```

*Source: [`raganything/processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/processor.py), line 1315*

This hardcoded weight ensures that hierarchical relationships dominate the scoring function. The value 10.0 was chosen to significantly amplify these edges compared to potential noise from weaker associations.

---

## Alternative Path: Weighted Edges in modalprocessors.py

RAG-Anything supports multiple processing pipelines. The [`modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/modalprocessors.py) module provides an alternate entry point for manually constructed multimodal chunks, using the same weight assignment pattern.

### Consistent Weight Pattern at Line 770

```python

# From modalprocessors.py edge creation logic

edge_data = {
    "src_id": child_id,
    "tgt_id": parent_id,
    "relationship_type": "belongs_to",
    "weight": 10.0,  # Same default as processor.py

    # ... additional metadata

}
await kg.upsert_edge(child_id, parent_id, edge_data)

```

*Source: [`raganything/modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/modalprocessors.py), line 770*

This parallel implementation ensures weight consistency regardless of which pipeline processes the multimodal content. Both paths funnel into the same LightRAG graph backend where weights are stored and retrieved.

---

## How Weighted Scores Influence Retrieval Ranking

The retrieval pipeline in RAG-Anything combines **vector similarity** with **graph-based relevance**, using edge weights as multiplicative factors in the scoring function.

### Scoring Mechanism

During query execution, the system:

1. Retrieves candidate nodes via vector similarity search against chunk embeddings
2. Traverses outgoing edges from each candidate to gather relationship context
3. Multiplies base similarity scores by edge weights to produce final rankings

```python

# Conceptual scoring flow (pseudo-code based on LightRAG integration)

for candidate in vector_candidates:
    base_score = candidate["embedding_similarity"]
    
    # Accumulate weighted edge contributions

    graph_bonus = 0
    for edge in await graph.get_out_edges(candidate["id"]):
        edge_relevance = calculate_edge_relevance(edge, query)
        graph_bonus += edge["weight"] * edge_relevance  # weight applied here

    
    candidate["final_score"] = base_score + graph_bonus

```

The default weight of **10.0** for "belongs_to" edges means these hierarchical relationships contribute ten times more to the score than a hypothetical unweighted edge would. This prioritizes results that maintain semantic coherence with their parent modal context.

---

## Customizing Weights for Domain-Specific Relationships

RAG-Anything's weight system is extensible. Developers can override the default 10.0 value when constructing custom relationship types.

### Example: Lower Weight for Weak Associations

```python

# Custom relationship with reduced weight for loose connections

references_relation = {
    "src_id": "eq_42",
    "tgt_id": "section_3",
    "description": "Equation 42 references Section 3",
    "keywords": "references,cites",
    "source_id": chunk_id,
    "weight": 4.5,  # Lower than belongs_to default

    "file_path": file_path,
}
await self.knowledge_graph_inst.upsert_edge(
    "eq_42", "section_3", references_relation
)

```

This flexibility allows fine-tuning of retrieval behavior. Critical hierarchical links can retain high weights while peripheral associations receive lower priority.

---

## Key Source Files for Weighted Relationship Scoring

| File | Purpose | Key Location |
|------|---------|------------|
| [`raganything/processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/processor.py) | Core pipeline for multimodal entity extraction and "belongs_to" edge creation with default weight | Line 1315: `belongs_to_relation` definition |
| [`raganything/modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/modalprocessors.py) | Alternative processing path for manual multimodal chunks, same weight pattern | Line 770: Edge creation logic |
| [`README.md`](https://github.com/HKUDS/RAG-Anything/blob/main/README.md) | High-level documentation of weighted scoring strategy | "Weighted Relationship Scoring" section |
| [`raganything/prompt.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/prompt.py) | LLM prompts generating relationship metadata (keywords, descriptions) used in edge construction |
| [`raganything/callbacks.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/callbacks.py) | Pub-sub hooks enabling dynamic weight modification during processing |

---

## Summary

- **RAG-Anything's multimodal knowledge graph** stores relationship weights as floating-point values in edge metadata through LightRAG's `upsert_edge()` API.

- **Default weight of 10.0** is hardcoded for "belongs_to" hierarchical edges in [`processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/processor.py) (line 1315) and [`modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/modalprocessors.py) (line 770), ensuring parent-child relationships dominate retrieval scoring.

- **Retrieval scoring** combines vector similarity with graph traversal, multiplying base scores by edge weights to produce final rankings.

- **Extensible design** allows developers to override default weights for custom relationship types, enabling domain-specific tuning of retrieval behavior.

---

## Frequently Asked Questions

### What is the default weight value for relationships in RAG-Anything?

The default weight is **10.0**, assigned to all "belongs_to" edges created during multimodal processing. This value is hardcoded in both [`processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/processor.py) and [`modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/modalprocessors.py) to ensure consistent hierarchical relationship strength across the knowledge graph.

### How does the weight value affect search results in RAG-Anything?

The weight acts as a **multiplicative factor** during retrieval scoring. When the system ranks candidate results, it multiplies base vector similarity scores by the edge weights from traversed relationships. The default 10.0 value for "belongs_to" edges means hierarchical connections contribute substantially more to final rankings than they would with unweighted edges.

### Can developers customize relationship weights in RAG-Anything?

Yes. While the "belongs_to" relationship uses a fixed 10.0 default, developers can specify custom weights when constructing other relationship types. Simply pass a different `weight` value in the edge dictionary before calling `knowledge_graph_inst.upsert_edge()`. This enables fine-tuning for domain-specific scenarios where certain relationships should have stronger or weaker influence on retrieval.

### Where in the RAG-Anything codebase are relationship weights assigned?

Relationship weights are assigned in two primary locations:
- **[`raganything/processor.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/processor.py) at line 1315**: The main multimodal pipeline creates "belongs_to" edges with `weight: 10.0` when processing extracted entities.
- **[`raganything/modalprocessors.py`](https://github.com/HKUDS/RAG-Anything/blob/main/raganything/modalprocessors.py) at line 770**: An alternative processing path for manual multimodal chunks uses the same weight assignment pattern.

Both locations feed into LightRAG's graph storage via `upsert_edge()` calls.