class GraphRagStrategyOptimizer {
constructor(flowName, apiToken) {
this.flowName = flowName;
this.apiToken = apiToken;
this.baseUrl = `https://${flowName}.flows.graphorlm.com`;
}
async getAllNodes() {
const response = await fetch(`${this.baseUrl}/graph-rag`, {
headers: { 'Authorization': `Bearer ${this.apiToken}` }
});
if (!response.ok) {
throw new Error(`Failed to fetch nodes: ${response.statusText}`);
}
return await response.json();
}
async optimizeKnowledgeGraphStrategy(nodeId, targetProfile = 'balanced') {
const profiles = {
'precision': {
topK: 8,
description: 'High-precision entity matching with focused relationships',
entityFocus: 'high',
relationshipFocus: 'low',
resourceUsage: 'low'
},
'balanced': {
topK: 15,
description: 'Balanced entity coverage and relationship exploration',
entityFocus: 'medium',
relationshipFocus: 'medium',
resourceUsage: 'medium'
},
'comprehensive': {
topK: 30,
description: 'Thorough knowledge graph exploration with extensive relationships',
entityFocus: 'high',
relationshipFocus: 'high',
resourceUsage: 'high'
},
'unlimited': {
topK: null,
description: 'Complete knowledge graph analysis with exhaustive coverage',
entityFocus: 'maximum',
relationshipFocus: 'maximum',
resourceUsage: 'maximum'
}
};
const profile = profiles[targetProfile];
if (!profile) {
throw new Error(`Invalid profile: ${targetProfile}. Available: ${Object.keys(profiles).join(', ')}`);
}
console.log(`π§ Optimizing Graph RAG node ${nodeId} for ${targetProfile} profile`);
console.log(` Configuration: Top K = ${profile.topK || 'unlimited'}`);
console.log(` Description: ${profile.description}`);
console.log(` Entity Focus: ${profile.entityFocus}`);
console.log(` Relationship Focus: ${profile.relationshipFocus}`);
console.log(` Resource Usage: ${profile.resourceUsage}`);
const response = await fetch(`${this.baseUrl}/graph-rag/${nodeId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${this.apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ config: { topK: profile.topK } })
});
if (!response.ok) {
throw new Error(`Optimization failed: ${response.statusText}`);
}
const result = await response.json();
console.log(`β
${result.message}`);
return result;
}
async batchKnowledgeGraphOptimization(optimizations) {
console.log(`π Starting batch knowledge graph optimization for ${optimizations.length} nodes`);
const results = [];
for (const { nodeId, profile, reason } of optimizations) {
try {
console.log(`\nπ― Processing ${nodeId}: ${reason || 'Manual optimization'}`);
const result = await this.optimizeKnowledgeGraphStrategy(nodeId, profile);
results.push({ nodeId, profile, success: true, result, reason });
// Small delay to avoid overwhelming the API
await new Promise(resolve => setTimeout(resolve, 800));
} catch (error) {
console.error(`β Failed to optimize ${nodeId}: ${error.message}`);
results.push({ nodeId, profile, success: false, error: error.message, reason });
}
}
this.generateKnowledgeGraphOptimizationReport(results);
return results;
}
generateKnowledgeGraphOptimizationReport(results) {
console.log('\nπ Knowledge Graph Optimization Report');
console.log('=====================================');
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Total Operations: ${results.length}`);
console.log(`Successful: ${successful.length}`);
console.log(`Failed: ${failed.length}`);
if (successful.length > 0) {
console.log('\nβ
Successful Knowledge Graph Optimizations:');
successful.forEach(({ nodeId, profile, reason }) => {
console.log(` ${nodeId} β ${profile} profile (${reason})`);
});
}
if (failed.length > 0) {
console.log('\nβ Failed Optimizations:');
failed.forEach(({ nodeId, profile, error, reason }) => {
console.log(` ${nodeId} (${profile}): ${error} - ${reason}`);
});
}
}
async recommendKnowledgeGraphOptimizations() {
const nodes = await this.getAllNodes();
const recommendations = [];
console.log('π Analyzing knowledge graph nodes for optimization opportunities...\n');
for (const node of nodes) {
const config = node.data.config || {};
const result = node.data.result || {};
const topK = config.topK;
const nodeName = node.data.name;
let recommendation = null;
// Knowledge graph specific analysis
const entityDensity = result.total_chunks > 0 ?
(result.total_entities || 0) / result.total_chunks : 0;
const relationshipRatio = result.total_entities > 0 ?
(result.total_relationships || 0) / result.total_entities : 0;
// Analysis logic for knowledge graphs
if (result.has_error) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Knowledge graph construction errors',
suggestedProfile: 'precision',
reason: 'Reduce complexity to address entity extraction stability issues',
priority: 'high',
entityDensity,
relationshipRatio
};
} else if (entityDensity > 0 && entityDensity < 1.0) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: `Low entity density: ${entityDensity.toFixed(2)} entities/chunk`,
suggestedProfile: 'comprehensive',
reason: 'Increase Top K to improve entity extraction coverage',
priority: 'medium',
entityDensity,
relationshipRatio
};
} else if (relationshipRatio > 0 && relationshipRatio < 0.5) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: `Low relationship ratio: ${relationshipRatio.toFixed(2)} relationships/entity`,
suggestedProfile: 'comprehensive',
reason: 'Increase relationship discovery through comprehensive strategy',
priority: 'medium',
entityDensity,
relationshipRatio
};
} else if (topK && topK > 40) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Very high Top K may cause excessive resource usage',
suggestedProfile: 'balanced',
reason: 'Balance knowledge graph quality with resource efficiency',
priority: 'low',
entityDensity,
relationshipRatio
};
} else if (result.processing && topK > 25) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Long processing time with high Top K for knowledge graph',
suggestedProfile: 'balanced',
reason: 'Balance knowledge graph construction time and quality',
priority: 'medium',
entityDensity,
relationshipRatio
};
}
if (recommendation) {
recommendations.push(recommendation);
}
}
this.printKnowledgeGraphRecommendations(recommendations);
return recommendations;
}
printKnowledgeGraphRecommendations(recommendations) {
if (recommendations.length === 0) {
console.log('β
No knowledge graph optimization recommendations - all nodes appear well-configured');
return;
}
console.log(`π‘ Found ${recommendations.length} knowledge graph optimization opportunities:\n`);
const byPriority = {
high: recommendations.filter(r => r.priority === 'high'),
medium: recommendations.filter(r => r.priority === 'medium'),
low: recommendations.filter(r => r.priority === 'low')
};
['high', 'medium', 'low'].forEach(priority => {
if (byPriority[priority].length > 0) {
const icon = priority === 'high' ? 'π΄' : priority === 'medium' ? 'π‘' : 'π’';
console.log(`${icon} ${priority.toUpperCase()} Priority (${byPriority[priority].length} items):`);
byPriority[priority].forEach(rec => {
console.log(` π§ ${rec.nodeName} (${rec.nodeId})`);
console.log(` Issue: ${rec.issue}`);
console.log(` Current Top K: ${rec.currentTopK || 'unlimited'}`);
console.log(` Suggested: ${rec.suggestedProfile} profile`);
console.log(` Reason: ${rec.reason}`);
if (rec.entityDensity > 0) {
console.log(` Entity Density: ${rec.entityDensity.toFixed(2)} entities/chunk`);
}
if (rec.relationshipRatio > 0) {
console.log(` Relationship Ratio: ${rec.relationshipRatio.toFixed(2)} relationships/entity`);
}
console.log();
});
}
});
}
async autoOptimizeKnowledgeGraph() {
const recommendations = await this.recommendKnowledgeGraphOptimizations();
if (recommendations.length === 0) {
console.log('π― No automatic optimizations needed');
return [];
}
const autoOptimizations = recommendations
.filter(rec => rec.priority === 'high')
.map(rec => ({
nodeId: rec.nodeId,
profile: rec.suggestedProfile,
reason: rec.reason
}));
if (autoOptimizations.length === 0) {
console.log('π― No high-priority automatic optimizations needed');
return [];
}
console.log(`π€ Auto-optimizing ${autoOptimizations.length} high-priority knowledge graph nodes...`);
return await this.batchKnowledgeGraphOptimization(autoOptimizations);
}
}
// Usage examples
const optimizer = new GraphRagStrategyOptimizer('my-rag-pipeline', 'YOUR_API_TOKEN');
// Single node optimization
optimizer.optimizeKnowledgeGraphStrategy('graph-rag-123', 'comprehensive').catch(console.error);
// Batch optimization
const batchOps = [
{ nodeId: 'graph-rag-123', profile: 'precision', reason: 'High entity density detected' },
{ nodeId: 'graph-rag-456', profile: 'balanced', reason: 'Optimal balance needed' },
{ nodeId: 'graph-rag-789', profile: 'comprehensive', reason: 'Low relationship ratio' }
];
optimizer.batchKnowledgeGraphOptimization(batchOps).catch(console.error);
// Get recommendations
optimizer.recommendKnowledgeGraphOptimizations().catch(console.error);
// Auto-optimize high priority issues
optimizer.autoOptimizeKnowledgeGraph().catch(console.error);