news 2026/9/10 23:10:42

OpenMAIC PBL v2 结课报告生成器:evaluator-final 提示词的结构化输出契约与工程实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenMAIC PBL v2 结课报告生成器:evaluator-final 提示词的结构化输出契约与工程实现

OpenMAIC PBL v2 结课报告生成器:evaluator-final 提示词的结构化输出契约与工程实现

【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC

本篇技术指南以 OpenMAIC 仓库中 PBL v2 教学引擎的最终评估系统提示词 evaluator-final.md 为骨架,剖析「整项目完结报告(Completion Report)」是如何由 LLM 生成、解析并持久化的:从严格 JSON 输出契约、四类字段的取值规范,到stars星级校准刻度、what_you_built/what_you_learned的反幻觉写作规则,再到与之配套的 SSE 流式评估 Agent、JSON Tail 解析器和场景化(role-play)变体。读完你将掌握 PBL v2 最终评估的完整链路,并能在自己的多智能体教学或评估系统中复用这套「叙事 + 结构化尾巴」的提示词工程模式。

背景:PBL v2 的三层评估体系与结课报告的位置

在进入提示词本身之前,先厘清它的上下文。OpenMAIC 的 PBL v2(Project-Based Learning,项目式学习)引擎中,Evaluator Agent 有三种评估模式,共享同一套流式模式(见 agents/evaluator.ts 顶部注释):

模式触发时机产出驱动 UI
runTaskEvaluation一个微任务(microtask)带提交完成后短反馈 +{strengths, improvements, score?}JSON 尾巴微任务级反馈
runMilestoneEvaluation一个里程碑(milestone)的最后一个微任务推进后反思卡片叙事 +{learned, performance, stars}JSON 尾巴MilestoneCard 反思卡片
runFinalEvaluation最后一个里程碑完成后短引言叙事 +{stars, what_you_built, what_you_learned, whats_next}JSON 尾巴Completion 结课页 Hero 区

本文的主角evaluator-final.md正是runFinalEvaluation的系统提示词。它专门负责为刚完成整个 PBL 项目的学习者撰写结课报告

为什么需要一个独立 Agent,而不是在 Instructor 上加一个工具?源码注释给出了两条理由:其一,系统提示词基调不同——评估者走「反思 / 报告」语气,与教学语气是冲突的,共用一套提示词会自我打架;其二,输出契约不同——评估者是「叙事 + JSON 尾巴」的固定结构,而 Instructor 是带工具调用的对话式回复。此外,独立的 SSE 调用让前端可以把「导师正在生成阶段反馈…」渲染为独立阶段,而不是神秘的多余 Instructor 回合。

第一要义:这是「页面」而非「聊天气泡」

提示词开头就划定了渲染约束:

This report is rendered as a dedicated page —NOTa chat bubble — so the structured bullets ARE the main content. Your narrative paragraph is just a short, warm intro at the top of that page.

这决定了整份提示词的写作策略:结构化列表才是主体内容,叙事段落只是页面顶部一段简短、温暖的开场白。因此字段规则中反复强调「不要重复列表内容」「保持叙事紧凑」。

在源码层面,这与评估 Agent 的流式策略完全对应。runShared中设定了shouldStreamTokens = false——评估输出是 JSON-only 的,且只有在结构化载荷持久化后才会渲染,因此原始 JSON 不会流式进入聊天(见 agents/evaluator.ts)。也就是说:结课报告的文本流在「确认 JSON 尾巴可解析」之前是不对学习者暴露的,保证学习者永远不会看到一段未成型的 JSON 或半截叙事。

输出契约:唯一的、严格形状的 JSON 对象

提示词规定输出的硬性形状:

{"feedback": "...", "stars": 4.5, "what_you_built": ["...", "...", "..."], "what_you_learned": ["...", "...", "..."], "whats_next": "..."}

附带三条输出格式铁律:

  1. 只输出一个合法的 JSON 对象,JSON 之外不得有任何散文;
  2. 不要用 markdown 包裹,不要用```json代码围栏
  3. 字段名严格如上,不可改名、不可增删。

当然,LLM 在实际推理中并不总是遵守「裸 JSON」的要求。这正是工程侧要兜底的地方——仓库中 eval-tail-parser.ts 的存在意义。它专门处理三类业界常见的「不听话」输出:

  • LLM 输出围栏包裹的 JSON、裸 JSON、或「散文 + JSON」混合 → 复用 OpenMAIC 共享的 JSON 修复解析器parseJsonResponse,通过parseEvaluationTail从多个候选(全文、任意围栏内容、尾部平衡花括号段)中自后向前找到最后一个可解析对象;
  • 围栏内 JSON 本身畸形 → 同样走共享修复逻辑,只有完全无法恢复对象时才返回null
  • 字段值类型不合法(见下节)→ 通过各normalize*函数钳制与归一。

而且这是有历史教训的:注释明确写道,这是 v1 仓库(Python 版)评估器踩过的坑——同样的三类失败模式当时迭代修复了很久,PBL v2 一次性全部编码进解析器里。

四个字段的取值规则

feedback:2~3 句的开场叙事

提示词给出的结构是:

  • 一句话点出学习者具体做了什么(用学习者自己的话描述的项目标题 + 一句话概括它做什么);
  • 一到两句突出一个具体高光时刻(某个恢复过来的报错、某个突然想通的概念、某个提速的阶段)——必须从下方 engagement rollup 取材,不得编造细节
  • 若「Integrative checks (stage synthesis)」部分含有学习者的作答,则优先以此为高光:明确表扬学习者如何跨阶段/跨项目连接了概念,并以记录的问答为根据,简短引用或转述。若没有记录作答,绝不虚构

同时明确禁止:标题、列表符号、长弧线叙事("from beginning to end...")、结尾号召。

stars:0-5 半星刻度的星级校准

stars是页面以星星图标渲染的视觉评分(不是 "/5" 分母),步进为 0.5。提示词给出了与里程碑卡片一致的校准刻度:

星级含义
5.0自信流畅完成
4.5大体顺利,有一两个小磕绊
4.0扎实,遇到预期内的障碍并干净利落地恢复(不确定时的默认值
3.5明显挣扎,但在提示下最终达成
3.0大量来回反复
< 3.0出现多个未解决的错误时

工程侧的normalizeStars(eval-tail-parser.ts)对这个字段做了完整防御:接受干净数字(4.53)、数字字符串("4")、"4.5/5""4.5 / 5"形式的分数串(取分子);越界值钳制到[0, 5]NaN/Infinity/ 非数字字符串(如"good""4 stars")/null/ 对象 / 数组一律拒绝返回null;最终Math.round(clamped * 2) / 2保证半星步进。解析失败时 UI 干净地隐藏评分,而不是渲染一个错误值。

what_you_built:3-5 条具体成果(名词短语)

要求学习者能一眼认出的名词短语:

  • ✓ "一个能猜数字的命令行小游戏"
  • ✓ "用户输入名字后会个性化打招呼"
  • ✗ "Working Python script"(太抽象)
  • ✗ "main.py"(只有文件名)

第一条必须是整个项目,其余为关键功能/能力。工程侧normalizeStringList(eval-tail-parser.ts)过滤非字符串、去空、剔除模板占位符并截断到最多 6 条(persistEvaluation传入6),防止失控的 LLM 撑爆存储。

what_you_learned:3-5 条学习者自己的话——最容易造假、被重点防范的字段

提示词用相当篇幅(原文最大的规则块)强调这是最常被垃圾内容伪造的字段

  • 禁止:任何像函数名、snake_case 标签、内部签名的东西。举例:python_install_verifiedif_elif_else_number_comparisonwhile_break_loop——这些是内部埋点标签,绝不允许出现在这里;
  • 禁止:学习者自己没使用过的行话("Conditional control flow"、"Loop invariants"、"Variable scoping");
  • ✓ 允许:"用 if/else 让程序根据输入做出不同反应";
  • ✓ 允许:"看到红色报错不再慌张,会逐行读错误信息找出问题"。

具体操作指令是:把 engagement rollup 里concepts_unlocked的内部签名翻译成学习者语言的自然句子,禁止原样粘贴签名。此外,若存在整合性阶段检查(integrative stage-check)的作答,至少一条what_you_learned应承认学习者做出的跨阶段连接。

whats_next:1-2 句、指向具体下一步

禁止泛泛而谈("keep learning!"),要基于刚做完的东西推荐具体的下一个项目或扩展方向。

证据从哪来:user 侧提示词的真实数据装配

系统提示词负责定规则,而user侧则由buildFinalEvalPrompt组装证据(见 eval-prompts.ts)。它拼接了四个数据块:

  1. 项目信息project.title+project.description
  2. 各里程碑反思卡片Per-milestone reflection cards):取每个 milestone 最新的kind === 'milestone'评估,带上strengths(截前 4 条)、stars、以及截断到 280 字符的反馈散文——注释强调要用叙事而非仅 strengths 列表,因为「叙事捕捉了我们希望结课卡片回映的人性化时刻」;
  3. engagement rollup 分析汇总formatProjectEngagementRollup):聚合每个里程碑的时长、学习者轮次、错误数(含重复错误)、完成微任务数、closing-check 质量直方图(weak/ok/strong)、去重后的概念集合等,让 LLM 有结构化事实依据,而不是默认生成泛泛的 "great work";
  4. 整合性检查formatProjectSynthesisChecks):从stage_synthesis_check事件(或回退到收尾微任务的 closing_check / 缓存 engagement)中取出核心概念、问题、学习者作答与质量标记,明确标注数据来源。

这正回应了提示词中「从 engagement rollup 取材、不编造细节」的要求——系统把真实遥测以结构化文本喂给模型,模型只能引用已有证据。

从 LLM 输出到持久化:一次「部分成功优于整体失败」的容错设计

评估完成后的落库逻辑在 agents/evaluator.ts 的persistEvaluation中:

  • 先用parseEvaluationTail解析 JSON 尾巴,解析失败是非致命的:仍持久化散文反馈(学习者能看到 LLM 说了什么),只是缺少结构化字段不渲染。注释明言:"partial success beats throwing the whole evaluation away on a malformed JSON tail";
  • kind === 'final'分支将tail.what_you_builtwhatYouBuilttail.what_you_learnedwhatYouLearnedtail.whats_nextwhatsNext,通过normalizeStringList/normalizeOptionalString归一,然后调用addEvaluation写入project.evaluations并追加evaluation_created运行时事件(evaluation.ts);
  • 类型层面,types.ts 中PBLEvaluationwhatYouBuilt/whatYouLearned/whatsNext被标注为final-evaluation-only字段,task / milestone 评估保持空值,前端以kind === 'final'为键来决定是否渲染;
  • 整个评估期间 Evaluator不调用任何工具,仅在最后、JSON 尾巴解析成功后追加一次project.evaluations——这让流式层保持简单,且解析失败时项目保持原封不动。

值得注意的一点:任务评估(task)使用score(0-100 整数),而里程碑与最终评估使用stars(0-5 半星)。提示词中明确禁止在结课报告里出现"score"/"/100"字段,也禁止使用 task 评估的strengths/improvements形状——三种评估形态刻意不做统一,而是让 UI 依据kind分支渲染。

场景化变体:evaluator-final-scenario.md 与 act_goals

当项目带有scenario(角色扮演/模拟场景)配置时,buildFinalEvalPrompt会切换系统提示词到 evaluator-final-scenario.md,并装配完全不同的证据:场景前提、角色扮演逐字记录(formatScenarioTranscript,保留尾部 6000 字符预算)、以及每幕(act)的目标清单(scenarioActGoalsScaffold)。

这是「技能练习」而非「知识构建」的评估:禁止谈论 concepts/code/artefacts,改为评判对话处理质量,输出契约多出一个act_goals数组。对齐是严格且基于索引的

  • 幕与幕之间按milestoneId对齐,幕内每个结论按goalIndex对齐(而非数组位置),防止模型重排同幕目标导致结论错挂;
  • normalizeActGoals(completion-stats.ts)要求模型返回的 goals 必须构成[0, N)的完美双射:每个索引恰好出现一次、在范围内、状态合法(achieved/partial/missed);
  • 任何一处不合规(缺幕、目标数不对、越界/重复/缺失 goalIndex、非法状态)都返回undefined,宁可让结课页回退到叙事 + 只读目标列表,也绝不展示错标或虚构的记分卡;
  • 目标文本、技能标签、幕标题永远来自项目数据,LLM 只贡献statusnote,从机制上杜绝它改写或捏造目标。

这一设计是「LLM 输出永远可以被平台严格校验」的极佳范例,普通项目与场景项目的最终评估在提示词、证据、输出契约三层完全隔离,互不污染。

结课报告提示词的工程要点回顾

回到evaluator-final.md本身,这套提示词之所以值得复用,在于它把「写作质量」与「工程可控性」做了清晰分工:

  1. 叙事与结构化解耦:页面级渲染让列表成为主体,叙事限定 2-3 句,既保证页面信息密度,又避免 LLM 长篇大论稀释重点;
  2. 反幻觉显式化:「从 rollup 取材」「禁止内部签名」「禁止学习者没说过的话」「没记录就不虚构」全部写成显式规则,并在 user 侧用formatProjectEngagementRollup/formatProjectSynthesisChecks提供真实证据锚点;
  3. 数值规范提前编码stars的 0.5 步进校准、范围钳制、非法值拒绝,在提示词与解析器normalizeStars中双重定义,保证 UI 永远拿到干净值;
  4. 失败降级而非硬失败:JSON 尾巴解析失败时保留散文,学习者不会面对空白页面;
  5. 规则与代码分离:提示词以 Markdown 文件存放(lib/pbl/v2/prompts/ 目录),由 prompts/loader.ts 读取并做{{language}}变量插值,改提示词文案无需触碰 TypeScript,人类审阅也只需通读一个文件。

如果你正在为自己的 AI 教学系统设计「项目完结报告」或「阶段反思卡片」功能,直接借鉴这套「系统规则 Markdown + user 证据装配 + JSON 尾巴解析 + 索引对齐校验」的组合,就能同时获得高质量文本与可验证的结构化数据。

【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 23:06:41

Linux操作系统核心原理与实战指南

1. 为什么需要理解Linux的本质第一次接触Linux时&#xff0c;大多数人都会陷入一个误区——把Linux当作Windows的替代品来使用。这种认知偏差会导致学习过程中遇到各种水土不服的情况。事实上&#xff0c;Linux代表着一套完全不同的操作系统哲学。操作系统本质上是一个资源管理…

作者头像 李华
网站建设 2026/9/10 23:05:33

PostgreSQL查询性能监控利器pg_stat_statements详解

1. 为什么需要监控PostgreSQL查询性能在数据库运维工作中&#xff0c;查询性能监控是DBA和开发人员每天都要面对的核心挑战。PostgreSQL作为功能最强大的开源关系型数据库之一&#xff0c;其性能监控有着独特的技术实现路径。当数据库响应变慢时&#xff0c;我们常常陷入这样的…

作者头像 李华
网站建设 2026/9/10 23:05:09

Beads 故障恢复手册:从 Dolt 数据损坏到主键分叉的完整救援指南

Beads 故障恢复手册&#xff1a;从 Dolt 数据损坏到主键分叉的完整救援指南 【免费下载链接】beads Beads - A memory upgrade for your coding agent 项目地址: https://gitcode.com/GitHub_Trending/beads1/beads 导读&#xff1a;本文以 Beads 开源仓库的恢复运维文档…

作者头像 李华