生成事件切换提示词,添加提示词表
This commit is contained in:
parent
d5430d257c
commit
75b73f1c2a
@ -184,6 +184,18 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
},
|
||||
initData: async (knex) => {},
|
||||
},
|
||||
//提示词表
|
||||
{
|
||||
name: "o_prompt",
|
||||
builder: (table) => {
|
||||
table.integer("id").notNullable();
|
||||
table.string("name");
|
||||
table.text("rompt");
|
||||
table.primary(["id"]);
|
||||
table.unique(["id"]);
|
||||
},
|
||||
initData: async (knex) => {},
|
||||
},
|
||||
//小说原文表
|
||||
{
|
||||
name: "o_novel",
|
||||
|
||||
@ -37,6 +37,7 @@ export default router.post(
|
||||
const chapterAllList = await u.db("o_novel").where("projectId", projectId).whereIn("id", totalNovelId);
|
||||
const novelClass = new u.cleanNovel();
|
||||
novelClass.emitter.on("item", async (item) => {
|
||||
console.log("%c Line:40 🍇 item", "background:#6ec1c2", item);
|
||||
await u
|
||||
.db("o_novel")
|
||||
.where("id", item.id)
|
||||
|
||||
8
src/types/database.d.ts
vendored
8
src/types/database.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
// @db-hash 0041ea9843a4bb46f03412c516ec323b
|
||||
// @db-hash 982ecc457e8b79aea4521c60afd06753
|
||||
//该文件由脚本自动生成,请勿手动修改
|
||||
|
||||
export interface memories {
|
||||
@ -117,6 +117,11 @@ export interface o_project {
|
||||
'videoModel'?: string | null;
|
||||
'videoRatio'?: string | null;
|
||||
}
|
||||
export interface o_prompt {
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'rompt'?: string | null;
|
||||
}
|
||||
export interface o_script {
|
||||
'content'?: string | null;
|
||||
'createTime'?: number | null;
|
||||
@ -235,6 +240,7 @@ export interface DB {
|
||||
"o_outline": o_outline;
|
||||
"o_outlineNovel": o_outlineNovel;
|
||||
"o_project": o_project;
|
||||
"o_prompt": o_prompt;
|
||||
"o_script": o_script;
|
||||
"o_scriptAssets": o_scriptAssets;
|
||||
"o_setting": o_setting;
|
||||
|
||||
@ -8,6 +8,7 @@ import getPath from "@/utils/getPath";
|
||||
import vm from "@/utils/vm";
|
||||
import task from "@/utils/taskRecord";
|
||||
import Ai from "@/utils/ai";
|
||||
import { getPrompts } from "@/utils/getPrompts";
|
||||
|
||||
export default {
|
||||
db,
|
||||
@ -20,4 +21,5 @@ export default {
|
||||
getPath,
|
||||
Ai,
|
||||
task,
|
||||
getPrompts,
|
||||
};
|
||||
|
||||
@ -26,21 +26,17 @@ class CleanNovel {
|
||||
|
||||
private async processChapter(novel: o_novel, intansce: ReturnType<typeof u.Ai.Text>): Promise<EventType | null> {
|
||||
try {
|
||||
const skill = await useSkill("universal_agent.md");
|
||||
|
||||
const prompt = await u.getPrompts("event");
|
||||
const resData = await intansce.invoke({
|
||||
system: skill.prompt,
|
||||
system: prompt,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "请根据以下小说章节生成事件摘要:\n" + novel.chapterData!,
|
||||
},
|
||||
],
|
||||
tools: skill.tools,
|
||||
});
|
||||
|
||||
const preData = resData.text;
|
||||
|
||||
this.emitter.emit("item", { id: novel.id, event: preData });
|
||||
return { id: novel.id!, event: preData };
|
||||
} catch (e) {
|
||||
@ -71,10 +67,7 @@ class CleanNovel {
|
||||
};
|
||||
|
||||
// 启动最多 concurrency 个并发任务
|
||||
const workers = Array.from(
|
||||
{ length: Math.min(this.concurrency, allChapters.length) },
|
||||
() => runNext()
|
||||
);
|
||||
const workers = Array.from({ length: Math.min(this.concurrency, allChapters.length) }, () => runNext());
|
||||
|
||||
await Promise.all(workers);
|
||||
|
||||
|
||||
59
src/utils/getPrompts.ts
Normal file
59
src/utils/getPrompts.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export async function getPrompts(type: string) {
|
||||
if (type == "event") {
|
||||
return `
|
||||
# 事件提取指令
|
||||
|
||||
你是小说文本分析助手。用户每次提供一个章节的原文,你提取该章的结构化事件信息。
|
||||
|
||||
## ⚠️ 输出约束(最高优先级,违反任何一条即为失败)
|
||||
|
||||
1. 你的**完整回复**只有一行,以 \`|\` 开头、以 \`|\` 结尾,恰好 7 个字段
|
||||
2. 回复的**第一个字符**必须是 \`|\`,**最后一个字符**必须是 \`|\`
|
||||
3. \`|\` 之前不许有任何字符——没有引导语、没有解释、没有"根据……"、没有"以下是……"
|
||||
4. \`|\` 之后不许有任何字符——没有总结、没有提取说明、没有改编建议
|
||||
5. 不输出表头行、分隔线、Markdown 标题、emoji、代码块标记
|
||||
|
||||
## 输出格式
|
||||
|
||||
\`\`\`
|
||||
| 第X章 {章节标题} | {涉及角色} | {核心事件} | {主线关系} | {信息密度} | {预估集长} | {情绪强度} |
|
||||
\`\`\`
|
||||
|
||||
### 字段规范
|
||||
|
||||
| 字段 | 格式要求 | 示例 |
|
||||
|------|----------|------|
|
||||
| 章节 | \`第X章 {章节标题}\` | \`第1章 职业危机与许愿\` |
|
||||
| 涉及角色 | 有实际戏份的角色,顿号分隔 | \`林逸、白有容\` |
|
||||
| 核心事件 | 30-60字,必须含动作+结果 | \`林逸因解密风潮事业崩塌,颓废中许愿触发魔法系统绑定\` |
|
||||
| 主线关系 | **必须**为 \`强/中/弱(3-8字理由)\` | \`强(动机建立+系统激活)\` |
|
||||
| 信息密度 | \`高\` / \`中\` / \`低\` | \`高\` |
|
||||
| 预估集长 | **必须**为 \`X秒\`,禁止用分钟 | \`50秒\` |
|
||||
| 情绪强度 | 文字标签,\`+\` 连接,禁止星级/数字 | \`转折+悬疑\` |
|
||||
|
||||
**主线关系判定**:强=直接推动主角弧线;中=补充世界观/人物关系/伏笔;弱=过渡/气氛。
|
||||
|
||||
**预估集长参考**:高密度+高情绪→45-60秒;中→35-45秒;低→25-35秒。
|
||||
|
||||
**可用情绪标签**:\`冲突\`、\`恐怖\`、\`情感\`、\`转折\`、\`高潮\`、\`平铺\`、\`喜剧\`、\`悬疑\`、\`情感崩溃\`。
|
||||
|
||||
## 输出示例
|
||||
|
||||
以下两个示例展示的是**完整回复**——除这一行外没有任何其他内容:
|
||||
|
||||
\`\`\`
|
||||
| 第1章 职业危机与许愿 | 林逸 | 职业魔术师林逸因解密打假风潮导致事业崩塌,颓废中感慨"如果会魔法就好了",意外触发神奇魔法系统绑定 | 强(主角动机建立+系统激活) | 高 | 50秒 | 转折+悬疑 |
|
||||
\`\`\`
|
||||
\`\`\`
|
||||
| 第12章 山间小憩 | 凌玄、苏晚卿 | 凌玄与苏晚卿在山间歇脚,苏晚卿回忆幼时往事,两人关系略有缓和但未实质推进 | 弱(气氛过渡) | 低 | 25秒 | 平铺+情感 |
|
||||
\`\`\`
|
||||
|
||||
## 提取规则
|
||||
|
||||
- 忠于原文,不推测、不脑补、不加入原文未出现的情节
|
||||
- 角色使用文中主要称呼,保持一致
|
||||
- 多条平行事件线时,选对主角影响最大的一条,其余简要带过
|
||||
- 对话密集章节,关注对话推动了什么结果,而非复述对话内容
|
||||
`;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user