πŸš€ -> Project on GitHub <-

LangGraph Multi-Hop Reasoning Guide

Navigation: Home Docs Quickstart Plugins OSINT

Overview

CrawlLama uses LangGraph for complex, multi-stage reasoning processes. This guide explains how the multi-hop reasoning system works and how to use it.

Architecture

Reasoning Graph

The multi-hop agent uses a StateGraph with the following nodes:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Router │──┐
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
 β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚Initial Searchβ”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚
 β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ Analyze │◄──┐
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
 β”‚ β”‚
 β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”‚
 β”‚ β”‚ β”‚
 Needs Ready β”‚
 more? β”‚ β”‚
 β”‚ β”‚ β”‚
 β–Ό β–Ό β”‚
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚Follow-Upβ”‚ β”‚Synthesizeβ”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚ β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚
 β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚Critique β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚
 β”Œβ”€β”€β”€β”΄β”€β”€β”€β”
 β”‚ β”‚
 Good Improve
 β”‚ β”‚
 β–Ό β”‚
 END └──► (back to Follow-Up)

Node Descriptions

1. Router Node

Purpose: Classifies query complexity

Logic:

Examples:

2. Initial Search Node

Purpose: First information search

Process:

  1. Performs web search with original query
  2. Collects initial information
  3. Stores results in context

3. Analyze Node

Purpose: Evaluation of collected information

Checks:

  1. Is information complete?
  2. What information is missing?
  3. Confidence score (0-100%)

Decision:

if complete and confidence >= threshold:
 β†’ Synthesize
else if steps < max_hops:
 β†’ Follow-Up
else:
 β†’ Synthesize (with available info)

4. Follow-Up Node

Purpose: Targeted follow-up searches

Process:

  1. LLM generates specific follow-up query
  2. Performs additional search
  3. Enriches context
  4. Back to Analyze

Example:

5. Synthesize Node

Purpose: Final answer generation

Process:

  1. Combines all context information
  2. Structures comprehensive answer
  3. Cites sources
  4. Generates coherent output

6. Critique Node (Optional)

Purpose: Self-critique of generated answer

Evaluation:

Decision:

if quality >= threshold:
 β†’ END
else if steps < max_hops:
 β†’ Follow-Up (for improvement)
else:
 β†’ END

Usage

Basic Usage

from core.langgraph_agent import MultiHopReasoningAgent
import json

# Load config
config = json.load(open("config.json"))

# Initialize agent
agent = MultiHopReasoningAgent(
 config=config,
 max_hops=3, # Max reasoning steps
 confidence_threshold=0.7, # Min confidence to stop
 enable_critique=True # Enable self-critique
)

# Query
result = agent.query("Compare Python and JavaScript for web development")

# Result structure
print(result["answer"]) # Final answer
print(result["confidence"]) # Confidence score
print(result["steps"]) # Number of hops taken
print(result["search_queries"]) # Queries performed
print(result["reasoning_path"]) # Step-by-step reasoning

Via CLI

# Enable multi-hop reasoning
python main.py --multihop "Complex question here"

# Custom max hops
python main.py --multihop --max-hops 5 "Your question"

Via API

curl -X POST http://localhost:8000/query \
 -H "Content-Type: application/json" \
 -d '{
 "query": "Compare Python and JavaScript",
 "use_multihop": true,
 "max_hops": 3
 }'

Configuration

config.json

{
 "llm": {
 "model": "qwen3:4b",
 "temperature": 0.7,
 "max_tokens": 4096
 },
 "multihop": {
 "enabled": true,
 "max_hops": 3,
 "confidence_threshold": 0.7,
 "enable_critique": true
 }
}

Parameter Tuning

max_hops:

confidence_threshold:

enable_critique:

Best Practices

1. When to Use Multi-Hop?

Suitable for:

Not suitable for:

2. Performance Optimization

# For fast answers
agent = MultiHopReasoningAgent(
 config=config,
 max_hops=2,
 confidence_threshold=0.6,
 enable_critique=False
)

# For maximum quality
agent = MultiHopReasoningAgent(
 config=config,
 max_hops=5,
 confidence_threshold=0.8,
 enable_critique=True
)

3. Monitoring

result = agent.query("Your question")

# Log reasoning path
for i, step in enumerate(result["reasoning_path"], 1):
 print(f"Step {i}: {step}")

# Check if enough information was gathered
if result["steps"] == max_hops:
 print("Warning: Reached max hops, might need more information")

Examples

Example 1: Technology Comparison

query = "Compare React and Vue.js for building SPAs"

result = agent.query(query)

# Reasoning path:
# 1. Router: Complex query detected
# 2. Initial search: "React vs Vue.js SPA"
# 3. Analyze: Need more details on performance
# 4. Follow-up: "React performance benchmarks"
# 5. Follow-up: "Vue.js modern features"
# 6. Synthesize: Comprehensive comparison
# 7. Critique: Quality check passed

Example 2: Pros/Cons Analysis

query = "What are the pros and cons of electric vehicles?"

result = agent.query(query)

# Expected hops: 2-3
# - Initial: General EV info
# - Follow-up 1: EV advantages
# - Follow-up 2: EV disadvantages
# - Synthesize: Balanced overview

Troubleshooting

Problem: Too Many Hops

Solution:

Problem: Poor Answer Quality

Solution:

Problem: Long Response Times

Solution:

Advanced Features

Adding Custom Nodes

# In langgraph_agent.py

def _custom_node(self, state: ReasoningState) -> ReasoningState:
 """Custom processing node."""
 # Your logic here
 return state

# Add to graph
workflow.add_node("custom", self._custom_node)
workflow.add_edge("analyze", "custom")

Extending State

class CustomReasoningState(ReasoningState):
 """Extended state with custom fields."""
 custom_data: List[str]
 extra_metadata: Dict[str, Any]

Further Resources