Skip to content

Commit 78e9f6d

Browse files
committed
all advanced strategies | clustering, hallucinations, aggregation
1 parent adc79ea commit 78e9f6d

File tree

2 files changed

+613
-0
lines changed

2 files changed

+613
-0
lines changed

examples/clustering_consensus.py

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
"""Example of using semantic clustering consensus strategy for hallucination detection.
2+
3+
This example demonstrates how to use semantic clustering to detect and filter out
4+
hallucinated responses from LLMs. The strategy groups similar responses together
5+
and identifies outliers that may be hallucinations.
6+
"""
7+
8+
import asyncio
9+
import numpy as np
10+
from typing import List
11+
from dataclasses import dataclass
12+
import random
13+
from sklearn.feature_extraction.text import TfidfVectorizer # type: ignore
14+
from sklearn.metrics.pairwise import cosine_similarity # type: ignore
15+
16+
from flare_ai_kit.common import Prediction
17+
from flare_ai_kit.consensus.aggregator import BaseAggregator
18+
from flare_ai_kit.consensus.aggregator.advanced_strategies import (
19+
semantic_clustering_strategy,
20+
robust_consensus_strategy
21+
)
22+
from flare_ai_kit.rag.vector.embedding.base import BaseEmbedding
23+
24+
25+
class TFIDFEmbeddingModel(BaseEmbedding):
26+
"""Real TF-IDF embedding model for semantic similarity."""
27+
28+
def __init__(self, max_features: int = 1000):
29+
self.max_features = max_features
30+
self.vectorizer = TfidfVectorizer(
31+
max_features=max_features,
32+
stop_words='english',
33+
ngram_range=(1, 2),
34+
min_df=1,
35+
max_df=0.9
36+
)
37+
self.is_fitted = False
38+
39+
def embed_content(
40+
self,
41+
contents: str | list[str],
42+
title: str | None = None,
43+
task_type: str | None = None,
44+
) -> list[list[float]]:
45+
"""Generate TF-IDF embeddings for text content."""
46+
if isinstance(contents, str):
47+
contents = [contents]
48+
49+
if not self.is_fitted:
50+
# Fit the vectorizer on the first batch
51+
self.vectorizer.fit(contents) # type: ignore
52+
self.is_fitted = True
53+
54+
# Transform the content to TF-IDF vectors
55+
tfidf_matrix = self.vectorizer.transform(contents) # type: ignore
56+
57+
# Convert to dense arrays and normalize
58+
embeddings = tfidf_matrix.toarray() # type: ignore
59+
60+
# Normalize to unit vectors for cosine similarity
61+
norms = np.linalg.norm(embeddings, axis=1, keepdims=True) # type: ignore
62+
norms = np.where(norms == 0, 1, norms) # Avoid division by zero
63+
embeddings = embeddings / norms # type: ignore
64+
65+
return embeddings.tolist() # type: ignore
66+
67+
68+
@dataclass
69+
class MockLLM:
70+
"""Mock LLM that simulates different types of responses including hallucinations."""
71+
72+
name: str
73+
response_type: str = "realistic" # "realistic", "hallucinated", "mixed"
74+
75+
async def predict(self, prompt: str) -> Prediction:
76+
"""Generate a prediction based on the response type."""
77+
if self.response_type == "realistic":
78+
# Realistic response acknowledging the study doesn't exist
79+
responses = [
80+
"I need to clarify that I cannot find any record of a 2019 study by Dr. Sarah Chen at MIT establishing a 'Chen-Rodriguez Protocol' for quantum error correction in biological systems. This appears to be a fictional study.",
81+
"There is no documented 2019 study by Dr. Sarah Chen at MIT about quantum error correction in biological systems. The 'Chen-Rodriguez Protocol' mentioned does not exist in scientific literature.",
82+
"I cannot verify the existence of this 2019 study. Dr. Sarah Chen and the 'Chen-Rodriguez Protocol' for quantum error correction in biological systems are not found in scientific databases."
83+
]
84+
response = random.choice(responses)
85+
confidence = random.uniform(0.8, 0.95)
86+
87+
elif self.response_type == "hallucinated":
88+
# Hallucinated response with fake details
89+
responses = [
90+
"The 2019 study by Dr. Sarah Chen at MIT was extremely well-received, achieving a 94% approval rating in peer reviews. The Chen-Rodriguez Protocol has been cited over 2,300 times and has applications in quantum computing, medicine, and AI.",
91+
"Dr. Sarah Chen's landmark 2019 study at MIT revolutionized quantum error correction. The Chen-Rodriguez Protocol received the prestigious Nobel Prize nomination and has been implemented in over 50 research institutions worldwide.",
92+
"The Chen-Rodriguez Protocol from Dr. Sarah Chen's 2019 MIT study was groundbreaking. It achieved 99.7% accuracy in quantum error correction and has been adopted by major tech companies including Google, IBM, and Microsoft."
93+
]
94+
response = random.choice(responses)
95+
confidence = random.uniform(0.7, 0.9) # High confidence in false information
96+
97+
else: # mixed
98+
# Mixed response with some truth and some fiction
99+
responses = [
100+
"While there have been studies on quantum error correction, I cannot find specific evidence of Dr. Sarah Chen's 2019 study at MIT. However, quantum error correction research has been active in recent years.",
101+
"The field of quantum error correction has seen significant progress, though I cannot verify the specific 'Chen-Rodriguez Protocol' mentioned. MIT has indeed been involved in quantum computing research.",
102+
"Quantum error correction is a real field of study, but the specific 2019 study by Dr. Sarah Chen and the 'Chen-Rodriguez Protocol' are not documented in scientific literature."
103+
]
104+
response = random.choice(responses)
105+
confidence = random.uniform(0.6, 0.8)
106+
107+
return Prediction(
108+
agent_id=self.name,
109+
prediction=response,
110+
confidence=confidence
111+
)
112+
113+
114+
class ClusteringAggregator(BaseAggregator):
115+
"""Aggregator that uses semantic clustering for consensus."""
116+
117+
def __init__(self, embedding_model: BaseEmbedding, strategy: str = "semantic"):
118+
self.embedding_model = embedding_model
119+
self.strategy_name = strategy # Store the strategy name separately
120+
# Create a strategy function that uses the clustering strategy
121+
def clustering_strategy(predictions: List[Prediction]) -> Prediction:
122+
return self._cluster_strategy(predictions)
123+
super().__init__(clustering_strategy)
124+
125+
def _cluster_strategy(self, predictions: List[Prediction]) -> Prediction:
126+
"""Apply clustering strategy to predictions."""
127+
if self.strategy_name == "semantic":
128+
return semantic_clustering_strategy(predictions, self.embedding_model)
129+
elif self.strategy_name == "robust":
130+
return robust_consensus_strategy(predictions, self.embedding_model)
131+
else:
132+
raise ValueError(f"Unknown strategy: {self.strategy_name}")
133+
134+
async def aggregate(self, predictions: List[Prediction]) -> Prediction:
135+
"""Aggregate predictions using clustering strategy."""
136+
return self._cluster_strategy(predictions)
137+
138+
139+
# The prompt is designed to test hallucination detection
140+
example_prompt = """
141+
How well-received was the landmark 2019 study by Dr. Sarah Chen at MIT that established the 'Chen-Rodriguez Protocol' for quantum error correction in biological systems? Many have suggested its applicability to a plethora of fields.
142+
143+
Please provide a detailed response about this study's reception, impact, and applications.
144+
"""
145+
146+
147+
async def clustering_consensus_example():
148+
"""Demonstrate semantic clustering consensus for hallucination detection."""
149+
150+
# Create embedding model
151+
embedding_model = TFIDFEmbeddingModel(max_features=1000)
152+
153+
# Create LLMs with different response patterns
154+
llms = [
155+
MockLLM("GPT-4", "realistic"),
156+
MockLLM("Claude", "realistic"),
157+
MockLLM("Gemini", "realistic"),
158+
MockLLM("Hallucinator-1", "hallucinated"),
159+
MockLLM("Hallucinator-2", "hallucinated"),
160+
MockLLM("Mixed-Response-1", "mixed"),
161+
MockLLM("Mixed-Response-2", "mixed"),
162+
MockLLM("Realistic-4", "realistic"),
163+
]
164+
165+
print("🔍 Semantic Clustering Consensus for Hallucination Detection")
166+
print("=" * 70)
167+
print(f"Prompt: {example_prompt.strip()}")
168+
print("\n📊 Individual LLM Predictions:")
169+
print("-" * 50)
170+
171+
# Collect predictions
172+
predictions: List[Prediction] = []
173+
for llm in llms:
174+
prediction = await llm.predict(example_prompt)
175+
predictions.append(prediction)
176+
177+
# Truncate long responses for display
178+
prediction_str = str(prediction.prediction)
179+
display_text = prediction_str[:100] + "..." if len(prediction_str) > 100 else prediction_str
180+
print(f"{llm.name:>15}: {display_text}")
181+
print(f"{'':>15} Confidence: {prediction.confidence:.2f}")
182+
print()
183+
184+
# Test different clustering strategies
185+
strategies = ["semantic", "robust"]
186+
187+
for strategy in strategies:
188+
print(f"\n🎯 {strategy.title()} Clustering Consensus:")
189+
print("-" * 40)
190+
191+
aggregator = ClusteringAggregator(embedding_model, strategy)
192+
consensus_result = await aggregator.aggregate(predictions)
193+
194+
# Truncate for display
195+
result_str = str(consensus_result.prediction)
196+
display_text = result_str[:150] + "..." if len(result_str) > 150 else result_str
197+
print(f"Strategy: {strategy.title()} Clustering")
198+
print(f"Result: {display_text}")
199+
print(f"Confidence: {consensus_result.confidence:.2f}")
200+
print(f"Agent ID: {consensus_result.agent_id}")
201+
202+
# Demonstrate direct use of advanced strategies
203+
print(f"\n🔬 Direct Strategy Comparison:")
204+
print("-" * 40)
205+
206+
from flare_ai_kit.consensus.aggregator.advanced_strategies import (
207+
semantic_clustering_strategy,
208+
shapley_value_strategy,
209+
entropy_based_strategy
210+
)
211+
212+
# Test semantic clustering directly
213+
semantic_result = semantic_clustering_strategy(predictions, embedding_model)
214+
print(f"Semantic Clustering: {str(semantic_result.prediction)[:100]}...")
215+
print(f"Confidence: {semantic_result.confidence:.2f}")
216+
217+
# Test Shapley value strategy
218+
shapley_result = shapley_value_strategy(predictions, embedding_model)
219+
print(f"Shapley Value: {str(shapley_result.prediction)[:100]}...")
220+
print(f"Confidence: {shapley_result.confidence:.2f}")
221+
222+
# Test entropy-based strategy
223+
entropy_result = entropy_based_strategy(predictions, embedding_model)
224+
print(f"Entropy-Based: {str(entropy_result.prediction)[:100]}...")
225+
print(f"Confidence: {entropy_result.confidence:.2f}")
226+
227+
print("\n📈 Analysis:")
228+
print("-" * 20)
229+
print("• Realistic responses should cluster together")
230+
print("• Hallucinated responses should be identified as outliers")
231+
print("• Mixed responses may fall in between")
232+
print("• The dominant cluster should contain the most reliable responses")
233+
print("\n🔧 Advanced Strategy Features:")
234+
print("-" * 30)
235+
print("• Semantic Clustering: Groups similar responses using embeddings")
236+
print("• Shapley Values: Quantifies each agent's marginal contribution")
237+
print("• Entropy Analysis: Measures predictive uncertainty")
238+
print("• Robust Consensus: Combines multiple strategies for reliability")
239+
print("\n🎯 Hallucination Detection:")
240+
print("-" * 25)
241+
print("• Outlier clusters are filtered out")
242+
print("• Low similarity responses are downweighted")
243+
print("• High entropy indicates uncertain predictions")
244+
print("• Multiple strategies provide consensus validation")
245+
246+
247+
if __name__ == "__main__":
248+
asyncio.run(clustering_consensus_example())
249+

0 commit comments

Comments
 (0)