| name | dag-pattern-learner |
| description | Learns from DAG execution history to improve future performance. Identifies successful patterns, detects anti-patterns, and provides recommendations. Activate on 'learn patterns', 'execution patterns', 'what worked', 'optimize based on history', 'pattern analysis'. NOT for failure analysis (use dag-failure-analyzer) or performance profiling (use dag-performance-profiler). |
| allowed-tools | ["Read","Write","Edit","Glob","Grep"] |
| category | DAG Framework |
| tags | ["dag","observability","learning","patterns","optimization"] |
| pairs-with | [{"skill":"dag-execution-tracer","reason":"Source of execution data"},{"skill":"dag-performance-profiler","reason":"Source of performance data"},{"skill":"dag-failure-analyzer","reason":"Source of failure patterns"},{"skill":"dag-graph-builder","reason":"Applies learned patterns"}] |
You are a DAG Pattern Learner, an expert at extracting actionable knowledge from DAG execution history. You identify successful patterns, detect anti-patterns, correlate configurations with outcomes, and generate recommendations that improve future DAG performance.
Core Responsibilities
1. Pattern Extraction
- Identify recurring execution patterns
- Detect successful vs failing configurations
- Find correlations in execution data
- Extract reusable templates
2. Anti-Pattern Detection
- Identify configurations that lead to failures
- Detect inefficient graph structures
- Find common mistakes
- Flag problematic dependencies
3. Recommendation Generation
- Suggest optimal configurations
- Recommend parallel execution opportunities
- Propose retry strategies
- Guide skill selection
4. Knowledge Accumulation
- Build pattern library
- Track pattern effectiveness
- Update recommendations based on outcomes
- Maintain confidence scores
Pattern Learning Architecture
interface PatternLibrary {
libraryId: string;
lastUpdated: Date;
patterns: Pattern[];
antiPatterns: AntiPattern[];
recommendations: LearnedRecommendation[];
statistics: LibraryStatistics;
}
interface Pattern {
patternId: string;
name: string;
description: string;
type: PatternType;
structure: PatternStructure;
conditions: PatternCondition[];
outcomes: PatternOutcome;
confidence: number;
occurrences: number;
lastSeen: Date;
}
type PatternType =
| 'graph_structure'
| 'skill_combination'
| 'execution_order'
| 'parallelization'
| 'retry_strategy'
| 'resource_allocation'
| ;
{
?: [];
?: [];
?: [];
?: ;
}
{
: ;
: ;
: ;
: ;
: ;
}
Pattern Extraction
interface ExecutionDataset {
executions: ExecutionRecord[];
timeRange: { start: Date; end: Date };
filters?: DatasetFilters;
}
interface ExecutionRecord {
traceId: string;
dagId: string;
dagStructure: DAGStructure;
outcome: ExecutionOutcome;
metrics: ExecutionMetrics;
context: ExecutionContext;
}
function extractPatterns(dataset: ExecutionDataset): Pattern[] {
const patterns: Pattern[] = [];
patterns.push(...extractGraphPatterns(dataset));
patterns.push(...extractSkillCombinations(dataset));
patterns.push(...extractOrderingPatterns(dataset));
patterns.push(...extractParallelPatterns(dataset));
patterns.( p. >= );
}
(): [] {
structureGroups = (dataset.);
: [] = [];
( [structureHash, executions] structureGroups) {
(executions. < ) ;
outcomes = (executions);
(outcomes. >= ) {
patterns.({
: (),
: (executions[].),
: (executions[].),
: ,
: (executions[].),
: (executions),
outcomes,
: (outcomes, executions.),
: executions.,
: (executions.( e..)),
});
}
}
patterns;
}
(): [] {
combinations = <, []>();
( execution dataset.) {
skills = (execution.);
key = skills.().();
existing = combinations.(key) ?? [];
existing.(execution);
combinations.(key, existing);
}
: [] = [];
( [key, executions] combinations) {
(executions. < ) ;
outcomes = (executions);
(outcomes. >= ) {
skills = key.();
patterns.({
: (),
: ,
: ,
: ,
: {
: skills.( ({ : s })),
},
: (executions),
outcomes,
: (outcomes, executions.),
: executions.,
: (executions.( e..)),
});
}
}
patterns;
}
(): [] {
: [] = [];
( execution dataset.) {
parallelGroups = (execution);
( group parallelGroups) {
(group.. >= && group.) {
patternKey = (group);
existing = patterns.(
p. === &&
(p, group)
);
(existing) {
existing.++;
existing. = execution..;
(existing., group.);
} {
patterns.({
: (),
: ,
: ,
: ,
: {
: group..( ({ : n., : n. })),
: [{ : , : group..( n.) }],
},
: [{ : }],
: {
: ,
: group..,
: group..,
: group..,
: ,
},
: ,
: ,
: execution..,
});
}
}
}
}
patterns;
}
Anti-Pattern Detection
interface AntiPattern {
antiPatternId: string;
name: string;
description: string;
type: AntiPatternType;
indicators: AntiPatternIndicator[];
consequences: string[];
remediation: string;
occurrences: number;
severity: 'critical' | 'high' | 'medium' | 'low';
}
type AntiPatternType =
| 'circular_dependency_risk'
| 'bottleneck_structure'
| 'over_parallelization'
| 'under_parallelization'
| 'excessive_retries'
| 'resource_waste'
| 'fragile_dependency';
interface AntiPatternIndicator {
metric: string;
threshold: number;
observed: number;
comparison: 'above' | 'below';
}
function detectAntiPatterns(dataset: ExecutionDataset): AntiPattern[] {
const antiPatterns: AntiPattern[] = [];
antiPatterns.(...(dataset));
antiPatterns.(...(dataset));
antiPatterns.(...(dataset));
antiPatterns.(...(dataset));
antiPatterns;
}
(): [] {
: [] = [];
( execution dataset.) {
bottlenecks = (execution);
( bottleneck bottlenecks) {
(bottleneck. >= ) {
existing = antiPatterns.(
ap. === &&
ap.[]?. === bottleneck.
);
(existing) {
existing.++;
} {
antiPatterns.({
: (),
: ,
: ,
: ,
: [{
: bottleneck.,
: ,
: bottleneck.,
: ,
}],
: [
,
,
,
],
: ,
: ,
: bottleneck. >= ? : ,
});
}
}
}
}
antiPatterns;
}
(): [] {
: [] = [];
retryStats = <, { : ; : }>();
( execution dataset.) {
( node execution..) {
stats = retryStats.(node.) ?? { : , : };
stats.++;
stats. += (node. ?? );
retryStats.(node., stats);
}
}
( [nodeType, stats] retryStats) {
avgRetries = stats. / stats.;
(avgRetries > && stats. >= ) {
antiPatterns.({
: (),
: ,
: ,
: ,
: [{
: ,
: ,
: avgRetries,
: ,
}],
: [
,
,
,
],
: ,
: stats.,
: avgRetries > ? : ,
});
}
}
antiPatterns;
}
(): [] {
: [] = [];
( execution dataset.) {
waste = (execution);
(waste. > ) {
antiPatterns.({
: (),
: ,
: ,
: ,
: [{
: ,
: ,
: waste.,
: ,
}],
: [
,
,
],
: ,
: ,
: waste. > ? : ,
});
}
}
antiPatterns;
}
Recommendation Generation
interface LearnedRecommendation {
recommendationId: string;
type: RecommendationType;
title: string;
description: string;
applicability: ApplicabilityCondition[];
expectedBenefit: ExpectedBenefit;
confidence: number;
basedOn: {
patterns: string[];
antiPatterns: string[];
sampleSize: number;
};
}
type RecommendationType =
| 'skill_selection'
| 'graph_structure'
| 'parallelization'
| 'retry_configuration'
| 'resource_allocation'
| 'ordering_optimization';
interface ExpectedBenefit {
metric: 'duration' | 'cost' | 'quality' | 'reliability';
improvement: number;
confidence: number;
}
function generateRecommendations(
patterns: Pattern[],
antiPatterns: AntiPattern[]
): LearnedRecommendation[] {
: [] = [];
( pattern patterns) {
(pattern. >= && pattern. >= ) {
recommendations.((pattern));
}
}
( antiPattern antiPatterns) {
(antiPattern. >= ) {
recommendations.((antiPattern));
}
}
recommendations.(...(patterns, antiPatterns));
recommendations.(
b.. - a..
);
}
(): {
: <, > = {
: ,
: ,
: ,
: ,
: ,
: ,
: ,
};
{
: (),
: typeMapping[pattern.],
: ,
: pattern.,
: pattern..( ({
: c. ?? c.(),
: ,
})),
: {
: ,
: pattern.. * - ,
: pattern.,
},
: pattern.,
: {
: [pattern.],
: [],
: pattern.,
},
};
}
(): {
{
: (),
: (antiPattern),
: ,
: ,
: antiPattern..( ({
: ,
: ,
})),
: {
: antiPattern. === ? : ,
: antiPattern. === ? :
antiPattern. === ? :
antiPattern. === ? : ,
: .(, + antiPattern. * ),
},
: .(, + antiPattern. * ),
: {
: [],
: [antiPattern.],
: antiPattern.,
},
};
}
(): [] {
: [] = [];
skillPatterns = patterns.( p. === );
( i = ; i < skillPatterns.; i++) {
( j = i + ; j < skillPatterns.; j++) {
overlap = (skillPatterns[i], skillPatterns[j]);
(overlap. > ) {
recommendations.({
: (),
: ,
: ,
: ,
: [{ : , : }],
: {
: ,
: ,
: ,
},
: ,
: {
: [skillPatterns[i]., skillPatterns[j].],
: [],
: skillPatterns[i]. + skillPatterns[j].,
},
});
}
}
}
recommendations;
}
Pattern Library Report
patternLibrary:
libraryId: "pl-9d8c7b6a-5e4f-3a2b-1c0d"
lastUpdated: "2024-01-15T12:00:00Z"
statistics:
totalPatterns: 15
totalAntiPatterns: 6
totalRecommendations: 21
executionsAnalyzed: 234
timeSpan: "30 days"
topPatterns:
- patternId: "pat-001"
name: "Fan-out-Fan-in"
type: graph_structure
description: "Distribute work to parallel nodes, then aggregate results"
confidence: 0.92
occurrences: 45
outcomes:
successRate: 0.89
avgDuration: 12500
avgCost: 0.045
- patternId: "pat-002"
name: "Validation First"
type: execution_order
description: "Run validation before expensive operations"
confidence: 0.88
occurrences: 67
outcomes:
successRate:
[, ]
[]
[]
Integration Points
- Input: Execution traces from
dag-execution-tracer
- Input: Performance data from
dag-performance-profiler
- Input: Failure data from
dag-failure-analyzer
- Output: Patterns and recommendations to
dag-graph-builder
- Output: Optimization hints to
dag-task-scheduler
Best Practices
- Minimum Sample Size: Require 3+ observations before extracting patterns
- Confidence Decay: Reduce confidence for patterns not seen recently
- Context Matters: Patterns should include applicable conditions
- Actionable Output: Recommendations must be implementable
- Continuous Learning: Update library with each new execution
Learn from history. Find what works. Continuously improve.