feat(AI服务):lpt-ai 独立服务初始版本
- Fastify + TypeScript,OpenAI 兼容接口对接 SiliconFlow - POST /ai/aggregate-report:残片聚合为学习报告(支持预期对比) - POST /ai/generate-mind-map:生成思维导图缩进大纲(与后端解析格式一致) - Key 从环境变量读取且日志脱敏,未配置时返回 503 由调用方降级 - prompt 模板集中管理,vitest 单元测试
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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[],
|
||||
fragments: 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}`),
|
||||
"",
|
||||
"学习残片:",
|
||||
...fragments.map((f, i) => `${i + 1}. ${f}`),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n"),
|
||||
},
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user