| name | dag-output-validator |
| description | Validates agent outputs against expected schemas and quality criteria. Ensures outputs meet structural requirements and content standards. Activate on 'validate output', 'output validation', 'schema validation', 'check output', 'output quality'. NOT for confidence scoring (use dag-confidence-scorer) or hallucination detection (use dag-hallucination-detector). |
| allowed-tools | ["Read","Write","Edit","Glob","Grep"] |
| category | DAG Framework |
| tags | ["dag","quality","validation","schemas","outputs"] |
| pairs-with | [{"skill":"dag-confidence-scorer","reason":"Provides validated output for scoring"},{"skill":"dag-hallucination-detector","reason":"Works together on quality checks"},{"skill":"dag-result-aggregator","reason":"Validates before aggregation"}] |
You are a DAG Output Validator, an expert at validating agent outputs against expected schemas and quality criteria. You ensure outputs meet structural requirements, contain required fields, and satisfy quality thresholds before being passed to downstream nodes.
Core Responsibilities
1. Schema Validation
- Validate output structure against JSON schemas
- Check required fields and types
- Validate nested structures
2. Content Validation
- Check content length and format
- Validate data ranges and constraints
- Ensure completeness of outputs
3. Quality Assessment
- Apply quality scoring rules
- Check against minimum thresholds
- Flag outputs needing review
4. Error Reporting
- Generate detailed validation reports
- Provide specific error locations
- Suggest corrections
Validation Architecture
interface OutputSchema {
type: 'object' | 'array' | 'string' | 'number' | 'boolean';
properties?: Record<string, OutputSchema>;
items?: OutputSchema;
required?: string[];
minLength?: number;
maxLength?: number;
minimum?: number;
maximum?: number;
pattern?: string;
enum?: unknown[];
format?: 'date' | 'uri' | 'email' | 'markdown' | 'code';
}
interface ValidationResult {
valid: boolean;
score: number;
errors: ValidationError[];
warnings: ValidationWarning[];
metadata: ValidationMetadata;
}
interface ValidationError {
path: string;
code: ;
: ;
: ;
: ;
: | ;
}
{
: ;
: ;
: ;
?: ;
}
Schema Validation
function validateAgainstSchema(
output: unknown,
schema: OutputSchema,
path: string = '$'
): ValidationError[] {
const errors: ValidationError[] = [];
const actualType = getType(output);
if (actualType !== schema.type) {
errors.push({
path,
code: 'TYPE_MISMATCH',
message: `Expected ${schema.type}, got ${actualType}`,
expected: schema.type,
actual: actualType,
severity: 'error',
});
return errors;
}
if (schema.type === 'object' && schema.properties) {
const obj = output as Record<string, unknown>;
for (const field of schema.required ?? []) {
if (!(field in obj)) {
errors.({
: ,
: ,
: ,
: ,
: ,
: ,
});
}
}
( [key, propSchema] .(schema.)) {
(key obj) {
errors.(...(
obj[key],
propSchema,
));
}
}
}
(schema. === && schema.) {
arr = output [];
(schema. && arr. < schema.) {
errors.({
path,
: ,
: ,
: schema.,
: arr.,
: ,
});
}
arr.( {
errors.(...(
item,
schema.!,
));
});
}
(schema. === ) {
str = output ;
(schema. && str. < schema.) {
errors.({
path,
: ,
: ,
: schema.,
: str.,
: ,
});
}
(schema.) {
regex = (schema.);
(!regex.(str)) {
errors.({
path,
: ,
: ,
: schema.,
: str,
: ,
});
}
}
}
(schema. === ) {
num = output ;
(schema. !== && num < schema.) {
errors.({
path,
: ,
: ,
: schema.,
: num,
: ,
});
}
(schema. !== && num > schema.) {
errors.({
path,
: ,
: ,
: schema.,
: num,
: ,
});
}
}
errors;
}
Content Quality Validation
interface ContentRules {
minWordCount?: number;
maxWordCount?: number;
requiredSections?: string[];
prohibitedPatterns?: string[];
codeBlockRequired?: boolean;
linksRequired?: boolean;
}
function validateContentQuality(
content: string,
rules: ContentRules
): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
let qualityScore = 1.0;
const words = content.split(/\s+/).filter(w => w.length > 0);
if (rules.minWordCount && words.length < rules.minWordCount) {
errors.push({
path: '$.content',
code: 'CONTENT_TOO_SHORT',
message: `Content has ${words.length} words, minimum is ${rules.minWordCount}`,
: rules.,
: words.,
: ,
});
qualityScore -= ;
}
(rules. && words. > rules.) {
warnings.({
: ,
: ,
: ,
: ,
});
qualityScore -= ;
}
(rules.) {
( section rules.) {
sectionPattern = (, );
(!sectionPattern.(content)) {
errors.({
: ,
: ,
: ,
: section,
: ,
: ,
});
qualityScore -= ;
}
}
}
(rules.) {
( pattern rules.) {
regex = (pattern, );
matches = content.(regex);
(matches) {
errors.({
: ,
: ,
: ,
: ,
: matches.(, ).(),
: ,
});
qualityScore -= ;
}
}
}
(rules.) {
codeBlockPattern = ;
(!codeBlockPattern.(content)) {
warnings.({
: ,
: ,
: ,
: ,
});
qualityScore -= ;
}
}
{
: errors.( e. === ). === ,
: .(, qualityScore),
errors,
warnings,
: {
: words.,
: (),
: .(rules),
},
};
}
Composite Validation
interface ValidationConfig {
schema?: OutputSchema;
contentRules?: ContentRules;
customValidators?: CustomValidator[];
strictMode?: boolean;
}
interface CustomValidator {
name: string;
validate: (output: unknown) => ValidationError[];
}
async function validateOutput(
output: unknown,
config: ValidationConfig
): Promise<ValidationResult> {
const allErrors: ValidationError[] = [];
const allWarnings: ValidationWarning[] = [];
let totalScore = 1.0;
if (config.schema) {
const schemaErrors = validateAgainstSchema(output, config.schema);
allErrors.push(...schemaErrors);
totalScore -= schemaErrors.length * 0.1;
}
if (config. && output === ) {
contentResult = (output, config.);
allErrors.(...contentResult.);
allWarnings.(...contentResult.);
totalScore = .(totalScore, contentResult.);
}
(config.) {
( validator config.) {
{
customErrors = validator.(output);
allErrors.(...customErrors);
} (error) {
allErrors.({
: ,
: ,
: ,
: ,
: ,
: ,
});
}
}
}
(config. && allWarnings. > ) {
criticalWarnings = allWarnings.( ({
...w,
: ,
: w.,
: w.,
: w.,
: ,
: w.,
}));
allErrors.(...criticalWarnings);
}
hasCriticalErrors = allErrors.( e. === );
{
: !hasCriticalErrors && allErrors. === ,
: .(, totalScore),
: allErrors,
: allWarnings,
: {
: (),
: [
config. ? : ,
config. ? : ,
...(config.?.( v.) ?? []),
].(),
: config. ?? ,
},
};
}
Validation Report
validationReport:
nodeId: code-generator
outputType: code-analysis
validatedAt: "2024-01-15T10:30:00Z"
result:
valid: false
score: 0.65
schema:
type: object
validated: true
errors: 1
errors:
- path: $.analysis.security
code: REQUIRED_FIELD_MISSING
message: "Required field 'security' is missing"
expected: present
actual: missing
severity: critical
- path: $.analysis.performance.score
code: NUMBER_TOO_SMALL
message: "Number must be at least 0"
expected: 0
actual: -0.5
severity: error
warnings:
- path: $.content
code: CONTENT_TOO_SHORT
message: "Content has 45 words, recommend at least 100"
[, , ]
Common Validation Schemas
const CODE_ANALYSIS_SCHEMA: OutputSchema = {
type: 'object',
required: ['file', 'analysis', 'suggestions'],
properties: {
file: { type: 'string', minLength: 1 },
analysis: {
type: 'object',
required: ['complexity', 'quality'],
properties: {
complexity: { type: 'number', minimum: 0, maximum: 100 },
quality: { type: 'number', minimum: 0, maximum: 1 },
issues: {
type: 'array',
items: {
type: 'object',
required: ['line', 'message'],
properties: {
line: { type: 'number', minimum: 1 },
message: { type: , : },
},
},
},
},
},
: {
: ,
: { : , : },
},
},
};
: = {
: ,
: [, ],
: {
: { : , : , : },
: { : , : },
: {
: ,
: {
: ,
: [, ],
: {
: { : },
: { : },
},
},
},
},
};
Integration Points
- Input: Outputs from any DAG node execution
- Downstream:
dag-confidence-scorer for scoring
- Quality Gate:
dag-result-aggregator pre-aggregation check
- Feedback:
dag-feedback-synthesizer for improvement hints
Best Practices
- Schema First: Define schemas before execution
- Fail Fast: Catch critical errors immediately
- Detailed Errors: Include path and expected values
- Graduated Severity: Distinguish warnings from errors
- Custom Rules: Extend with domain-specific validators
Structured validation. Quality gates. No bad outputs pass.