feat(流程图): 没走对的图,AI 对照答案说出错在哪个框、该怎么改,并把那个框标红
原来只有程序拼出的现象(「输出 a」输出的是 2,应该是 8),指的是出结果的框, 错的根子常在前面,学生和老师都看不出该改哪里。跑完以后再请 AI 看题目、图、 没走对的几组和老师的答案,写「哪里错了 / 可以这样改」两句,指出真正要改的框; 提交列表右栏的图和题目页画布上标红它。等级照旧只由跑出来的结果定, 点评失败或像代码就不要,退回只显示逐组结果。老提交不补。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8bd3d998ae
commit
d2fc0382ec
6 files changed
+256
-15
No files matched your search
@@ -24,6 +24,13 @@ import { flowchartCases, type FlowchartCase } from "./cases"
|
||||
import { buildProgram, describeDoc, flowBoxes, judgeCase, TRANSLATE_PROMPT } from "./program"
|
||||
import { gradeForCases, gradeForScore } from "./grade"
|
||||
import type { FlowchartJobData } from "./job"
|
||||
import {
|
||||
flowchartAnswer,
|
||||
parseReview,
|
||||
REVIEW_PROMPT,
|
||||
reviewInput,
|
||||
type FlowchartReview,
|
||||
} from "./review"
|
||||
|
||||
type Problem = typeof schema.problem.$inferSelect
|
||||
|
||||
@@ -43,7 +50,7 @@ interface Evaluation {
|
||||
* (有一张 C 再交变 S),学生学会了原样连点 —— 22% 的提交和上一次一模一样;评语里还写
|
||||
* node_9 这种学生看不到的编号。现在对不对由程序跑出来的输出决定,和模型的心情无关。
|
||||
*/
|
||||
function translateInput(problem: Problem, doc: FlowDoc, cases: FlowchartCase[]) {
|
||||
function problemBrief(problem: Problem, cases: FlowchartCase[]) {
|
||||
const samples = cases.filter((item) => item.name.startsWith("例子")).slice(0, 3)
|
||||
return [
|
||||
`题目:${problem.title}`,
|
||||
@@ -51,13 +58,39 @@ function translateInput(problem: Problem, doc: FlowDoc, cases: FlowchartCase[])
|
||||
`输入说明:${plainText(problem.inputDescription).slice(0, 400) || "无"}`,
|
||||
`输出说明:${plainText(problem.outputDescription).slice(0, 400) || "无"}`,
|
||||
...samples.map((item) => `${item.name}的输入:\n${item.input}`),
|
||||
"",
|
||||
"<flowchart>",
|
||||
describeDoc(doc),
|
||||
"</flowchart>",
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
function translateInput(problem: Problem, doc: FlowDoc, cases: FlowchartCase[]) {
|
||||
return [problemBrief(problem, cases), "", "<flowchart>", describeDoc(doc), "</flowchart>"].join(
|
||||
"\n",
|
||||
)
|
||||
}
|
||||
|
||||
/** 没走对时的点评(见 review.ts)。出什么错都只是没有点评,评分照常落库 */
|
||||
async function review(
|
||||
problem: Problem,
|
||||
doc: FlowDoc,
|
||||
cases: FlowchartCase[],
|
||||
code: Record<string, string | null>,
|
||||
results: FlowchartCaseResult[],
|
||||
texts: Map<string, string>,
|
||||
): Promise<FlowchartReview | null> {
|
||||
try {
|
||||
const input = reviewInput({
|
||||
brief: problemBrief(problem, cases),
|
||||
flowchart: describeDoc(doc),
|
||||
code,
|
||||
results,
|
||||
answer: flowchartAnswer(problem.answers),
|
||||
})
|
||||
return parseReview(await completeChat(REVIEW_PROMPT, input, { json: true }), texts)
|
||||
} catch (error) {
|
||||
console.error(`Failed to review flowchart for problem ${problem.id}`, error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** 交上来的结构树(压缩过的);2026-10 之前的 vue-flow 格式读不出来,给 null */
|
||||
function flowDocOf(data: unknown): FlowDoc | null {
|
||||
const record = asRecord(data)
|
||||
@@ -144,13 +177,22 @@ async function evaluateByRunning(
|
||||
|
||||
const passed = results.filter((row) => row.ok).length
|
||||
const grade = gradeForCases(passed, results.length, style !== "")
|
||||
const report: FlowchartCaseReport = { version: 2, passed, total: results.length, cases: results }
|
||||
// 全对时「还可以更好」用翻译那一步顺带给的写法建议;没全对才另外点评「错在哪、怎么改」
|
||||
const advice =
|
||||
passed < results.length ? await review(problem, doc, cases, code, results, texts) : null
|
||||
const report: FlowchartCaseReport = {
|
||||
version: 2,
|
||||
passed,
|
||||
total: results.length,
|
||||
cases: results,
|
||||
focus: advice?.at ?? null,
|
||||
}
|
||||
return {
|
||||
// 分数只给统计和老的列表用:没全对时是走对的比例,全对时 A 90、S 100
|
||||
score: grade === "S" ? 100 : grade === "A" ? 90 : Math.round((passed / results.length) * 100),
|
||||
grade,
|
||||
feedback: "",
|
||||
suggestions: passed === results.length ? style : "",
|
||||
feedback: advice?.wrong ?? "",
|
||||
suggestions: passed === results.length ? style : (advice?.fix ?? ""),
|
||||
criteria: { ...report },
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user