xiaohongshu
xiaohongshu
dag-output-validator
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-scor...
Full skill instructions
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.
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; // 0-1 quality score
errors: ValidationError[];
warnings: ValidationWarning[];
metadata: ValidationMetadata;
}
interface ValidationError {
path: string; // JSON path to error location
code: string; // Error code
message: string; // Human-readable message
expected: unknown; // What was expected
actual: unknown; // What was received
severity: 'error' | 'critical';
}
interface ValidationWarning {
path: string;
code: string;
message: string;
suggestion?: string;
}
function validateAgainstSchema(
output: unknown,
schema: OutputSchema,
path: string = '$'
): ValidationError[] {
const errors: ValidationError[] = [];
// Type validation
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; // Can't continue if type is wrong
}
// Object validation
if (schema.type === 'object' && schema.properties) {
const obj = output as Record<string, unknown>;
// Required fields
for (const field of schema.required ?? []) {
if (!(field in obj)) {
errors.push({
path: `${path}.${field}`,
code: 'REQUIRED_FIELD_MISSING',
message: `Required field '${field}' is missing`,
expected: 'present',
actual: 'missing',
severity: 'critical',
});
}
}
// Validate each property
for (const [key, propSchema] of Object.entries(schema.properties)) {
if (key in obj) {
errors.push(...validateAgainstSchema(
obj[key],
propSchema,
`${path}.${key}`
));
}
}
}
// Array validation
if (schema.type === 'array' && schema.items) {
const arr = output as unknown[];
if (schema.minLength && arr.length < schema.minLength) {
errors.push({
path,
code: 'ARRAY_TOO_SHORT',
message: `Array must have at least ${schema.minLength} items`,
expected: schema.minLength,
actual: arr.length,
severity: 'error',
});
}
// Validate each item
arr.forEach((item, index) => {
errors.push(...validateAgainstSchema(
item,
schema.items!,
`${path}[${index}]`
));
});
}
// String validation
if (schema.type === 'string') {
const str = output as string;
if (schema.minLength && str.length < schema.minLength) {
errors.push({
path,
code: 'STRING_TOO_SHORT',
message: `String must be at least ${schema.minLength} characters`,
expected: schema.minLength,
actual: str.length,
severity: 'error',
});
}
if (schema.pattern) {
const regex = new RegExp(schema.pattern);
if (!regex.test(str)) {
errors.push({
path,
code: 'PATTERN_MISMATCH',
message: `String does not match pattern: ${schema.pattern}`,
expected: schema.pattern,
actual: str,
severity: 'error',
});
}
}
}
// Number validation
if (schema.type === 'number') {
const num = output as number;
if (schema.minimum !== undefined && num < schema.minimum) {
errors.push({
path,
code: 'NUMBER_TOO_SMALL',
message: `Number must be at least ${schema.minimum}`,
expected: schema.minimum,
actual: num,
severity: 'error',
});
}
if (schema.maximum !== undefined && num > schema.maximum) {
errors.push({
path,
code: 'NUMBER_TOO_LARGE',
message: `Number must be at most ${schema.maximum}`,
expected: schema.maximum,
actual: num,
severity: 'error',
});
}
}
return errors;
}
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;
// Word count
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}`,
expected: rules.minWordCount,
actual: words.length,
severity: 'error',
});
qualityScore -= 0.3;
}
if (rules.maxWordCount && words.length > rules.maxWordCount) {
warnings.push({
path: '$.content',
code: 'CONTENT_TOO_LONG',
message: `Content has ${words.length} words, maximum is ${rules.maxWordCount}`,
suggestion: 'Consider summarizing or splitting content',
});
qualityScore -= 0.1;
}
// Required sections
if (rules.requiredSections) {
for (const section of rules.requiredSections) {
const sectionPattern = new RegExp(`##?\\s*${section}`, 'i');
if (!sectionPattern.test(content)) {
errors.push({
path: '$.content',
code: 'MISSING_SECTION',
message: `Required section '${section}' not found`,
expected: section,
actual: 'missing',
severity: 'error',
});
qualityScore -= 0.2;
}
}
}
// Prohibited patterns
if (rules.prohibitedPatterns) {
for (const pattern of rules.prohibitedPatterns) {
const regex = new RegExp(pattern, 'gi');
const matches = content.match(regex);
if (matches) {
errors.push({
path: '$.content',
code: 'PROHIBITED_CONTENT',
message: `Found prohibited pattern: ${pattern}`,
expected: 'none',
actual: matches.slice(0, 3).join(', '),
severity: 'error',
});
qualityScore -= 0.3;
}
}
}
// Code block check
if (rules.codeBlockRequired) {
const codeBlockPattern = /```[\s\S]*?```/;
if (!codeBlockPattern.test(content)) {
warnings.push({
path: '$.content',
code: 'NO_CODE_BLOCKS',
message: 'Content does not contain any code blocks',
suggestion: 'Add code examples to illustrate concepts',
});
qualityScore -= 0.1;
}
}
return {
valid: errors.filter(e => e.severity === 'critical').length === 0,
score: Math.max(0, qualityScore),
errors,
warnings,
metadata: {
wordCount: words.length,
validatedAt: new Date(),
rulesApplied: Object.keys(rules),
},
};
}
interface ValidationConfig {
schema?: OutputSchema;
contentRules?: ContentRules;
customValidators?: CustomValidator[];
strictMode?: boolean; // Fail on warnings
}
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;
// Schema validation
if (config.schema) {
const schemaErrors = validateAgainstSchema(output, config.schema);
allErrors.push(...schemaErrors);
totalScore -= schemaErrors.length * 0.1;
}
// Content validation
if (config.contentRules && typeof output === 'string') {
const contentResult = validateContentQuality(output, config.contentRules);
allErrors.push(...contentResult.errors);
allWarnings.push(...contentResult.warnings);
totalScore = Math.min(totalScore, contentResult.score);
}
// Custom validators
if (config.customValidators) {
for (const validator of config.customValidators) {
try {
const customErrors = validator.validate(output);
allErrors.push(...customErrors);
} catch (error) {
allErrors.push({
path: '$',
code: 'VALIDATOR_FAILED',
message: `Custom validator '${validator.name}' failed: ${error}`,
expected: 'success',
actual: 'error',
severity: 'error',
});
}
}
}
// Strict mode
if (config.strictMode && allWarnings.length > 0) {
const criticalWarnings = allWarnings.map(w => ({
...w,
severity: 'error' as const,
path: w.path,
code: w.code,
message: w.message,
expected: 'no warnings',
actual: w.message,
}));
allErrors.push(...criticalWarnings);
}
const hasCriticalErrors = allErrors.some(e => e.severity === 'critical');
return {
valid: !hasCriticalErrors && allErrors.length === 0,
score: Math.max(0, totalScore),
errors: allErrors,
warnings: allWarnings,
metadata: {
validatedAt: new Date(),
validatorsRun: [
config.schema ? 'schema' : null,
config.contentRules ? 'content' : null,
...(config.customValidators?.map(v => v.name) ?? []),
].filter(Boolean),
strictMode: config.strictMode ?? false,
},
};
}
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"
suggestion: "Expand analysis with more details"
metadata:
wordCount: 45
validatorsRun: [schema, content, customSecurity]
strictMode: false
suggestions:
- "Add 'security' field to analysis object"
- "Ensure performance.score is non-negative"
- "Expand content to provide more detail"
// Code analysis output schema
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: 'string', minLength: 1 },
},
},
},
},
},
suggestions: {
type: 'array',
items: { type: 'string', minLength: 1 },
},
},
};
// Documentation output schema
const DOCUMENTATION_SCHEMA: OutputSchema = {
type: 'object',
required: ['title', 'content'],
properties: {
title: { type: 'string', minLength: 1, maxLength: 200 },
content: { type: 'string', minLength: 100 },
sections: {
type: 'array',
items: {
type: 'object',
required: ['heading', 'body'],
properties: {
heading: { type: 'string' },
body: { type: 'string' },
},
},
},
},
};
dag-confidence-scorer for scoringdag-result-aggregator pre-aggregation checkdag-feedback-synthesizer for improvement hintsStructured validation. Quality gates. No bad outputs pass.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience