Templates/EdTech/Automated essay grading + feedback

Automated essay grading + feedback

Rubric-based grade + structured feedback per essay. Always-human reviewer-gate on grade appeals; spec hash binds the rubric so silent rubric changes are detectable.

Category: classifier·Reviewer-gate: on-low-confidence·For EdTech

What this template is

Pattern: classifier producing closed-enum grade band + bounded-text feedback against a rubric. The rubric (spec) is hash-committed; appeals processes can prove which rubric version graded a given essay. Reviewer-gate primarily fires through your appeals workflow (always-human on appeal). For child-data: input is hash-only — the raw essay never enters the chain.

The template

TypeScript · BSL-1.1 · License

import { RuntimeAISpec } from '@promethean/runtime-ai';

export const essayGraderSpec: RuntimeAISpec = {
  specId: 'essay-grader-v1',
  displayName: 'Automated essay grading + feedback',
  description:
    'Rubric-based grade + structured feedback per essay.',
  category: 'classifier',
  schemaVersion: 'promethean-runtime-ai-spec-1.0',
  canonicalForm: 'v1',

  inputSchema: {
    fields: [
      { name: 'submissionId', type: 'string', required: true,
        redaction: 'hash-only' },
      { name: 'rubricKey', type: 'string', required: true,
        maxLength: 64 },
      // Essay content is student PII; never enters the chain raw.
      { name: 'essayText', type: 'string', required: true,
        maxLength: 20_000, redaction: 'hash-only' },
      { name: 'gradeLevel', type: 'enum', required: true,
        enumValues: ['elementary', 'middle', 'high', 'undergrad', 'graduate'] },
    ],
  },

  outputSchema: {
    fields: [
      { name: 'gradeBand', type: 'enum', required: true,
        enumValues: ['A', 'B', 'C', 'D', 'F', 'incomplete'] },
      { name: 'rubricScores', type: 'string-list', required: true,
        maxItems: 8, maxLength: 80 },
      { name: 'feedbackText', type: 'string', required: true,
        maxLength: 1500 },
      { name: 'confidence', type: 'number', required: true,
        min: 0, max: 1 },
    ],
  },

  promptTemplate: {
    system:
      'You grade essays against the rubric. ' +
      'Be constructive in feedback. ' +
      'For incomplete or off-topic essays, use gradeBand=incomplete. ' +
      'Each rubricScore string: "criterion-name:score evidence-snippet".',
    user:
      'Submission {{submissionId}}, rubric {{rubricKey}}, level {{gradeLevel}}. ' +
      'Essay: {{essayText}}.',
  },

  modelIdentity: {
    provider: 'anthropic',
    model: 'claude-sonnet-4-5',
    version: '20250929',
  },

  reviewerGate: 'on-low-confidence',
  lowConfidenceThreshold: 0.7,
  maxLatencyMs: 8000,
  fallbackBehavior: 'queue-for-review',
};

Regulations addressed

This template's configuration choices map to specific regulatory obligations. The substrate doesn't certify compliance — but the spec hash + reviewer-verdict + modelIdentity per L12 entry give you the evidence layer for these citations:

  • ·EU AI Act Annex III §3 — education + vocational training
  • ·GDPR Art. 8 — child-data
  • ·FERPA — Family Educational Rights and Privacy Act (US)
  • ·COPPA — under-13 (US)

See citations index for official source URLs →

Installation + usage

  1. Create a free Dev-tier workspace — API key + Ed25519 signing key issued instantly.
  2. Install the SDK: npm install https://promethean.software/runtime-ai/latest.tgz.
  3. Paste the template above into your codebase. Adjust modelIdentity + prompt for your context.
  4. Call runConstrainedAI(spec, input, { client, receiptLogPath, productId, signingKey }) from your service code. For local testing pass createMockRuntimeAIClient(spec); for production, an Anthropic / OpenAI / Azure adapter.
  5. Verify the chain with the Apache-2.0 verifier.