修复embedding失误导入成llm的问题
This commit is contained in:
+69
-14
@@ -68,7 +68,7 @@ def summarize_recent_chapters(
|
|||||||
short_summary = response_text
|
short_summary = response_text
|
||||||
return (short_summary, next_chapter_keywords)
|
return (short_summary, next_chapter_keywords)
|
||||||
|
|
||||||
def generate_chapter_draft(
|
def build_chapter_prompt(
|
||||||
api_key: str,
|
api_key: str,
|
||||||
base_url: str,
|
base_url: str,
|
||||||
model_name: str,
|
model_name: str,
|
||||||
@@ -91,10 +91,7 @@ def generate_chapter_draft(
|
|||||||
timeout: int = 600
|
timeout: int = 600
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
根据 novel_number 判断是否为第一章。
|
构造当前章节的请求提示词,不调用 LLM,仅返回构造好的提示词字符串。
|
||||||
- 若是第一章,则使用 first_chapter_draft_prompt
|
|
||||||
- 否则使用 next_chapter_draft_prompt
|
|
||||||
最终将生成文本存入 chapters/chapter_{novel_number}.txt。
|
|
||||||
"""
|
"""
|
||||||
arch_file = os.path.join(filepath, "Novel_architecture.txt")
|
arch_file = os.path.join(filepath, "Novel_architecture.txt")
|
||||||
novel_architecture_text = read_file(arch_file)
|
novel_architecture_text = read_file(arch_file)
|
||||||
@@ -155,15 +152,12 @@ def generate_chapter_draft(
|
|||||||
else:
|
else:
|
||||||
previous_chapter_excerpt = text_block
|
previous_chapter_excerpt = text_block
|
||||||
break
|
break
|
||||||
from llm_adapters import create_llm_adapter # 避免循环依赖
|
from embedding_adapters import create_embedding_adapter # 避免循环依赖
|
||||||
embedding_adapter = create_llm_adapter(
|
embedding_adapter = create_embedding_adapter(
|
||||||
interface_format=embedding_interface_format,
|
embedding_interface_format,
|
||||||
base_url=embedding_url,
|
embedding_api_key,
|
||||||
model_name=embedding_model_name,
|
embedding_url,
|
||||||
api_key=embedding_api_key,
|
embedding_model_name
|
||||||
temperature=temperature,
|
|
||||||
max_tokens=max_tokens,
|
|
||||||
timeout=timeout
|
|
||||||
)
|
)
|
||||||
retrieval_query = short_summary + " " + next_chapter_keywords
|
retrieval_query = short_summary + " " + next_chapter_keywords
|
||||||
relevant_context = get_relevant_context_from_vector_store(
|
relevant_context = get_relevant_context_from_vector_store(
|
||||||
@@ -195,6 +189,67 @@ def generate_chapter_draft(
|
|||||||
context_excerpt=relevant_context,
|
context_excerpt=relevant_context,
|
||||||
previous_chapter_excerpt=previous_chapter_excerpt
|
previous_chapter_excerpt=previous_chapter_excerpt
|
||||||
)
|
)
|
||||||
|
return prompt_text
|
||||||
|
|
||||||
|
def generate_chapter_draft(
|
||||||
|
api_key: str,
|
||||||
|
base_url: str,
|
||||||
|
model_name: str,
|
||||||
|
filepath: str,
|
||||||
|
novel_number: int,
|
||||||
|
word_number: int,
|
||||||
|
temperature: float,
|
||||||
|
user_guidance: str,
|
||||||
|
characters_involved: str,
|
||||||
|
key_items: str,
|
||||||
|
scene_location: str,
|
||||||
|
time_constraint: str,
|
||||||
|
embedding_api_key: str,
|
||||||
|
embedding_url: str,
|
||||||
|
embedding_interface_format: str,
|
||||||
|
embedding_model_name: str,
|
||||||
|
embedding_retrieval_k: int = 2,
|
||||||
|
interface_format: str = "openai",
|
||||||
|
max_tokens: int = 2048,
|
||||||
|
timeout: int = 600,
|
||||||
|
custom_prompt_text: str = None # 新增参数,若不为 None,则使用用户编辑后的提示词
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
根据 novel_number 判断是否为第一章。
|
||||||
|
- 若是第一章,则使用 first_chapter_draft_prompt
|
||||||
|
- 否则使用 next_chapter_draft_prompt
|
||||||
|
若 custom_prompt_text 提供,则以此作为提示词进行生成。
|
||||||
|
最终将生成文本存入 chapters/chapter_{novel_number}.txt。
|
||||||
|
"""
|
||||||
|
# 构造提示词:若用户提供了编辑后的提示词,则使用之;否则构造默认提示词
|
||||||
|
if custom_prompt_text is None:
|
||||||
|
prompt_text = build_chapter_prompt(
|
||||||
|
api_key=api_key,
|
||||||
|
base_url=base_url,
|
||||||
|
model_name=model_name,
|
||||||
|
filepath=filepath,
|
||||||
|
novel_number=novel_number,
|
||||||
|
word_number=word_number,
|
||||||
|
temperature=temperature,
|
||||||
|
user_guidance=user_guidance,
|
||||||
|
characters_involved=characters_involved,
|
||||||
|
key_items=key_items,
|
||||||
|
scene_location=scene_location,
|
||||||
|
time_constraint=time_constraint,
|
||||||
|
embedding_api_key=embedding_api_key,
|
||||||
|
embedding_url=embedding_url,
|
||||||
|
embedding_interface_format=embedding_interface_format,
|
||||||
|
embedding_model_name=embedding_model_name,
|
||||||
|
embedding_retrieval_k=embedding_retrieval_k,
|
||||||
|
interface_format=interface_format,
|
||||||
|
max_tokens=max_tokens,
|
||||||
|
timeout=timeout
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
prompt_text = custom_prompt_text
|
||||||
|
|
||||||
|
chapters_dir = os.path.join(filepath, "chapters")
|
||||||
|
os.makedirs(chapters_dir, exist_ok=True)
|
||||||
|
|
||||||
llm_adapter = create_llm_adapter(
|
llm_adapter = create_llm_adapter(
|
||||||
interface_format=interface_format,
|
interface_format=interface_format,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from llm_adapters import create_llm_adapter
|
from llm_adapters import create_llm_adapter
|
||||||
|
from embedding_adapters import create_embedding_adapter
|
||||||
from prompt_definitions import summary_prompt, update_character_state_prompt
|
from prompt_definitions import summary_prompt, update_character_state_prompt
|
||||||
from novel_generator.common import invoke_with_cleaning
|
from novel_generator.common import invoke_with_cleaning
|
||||||
from utils import read_file, clear_file_content, save_string_to_txt
|
from utils import read_file, clear_file_content, save_string_to_txt
|
||||||
@@ -75,14 +76,11 @@ def finalize_chapter(
|
|||||||
save_string_to_txt(new_char_state, character_state_file)
|
save_string_to_txt(new_char_state, character_state_file)
|
||||||
|
|
||||||
update_vector_store(
|
update_vector_store(
|
||||||
embedding_adapter=create_llm_adapter(
|
embedding_adapter=create_embedding_adapter(
|
||||||
interface_format=embedding_interface_format,
|
embedding_interface_format,
|
||||||
base_url=embedding_url,
|
embedding_api_key,
|
||||||
model_name=embedding_model_name,
|
embedding_url,
|
||||||
api_key=embedding_api_key,
|
embedding_model_name
|
||||||
temperature=temperature,
|
|
||||||
max_tokens=max_tokens,
|
|
||||||
timeout=timeout
|
|
||||||
),
|
),
|
||||||
new_chapter=chapter_text,
|
new_chapter=chapter_text,
|
||||||
filepath=filepath
|
filepath=filepath
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def import_knowledge_file(
|
|||||||
logging.warning("知识库文件内容为空。")
|
logging.warning("知识库文件内容为空。")
|
||||||
return
|
return
|
||||||
paragraphs = advanced_split_content(content)
|
paragraphs = advanced_split_content(content)
|
||||||
from llm_adapters import create_embedding_adapter
|
from embedding_adapters import create_embedding_adapter
|
||||||
embedding_adapter = create_embedding_adapter(
|
embedding_adapter = create_embedding_adapter(
|
||||||
embedding_interface_format,
|
embedding_interface_format,
|
||||||
embedding_api_key,
|
embedding_api_key,
|
||||||
|
|||||||
@@ -131,8 +131,11 @@ def generate_chapter_draft_ui(self):
|
|||||||
embedding_model_name = self.embedding_model_name_var.get().strip()
|
embedding_model_name = self.embedding_model_name_var.get().strip()
|
||||||
embedding_k = self.safe_get_int(self.embedding_retrieval_k_var, 4)
|
embedding_k = self.safe_get_int(self.embedding_retrieval_k_var, 4)
|
||||||
|
|
||||||
self.safe_log(f"开始生成第{chap_num}章草稿...")
|
self.safe_log(f"生成第{chap_num}章草稿:准备生成请求提示词...")
|
||||||
draft_text = generate_chapter_draft(
|
|
||||||
|
# 调用新添加的 build_chapter_prompt 函数构造初始提示词
|
||||||
|
from novel_generator.chapter import build_chapter_prompt
|
||||||
|
prompt_text = build_chapter_prompt(
|
||||||
api_key=api_key,
|
api_key=api_key,
|
||||||
base_url=base_url,
|
base_url=base_url,
|
||||||
model_name=model_name,
|
model_name=model_name,
|
||||||
@@ -154,6 +157,67 @@ def generate_chapter_draft_ui(self):
|
|||||||
max_tokens=max_tokens,
|
max_tokens=max_tokens,
|
||||||
timeout=timeout_val
|
timeout=timeout_val
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 弹出可编辑提示词对话框,等待用户确认或取消
|
||||||
|
result = {"prompt": None}
|
||||||
|
event = threading.Event()
|
||||||
|
|
||||||
|
def create_dialog():
|
||||||
|
dialog = ctk.CTkToplevel(self.master)
|
||||||
|
dialog.title("当前章节请求提示词(可编辑)")
|
||||||
|
dialog.geometry("600x400")
|
||||||
|
text_box = ctk.CTkTextbox(dialog, wrap="word", font=("Microsoft YaHei", 12))
|
||||||
|
text_box.pack(fill="both", expand=True, padx=10, pady=10)
|
||||||
|
text_box.insert("0.0", prompt_text)
|
||||||
|
button_frame = ctk.CTkFrame(dialog)
|
||||||
|
button_frame.pack(pady=10)
|
||||||
|
def on_confirm():
|
||||||
|
result["prompt"] = text_box.get("1.0", "end").strip()
|
||||||
|
dialog.destroy()
|
||||||
|
event.set()
|
||||||
|
def on_cancel():
|
||||||
|
result["prompt"] = None
|
||||||
|
dialog.destroy()
|
||||||
|
event.set()
|
||||||
|
btn_confirm = ctk.CTkButton(button_frame, text="确认使用", font=("Microsoft YaHei", 12), command=on_confirm)
|
||||||
|
btn_confirm.pack(side="left", padx=10)
|
||||||
|
btn_cancel = ctk.CTkButton(button_frame, text="取消请求", font=("Microsoft YaHei", 12), command=on_cancel)
|
||||||
|
btn_cancel.pack(side="left", padx=10)
|
||||||
|
# 若用户直接关闭弹窗,则调用 on_cancel 处理
|
||||||
|
dialog.protocol("WM_DELETE_WINDOW", on_cancel)
|
||||||
|
dialog.grab_set()
|
||||||
|
self.master.after(0, create_dialog)
|
||||||
|
event.wait() # 等待用户操作完成
|
||||||
|
edited_prompt = result["prompt"]
|
||||||
|
if edited_prompt is None:
|
||||||
|
self.safe_log("❌ 用户取消了草稿生成请求。")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.safe_log("开始生成章节草稿...")
|
||||||
|
from novel_generator.chapter import generate_chapter_draft
|
||||||
|
draft_text = generate_chapter_draft(
|
||||||
|
api_key=api_key,
|
||||||
|
base_url=base_url,
|
||||||
|
model_name=model_name,
|
||||||
|
filepath=filepath,
|
||||||
|
novel_number=chap_num,
|
||||||
|
word_number=word_number,
|
||||||
|
temperature=temperature,
|
||||||
|
user_guidance=user_guidance,
|
||||||
|
characters_involved=char_inv,
|
||||||
|
key_items=key_items,
|
||||||
|
scene_location=scene_loc,
|
||||||
|
time_constraint=time_constr,
|
||||||
|
embedding_api_key=embedding_api_key,
|
||||||
|
embedding_url=embedding_url,
|
||||||
|
embedding_interface_format=embedding_interface_format,
|
||||||
|
embedding_model_name=embedding_model_name,
|
||||||
|
embedding_retrieval_k=embedding_k,
|
||||||
|
interface_format=interface_format,
|
||||||
|
max_tokens=max_tokens,
|
||||||
|
timeout=timeout_val,
|
||||||
|
custom_prompt_text=edited_prompt # 使用用户编辑后的提示词
|
||||||
|
)
|
||||||
if draft_text:
|
if draft_text:
|
||||||
self.safe_log(f"✅ 第{chap_num}章草稿生成完成。请在左侧查看或编辑。")
|
self.safe_log(f"✅ 第{chap_num}章草稿生成完成。请在左侧查看或编辑。")
|
||||||
self.master.after(0, lambda: self.show_chapter_in_textbox(draft_text))
|
self.master.after(0, lambda: self.show_chapter_in_textbox(draft_text))
|
||||||
|
|||||||
Reference in New Issue
Block a user