llm-output-eval-gate
Skill1 starsChanged 36 days agoMITView on GitHub
Add a two-layer quality gate around any LLM call so bad model output never reaches the user. Use when building agents or apps that call an LLM for structured output (plans, JSON, reviews, summaries) and need deterministic validation, model-based scoring, bounded auto-retry, best-of fallback, and an audit log. Not for prompt authoring, model selection, or replacing human review of high-stakes output.
In this repository30 other files it gives its agents.
- anna-app-publishSkill
- campus-jobs-radarSkill
- career-pivot-researchSkill
- cf-pages-deploySkill
- company-risk-checkSkill
- github-repo-launch-polishSkill
- github-repo-repair-auditSkill
- headless-webapp-screenshotsSkill
- historical-remotion-filmSkill
- interview-debriefSkill
- job-application-screenerSkill
- job-application-trackerSkill
- memory-sync-abcSkill
- offer-decision-frameworkSkill
- online-assessment-solverSkill
- personal-secretary-memorySkill
- personal-tone-writingSkill
- portfolio-github-workflowSkill
- recruiting-source-huntingSkill
- remotion-delivery-qaSkill
- resume-jd-matcherSkill
- resume-jd-tailorSkill
- resume-polish-craftSkill
- session-checkpointSkill
- session-log-archaeologySkill
- single-file-html-toolSkill
- static-site-deploy-verifySkill
- vibecoding-resume-storySkill
- video-portfolio-performanceSkill
- workflow-distillerSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 4 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 42
Write validate and judge per domain.
- Distinctive: line 50
Put hard constraints in L1, taste in L2.
- Distinctive: line 51
Always define the fallback: best-of-attempts, a safe default, or a clear error — never an unvalidated render.
- Distinctive: line 57
Before, a typical AI feature ships whatever the model returns:
- Distinctive: line 64
After, the same call is wrapped in the gate:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
LLM Output Eval Gate
Most "AI features" are a thin shell over an LLM API: whatever the model returns is shown to the user, wrong or not. This skill wraps every LLM call in a quality gate so unusable output is caught, retried, and logged.
The Pattern
generate → L1 deterministic validation → L2 quality scoring → pass
│ │
└─ fail ─→ retry (bounded) ─→ fall back to best attempt
│
└─ log every attempt (auditable)- L1 — deterministic rules. Cheap, instant, no model involved. Check JSON structure, required fields, enum values, numeric ranges, count bounds, duplicates, and any domain budget (e.g. total minutes ≤ available time). L1 failures skip L2 entirely.
- L2 — quality scoring. LLM-as-Judge when an API is available; a heuristic scorer as offline fallback so behavior stays consistent without a key. Score 0-10 against a threshold (default 7).
- Bounded retry. Retry at most 2 times. Track the best-scoring attempt and fall back to it if nothing passes — never return nothing.
- Audit log. Persist every attempt: pass/fail, issues, score, retry count, mode (live/mock), timestamp. Surface the log inside the product, not just in dev tools.
Implementation
Copy scripts/eval-gate.js into the project (vanilla JS, zero dependencies, works in browser and Node). It exposes one async function:
var res = await EvalGate.gate({
name: "plan", // label used in logs
generate: async (attempt) => {...}, // call the LLM, return parsed result
validate: (result) => ({ pass, issues }), // L1 rules
judge: async (result) => ({ score, comment }), // L2 scoring
threshold: 7,
maxRetries: 2
});
// res = { ok, result, report:{ attempts, retries, finalPass, finalScore, mode } }Write validate and judge per domain; the gate mechanics never change.
Setting The Threshold
Do not pick the threshold by intuition. Build a small set of deliberately-bad outputs (too many items, over budget, wrong enums, duplicate titles) and a few known-good ones, then choose the lowest threshold that blocks every bad sample without rejecting good ones. Keep the threshold in config so it can be tuned without a deploy. A demo mode that intentionally generates a bad first output is the fastest way to prove the gate works.
Design Rules
- Put hard constraints in L1, taste in L2. Anything checkable without a model belongs in L1.
- Always define the fallback: best-of-attempts, a safe default, or a clear error — never an unvalidated render.
- Make the retry loop visible to the user (badge, toast, log entry). The gate is a product feature, not hidden plumbing.
- Mock mode must reproduce the same pass/fail behavior as live mode, including a deliberately-failing first attempt, so the pipeline is demoable without a key.
Before / After
Before, a typical AI feature ships whatever the model returns:
var plan = await callLLM(prompt);
render(plan); // 字段缺失、超预算、格式错,用户直接看到After, the same call is wrapped in the gate:
var res = await EvalGate.gate({
name: "plan",
generate: callLLM,
validate: (r) => ({ pass: r.items.length <= 5 && r.minutes <= 240, issues: [] }),
judge: scorePlan,
threshold: 7,
maxRetries: 2
});
if (!res.ok) renderFallback(res.result); // 永远有东西可渲染,且每次尝试都有日志Bad output is caught, retried at most twice, and logged before it can reach the user.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

