diff --git a/main.py b/main.py index f097398..ae9e28d 100644 --- a/main.py +++ b/main.py @@ -13,6 +13,7 @@ import core.posterGen as posterGen import core.simple_collage as simple_collage from utils.resource_loader import ResourceLoader from utils.tweet_generator import generate_single_content, run_topic_generation_pipeline # Import the new pipeline function +from utils.prompt_manager import PromptManager # Import PromptManager import random TEXT_POSBILITY = 0.3 # Consider moving this to config if it varies @@ -56,6 +57,14 @@ def generate_content_and_posters_step(config, run_id, tweet_topic_record): output_dir = os.path.join(base_output_dir, run_id) # Directory for this specific run # --- Pre-load resources and initialize shared objects --- + # Initialize PromptManager once for this phase + try: + prompt_manager = PromptManager(config) + except Exception as e: + print(f"Error initializing PromptManager: {e}") + traceback.print_exc() + return + # Load content generation system prompt once content_system_prompt = ResourceLoader.load_system_prompt(config["content_system_prompt"]) if not content_system_prompt: @@ -95,12 +104,19 @@ def generate_content_and_posters_step(config, run_id, tweet_topic_record): for j in range(config["variants"]): variant_index = j + 1 print(f" Generating Variant {variant_index}/{config['variants']}...") + + # Get prompts for this specific topic item using PromptManager + content_system_prompt, content_user_prompt = prompt_manager.get_content_prompts(topic) + + if not content_system_prompt or not content_user_prompt: + print(f" Skipping Variant {variant_index} due to missing content prompts.") + continue # Skip this variant if prompts failed + time.sleep(random.random() * 0.5) # Slightly reduced delay try: - # Use the pre-initialized AI Agent + # Use the pre-initialized AI Agent and pass the specific prompts tweet_content, gen_result = generate_single_content( - ai_agent, content_system_prompt, topic, - config["prompts_dir"], config["resource_dir"], + ai_agent, content_system_prompt, content_user_prompt, topic, output_dir, run_id, topic_index, variant_index, config.get("content_temperature", 0.3) ) if tweet_content: diff --git a/utils/prompt_manager.py b/utils/prompt_manager.py new file mode 100644 index 0000000..3f3fb1c --- /dev/null +++ b/utils/prompt_manager.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Manages the construction of prompts for different AI generation tasks. +""" + +import os +import traceback +from .resource_loader import ResourceLoader # Use relative import within the same package + +class PromptManager: + """Handles the loading and construction of prompts.""" + + def __init__(self, config): + """Initializes the PromptManager with the global configuration.""" + self.config = config + # Instantiate ResourceLoader once, assuming it's mostly static methods or stateless + self.resource_loader = ResourceLoader() + + def get_topic_prompts(self): + """Constructs the system and user prompts for topic generation.""" + print("Constructing prompts for topic generation...") + try: + # --- System Prompt --- + system_prompt_path = self.config.get("topic_system_prompt") + if not system_prompt_path: + print("Error: topic_system_prompt path not specified in config.") + return None, None + + # Use ResourceLoader's static method directly + system_prompt = ResourceLoader.load_file_content(system_prompt_path) + if not system_prompt: + print(f"Error: Failed to load topic system prompt from '{system_prompt_path}'.") + return None, None + + # --- User Prompt --- + user_prompt_path = self.config.get("topic_user_prompt") + if not user_prompt_path: + print("Error: topic_user_prompt path not specified in config.") + return None, None + + base_user_prompt = ResourceLoader.load_file_content(user_prompt_path) + if base_user_prompt is None: # Check for None explicitly + print(f"Error: Failed to load base topic user prompt from '{user_prompt_path}'.") + return None, None + + # --- Build the dynamic part of the user prompt (Logic moved from prepare_topic_generation) --- + user_prompt_dynamic = "你拥有的创作资料如下:\n" + + # Add genPrompts directory structure + gen_prompts_path = self.config.get("prompts_dir") + if gen_prompts_path and os.path.isdir(gen_prompts_path): + try: + gen_prompts_list = os.listdir(gen_prompts_path) + for gen_prompt_folder in gen_prompts_list: + folder_path = os.path.join(gen_prompts_path, gen_prompt_folder) + if os.path.isdir(folder_path): + try: + # List files, filter out subdirs if needed + gen_prompts_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] + user_prompt_dynamic += f"{gen_prompt_folder}\n{gen_prompts_files}\n" + except OSError as e: + print(f"Warning: Could not list directory {folder_path}: {e}") + except OSError as e: + print(f"Warning: Could not list base prompts directory {gen_prompts_path}: {e}") + else: + print(f"Warning: Prompts directory '{gen_prompts_path}' not found or invalid.") + + # Add resource directory contents + resource_dir_config = self.config.get("resource_dir", []) + for dir_info in resource_dir_config: + source_type = dir_info.get("type", "UnknownType") + source_file_paths = dir_info.get("file_path", []) + for file_path in source_file_paths: + # Use ResourceLoader's static method + file_content = ResourceLoader.load_file_content(file_path) + if file_content: + user_prompt_dynamic += f"{source_type}信息:\n{os.path.basename(file_path)}\n{file_content}\n\n" + else: + print(f"Warning: Could not load resource file {file_path}") + + # Add dateline information (optional) + user_prompt_dir = os.path.dirname(user_prompt_path) + dateline_path = os.path.join(user_prompt_dir, "2025各月节日宣传节点时间表.md") # Consider making this configurable + if os.path.exists(dateline_path): + dateline_content = ResourceLoader.load_file_content(dateline_path) + if dateline_content: + user_prompt_dynamic += f"\n{dateline_content}" + + # Combine dynamic part, base template, and final parameters + user_prompt = user_prompt_dynamic + base_user_prompt + + select_num = self.config.get("num", 1) # Default to 1 if not specified + select_date = self.config.get("date", "") + user_prompt += f"\n选题数量:{select_num}\n选题日期:{select_date}\n" + # --- End of moved logic --- + + print(f"Topic prompts constructed. System: {len(system_prompt)} chars, User: {len(user_prompt)} chars.") + return system_prompt, user_prompt + + except Exception as e: + print(f"Error constructing topic prompts: {e}") + traceback.print_exc() + return None, None + + def get_content_prompts(self, topic_item): + """Constructs the system and user prompts for content generation based on a topic item.""" + print(f"Constructing content prompts for topic: {topic_item.get('object', 'N/A')}...") + try: + # --- System Prompt --- + system_prompt_path = self.config.get("content_system_prompt") + if not system_prompt_path: + print("Error: content_system_prompt path not specified in config.") + return None, None + # Use ResourceLoader's static method. load_system_prompt was just load_file_content. + system_prompt = ResourceLoader.load_file_content(system_prompt_path) + if not system_prompt: + print(f"Error: Failed to load content system prompt from '{system_prompt_path}'.") + return None, None + + # --- User Prompt (Logic moved from ResourceLoader.build_user_prompt) --- + user_prompt = "" + prompts_dir = self.config.get("prompts_dir") + resource_dir_config = self.config.get("resource_dir", []) + + if not prompts_dir or not os.path.isdir(prompts_dir): + print(f"Warning: Prompts directory '{prompts_dir}' not found or invalid. Content user prompt might be incomplete.") + # Decide whether to return error or continue with potentially incomplete prompt + + # 1. 添加Demand部分 (based on topic_item['logic']) + try: + logic_file = f"{topic_item['logic']}.txt" + demand_path = os.path.join(prompts_dir, "Demand", logic_file) + demand_content = ResourceLoader.load_file_content(demand_path) + if demand_content: + user_prompt += f"Demand:\n{demand_content}\n" + else: + print(f"Warning: Demand file not found or empty: {demand_path}") + except KeyError: + print("Warning: 'logic' key missing in topic_item for Demand prompt.") + except Exception as e: + print(f"Error processing Demand prompt: {e}") + + # 2. 添加Object信息 (based on topic_item['object']) + try: + object_name_base = topic_item['object'] # This might be '景点信息-XXX.txt' + object_file_path = None + # Find the full path for the object file from config + for dir_info in resource_dir_config: + if dir_info.get("type") == "Object": + for file_path in dir_info.get("file_path", []): + # Match basename, assuming topic_item['object'] is the basename + if os.path.basename(file_path) == object_name_base: + object_file_path = file_path + break + if object_file_path: break + + if object_file_path: + object_content = ResourceLoader.load_file_content(object_file_path) + if object_content: + user_prompt += f"Object信息:\n{object_content}\n" + else: + print(f"Warning: Object file could not be loaded: {object_file_path}") + else: + # If basename match fails, maybe topic_item['object'] is just 'XXX'? + # Try finding based on substring? This might be ambiguous. + print(f"Warning: Object file path not found in config matching basename: {object_name_base}") + except KeyError: + print("Warning: 'object' key missing in topic_item for Object prompt.") + except Exception as e: + print(f"Error processing Object prompt: {e}") + + # 3. 添加Product信息 (if applicable, based on topic_item['product'] and ['product_logic']) + try: + product_name = topic_item.get('product') + product_logic = topic_item.get('product_logic') + if product_name and product_logic: + product_logic_file = f"{product_logic}.txt" + product_logic_path = os.path.join(prompts_dir, "Demand", product_logic_file) # Assuming product logic is also in Demand? + product_logic_content = ResourceLoader.load_file_content(product_logic_path) + if product_logic_content: + user_prompt += f"Produce Demand:\n{product_logic_content}\n" + else: + print(f"Warning: Product Demand file not found or empty: {product_logic_path}") + + product_file_path = None + for dir_info in resource_dir_config: + if dir_info.get("type") == "Product": + for file_path in dir_info.get("file_path", []): + # Match basename + if os.path.basename(file_path) == product_name: + product_file_path = file_path + break + if product_file_path: break + + if product_file_path: + product_content = ResourceLoader.load_file_content(product_file_path) + if product_content: + user_prompt += f"Product信息:\n{product_content}\n" + else: + print(f"Warning: Product file could not be loaded: {product_file_path}") + else: + print(f"Warning: Product file path not found in config for: {product_name}") + except KeyError as e: + print(f"Warning: Missing 'product' or 'product_logic' key in topic_item for Product prompt: {e}") + except Exception as e: + print(f"Error processing Product prompt: {e}") + + # 4. 添加Style信息 (based on topic_item['style']) + try: + style_file = f"{topic_item['style']}.txt" + style_path = os.path.join(prompts_dir, "Style", style_file) + style_content = ResourceLoader.load_file_content(style_path) + if style_content: + user_prompt += f"Style:\n{style_content}\n" + else: + print(f"Warning: Style file not found or empty: {style_path}") + except KeyError: + print("Warning: 'style' key missing in topic_item for Style prompt.") + except Exception as e: + print(f"Error processing Style prompt: {e}") + + # 5. 添加Refer信息 (based on topic_item['style_logic']) + try: + refer_file = f"{topic_item['style_logic']}.txt" + refer_path = os.path.join(prompts_dir, "Refer", refer_file) + refer_content = ResourceLoader.load_file_content(refer_path) + if refer_content: + user_prompt += f"Refer:\n{refer_content}\n" + else: + print(f"Warning: Refer file not found or empty: {refer_path}") + except KeyError: + print("Warning: 'style_logic' key missing in topic_item for Refer prompt.") + except Exception as e: + print(f"Error processing Refer prompt: {e}") + + # --- End of moved logic --- + + print(f"Content prompts constructed. System: {len(system_prompt)} chars, User: {len(user_prompt)} chars.") + return system_prompt, user_prompt + + except KeyError as e: + # Catch potential KeyErrors from accessing topic_item if a required key is missing early on + print(f"Error constructing content prompts: Missing essential key '{e}' in topic_item: {topic_item}") + return None, None + except Exception as e: + print(f"Error constructing content prompts: {e}") + traceback.print_exc() + return None, None \ No newline at end of file diff --git a/utils/resource_loader.py b/utils/resource_loader.py index 0a601b8..5a198b6 100644 --- a/utils/resource_loader.py +++ b/utils/resource_loader.py @@ -14,25 +14,33 @@ class ResourceLoader: return content else: print(f"文件不存在: {file_path}") - return "" + # Return None for non-existent file to distinguish from empty file + return None except Exception as e: - print(f"加载文件内容失败: {e}") - return "" + print(f"加载文件 '{file_path}' 内容失败: {e}") + # Return None on error as well + return None @staticmethod def load_all_refer_files(refer_dir, refer_content_length=50): """加载Refer目录下的所有文件内容""" refer_content = "" + if not refer_dir or not os.path.isdir(refer_dir): + print(f"Warning: Refer directory '{refer_dir}' not found or invalid.") + return "" try: - if os.path.exists(refer_dir): - files = os.listdir(refer_dir) - for file in files: - file_path = os.path.join(refer_dir, file) - if os.path.isfile(file_path): - content = ResourceLoader.load_file_content(file_path) + files = os.listdir(refer_dir) + for file in files: + file_path = os.path.join(refer_dir, file) + if os.path.isfile(file_path): + # Use the updated load_file_content + content = ResourceLoader.load_file_content(file_path) + if content: # Check if content was loaded successfully # 用\n分割content,取前length条 content_lines = content.split("\n") - content_lines = random.sample(content_lines, refer_content_length) + # Ensure refer_content_length doesn't exceed available lines + sample_size = min(refer_content_length, len(content_lines)) + content_lines = random.sample(content_lines, sample_size) content = "\n".join(content_lines) refer_content += f"## {file}\n{content}\n\n" return refer_content @@ -43,6 +51,8 @@ class ResourceLoader: @staticmethod def find_file_by_name(directory, file_name, exact_match=True): """查找文件,支持精确匹配和模糊匹配""" + if not directory or not file_name: + return None try: # 确保传入的文件名包含后缀 if not file_name.endswith(".txt"): @@ -50,123 +60,22 @@ class ResourceLoader: # 精确匹配 exact_path = os.path.join(directory, file_name) - if os.path.exists(exact_path): + if os.path.exists(exact_path) and os.path.isfile(exact_path): return exact_path # 如果不需要精确匹配,尝试模糊匹配 - if not exact_match and os.path.exists(directory): + if not exact_match and os.path.isdir(directory): file_name_base = file_name.replace(".txt", "") for file in os.listdir(directory): - if file_name_base in file: - return os.path.join(directory, file) + if os.path.isfile(os.path.join(directory, file)) and file_name_base in file: + return os.path.join(directory, file) return None except Exception as e: - print(f"查找文件失败: {e}") + print(f"查找文件 '{file_name}' 在 '{directory}' 失败: {e}") return None @staticmethod - def build_user_prompt(item, prompts_dir, resource_dir): - """根据选题信息构建用户提示词""" - batch_prompt = f"选题日期:{item['date']}\n" - - # 基础目录设置 - style_dir = os.path.join(prompts_dir, "Style") - demand_dir = os.path.join(prompts_dir, "Demand") - refer_dir = os.path.join(prompts_dir, "Refer") - - # 从resource_dir中获取Object和Product资源 - object_resource = next((res for res in resource_dir if res["type"] == "Object"), None) - product_resource = next((res for res in resource_dir if res["type"] == "Product"), None) - - # 添加所有标签内容到批处理提示中 - if 'index' in item and item['index']: - batch_prompt += f"选题序号:{item['index']}\n" - if 'logic' in item and item['logic']: - batch_prompt += f"选定逻辑:{item['logic']}\n" - - # 处理Object信息 - if 'object' in item and item['object'] and object_resource: - batch_prompt += f"选定对象:{item['object']}\n" - # 查找包含对象名称的文件路径 - object_file = None - for file_path in object_resource["file_path"]: - if item['object'] in file_path: - object_file = file_path - break - - if object_file: - object_content = ResourceLoader.load_file_content(object_file) - batch_prompt += f"对象信息:\n{object_content}\n" - - # 处理Product信息 - if 'product' in item and item['product'] and product_resource: - batch_prompt += f"选定产品:{item['product']}\n" - # 尝试从产品名称中提取前缀 - product_parts = item['product'].split("-") - product_prefix = product_parts[0] if product_parts and product_parts[0] else item['product'] - - # 查找包含产品前缀的文件路径 - product_file = None - for file_path in product_resource["file_path"]: - if product_prefix in file_path: - product_file = file_path - break - - if product_file: - product_content = ResourceLoader.load_file_content(product_file) - batch_prompt += f"产品信息:\n{product_content}\n" - - # 处理Product Logic - if 'product_logic' in item and item['product_logic']: - batch_prompt += f"选定产品的逻辑:{item['product_logic']}\n" - - # 处理Style信息 - if 'style' in item and item['style']: - batch_prompt += f"选题风格:{item['style']}\n" - - # 加载风格提示词 - style_file = ResourceLoader.find_file_by_name(style_dir, item['style'], False) - if style_file: - style_content = ResourceLoader.load_file_content(style_file) - batch_prompt += f"风格提示词:\n{style_content}\n" - - # 处理Style Logic - if 'style_logic' in item and item['style_logic']: - batch_prompt += f"选题风格的逻辑:{item['style_logic']}\n" - - # 处理Target Audience - if 'target_audience' in item and item['target_audience']: - batch_prompt += f"目标受众:{item['target_audience']}\n" - # 尝试加载目标受众文件 - audience_file = ResourceLoader.find_file_by_name(demand_dir, item['target_audience'], False) - if audience_file: - audience_content = ResourceLoader.load_file_content(audience_file) - batch_prompt += f"目标受众信息:\n{audience_content}\n" - - # 处理Target Audience Logic - if 'target_audience_logic' in item and item['target_audience_logic']: - batch_prompt += f"目标受众逻辑:{item['target_audience_logic']}\n" - - # 加载所有Refer文件 - refer_content = ResourceLoader.load_all_refer_files(refer_dir) - if refer_content: - batch_prompt += f"\n参考资料:\n{refer_content}\n" - - return batch_prompt - - @staticmethod - def load_system_prompt(prompt_file): - """加载系统提示词文件""" - try: - with open(prompt_file, 'r', encoding='utf-8') as f: - system_prompt = f.read() - return system_prompt - except Exception as e: - print(f"加载系统提示词文件失败: {e}") - return "" - - @staticmethod def create_summary_file(output_dir, run_id, topics_count): """创建汇总文件并返回路径""" summary_file = os.path.join(output_dir, f"summary.md") diff --git a/utils/tweet_generator.py b/utils/tweet_generator.py index 9263da7..210e7eb 100644 --- a/utils/tweet_generator.py +++ b/utils/tweet_generator.py @@ -13,7 +13,9 @@ sys.path.append('/root/autodl-tmp') # 从本地模块导入 from TravelContentCreator.core.ai_agent import AI_Agent from TravelContentCreator.core.topic_parser import TopicParser -from TravelContentCreator.utils.resource_loader import ResourceLoader +# ResourceLoader is now used implicitly via PromptManager +# from TravelContentCreator.utils.resource_loader import ResourceLoader +from TravelContentCreator.utils.prompt_manager import PromptManager # Import PromptManager class tweetTopic: def __init__(self, index, date, logic, object, product, product_logic, style, style_logic, target_audience, target_audience_logic): @@ -132,13 +134,19 @@ def generate_topics(ai_agent, system_prompt, user_prompt, output_dir, temperatur return run_id, tweet_topic_record -def generate_single_content(ai_agent, system_prompt, item, prompts_dir, resource_dir, output_dir, run_id, +def generate_single_content(ai_agent, system_prompt, user_prompt, item, output_dir, run_id, article_index, variant_index, temperature=0.3, top_p=0.4, presence_penalty=1.5): - """生成单篇文章内容""" + """生成单篇文章内容. Requires prompts to be passed in.""" try: - # 构建提示词 - user_prompt = ResourceLoader.build_user_prompt(item, prompts_dir, resource_dir) - print(f"完成提示词构建,长度为 {len(user_prompt)} 字符") + # Prompts are now passed directly as arguments + # No longer build user_prompt here + # user_prompt = ResourceLoader.build_user_prompt(item, prompts_dir, resource_dir) + + if not system_prompt or not user_prompt: + print("Error: System or User prompt is empty. Cannot generate content.") + return None, None + + print(f"Using pre-constructed prompts. User prompt length: {len(user_prompt)}") # 添加随机停顿,避免请求过于频繁 time.sleep(random.random() * 0.5 + 0.1) @@ -190,8 +198,7 @@ def generate_content(ai_agent, system_prompt, topics, output_dir, run_id, prompt # 调用单篇文章生成函数 tweet_content, result = generate_single_content( - ai_agent, system_prompt, item, prompts_dir, resource_dir, - output_dir, run_id, i+1, j+1, temperature + ai_agent, system_prompt, item, output_dir, run_id, i+1, j+1, temperature ) if tweet_content: @@ -206,73 +213,53 @@ def generate_content(ai_agent, system_prompt, topics, output_dir, run_id, prompt def prepare_topic_generation( - select_date, select_num, - system_prompt_path, user_prompt_path, - base_url="vllm", model_name="qwenQWQ", api_key="EMPTY", - gen_prompts_path="/root/autodl-tmp/TravelContentCreator/genPrompts", - resource_dir="/root/autodl-tmp/TravelContentCreator/resource", - output_dir="/root/autodl-tmp/TravelContentCreator/result" + config # Pass the whole config dictionary now + # select_date, select_num, + # system_prompt_path, user_prompt_path, + # base_url="vllm", model_name="qwenQWQ", api_key="EMPTY", + # gen_prompts_path="/root/autodl-tmp/TravelContentCreator/genPrompts", + # resource_dir="/root/autodl-tmp/TravelContentCreator/resource", + # output_dir="/root/autodl-tmp/TravelContentCreator/result" ): - """准备选题生成的环境和参数""" - # 创建AI Agent - ai_agent = AI_Agent(base_url, model_name, api_key) - - # 加载系统提示词 - with open(system_prompt_path, "r", encoding="utf-8") as f: - system_prompt = f.read() + """准备选题生成的环境和参数. Returns agent and prompts.""" - # 构建用户提示词 - user_prompt = "你拥有的创作资料如下:\n" + # Initialize PromptManager + prompt_manager = PromptManager(config) - # 加载genPrompts目录下的文件 - gen_prompts_list = os.listdir(gen_prompts_path) - for gen_prompt_folder in gen_prompts_list: - folder_path = os.path.join(gen_prompts_path, gen_prompt_folder) - # 检查是否为目录 - if os.path.isdir(folder_path): - gen_prompts = os.listdir(folder_path) - user_prompt += f"{gen_prompt_folder}\n{gen_prompts}\n" + # Get prompts using PromptManager + system_prompt, user_prompt = prompt_manager.get_topic_prompts() - # 加载source文档内的目标文件 - ## 其实只会有Object和Product两个文件夹 - ## 所以可以简化代码 - for dir in resource_dir: - source_type = dir["type"] - # source_num = dir["num"] - source_file_path = dir["file_path"] - for file in source_file_path: - with open(file, "r", encoding="utf-8") as f: - user_prompt += f"{source_type}信息:\n{file.split('/')[-1]}\n{f.read()}\n\n" - - # 加载日期信息 - dateline_path = os.path.join(os.path.dirname(user_prompt_path), "2025各月节日宣传节点时间表.md") - if os.path.exists(dateline_path): - with open(dateline_path, "r", encoding="utf-8") as f: - dateline = f.read() - user_prompt += f"\n{dateline}" + if not system_prompt or not user_prompt: + print("Error: Failed to get topic generation prompts.") + return None, None, None, None - # 加载用户提示词模板 - with open(user_prompt_path, "r", encoding="utf-8") as f: - user_prompt += f.read() + # 创建AI Agent (still create agent here for the topic generation phase) + try: + print("Initializing AI Agent for topic generation...") + ai_agent = AI_Agent(config["api_url"], config["model"], config["api_key"]) + except Exception as e: + print(f"Error initializing AI Agent for topic generation: {e}") + traceback.print_exc() + return None, None, None, None + + # Removed prompt loading/building logic, now handled by PromptManager - # 添加选题数量和日期 - user_prompt += f"\n选题数量:{select_num}\n选题日期:{select_date}\n" - - return ai_agent, system_prompt, user_prompt, output_dir + # Return agent and the generated prompts + return ai_agent, system_prompt, user_prompt, config["output_dir"] def run_topic_generation_pipeline(config): """Runs the complete topic generation pipeline based on the configuration.""" print("Step 1: Generating Topics...") # Prepare necessary inputs and the AI agent for topic generation - # Note: prepare_topic_generation already initializes an AI_Agent + ai_agent, system_prompt, user_prompt, base_output_dir = None, None, None, None try: - ai_agent, system_prompt, user_prompt, base_output_dir = prepare_topic_generation( - config.get("date", datetime.now().strftime("%Y-%m-%d")), # Use current date if not specified - config["num"], config["topic_system_prompt"], config["topic_user_prompt"], - config["api_url"], config["model"], config["api_key"], config["prompts_dir"], - config["resource_dir"], config["output_dir"] - ) + # Pass the config directly to prepare_topic_generation + ai_agent, system_prompt, user_prompt, base_output_dir = prepare_topic_generation(config) + + if not ai_agent or not system_prompt or not user_prompt: + raise ValueError("Failed to prepare topic generation (agent or prompts missing).") + except Exception as e: print(f"Error during topic generation preparation: {e}") traceback.print_exc() @@ -356,8 +343,7 @@ def main(): if True: # 1. 首先生成选题 ai_agent, system_prompt, user_prompt, output_dir = prepare_topic_generation( - config_file["date"], config_file["num"], config_file["topic_system_prompt"], config_file["topic_user_prompt"], - config_file["api_url"], config_file["model"], config_file["api_key"], config_file["prompts_dir"], config_file["resource_dir"], config_file["output_dir"] + config_file ) run_id, tweet_topic_record = generate_topics(