Files
lpt-ai/src/llm/prompts.ts
T

155 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Prompt 模板集中管理。
* 修改提示词只动这个文件,方便版本对照与回滚。
*/
import type { ChatMessage } from "./client.js";
export interface FragmentInput {
content: string;
createdTime?: string;
}
/**
* 残片聚合为学习报告。
* 原则:报告是写给"未来复习的自己"的,保留具体知识点,剔除口语碎屑;
* 不虚构残片中不存在的内容。
*/
export function aggregateReportPrompt(
taskName: string,
fragments: FragmentInput[],
expectation?: string,
): ChatMessage[] {
const fragmentLines = fragments
.map((f, i) => `${i + 1}. ${f.content}${f.createdTime ? `${f.createdTime}` : ""}`)
.join("\n");
const expectationBlock = expectation
? `\n本次学习开始前的预期目标:\n${expectation}\n`
: "";
return [
{
role: "system",
content: [
"你是一名学习记录整理助手。用户在一次学习会话中随手记录了若干学习残片,",
"请将它们整理为一份简洁的学习报告。要求:",
"1. 只基于残片内容,不虚构、不扩写残片中没有的知识;",
"2. 保留具体的知识点、概念、结论,去掉口语化的碎屑;",
"3. 按逻辑而非时间组织内容,相关的点合并;",
"4. 报告以要点形式呈现,控制在 300 字以内;",
"5. 如果提供了学习预期,在报告末尾用一句话说明本次学习与预期的差距(完成/部分完成/未涉及);",
"6. 直接输出报告正文,不要输出「报告如下」之类的引导语。",
].join(""),
},
{
role: "user",
content: `学习任务:${taskName}\n${expectationBlock}\n本次学习的残片记录:\n${fragmentLines}`,
},
];
}
/**
* 从学习报告生成标准思维导图(预留,用于替代 Java 端 BuiltinMindMapGenerator)。
* 输出为缩进大纲文本,与后端 MindMapTreeTool.parseOutline 格式一致。
*/
export function generateMindMapPrompt(
taskName: string,
taskDescription: string,
reports: string[],
): ChatMessage[] {
return [
{
role: "system",
content: [
"你是一名知识结构整理助手。请阅读某个学习任务的全部学习报告,",
"将其中的知识点整理成一份思维导图大纲。要求:",
"1. 第一行是导图根标题(任务主题);",
"2. 之后每行一个节点,用两个空格的缩进表示层级;",
"3. 按知识的内在结构组织(概念→细分→要点),不按时间顺序;",
"4. 合并重复的知识点;",
"5. 只基于给定内容,不补充外部知识;",
"6. 直接输出大纲,不要任何解释。",
].join(""),
},
{
role: "user",
content: [
`学习任务:${taskName}`,
taskDescription ? `任务描述:${taskDescription}` : "",
"",
"学习报告:",
...reports.map((r, i) => `${i + 1}. ${r}`),
]
.filter(Boolean)
.join("\n"),
},
];
}
/**
* 回忆对比:将用户凭记忆写的导图与标准导图语义对比。
*
* AI 只需输出平铺的匹配/遗漏/额外列表(不输出树结构,树标注由 Java 端完成)。
*
* 输出要求:严格 JSON,不要 markdown 代码块,格式如下:
* {
* "matches": [
* { "standardTitle": "A知识点", "recallTitle": "知识点A" }
* ],
* "missedTitles": ["在标准导图中但用户未回忆到的节点标题"],
* "extraNodes": [
* { "title": "用户额外回忆的知识点", "path": "所属路径" }
* ],
* "recallRatio": 1.0,
* "evaluation": "中文评价 2-5 句"
* }
*
* matches 中 standardTitle 必须与标准导图中的节点标题逐字一致。
* missedTitles 存放标准导图中有但用户完全没提到的节点标题。
* extraNodes 的 path 用 "根 > 父节点 > 当前节点" 格式。
*/
export function compareRecallPrompt(
taskName: string,
standardOutline: string,
recallOutline: string,
): ChatMessage[] {
return [
{
role: "system",
content: [
"你是一名学习评估专家。请对比两份思维导图大纲:",
"1. 标准导图(系统从学习报告中提炼的知识结构)",
"2. 用户导图(用户凭记忆回忆的知识结构)",
"",
"你的任务:",
"- 对标准导图的每个非根节点,判断用户在回忆中是否覆盖了它;",
"- 匹配应基于语义理解:同义表达算匹配(如\"锁升级\"≈\"锁膨胀\");",
"- 考虑层级上下文:节点在用户导图中的归属逻辑正确即可;",
"- 找出用户额外回忆的、标准导图中没有的知识点;",
"- 统计覆盖率 = 命中数 / (命中数 + 遗漏数);",
"- 用中文写一段评价(2-5 句话)。",
"",
"重要:你不需要输出标准导图的树结构。只需列出 matches(匹配对)、",
"missedTitles(遗漏的节点标题列表)、extraNodes(额外节点列表)。",
"matches 中的 standardTitle 必须与标准导图中的标题文字完全一致,不要改写。",
"输出必须是有效 JSON 对象,不要包含 ```json 之类的标记,直接输出 JSON。",
].join("\n"),
},
{
role: "user",
content: [
`学习任务:${taskName}`,
"",
"===== 标准导图(知识结构)=====",
standardOutline,
"",
"===== 用户回忆导图 =====",
recallOutline,
"",
"请输出 JSON(只包含 matches、missedTitles、extraNodes、recallRatio、evaluation 五个字段):",
].join("\n"),
},
];
}