完成对生成逻辑的优化,但也发现新的问题

前后章节的衔接有问题,这里想着应该要把前一个章节内容发送作为参考,不然中断感很重
This commit is contained in:
YILING0013
2025-02-05 22:43:09 +08:00
parent dd78666071
commit f388403b08
3 changed files with 76 additions and 57 deletions
+34 -39
View File
@@ -431,8 +431,6 @@ def Chapter_blueprint_generate(
return
# 从内容中尽量提取 number_of_chapters
# 如果之前已经存储了 number_of_chapters,可以在外面传入,这里做简化:
# 这里用正则或者其他逻辑提取,但演示时直接写 10 也可
match_chaps = re.search(r'约(\d+)章', architecture_text)
if match_chaps:
number_of_chapters = int(match_chaps.group(1))
@@ -440,10 +438,7 @@ def Chapter_blueprint_generate(
number_of_chapters = 10 # fallback
# 提取三幕式文本
# 在写入时,我们将 4) 三幕式情节架构 作为传给 prompt 的核心
# 这里做一个简易匹配
plot_arch_text = ""
# 假设 "#=== 4) 三幕式情节架构 ===" 是分隔点
pat_plot = r'#=== 4\) 三幕式情节架构 ===\n([\s\S]+)$'
m = re.search(pat_plot, architecture_text)
if m:
@@ -556,7 +551,6 @@ def update_plot_arcs(
# ========== 3) 生成章节草稿 ==========
def generate_chapter_draft(
api_key: str,
base_url: str,
@@ -570,6 +564,10 @@ def generate_chapter_draft(
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
) -> str:
"""
@@ -577,7 +575,7 @@ def generate_chapter_draft(
- novel_architecture 取自 Novel_architecture.txt
- blueprint 取自 Novel_directory.txt
- global_summary, character_state 分别取自全局摘要、角色状态文件
- 向量库检索上下文
- 向量库检索上下文embedding_*参数)
- 用户还可以额外提供四个可选元素:核心人物、关键道具、空间坐标、时间压力
"""
@@ -609,25 +607,21 @@ def generate_chapter_draft(
recent_3_texts = get_last_n_chapters_text(chapters_dir, novel_number, n=3)
merged_query_str = "回顾剧情:\n" + "\n".join(recent_3_texts) + "\n" + user_guidance
# 4) 检索向量库上下文
# 4) 检索向量库上下文 (使用embedding_*参数)
relevant_context = get_relevant_context_from_vector_store(
api_key=api_key,
base_url=base_url,
api_key=embedding_api_key,
base_url=embedding_url,
query=merged_query_str,
embedding_model_name=model_name,
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
filepath=filepath,
k=embedding_retrieval_k
)
if not relevant_context.strip():
relevant_context = "(无检索到的上下文)"
# 5) 构造prompt,调用 scene_dynamics_prompt
# 在这里,我们拆分架构文本,以便给模型提供:
# - “世界观”与“小说设定”可以从 arch_file 中的相应片段读取
# 这里为了简化,直接把 novel_architecture_text 整体塞入 novel_setting
# 也可更精细地拆分 "#=== 3) 世界观 ===" 片段给 world_building
# 下方仅作示例。
# 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:
@@ -658,9 +652,8 @@ def generate_chapter_draft(
character_state=character_state_text
)
# 因为我们还想让模型了解向量库检索到的上下文,可以合并到最后
# 合并检索到的上下文和用户指导
prompt_text += f"\n\n【检索到的上下文】\n{relevant_context}"
# 也可合并用户指导
prompt_text += f"\n\n【用户指导】\n{user_guidance}\n"
model = ChatOpenAI(
@@ -674,8 +667,7 @@ def generate_chapter_draft(
if not chapter_content.strip():
logging.warning("Generated chapter draft is empty.")
# 6) 写入 chapters 目录
chapters_dir = os.path.join(filepath, "chapters")
# 6) 写入 chapters
os.makedirs(chapters_dir, exist_ok=True)
chapter_file = os.path.join(chapters_dir, f"chapter_{novel_number}.txt")
@@ -695,6 +687,9 @@ def finalize_chapter(
model_name: str,
temperature: float,
filepath: str,
embedding_api_key: str,
embedding_url: str,
embedding_interface_format: str,
embedding_model_name: str
):
"""
@@ -707,7 +702,7 @@ def finalize_chapter(
logging.warning(f"Chapter {novel_number} is empty, cannot finalize.")
return
# 如果长度比目标少很多,可考虑在此扩写
# 若篇幅过短,可尝试扩写
if len(chapter_text) < 0.6 * word_number:
chapter_text = enrich_chapter_text(chapter_text, word_number, api_key, base_url, model_name, temperature)
clear_file_content(chapter_file)
@@ -750,12 +745,13 @@ def finalize_chapter(
clear_file_content(character_state_file)
save_string_to_txt(new_char_state, character_state_file)
# 3) 更新向量库
# 3) 更新向量库 (embedding相关)
update_vector_store(
api_key=api_key,
base_url=base_url,
api_key=embedding_api_key,
base_url=embedding_url,
new_chapter=chapter_text,
model_name=embedding_model_name, # 用于embedding
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
filepath=filepath
)
@@ -827,15 +823,14 @@ def advanced_split_content(content: str,
return final_segments
def import_knowledge_file(
api_key: str,
base_url: str,
interface_format: str,
embedding_api_key: str,
embedding_url: str,
embedding_interface_format: str,
embedding_model_name: str,
file_path: str,
embedding_base_url: str,
filepath: str
):
logging.info(f"开始导入知识库文件: {file_path}, 接口格式: {interface_format}, 模型: {embedding_model_name}")
logging.info(f"开始导入知识库文件: {file_path}, 接口格式: {embedding_interface_format}, 模型: {embedding_model_name}")
if not os.path.exists(file_path):
logging.warning(f"知识库文件不存在: {file_path}")
return
@@ -847,20 +842,20 @@ def import_knowledge_file(
paragraphs = advanced_split_content(content)
# 若向量库不存在则初始化,否则追加
# 尝试加载已有的向量库
store = load_vector_store(
api_key=api_key,
base_url=base_url if base_url else "http://localhost:11434/v1",
interface_format=interface_format,
api_key=embedding_api_key,
base_url=embedding_url if embedding_url else "http://localhost:11434/v1",
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
filepath=filepath
)
if not store:
logging.info("Vector store does not exist. Initializing a new one for knowledge import...")
init_vector_store(
api_key=api_key,
base_url=base_url if base_url else "http://localhost:11434/v1",
interface_format=interface_format,
api_key=embedding_api_key,
base_url=embedding_url if embedding_url else "http://localhost:11434/v1",
interface_format=embedding_interface_format,
embedding_model_name=embedding_model_name,
texts=paragraphs,
filepath=filepath