Claude-skill-registry Agent Self-Correction
AI agent self-correction mechanisms: error detection, validation loops, recovery strategies, confidence scoring, and iterative refinement
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/agent-self-correction" ~/.claude/skills/majiayu000-claude-skill-registry-agent-self-correction && rm -rf "$T"
manifest:
skills/data/agent-self-correction/SKILL.mdsource content
Agent Self-Correction
Overview
AI agent self-correction mechanisms enable agents to detect errors, validate outputs, and automatically recover from failures. This includes validation loops, confidence scoring, iterative refinement, and recovery strategies to improve reliability.
Why This Matters
- Reliability: Agents แก้ error ได้เองโดยไม่ต้อง human intervention
- Quality: Output มีคุณภาพสูงขึ้น
- Trust: Users มั่นใจในผลลัพธ์ที่ได้
- Efficiency: ลด retry loops ที่ไม่จำเป็น
Core Concepts
1. Error Detection
interface ErrorDetection { type: 'syntax' | 'semantic' | 'logic' | 'format' severity: 'low' | 'medium' | 'high' | 'critical' message: string location?: string } class ErrorDetector { detectErrors(output: string, context: any): ErrorDetection[] { const errors: ErrorDetection[] = [] // Syntax errors errors.push(...this.detectSyntaxErrors(output)) // Semantic errors errors.push(...this.detectSemanticErrors(output, context)) // Logic errors errors.push(...this.detectLogicErrors(output, context)) // Format errors errors.push(...this.detectFormatErrors(output, context)) return errors } private detectSyntaxErrors(output: string): ErrorDetection[] { const errors: ErrorDetection[] = [] // Check for unclosed brackets const openBrackets = (output.match(/\(/g) || []).length const closeBrackets = (output.match(/\)/g) || []).length if (openBrackets !== closeBrackets) { errors.push({ type: 'syntax', severity: 'high', message: 'Unclosed brackets detected', }) } // Check for unclosed quotes const quotes = output.match(/"/g) if (quotes && quotes.length % 2 !== 0) { errors.push({ type: 'syntax', severity: 'high', message: 'Unclosed quotes detected', }) } return errors } private detectSemanticErrors(output: string, context: any): ErrorDetection[] { const errors: ErrorDetection[] = [] // Check for hallucinations (if context provided) if (context.facts) { const outputFacts = this.extractFacts(output) for (const fact of outputFacts) { if (!context.facts.includes(fact)) { errors.push({ type: 'semantic', severity: 'medium', message: `Potential hallucination: "${fact}" not in context`, }) } } } return errors } private detectLogicErrors(output: string, context: any): ErrorDetection[] { const errors: ErrorDetection[] = [] // Check for contradictions const statements = this.extractStatements(output) for (let i = 0; i < statements.length; i++) { for (let j = i + 1; j < statements.length; j++) { if (this.areContradictory(statements[i], statements[j])) { errors.push({ type: 'logic', severity: 'high', message: 'Contradictory statements detected', }) } } } return errors } private detectFormatErrors(output: string, context: any): ErrorDetection[] { const errors: ErrorDetection[] = [] // Check if JSON is valid when expected if (context.expectedFormat === 'json') { try { JSON.parse(output) } catch (e) { errors.push({ type: 'format', severity: 'critical', message: 'Invalid JSON output', }) } } return errors } private extractFacts(text: string): string[] { // Extract factual statements return [] } private extractStatements(text: string): string[] { // Extract logical statements return [] } private areContradictory(a: string, b: string): boolean { // Check if two statements contradict return false } }
2. Validation Loops
interface ValidationResult { isValid: boolean errors: string[] warnings: string[] confidence: number } class ValidationLoop { private maxIterations: number = 3 private confidenceThreshold: number = 0.8 async executeWithValidation<T>( task: () => Promise<T>, validator: (result: T) => ValidationResult, corrector: (result: T, errors: string[]) => Promise<T> ): Promise<T> { let result = await task() let iteration = 0 while (iteration < this.maxIterations) { const validation = validator(result) if (validation.isValid && validation.confidence >= this.confidenceThreshold) { return result } console.log(`Iteration ${iteration + 1}: Validation failed`) console.log('Errors:', validation.errors) console.log('Warnings:', validation.warnings) console.log('Confidence:', validation.confidence) // Correct the result result = await corrector(result, validation.errors) iteration++ } throw new Error(`Validation failed after ${this.maxIterations} iterations`) } } // Usage const loop = new ValidationLoop() const result = await loop.executeWithValidation( // Task: Generate code async () => { return await llm.generate('Write a function to sort an array') }, // Validator: Check code quality (code: string) => { const errors: string[] = [] const warnings: string[] = [] let confidence = 1.0 // Check for syntax errors try { // Validate syntax } catch (e) { errors.push('Syntax error') confidence -= 0.5 } // Check for best practices if (!code.includes('error handling')) { warnings.push('Missing error handling') confidence -= 0.1 } return { isValid: errors.length === 0, errors, warnings, confidence, } }, // Corrector: Fix issues async (code: string, errors: string[]) => { const prompt = `Fix the following issues in this code: Code: ${code} Issues: ${errors.join(', ')} Return the corrected code only.` return await llm.generate(prompt) } )
3. Confidence Scoring
interface ConfidenceMetrics { overall: number components: { syntax: number semantic: number logic: number completeness: number } reasoning: string[] } class ConfidenceScorer { calculateConfidence(output: string, context: any): ConfidenceMetrics { const components = { syntax: this.scoreSyntax(output), semantic: this.scoreSemantic(output, context), logic: this.scoreLogic(output, context), completeness: this.scoreCompleteness(output, context), } const overall = ( components.syntax * 0.2 + components.semantic * 0.3 + components.logic * 0.3 + components.completeness * 0.2 ) const reasoning = this.generateReasoning(components) return { overall, components, reasoning } } private scoreSyntax(output: string): number { let score = 1.0 // Check for balanced brackets const brackets = output.match(/[(){}\[\]]/g) || [] let balance = 0 for (const bracket of brackets) { if (['(', '{', '['].includes(bracket)) { balance++ } else { balance-- } if (balance < 0) { score -= 0.3 } } if (balance !== 0) { score -= 0.3 } // Check for proper punctuation if (output.endsWith('.') || output.endsWith(',')) { score += 0.1 } return Math.max(0, Math.min(1, score)) } private scoreSemantic(output: string, context: any): number { let score = 1.0 // Check for consistency with context if (context.keywords) { const outputKeywords = output.toLowerCase().split(/\s+/) const matchedKeywords = context.keywords.filter((k: string) => outputKeywords.includes(k.toLowerCase()) ) score = matchedKeywords.length / context.keywords.length } return score } private scoreLogic(output: string, context: any): number { let score = 1.0 // Check for logical flow const sentences = output.split(/[.!?]/).filter(s => s.trim()) if (sentences.length < 2) { score -= 0.2 } // Check for contradictions // (implementation depends on domain) return Math.max(0, Math.min(1, score)) } private scoreCompleteness(output: string, context: any): number { let score = 1.0 // Check if all required elements are present if (context.requiredElements) { const present = context.requiredElements.filter((e: string) => output.includes(e) ) score = present.length / context.requiredElements.length } // Check output length if (context.minLength && output.length < context.minLength) { score -= 0.3 } if (context.maxLength && output.length > context.maxLength) { score -= 0.3 } return Math.max(0, Math.min(1, score)) } private generateReasoning(components: any): string[] { const reasoning: string[] = [] if (components.syntax < 0.8) { reasoning.push('Syntax issues detected') } if (components.semantic < 0.8) { reasoning.push('Semantic inconsistencies found') } if (components.logic < 0.8) { reasoning.push('Logical flow could be improved') } if (components.completeness < 0.8) { reasoning.push('Response may be incomplete') } return reasoning } }
4. Recovery Strategies
interface RecoveryStrategy { name: string canHandle: (error: Error) => boolean recover: (error: Error, context: any) => Promise<any> } class RecoveryManager { private strategies: RecoveryStrategy[] = [] addStrategy(strategy: RecoveryStrategy): void { this.strategies.push(strategy) } async recover(error: Error, context: any): Promise<any> { for (const strategy of this.strategies) { if (strategy.canHandle(error)) { console.log(`Applying recovery strategy: ${strategy.name}`) return await strategy.recover(error, context) } } throw new Error(`No recovery strategy found for error: ${error.message}`) } } // Common recovery strategies const recoveryManager = new RecoveryManager() // Retry strategy recoveryManager.addStrategy({ name: 'retry', canHandle: (error) => error instanceof NetworkError, recover: async (error, context) => { await sleep(1000) // Exponential backoff return context.task() }, }) // Fallback strategy recoveryManager.addStrategy({ name: 'fallback', canHandle: (error) => error instanceof APIError, recover: async (error, context) => { return context.fallbackValue }, }) // Rephrase strategy recoveryManager.addStrategy({ name: 'rephrase', canHandle: (error) => error instanceof ValidationError, recover: async (error, context) => { const rephrased = await llm.generate( `Rephrase this request to be clearer: ${context.originalRequest}` ) return await context.task(rephrased) }, }) // Simplify strategy recoveryManager.addStrategy({ name: 'simplify', canHandle: (error) => error instanceof ComplexityError, recover: async (error, context) => { const simplified = await llm.generate( `Simplify this request: ${context.originalRequest}` ) return await context.task(simplified) }, })
5. Iterative Refinement
class IterativeRefiner { private maxIterations: number = 5 private improvementThreshold: number = 0.1 async refine<T>( initial: T, evaluator: (item: T) => number, refiner: (item: T, feedback: string) => Promise<T> ): Promise<T> { let current = initial let currentScore = evaluator(current) let iteration = 0 while (iteration < this.maxIterations) { const feedback = this.generateFeedback(current, currentScore) const refined = await refiner(current, feedback) const refinedScore = evaluator(refined) const improvement = (refinedScore - currentScore) / currentScore console.log(`Iteration ${iteration + 1}:`) console.log(` Current score: ${currentScore}`) console.log(` Refined score: ${refinedScore}`) console.log(` Improvement: ${(improvement * 100).toFixed(2)}%`) if (improvement < this.improvementThreshold) { console.log('Improvement below threshold, stopping') break } current = refined currentScore = refinedScore iteration++ } return current } private generateFeedback<T>(item: T, score: number): string { const feedback: string[] = [] if (score < 0.5) { feedback.push('Significant improvements needed') } else if (score < 0.8) { feedback.push('Moderate improvements needed') } else { feedback.push('Minor improvements possible') } // Add specific feedback based on item type // (implementation depends on domain) return feedback.join('. ') } } // Usage const refiner = new IterativeRefiner() const refinedCode = await refiner.refine( initialCode, // Evaluator: Code quality score (code: string) => { let score = 1.0 // Check for error handling if (code.includes('try') && code.includes('catch')) { score += 0.2 } // Check for comments if (code.includes('//') || code.includes('/*')) { score += 0.1 } // Check for tests if (code.includes('test') || code.includes('spec')) { score += 0.1 } return Math.min(1, score) }, // Refiner: Improve code async (code: string, feedback: string) => { const prompt = `Improve this code based on feedback: Code: ${code} Feedback: ${feedback} Return the improved code only.` return await llm.generate(prompt) } )
6. Self-Reflection
interface ReflectionResult { success: boolean confidence: number issues: string[] improvements: string[] } class SelfReflectiveAgent { async execute(task: string): Promise<string> { // Execute task const output = await this.generateOutput(task) // Reflect on output const reflection = await this.reflect(output, task) // If issues found, refine if (!reflection.success || reflection.confidence < 0.8) { console.log('Self-reflection detected issues, refining...') return await this.refine(output, reflection.issues) } return output } private async generateOutput(task: string): Promise<string> { // Generate initial output return await llm.generate(task) } private async reflect(output: string, task: string): Promise<ReflectionResult> { const prompt = `Reflect on this output for the given task: Task: ${task} Output: ${output} Evaluate: 1. Does the output address the task? 2. Is the output complete? 3. Is the output accurate? 4. Are there any issues? Return JSON with: success, confidence, issues, improvements` const reflection = await llm.generate(prompt) return JSON.parse(reflection) } private async refine(output: string, issues: string[]): Promise<string> { const prompt = `Refine this output to address the following issues: Output: ${output} Issues: ${issues.join(', ')} Return the refined output only.` return await llm.generate(prompt) } }
Quick Start
// 1. Set up error detection const detector = new ErrorDetector() // 2. Set up validation loop const loop = new ValidationLoop() // 3. Execute with self-correction const result = await loop.executeWithValidation( () => llm.generate(task), (output) => { const errors = detector.detectErrors(output, context) return { isValid: errors.length === 0, errors: errors.map(e => e.message), warnings: [], confidence: 1.0 - (errors.length * 0.2), } }, (output, errors) => llm.generate(`Fix: ${errors.join(', ')}\nOutput: ${output}`) )
Production Checklist
- Error detection implemented
- Validation loops configured
- Confidence scoring enabled
- Recovery strategies defined
- Iterative refinement active
- Self-reflection enabled
- Monitoring/logging in place
- Fallback mechanisms defined
Anti-patterns
- No error detection: ไม่ตรวจสอบผลลัพธ์
- Infinite loops: Validation loops ไม่มี max iterations
- Over-correction: แก้ปัญหาจนเกินไป
- No fallback: ไม่มี strategy สำรองเมื่อ recovery ล้มเหลว
- Ignoring confidence: ไม่สนใจ confidence scores
Integration Points
- LLM APIs
- Monitoring systems
- Logging frameworks
- Alerting systems
- Feedback loops