Partial Results Aggregation
@dataclass
class PartialResults:
succeeded: list[SubagentResult]
failed: list[SubagentResult]
total_tasks: int
@property
def success_rate(self) -> float:
return len(self.succeeded) / self.total_tasks
@property
def is_viable_for_synthesis(self) -> bool:
"""Can we produce a useful synthesis from what we have?"""
return self.success_rate >= 0.5 # At least half succeeded
def failed_descriptions(self) -> list[str]:
return [f"{r.task_description} ({r.error_category})" for r in self.failed]
def synthesis_prompt(self, original_task: str) -> str:
return f"""
Synthesize a research report from partial results.
ORIGINAL TASK: {original_task}
AVAILABLE DATA ({len(self.succeeded)} of {self.total_tasks} sources):
{chr(10).join(f"SOURCE {i+1}: {r.result}" for i, r in enumerate(self.succeeded))}
MISSING DATA ({len(self.failed)} sources failed):
{chr(10).join(f"- {desc}" for desc in self.failed_descriptions())}
INSTRUCTIONS:
1. Synthesize from the available sources
2. For each conclusion, note which sources support it
3. Explicitly acknowledge the missing data areas
4. Do NOT speculate or fill in the missing areas
5. Include a "Data Limitations" section noting what's missing and why it matters
The report should be useful despite the gaps, not pretend they don't exist.
"""
Storing Failed Tasks for Later Retry
class FailureTracker:
"""Tracks failed tasks for potential retry in follow-up batch."""
def __init__(self, storage):
self.storage = storage
def record_failures(self, run_id: str, failures: list[SubagentResult]):
self.storage.save(f"failures:{run_id}", {
"run_id": run_id,
"timestamp": utcnow(),
"failed_tasks": [
{
"task_id": f.task_id,
"task_description": f.task_description,
"error_category": f.error_category,
"is_retryable": f.is_retryable
}
for f in failures
]
})
def get_retryable_failures(self, run_id: str) -> list[dict]:
data = self.storage.load(f"failures:{run_id}")
if not data:
return []
return [t for t in data["failed_tasks"] if t["is_retryable"]]
Key Takeaways
- Partial success is valid — synthesize from what you have
- Tell Claude what’s missing in the synthesis prompt — prevents false confidence
- is_viable_for_synthesis — check if enough data exists before attempting synthesis
- Store failed task IDs — enables targeted retry in follow-up runs
- Data Limitations section in output — honest about gaps