Files
llm_wiki/tools/experiments/wiki-generation-compare/scripts/run-b-singlestep.py
T

196 lines
6.3 KiB
Python

#!/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")