#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 使用 singlestep 提示词对测试文件生成 WIKI 直接使用当前 opencode 配置的 LLM """ import os import re import json from datetime import datetime import openai # 配置 base_dir = os.getcwd() experiment_dir = os.path.join(base_dir, "tools", "experiments", "wiki-generation-compare") source_file = os.path.join(base_dir, "raw", "呼吸之间_李谨伯", "第一编 从身体入手.md") output_dir = os.path.join(experiment_dir, "output", "group-b-real") prompt_file = os.path.join(experiment_dir, "prompts", "singlestep.md") # 创建输出目录 os.makedirs(output_dir, exist_ok=True) os.makedirs(os.path.join(output_dir, "wiki", "concepts"), exist_ok=True) os.makedirs(os.path.join(output_dir, "wiki", "methods"), exist_ok=True) os.makedirs(os.path.join(output_dir, "wiki", "entities"), exist_ok=True) # 记录开始时间 start_time = datetime.now() start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S") print("=== B 组测试:Single-Step 模式(使用 9router reasoning 模型)===") print(f"开始时间: {start_time_str}") # 读取源文件 print(f"\n读取源文件: {source_file}") with open(source_file, 'r', encoding='utf-8') as f: source_content = f.read() print(f" 源文件长度: {len(source_content)} 字符") # 读取 prompt print(f"\n读取 prompt: {prompt_file}") with open(prompt_file, 'r', encoding='utf-8') as f: template = f.read() # 替换 {SOURCE_CONTENT} full_prompt = template.replace("{SOURCE_CONTENT}", source_content) print(f" Prompt 长度: {len(full_prompt)} 字符") # 检查 API Key api_key = os.environ.get('OPENAI_API_KEY') if not api_key: print("[ERROR] 未找到 OPENAI_API_KEY 环境变量") exit(1) print(f" API Key 长度: {len(api_key)}") # 尝试不同的模型名称 models_to_try = [ "9router/reasoning", "reasoning", "openai/gpt-4o-mini", "gpt-4o-mini", "openai/gpt-3.5-turbo", "gpt-3.5-turbo" ] # 尝试连接并获取可用模型 print("\n查找可用模型...") available_models = [] for model_name in models_to_try: try: client = openai.OpenAI(api_key=api_key, timeout=60) # 先尝试简单的 chat completion test_response = client.chat.completions.create( model=model_name, messages=[{"role": "user", "content": "hi"}], max_tokens=5 ) print(f" [OK] 模型可用: {model_name}") available_models.append(model_name) break except Exception as e: print(f" [X] {model_name}: {type(e).__name__}") if "404" not in str(e) and "not exist" not in str(e): # 如果不是 404,可能是网络问题 print(f" 错误详情: {str(e)[:200]}") if not available_models: print("\n[ERROR] 没有可用的模型") exit(1) # 使用第一个可用的模型 selected_model = available_models[0] print(f"\n使用模型: {selected_model}") # 初始化客户端 client = openai.OpenAI(api_key=api_key, timeout=300) # 调用 LLM 生成 print("\n调用 LLM 生成 Wiki 页面...") try: response = client.chat.completions.create( model=selected_model, messages=[ { "role": "system", "content": "你是一位知识库构建专家。请直接从源文件中提取关键术语并生成 Wiki 页面。" }, { "role": "user", "content": full_prompt } ], temperature=0.5, max_tokens=16000 ) generation_result = response.choices[0].message.content print(f" [OK] LLM 生成完成") print(f" 生成内容长度: {len(generation_result)} 字符") # 保存原始生成结果 raw_output_file = os.path.join(output_dir, "raw_generation.md") with open(raw_output_file, 'w', encoding='utf-8') as f: f.write(generation_result) print(f" [OK] 原始生成结果已保存到: {raw_output_file}") except Exception as e: print(f" [ERROR] LLM API 调用失败: {type(e).__name__}: {e}") exit(1) # 解析生成结果 print("\n解析生成的 Wiki 页面...") sample_pages = [] # 解析 ---FILE: ... ---END FILE--- 块 file_blocks = re.findall(r'---FILE: (.*?)---(.*?)---END FILE---', generation_result, re.DOTALL) if not file_blocks: print(" [WARNING] 未找到标准文件块格式,尝试宽松匹配...") file_blocks = re.findall(r'FILE: (.*?)\n(.*?)(?=(?:FILE:|$))', generation_result, re.DOTALL) print(f" 解析到 {len(file_blocks)} 个文件块") for i, block in enumerate(file_blocks): if isinstance(block, tuple): file_path = block[0].strip() file_content = block[1].strip() else: continue # 创建目录(如果需要) full_path = os.path.join(output_dir, file_path) file_dir = os.path.dirname(full_path) os.makedirs(file_dir, exist_ok=True) # 写入文件 with open(full_path, 'w', encoding='utf-8') as f: f.write(file_content) sample_pages.append(full_path) print(f" [OK] 生成 [{i+1}/{len(file_blocks)}]: {file_path}") # 记录结束时间 end_time = datetime.now() end_time_str = end_time.strftime("%Y-%m-%d %H:%M:%S") duration = (end_time - start_time).total_seconds() / 60 print(f"\n=== B 组测试完成 ===") print(f"结束时间: {end_time_str}") print(f"总耗时: {round(duration, 2)} 分钟") print(f"生成文件数: {len(sample_pages)}") # 保存元数据 metadata = { "group": "B-real", "mode": "Single-Step", "sourceFile": "raw/呼吸之间_李谨伯/第一编 从身体入手.md", "startTime": start_time_str, "endTime": end_time_str, "durationMinutes": round(duration, 2), "pagesGenerated": len(sample_pages), "model": selected_model, "rawContentLength": len(generation_result), "status": "success" } metadata_file = os.path.join(output_dir, "metadata.json") with open(metadata_file, 'w', encoding='utf-8') as f: json.dump(metadata, f, ensure_ascii=False, indent=2) print(f"\n[OK] 元数据已保存到: {metadata_file}") print(f"\n输出文件位置:") print(f" 原始生成: {raw_output_file}") print(f" Wiki 页面: {output_dir}/wiki/") print(f" 元数据: {metadata_file}") print(f"\n接下来可以运行评估脚本对比 A 组和 B 组的结果:") print(f" python tools/experiments/wiki-generation-compare/scripts/evaluate-real.py")