Result Aggregation Strategies
When multiple parallel workers produce results, you need strategies to combine them meaningfully. This lesson covers techniques for aggregating diverse outputs.
Aggregation Challenges
Combining parallel results is not always straightforward:
- Different formats: Workers may produce varying output structures
- Conflicting data: Workers may disagree on findings
- Varying quality: Some results may be more reliable than others
- Incomplete data: Some workers may return partial results
Simple Aggregation Patterns
Array Collection
Gather all results into a list:
const allResults = await Promise.all(workers.map(w => w.process(input)));
return { items: allResults, count: allResults.length };
Object Merge
Combine results into a single object:
async function mergeObjects(workers, input) {
const results = await Promise.all(workers.map(w => w.process(input)));
return results.reduce((merged, result) => {
return { ...merged, ...result };
}, {});
}
Field-Specific Combination
Different combination strategies per field:
Loading Prompt Playground...
Statistical Aggregation
Average and Weighted Average
function aggregate(results, weights = null) {
if (!weights) {
// Simple average
return results.reduce((sum, r) => sum + r, 0) / results.length;
}
// Weighted average
let weightedSum = 0;
let totalWeight = 0;
for (let i = 0; i < results.length; i++) {
weightedSum += results[i] * weights[i];
totalWeight += weights[i];
}
return weightedSum / totalWeight;
}
Median for Outlier Resistance
function medianAggregate(results) {
const sorted = [...results].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return (sorted[mid - 1] + sorted[mid]) / 2;
}
return sorted[mid];
}
Voting Systems
function majorityVote(results) {
const votes = {};
for (const result of results) {
votes[result] = (votes[result] || 0) + 1;
}
const winner = Object.entries(votes)
.sort(([, a], [, b]) => b - a)[0];
return {
result: winner[0],
votes: winner[1],
total: results.length,
agreement: winner[1] / results.length
};
}
Conflict Resolution
Priority-Based Resolution
When workers disagree, use priority:
function resolveByPriority(results, priorities) {
// Sort by priority (higher = more trusted)
const sorted = results
.map((r, i) => ({ result: r, priority: priorities[i] }))
.sort((a, b) => b.priority - a.priority);
// Return highest priority result
return sorted[0].result;
}
Confidence-Based Resolution
Use confidence scores to break ties:
Loading Prompt Playground...
Human Escalation
When automated resolution fails:
async function resolveWithEscalation(results, threshold = 0.6) {
const consensus = findConsensus(results);
if (consensus.agreement >= threshold) {
return { result: consensus.result, source: 'automated' };
}
// No clear winner - queue for human review
const ticket = await createReviewTicket({
results,
disagreement: describeDisagreement(results),
suggestedResolution: consensus.result
});
return {
result: null,
source: 'pending_human_review',
ticket: ticket.id
};
}
Structured Result Combination
Nested Aggregation
For complex nested structures:
function aggregateNested(results) {
return {
metadata: {
workerCount: results.length,
timestamp: Date.now()
},
analysis: {
sentiment: averageField(results, 'analysis.sentiment'),
confidence: minField(results, 'analysis.confidence')
},
entities: mergeArrays(results.map(r => r.entities)),
summary: selectBest(results.map(r => r.summary), 'length')
};
}
Template-Based Combination
Loading Prompt Playground...
Quality-Based Aggregation
Filtering Low-Quality Results
function filterAndAggregate(results, qualityField = 'confidence', minQuality = 0.5) {
const qualified = results.filter(r => r[qualityField] >= minQuality);
if (qualified.length === 0) {
return { error: 'No results met quality threshold' };
}
return aggregate(qualified);
}
Quality-Weighted Combination
function qualityWeightedAggregate(results) {
const totalQuality = results.reduce((sum, r) => sum + r.confidence, 0);
const weighted = results.reduce((acc, result) => {
const weight = result.confidence / totalQuality;
for (const [key, value] of Object.entries(result.scores)) {
acc[key] = (acc[key] || 0) + value * weight;
}
return acc;
}, {});
return weighted;
}
Exercise: Design an Aggregation Strategy
Design aggregation for this complex scenario:
Loading Prompt Playground...
Key Takeaways
- Simple aggregation works for homogeneous results
- Statistical methods (average, median, voting) handle numeric data
- Conflict resolution needs clear priority rules
- Confidence-based resolution uses quality signals
- Escalate to humans when automated resolution fails
- Template-based combination structures complex outputs
- Filter low-quality results before aggregating
- Weight contributions by result quality
- Design aggregation strategy based on the specific use case
In the next module, we'll explore memory and context management across chain steps.

