Unilearning · AI

The boundary of AI grading: drafts to the AI, decisions to people

The riskiest part of AI grading is not accuracy — it is accountability. We write AI output into extension columns rather than business-state columns, drawing that line in the data model.

When we built AI grading, one question took a long time to settle: does a score produced by the AI actually count? If it counts, who answers for it when it is wrong? If it does not, what exactly is the AI for?

The conclusion we landed on: the AI writes drafts, and the teacher makes the call. And this boundary is not written into product documentation — it is written into the data model.

Drafts go into extension columns, business state stays untouched

The learning-record table has explicit business-state columns (submitted / reviewed, and so on) and a score column. AI output never goes into those columns; it goes into attributes, a JSONB extension column.

ai domain — drafts written to the extension column
01// 草稿挂在扩展属性上,业务状态列不动
02record.attributes["ai_feedback"] = {
03 "score": 82,
04 "comment": "第二问的推导跳了一步,建议补上边界条件…",
05 "model": "glm-4",
06 "generated_at": "2026-06-25T10:12:03Z",
07 "draft": true
08}
09
10// 终审仍走教师既有的 feedback 接口
11POST /tv1/teacher/homeworks/{hid}/feedback

Whole-class grading must tolerate partial failure

A class has dozens of submissions; the whole batch must not roll back because the seventh one timed out. So the batch endpoint processes work in chunks: a single failure does not interrupt the rest of the batch, errors are reported per item, and the next run retries automatically — records that already have a draft are skipped, so tokens are never burned twice.

  • Only records in the submitted state are processed; final-reviewed ones never get a new draft
  • Records that already have a draft are skipped automatically, avoiding duplicate model calls
  • A single failure reports an error for that item only, leaving the rest of the batch untouched
  • Work is processed in chunks with a cap of 100 per batch, so one request cannot overwhelm the model service

Graceful degradation when unconfigured

When no LLM endpoint is configured, the AI grading endpoint returns 501 and every other feature is completely unaffected. This design lets customers who want to try AI and customers who want nothing to do with it run the same build.

We push the parts AI speeds up as far as they will go — but the question of who answers for the result is not something we hand to the model.

More Notes
Get in touch

Hand the complexity of identity, agents and private domain to one governable kernel

Whether you are replacing an existing IAM, building an agent platform, or trying to make private-domain operations actually work — start with a 30-minute architecture call. We will first judge whether this is the kind of problem we are good at, and say so plainly if it is not.