This commit is contained in:
YILING0013
2025-02-06 15:01:07 +08:00
parent a000b6929b
commit f0efb2947e
3 changed files with 70 additions and 36 deletions
+6 -18
View File
@@ -501,11 +501,9 @@ def summarize_recent_chapters(
)
combined_text = "\n".join(chapters_text_list)
prompt = f"""你是一名资深长篇小说写作辅助AI,下面是最近几章的合并文本:
{combined_text}
prompt = f"""你是一名资深长篇小说编辑,分析以下合并文本:\n\n {combined_text} \n\n
请用中文输出不超过1000字的摘要,只包含主要剧情进展、角色变化、冲突焦点等要点:
重点强调最后一章的重要内容,以及最后一幕场景细节。
从中提取并预测下一章节的关键字[关键物品/人物/地点/事件/情节]
"""
summary_text = invoke_with_cleaning(model, prompt)
@@ -622,16 +620,7 @@ def generate_chapter_draft(
if not relevant_context.strip():
relevant_context = "(无检索到的上下文)"
# 5) 构造prompt
# 拆分 world_building_text, novel_architecture_text 等等
world_building_text = ""
match_world = re.search(r'#=== 3\) 世界观 ===\n([\s\S]+?)\n#===', novel_architecture_text)
if match_world:
world_building_text = match_world.group(1).strip()
else:
world_building_text = "暂无世界观信息"
novel_setting_text = novel_architecture_text # 整份当做“小说设定”参考
novel_setting_text = novel_architecture_text
prompt_text = scene_dynamics_prompt.format(
novel_number=novel_number,
@@ -648,7 +637,6 @@ def generate_chapter_draft(
scene_location=scene_location,
time_constraint=time_constraint,
world_building=world_building_text,
novel_setting=novel_setting_text,
global_summary=global_summary_text,
character_state=character_state_text
@@ -656,7 +644,7 @@ def generate_chapter_draft(
# 合并检索到的上下文和用户指导
prompt_text += f"\n\n【检索到的上下文】\n{relevant_context}"
prompt_text += f"\n\n用户指导】\n{user_guidance}\n"
prompt_text += f"\n\n章节额外指导】\n{user_guidance}\n"
model = ChatOpenAI(
model=model_name,
@@ -847,7 +835,7 @@ def import_knowledge_file(
# 尝试加载已有的向量库
store = load_vector_store(
api_key=embedding_api_key,
base_url=embedding_url if embedding_url else "http://localhost:11434/v1",
base_url=embedding_url if embedding_url else "http://localhost:11434/api",
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
filepath=filepath
@@ -856,7 +844,7 @@ def import_knowledge_file(
logging.info("Vector store does not exist. Initializing a new one for knowledge import...")
init_vector_store(
api_key=embedding_api_key,
base_url=embedding_url if embedding_url else "http://localhost:11434/v1",
base_url=embedding_url if embedding_url else "http://localhost:11434/api",
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
texts=paragraphs,
+48 -14
View File
@@ -83,19 +83,19 @@ plot_architecture_prompt = """\
世界观:{world_building}
要求按以下结构设计:
第一幕(触发)
第一幕(触发)
- 日常状态中的异常征兆(3处铺垫)
- 引出故事:展示主线、暗线、副线的开端
- 关键事件:打破平衡的催化剂(需改变至少3个角色的关系)
- 错误抉择:主角的认知局限导致的错误反应
第二幕(对抗)
第二幕(对抗)
- 剧情升级:主线+副线的交叉点
- 双重压力:外部障碍升级+内部挫折
- 虚假胜利:看似解决实则深化危机的转折点
- 灵魂黑夜:世界观认知颠覆时刻
第三幕(解决)
第三幕(解决)
- 代价显现:解决危机必须牺牲的核心价值
- 嵌套转折:至少包含三层认知颠覆(表面解→新危机→终极抉择)
- 余波:留下2个开放式悬念因子
@@ -169,12 +169,43 @@ update_character_state_prompt = """\
{old_state}
请更新角色状态,内容包括:
角色属性:
- 角色物品
- 能力
- 状态
- 主要角色间关系网
- 触发或加深的事件
角色A属性:
├──物品:
├──道具1:描述
├──道具2:描述
...
├──能力
├──技能1:描述
├──技能2:描述
...
├──状态
├──身体状态:
├──Buff/Debuff
├──心理状态:描述
├──主要角色间关系网
├──角色B:描述
├──角色C:描述
...
├──触发或加深的事件
├──事件1:描述
├──事件2:描述
...
角色B属性:
├──物品
├──...
├──能力
├──...
├──状态
├──...
├──主要角色间关系网
├──...
├──触发或加深的事件
├──...
角色C属性:
......
新出场角色:
- 任何新增角色或临时出场人物的基本信息
@@ -203,10 +234,13 @@ scene_dynamics_prompt = """\
- 时间压力(可能未指定){time_constraint}
参考文档:
- 世界观:{world_building}
- 小说设定:{novel_setting}
- 全局摘要:{global_summary}
- 角色状态:{character_state}
- 小说设定:\n{novel_setting}\n
- 全局摘要:\n{global_summary}\n
- 角色状态:\n{character_state}\n
前章片段(可能为空)\n{previous_chapter_excerpt}\n
本地向量库检索到的上下文片段(可能为空):\n{context_excerpt}\n
请完成第 {novel_number} 章的正文,至少设计下方2个具有动态张力的场景:
1. 对话场景:
@@ -224,7 +258,7 @@ scene_dynamics_prompt = """\
- 隐喻系统的运用(连接世界观符号)
- 决策前的价值天平描写
最后设置一个"钩链转折":结尾时回收旧悬念/创造新悬念/抛出新危机/颠覆某个认知预设/神转折等。
文末设置一个"钩链转折":结尾时回收旧悬念/创造新悬念/抛出新危机/颠覆某个认知预设/神转折等。
格式要求:
- 仅返回章节正文文本;
+16 -4
View File
@@ -208,9 +208,12 @@ class NovelGeneratorGUI:
def build_ai_config_tab(self):
def on_interface_format_changed(new_value):
if new_value == "OpenAI":
if new_value == "Ollama":
self.base_url_var.set("http://localhost:11434/v1")
elif new_value == "ML Studio":
self.base_url_var.set("http://localhost:1234/v1")
elif new_value == "OpenAI":
self.base_url_var.set("https://api.openai.com/v1")
# 可根据需要扩展 Ollama / ML Studio 等
for i in range(5):
self.ai_config_tab.grid_rowconfigure(i, weight=0)
@@ -230,7 +233,7 @@ class NovelGeneratorGUI:
interface_label = ctk.CTkLabel(self.ai_config_tab, text="LLM 接口格式:", font=("Microsoft YaHei", 12))
interface_label.grid(row=2, column=0, padx=5, pady=5, sticky="e")
interface_options = ["OpenAI"]
interface_options = ["OpenAI", "Ollama", "ML Studio"]
interface_dropdown = ctk.CTkOptionMenu(
self.ai_config_tab,
values=interface_options,
@@ -268,6 +271,14 @@ class NovelGeneratorGUI:
self.temp_value_label.grid(row=4, column=2, padx=1, pady=1, sticky="w")
def build_embeddings_config_tab(self):
def on_embedding_interface_changed(new_value):
if new_value == "Ollama":
self.embedding_url_var.set("http://localhost:11434/api")
elif new_value == "ML Studio":
self.embedding_url_var.set("http://localhost:1234/v1")
elif new_value == "OpenAI":
self.embedding_url_var.set("https://api.openai.com/v1")
for i in range(5):
self.embeddings_config_tab.grid_rowconfigure(i, weight=0)
self.embeddings_config_tab.grid_columnconfigure(0, weight=0)
@@ -280,11 +291,12 @@ class NovelGeneratorGUI:
emb_interface_label = ctk.CTkLabel(self.embeddings_config_tab, text="Embedding 接口格式:", font=("Microsoft YaHei", 12))
emb_interface_label.grid(row=1, column=0, padx=5, pady=5, sticky="e")
emb_interface_options = ["OpenAI"] # 可扩展
emb_interface_options = ["OpenAI", "Ollama", "ML Studio"]
emb_interface_dropdown = ctk.CTkOptionMenu(
self.embeddings_config_tab,
values=emb_interface_options,
variable=self.embedding_interface_format_var,
command=on_embedding_interface_changed,
font=("Microsoft YaHei", 12)
)
emb_interface_dropdown.grid(row=1, column=1, padx=5, pady=5, sticky="nsew")