llmverify
Version:
AI Output Verification Toolkit — Local-first LLM safety, hallucination detection, PII redaction, prompt injection defense, and runtime monitoring. Zero telemetry. OWASP LLM Top 10 aligned.
111 lines • 14.4 kB
JavaScript
;
/**
* Hallucination Engine
*
* Identifies risk indicators in AI outputs.
* Does NOT definitively detect hallucinations - that requires ground truth.
*
* @module engines/hallucination
* @author Haiec
* @license MIT
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.HallucinationEngine = void 0;
const claim_extractor_1 = require("./claim-extractor");
const risk_analyzer_1 = require("./risk-analyzer");
class HallucinationEngine {
constructor(config) {
this.config = config;
this.LIMITATIONS = [
'Pattern-based detection only (free tier)',
'Cannot verify factual accuracy without ground truth sources',
'English language only',
'Context-dependent false positives possible',
'Novel phrasings may not be detected',
'Requires human validation for production use'
];
this.METHODOLOGY = 'Risk indicator identification using linguistic pattern analysis. ' +
'Analyzes claim specificity, citation presence, language patterns, and ' +
'contradiction signals. Does NOT verify factual accuracy. ' +
'Results indicate likelihood that claims need human review.';
}
async detect(content) {
// Step 1: Extract claims
let claims = (0, claim_extractor_1.extractClaims)(content);
// Step 2: Analyze risk indicators for each claim
claims = claims.map(claim => (0, risk_analyzer_1.analyzeRiskIndicators)(claim, this.config));
// Step 3: Check for contradictions
claims = (0, risk_analyzer_1.checkContradictions)(claims);
// Step 4: Identify suspicious claims
const suspiciousClaims = claims.filter(claim => {
const totalRisk = this.calculateClaimRisk(claim);
return totalRisk > 0.5;
});
// Step 5: Calculate overall risk score
const riskScore = this.calculateRiskScore(claims);
// Step 6: Calculate risk indicators summary
const riskIndicators = this.summarizeRiskIndicators(claims);
// Step 7: Calculate confidence
const confidence = this.calculateConfidence(claims);
return {
claims,
suspiciousClaims,
riskScore,
confidence,
riskIndicators,
limitations: this.LIMITATIONS,
methodology: this.METHODOLOGY
};
}
calculateClaimRisk(claim) {
return (claim.riskIndicators.lackOfSpecificity * 0.3 +
(claim.riskIndicators.missingCitation ? 0.3 : 0) +
(claim.riskIndicators.vagueLanguage ? 0.2 : 0) +
(claim.riskIndicators.contradictionSignal ? 0.2 : 0));
}
calculateRiskScore(claims) {
if (claims.length === 0)
return 0;
const totalRisk = claims.reduce((sum, claim) => {
return sum + this.calculateClaimRisk(claim);
}, 0);
return Math.min(totalRisk / claims.length, 1.0);
}
summarizeRiskIndicators(claims) {
if (claims.length === 0) {
return {
lackOfSpecificity: 0,
missingCitations: 0,
vagueLanguage: 0,
contradictionSignals: 0
};
}
return {
lackOfSpecificity: claims.reduce((sum, c) => sum + c.riskIndicators.lackOfSpecificity, 0) / claims.length,
missingCitations: claims.filter(c => c.riskIndicators.missingCitation).length,
vagueLanguage: claims.filter(c => c.riskIndicators.vagueLanguage).length,
contradictionSignals: claims.filter(c => c.riskIndicators.contradictionSignal).length
};
}
calculateConfidence(claims) {
const sampleSize = claims.length;
const baseLine = Math.min(sampleSize / 10, 1.0);
const value = sampleSize < 3 ? baseLine * 0.5 : baseLine;
const margin = 0.2 * (1 - value);
return {
value: Math.max(0.3, value),
interval: [
Math.max(0, value - margin),
Math.min(1, value + margin)
],
method: 'heuristic',
factors: {
patternStrength: value,
contextClarity: value,
historicalAccuracy: 0.7
}
};
}
}
exports.HallucinationEngine = HallucinationEngine;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZW5naW5lcy9oYWxsdWNpbmF0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7O0dBU0c7OztBQUlILHVEQUFrRDtBQUNsRCxtREFBNkU7QUFFN0UsTUFBYSxtQkFBbUI7SUFnQjlCLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBZmpCLGdCQUFXLEdBQUc7WUFDN0IsMENBQTBDO1lBQzFDLDZEQUE2RDtZQUM3RCx1QkFBdUI7WUFDdkIsNENBQTRDO1lBQzVDLHFDQUFxQztZQUNyQyw4Q0FBOEM7U0FDL0MsQ0FBQztRQUVlLGdCQUFXLEdBQzFCLG1FQUFtRTtZQUNuRSx3RUFBd0U7WUFDeEUsMkRBQTJEO1lBQzNELDREQUE0RCxDQUFDO0lBRTFCLENBQUM7SUFFdEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFlO1FBQzFCLHlCQUF5QjtRQUN6QixJQUFJLE1BQU0sR0FBRyxJQUFBLCtCQUFhLEVBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEMsaURBQWlEO1FBQ2pELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQzFCLElBQUEscUNBQXFCLEVBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FDMUMsQ0FBQztRQUVGLG1DQUFtQztRQUNuQyxNQUFNLEdBQUcsSUFBQSxtQ0FBbUIsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUVyQyxxQ0FBcUM7UUFDckMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqRCxPQUFPLFNBQVMsR0FBRyxHQUFHLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7UUFFSCx1Q0FBdUM7UUFD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QUcsQ0FBQyxDQUFDO1FBRWhELE1BQU0sS0FBSyxHQUFHLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUN6RCxNQUFNLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFFakMsT0FBTztZQUNMLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUM7WUFDM0IsUUFBUSxFQUFFO2dCQUNSLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUM7YUFDNUI7WUFDRCxNQUFNLEVBQUUsV0FBVztZQUNuQixPQUFPLEVBQUU7Z0JBQ1AsZUFBZSxFQUFFLEtBQUs7Z0JBQ3RCLGNBQWMsRUFBRSxLQUFLO2dCQUNyQixrQkFBa0IsRUFBRSxHQUFHO2FBQ3hCO1NBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXRIRCxrREFzSEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhhbGx1Y2luYXRpb24gRW5naW5lXG4gKiBcbiAqIElkZW50aWZpZXMgcmlzayBpbmRpY2F0b3JzIGluIEFJIG91dHB1dHMuXG4gKiBEb2VzIE5PVCBkZWZpbml0aXZlbHkgZGV0ZWN0IGhhbGx1Y2luYXRpb25zIC0gdGhhdCByZXF1aXJlcyBncm91bmQgdHJ1dGguXG4gKiBcbiAqIEBtb2R1bGUgZW5naW5lcy9oYWxsdWNpbmF0aW9uXG4gKiBAYXV0aG9yIEhhaWVjXG4gKiBAbGljZW5zZSBNSVRcbiAqL1xuXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi90eXBlcy9jb25maWcnO1xuaW1wb3J0IHsgSGFsbHVjaW5hdGlvblJlc3VsdCwgQ2xhaW0sIENvbmZpZGVuY2VTY29yZSB9IGZyb20gJy4uLy4uL3R5cGVzL3Jlc3VsdHMnO1xuaW1wb3J0IHsgZXh0cmFjdENsYWltcyB9IGZyb20gJy4vY2xhaW0tZXh0cmFjdG9yJztcbmltcG9ydCB7IGFuYWx5emVSaXNrSW5kaWNhdG9ycywgY2hlY2tDb250cmFkaWN0aW9ucyB9IGZyb20gJy4vcmlzay1hbmFseXplcic7XG5cbmV4cG9ydCBjbGFzcyBIYWxsdWNpbmF0aW9uRW5naW5lIHtcbiAgcHJpdmF0ZSByZWFkb25seSBMSU1JVEFUSU9OUyA9IFtcbiAgICAnUGF0dGVybi1iYXNlZCBkZXRlY3Rpb24gb25seSAoZnJlZSB0aWVyKScsXG4gICAgJ0Nhbm5vdCB2ZXJpZnkgZmFjdHVhbCBhY2N1cmFjeSB3aXRob3V0IGdyb3VuZCB0cnV0aCBzb3VyY2VzJyxcbiAgICAnRW5nbGlzaCBsYW5ndWFnZSBvbmx5JyxcbiAgICAnQ29udGV4dC1kZXBlbmRlbnQgZmFsc2UgcG9zaXRpdmVzIHBvc3NpYmxlJyxcbiAgICAnTm92ZWwgcGhyYXNpbmdzIG1heSBub3QgYmUgZGV0ZWN0ZWQnLFxuICAgICdSZXF1aXJlcyBodW1hbiB2YWxpZGF0aW9uIGZvciBwcm9kdWN0aW9uIHVzZSdcbiAgXTtcbiAgXG4gIHByaXZhdGUgcmVhZG9ubHkgTUVUSE9ET0xPR1kgPSBcbiAgICAnUmlzayBpbmRpY2F0b3IgaWRlbnRpZmljYXRpb24gdXNpbmcgbGluZ3Vpc3RpYyBwYXR0ZXJuIGFuYWx5c2lzLiAnICtcbiAgICAnQW5hbHl6ZXMgY2xhaW0gc3BlY2lmaWNpdHksIGNpdGF0aW9uIHByZXNlbmNlLCBsYW5ndWFnZSBwYXR0ZXJucywgYW5kICcgK1xuICAgICdjb250cmFkaWN0aW9uIHNpZ25hbHMuIERvZXMgTk9UIHZlcmlmeSBmYWN0dWFsIGFjY3VyYWN5LiAnICtcbiAgICAnUmVzdWx0cyBpbmRpY2F0ZSBsaWtlbGlob29kIHRoYXQgY2xhaW1zIG5lZWQgaHVtYW4gcmV2aWV3Lic7XG4gIFxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogQ29uZmlnKSB7fVxuICBcbiAgYXN5bmMgZGV0ZWN0KGNvbnRlbnQ6IHN0cmluZyk6IFByb21pc2U8SGFsbHVjaW5hdGlvblJlc3VsdD4ge1xuICAgIC8vIFN0ZXAgMTogRXh0cmFjdCBjbGFpbXNcbiAgICBsZXQgY2xhaW1zID0gZXh0cmFjdENsYWltcyhjb250ZW50KTtcbiAgICBcbiAgICAvLyBTdGVwIDI6IEFuYWx5emUgcmlzayBpbmRpY2F0b3JzIGZvciBlYWNoIGNsYWltXG4gICAgY2xhaW1zID0gY2xhaW1zLm1hcChjbGFpbSA9PiBcbiAgICAgIGFuYWx5emVSaXNrSW5kaWNhdG9ycyhjbGFpbSwgdGhpcy5jb25maWcpXG4gICAgKTtcbiAgICBcbiAgICAvLyBTdGVwIDM6IENoZWNrIGZvciBjb250cmFkaWN0aW9uc1xuICAgIGNsYWltcyA9IGNoZWNrQ29udHJhZGljdGlvbnMoY2xhaW1zKTtcbiAgICBcbiAgICAvLyBTdGVwIDQ6IElkZW50aWZ5IHN1c3BpY2lvdXMgY2xhaW1zXG4gICAgY29uc3Qgc3VzcGljaW91c0NsYWltcyA9IGNsYWltcy5maWx0ZXIoY2xhaW0gPT4ge1xuICAgICAgY29uc3QgdG90YWxSaXNrID0gdGhpcy5jYWxjdWxhdGVDbGFpbVJpc2soY2xhaW0pO1xuICAgICAgcmV0dXJuIHRvdGFsUmlzayA+IDAuNTtcbiAgICB9KTtcbiAgICBcbiAgICAvLyBTdGVwIDU6IENhbGN1bGF0ZSBvdmVyYWxsIHJpc2sgc2NvcmVcbiAgICBjb25zdCByaXNrU2NvcmUgPSB0aGlzLmNhbGN1bGF0ZVJpc2tTY29yZShjbGFpbXMpO1xuICAgIFxuICAgIC8vIFN0ZXAgNjogQ2FsY3VsYXRlIHJpc2sgaW5kaWNhdG9ycyBzdW1tYXJ5XG4gICAgY29uc3Qgcmlza0luZGljYXRvcnMgPSB0aGlzLnN1bW1hcml6ZVJpc2tJbmRpY2F0b3JzKGNsYWltcyk7XG4gICAgXG4gICAgLy8gU3RlcCA3OiBDYWxjdWxhdGUgY29uZmlkZW5jZVxuICAgIGNvbnN0IGNvbmZpZGVuY2UgPSB0aGlzLmNhbGN1bGF0ZUNvbmZpZGVuY2UoY2xhaW1zKTtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgY2xhaW1zLFxuICAgICAgc3VzcGljaW91c0NsYWltcyxcbiAgICAgIHJpc2tTY29yZSxcbiAgICAgIGNvbmZpZGVuY2UsXG4gICAgICByaXNrSW5kaWNhdG9ycyxcbiAgICAgIGxpbWl0YXRpb25zOiB0aGlzLkxJTUlUQVRJT05TLFxuICAgICAgbWV0aG9kb2xvZ3k6IHRoaXMuTUVUSE9ET0xPR1lcbiAgICB9O1xuICB9XG4gIFxuICBwcml2YXRlIGNhbGN1bGF0ZUNsYWltUmlzayhjbGFpbTogQ2xhaW0pOiBudW1iZXIge1xuICAgIHJldHVybiAoXG4gICAgICBjbGFpbS5yaXNrSW5kaWNhdG9ycy5sYWNrT2ZTcGVjaWZpY2l0eSAqIDAuMyArXG4gICAgICAoY2xhaW0ucmlza0luZGljYXRvcnMubWlzc2luZ0NpdGF0aW9uID8gMC4zIDogMCkgK1xuICAgICAgKGNsYWltLnJpc2tJbmRpY2F0b3JzLnZhZ3VlTGFuZ3VhZ2UgPyAwLjIgOiAwKSArXG4gICAgICAoY2xhaW0ucmlza0luZGljYXRvcnMuY29udHJhZGljdGlvblNpZ25hbCA/IDAuMiA6IDApXG4gICAgKTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBjYWxjdWxhdGVSaXNrU2NvcmUoY2xhaW1zOiBDbGFpbVtdKTogbnVtYmVyIHtcbiAgICBpZiAoY2xhaW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgXG4gICAgY29uc3QgdG90YWxSaXNrID0gY2xhaW1zLnJlZHVjZSgoc3VtLCBjbGFpbSkgPT4ge1xuICAgICAgcmV0dXJuIHN1bSArIHRoaXMuY2FsY3VsYXRlQ2xhaW1SaXNrKGNsYWltKTtcbiAgICB9LCAwKTtcbiAgICBcbiAgICByZXR1cm4gTWF0aC5taW4odG90YWxSaXNrIC8gY2xhaW1zLmxlbmd0aCwgMS4wKTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBzdW1tYXJpemVSaXNrSW5kaWNhdG9ycyhjbGFpbXM6IENsYWltW10pIHtcbiAgICBpZiAoY2xhaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbGFja09mU3BlY2lmaWNpdHk6IDAsXG4gICAgICAgIG1pc3NpbmdDaXRhdGlvbnM6IDAsXG4gICAgICAgIHZhZ3VlTGFuZ3VhZ2U6IDAsXG4gICAgICAgIGNvbnRyYWRpY3Rpb25TaWduYWxzOiAwXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgbGFja09mU3BlY2lmaWNpdHk6IGNsYWltcy5yZWR1Y2UoKHN1bSwgYykgPT4gXG4gICAgICAgIHN1bSArIGMucmlza0luZGljYXRvcnMubGFja09mU3BlY2lmaWNpdHksIDApIC8gY2xhaW1zLmxlbmd0aCxcbiAgICAgIG1pc3NpbmdDaXRhdGlvbnM6IGNsYWltcy5maWx0ZXIoYyA9PiBcbiAgICAgICAgYy5yaXNrSW5kaWNhdG9ycy5taXNzaW5nQ2l0YXRpb24pLmxlbmd0aCxcbiAgICAgIHZhZ3VlTGFuZ3VhZ2U6IGNsYWltcy5maWx0ZXIoYyA9PiBcbiAgICAgICAgYy5yaXNrSW5kaWNhdG9ycy52YWd1ZUxhbmd1YWdlKS5sZW5ndGgsXG4gICAgICBjb250cmFkaWN0aW9uU2lnbmFsczogY2xhaW1zLmZpbHRlcihjID0+IFxuICAgICAgICBjLnJpc2tJbmRpY2F0b3JzLmNvbnRyYWRpY3Rpb25TaWduYWwpLmxlbmd0aFxuICAgIH07XG4gIH1cbiAgXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29uZmlkZW5jZShjbGFpbXM6IENsYWltW10pOiBDb25maWRlbmNlU2NvcmUge1xuICAgIGNvbnN0IHNhbXBsZVNpemUgPSBjbGFpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJhc2VMaW5lID0gTWF0aC5taW4oc2FtcGxlU2l6ZSAvIDEwLCAxLjApO1xuICAgIFxuICAgIGNvbnN0IHZhbHVlID0gc2FtcGxlU2l6ZSA8IDMgPyBiYXNlTGluZSAqIDAuNSA6IGJhc2VMaW5lO1xuICAgIGNvbnN0IG1hcmdpbiA9IDAuMiAqICgxIC0gdmFsdWUpO1xuICAgIFxuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogTWF0aC5tYXgoMC4zLCB2YWx1ZSksXG4gICAgICBpbnRlcnZhbDogW1xuICAgICAgICBNYXRoLm1heCgwLCB2YWx1ZSAtIG1hcmdpbiksXG4gICAgICAgIE1hdGgubWluKDEsIHZhbHVlICsgbWFyZ2luKVxuICAgICAgXSxcbiAgICAgIG1ldGhvZDogJ2hldXJpc3RpYycsXG4gICAgICBmYWN0b3JzOiB7XG4gICAgICAgIHBhdHRlcm5TdHJlbmd0aDogdmFsdWUsXG4gICAgICAgIGNvbnRleHRDbGFyaXR5OiB2YWx1ZSxcbiAgICAgICAgaGlzdG9yaWNhbEFjY3VyYWN5OiAwLjdcbiAgICAgIH1cbiAgICB9O1xuICB9XG59XG4iXX0=