龍騰 AI 非選批閱平台 開發者文件中心
提交與批閱

人工覆核

產生新的批閱結果版本、樂觀鎖、覆核紀錄,以及覆核觸發的事件

當 AI 產生的批閱結果需要調整時,除了在客戶端逕行修正外,請對該批閱結果版本回傳一筆覆核(revise)記錄,產生新的批閱結果版本。

Loading diagram...

送出覆核

使用 POST /v1/responses/{id}/evaluation/revise 端點送出覆核。該端點動作需要 API Key 具有 evaluations:revise scope。

每次請求中都必填 expected_versionreason。其餘欄位依原有批閱結果的項目而定。

原有批閱結果帶有的欄位覆核需送出的欄位覆核不得送出的欄位
dimensionsdimensions(必填),只列出要修改的向度scoreblanks
blanksblanks(必填),只列出要修改的格子scoredimensions
criteriascore.earned(必填)dimensionsblankscriteria

若該題目採用分析式評分(批閱結果存在 dimensions)或為填空題時,覆核僅應送出有修正的部分,且無須送出計算後更新的總分。未送出的部分將自動沿用前一版,並且由伺服器計算更新總分。

若題目採用整體式評分(批閱結果存在 criteria)時,覆核僅應送出 score.earned 的總分。若需要補充修正方向與理由,應於 reason 中說明。

覆核者不受評分標準的級距限制(但仍受上下界限制,詳見驗證規則)。

範例:分析式評分

{
  "expected_version": 1,
  "dimensions": [
    {
      "key": "內容正確性",
      "score": { "earned": 4.5 },
      "feedback": "替代論證可接受,酌予提高。"
    }
  ],
  "feedback": "學生以替代論證說明暗反應,內容大致正確。",
  "reason": "學生以替代論證方式作答,原評分低估其正確性。"
}

原本兩個向度為 3 + 4 = 7 分,覆核後回應的 score.earned4.5 + 4 = 8.5,由伺服器算出。

範例:填充題

填充題的覆核不送總分。列出要修改的格子即可,其餘的格子由伺服器沿用前一版,總分則由各格加總得出。三格的題目中只改第二格時,請求就只有一筆:

{
  "expected_version": 1,
  "blanks": [
    {
      "key": "mockBlank2r7fnq2xoahd",
      "score": { "earned": 1 },
      "feedback": "「囊狀膜」為可接受的同義說法,予以部分給分。"
    }
  ],
  "reason": "accepted[] 未涵蓋此同義詞,原判定過嚴"
}

回應的 score.earned2 + 1 + 2 = 5,由伺服器算出。若請求另外帶了 score,會得到 400 而不是以其中一個為準。

範例:整體式評分

{
  "expected_version": 1,
  "score": { "earned": 18 },
  "feedback": "取材切題,惟結構稍鬆散。",
  "reason": "計分程式判定離題並封頂,惟本文確有扣題,原判定過嚴。"
}

這種結果沒有構成總分的部分可以修正,因此覆核者直接指定總分。請求中不得帶 criteria

樂觀鎖

送出覆核時,請求應帶有 expected_version 參數,標示該次修正所依據的版本(也就是客戶端讀取到的目前最新版本)。系統建立覆核版本時,將檢核該參數是否正確等於系統中存在的最新版本。

若自讀取到寫入覆核的期間內,有另一位覆核者已先寫入新版本,導致 expected_version 不等於寫入當下系統的最新版本時,該請求會回應 409 ERR_CONFLICT 錯誤,且不建立任何版本。

{
  "error": {
    "code": "ERR_CONFLICT",
    "message": "Evaluation has been updated since the version you based on",
    "details": { "expected": 1, "current": 2 },
    "request_id": "req_01j9f3k2m1"
  }
}

在此狀況下,請勿逕行只修改 expected_version 為最新版本便直接重送,而使其他覆核者的修改丟失。

請重新讀取最新批閱結果,將修正重新套用,並再次確認修改內容,如下範例:

async function revise(responseId: string, patch: ReviseInput) {
  const latest = await getLatestEvaluation(responseId);
  const res = await post(`/responses/${responseId}/evaluation/revise`, {
    ...patch,
    expected_version: latest.version,
  });

  if (res.status === 409) {
    // 已有較新的版本落地:將最新結果送回 UI 由覆核者重新判斷,不自動重試
    throw new StaleEvaluationError(await getLatestEvaluation(responseId));
  }
  return res;
}

驗證規則

以下驗證規則將會在建立覆核版本時執行。違反將回應 400 ERR_VALIDATION_FAILED 錯誤。

  1. reason 為必填:請清楚描述覆核的理由、項目等說明資訊。該些描述將不可變的儲存於版本紀錄中。
  2. 分數更新後的有效值域score.earned 不得為負,也不得高於題目滿分;逐格的 earned 同樣必須落在該格的 [0, max_score] 之內。超出範圍會得到 400 ERR_VALIDATION_FAILED 錯誤。
  3. 分析式評分或填充題需進行至少一項修正:若完全未傳入修正項目,將回應錯誤。

回應

回應為 200,內容是新的批閱結果版本,並附帶 previous_score

{
  "data": {
    "id": "eval_6Vq1Zr",
    "response_id": "resp_5Kc3Yv",
    "version": 2,
    "method": "rubric_grading",
    "score": { "earned": 8.5, "max": 10 },
    "dimensions": [
      {
        "key": "內容正確性",
        "score": { "earned": 4.5, "max": 6 },
        "feedback": "替代論證可接受,酌予提高。"
      },
      { "key": "完整性", "score": { "earned": 4, "max": 4 } }
    ],
    "feedback": "學生以替代論證說明暗反應,內容大致正確。",
    "reason": "學生以替代論證方式作答,原評分低估其正確性。",
    "graded_by": "user_3Nb7Qh",
    "graded_at": "2026-03-02T14:10:00Z",
    "previous_score": { "earned": 7, "max": 10 }
  }
}

previous_score 出現在覆核的回應中,供確認畫面使用。它不屬於儲存的批閱結果,後續讀取不會回傳。

Webhook 事件

客戶端可以訂閱 Webhookresponse.evaluation_revised 事件,以在建立新的覆核版本時接收主動通知。

覆核清單

使用 GET /v1/submissions/{submission_id}/evaluation-revisions 端點以讀取一份題目作答的歷次覆核請求:

{
  "data": [
    {
      "response_id": "resp_5Kc3Yv",
      "question_ref": "q_7g2NkP:2",
      "evaluation_id": "eval_6Vq1Zr",
      "version": 2,
      "score": { "earned": 8.5, "max": 10 },
      "previous_score": { "earned": 7, "max": 10 },
      "delta": 1.5,
      "graded_by": "user_3Nb7Qh",
      "reason": "學生以替代論證方式作答,原評分低估其正確性。",
      "graded_at": "2026-03-02T14:10:00Z",
      "method": "rubric_grading"
    }
  ],
  "pagination": { "has_more": false }
}

deltascore.earned − previous_score.earned,覆核調降時為負值。evaluation_id 是該覆核版本自身的 id。

本端點回傳覆核請求及事件本身的記錄,與 GET /responses/{id}/evaluation/history 回傳歷次批閱結果版本(經套用覆核後的結果)不同。

相關

本頁內容