263 lines
9.9 KiB
Python
263 lines
9.9 KiB
Python
'''
|
|
* @file DeepSeekPromptGenerator.py
|
|
* @brief Generate optimized image prompts using DeepSeek API
|
|
*
|
|
* @author WuYingwen
|
|
* @GitHub @wuyingwen10
|
|
* @Contact 2211537@mail.nankai.edu.cn
|
|
* @date 2025-06-10
|
|
* @version v1.0.0
|
|
*
|
|
* @note
|
|
* - Uses DeepSeek API for prompt optimization
|
|
* - Supports multiple API configurations
|
|
*
|
|
* @copyright
|
|
* (c) 2025 Nankai University
|
|
'''
|
|
|
|
import requests
|
|
import json
|
|
import os
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
SYSTEM_PROMPT_TEMPLATE = """
|
|
As an AI prompt engineering expert, please generate a prompt that meets the following requirements based on the topic I provide. Note: You should follow the style of the example (emulating the writing style only, not the content) and transform the user's request into a detailed prompt.
|
|
|
|
Requirements (strictly adhere to all six):
|
|
1: Use simple natural language sentences to describe the scene. Avoid overly long or complex sentence structures. Do not use special symbols like *.
|
|
2: Express in English.
|
|
3: Provide only the prompt content without any explanations or notes.
|
|
4: Each prompt must be at least 50 words but no more than 200 words.
|
|
5: Avoid ambiguous expressions.
|
|
6: Add "no text, no AI style" at the beginning.
|
|
|
|
Example:
|
|
no text, no AI style
|
|
Cartoon-Style Nankai University Main Building,
|
|
vividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.
|
|
|
|
Translucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.
|
|
|
|
Environment:
|
|
Surreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.
|
|
"""
|
|
|
|
API_CONFIGS = [
|
|
{
|
|
"name": "DeepSeek Official Chat API",
|
|
"model": "deepseek-chat",
|
|
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
|
|
"base_url": "https://api.deepseek.com"
|
|
},
|
|
{
|
|
"name": "DeepSeek-R1 Backup",
|
|
"model": "deepseek-r1",
|
|
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
|
|
"base_url": "https://cloud.infini-ai.com/maas/v1/"
|
|
},
|
|
{
|
|
"name": "DeepSeek-V3 Backup",
|
|
"model": "deepseek-v3",
|
|
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
|
|
"base_url": "https://cloud.infini-ai.com/maas/v1/"
|
|
}
|
|
]
|
|
|
|
def generate_prompt(user_topic):
|
|
"""Generate optimized prompt using DeepSeek API"""
|
|
full_prompt = SYSTEM_PROMPT_TEMPLATE + f"\n\nTopic: {user_topic}"
|
|
|
|
for config in API_CONFIGS:
|
|
try:
|
|
print(f"Attempting API: {config['name']}...")
|
|
endpoint = f"{config['base_url']}/chat/completions"
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {config['api_key']}"
|
|
}
|
|
|
|
payload = {
|
|
"model": config["model"],
|
|
"messages": [{"role": "user", "content": full_prompt}],
|
|
"temperature": 0.7,
|
|
"max_tokens": 2000,
|
|
"stream": False
|
|
}
|
|
|
|
response = requests.post(endpoint, headers=headers, json=payload, timeout=30)
|
|
response.raise_for_status()
|
|
|
|
result = response.json()
|
|
return result['choices'][0]['message']['content'].strip()
|
|
|
|
except Exception as e:
|
|
print(f"Error with {config['name']}: {str(e)}")
|
|
continue
|
|
|
|
raise Exception("All API attempts failed")
|
|
|
|
def save_deepseek_output(prompt_content, output_prefix):
|
|
"""Save DeepSeek output to file with the same naming pattern as images"""
|
|
output_dir = "../outputs/deepseek_output"
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
|
|
|
|
filename = f"{output_prefix}_{timestamp}.txt"
|
|
file_path = os.path.join(output_dir, filename)
|
|
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
f.write(prompt_content)
|
|
|
|
return file_path
|
|
|
|
def test_multiple_topics():
|
|
"""测试多个主题的提示词生成"""
|
|
test_topics = [
|
|
"设计一张南开大学的海报,要求风格为卡通风格,包含南开大学的标志性建筑和校园元素。",
|
|
"创建一个关于人工智能与未来科技的海报",
|
|
"设计一张关于环保主题的宣传海报"
|
|
]
|
|
|
|
print(f"{'-'*50}\n🧪 开始测试多个主题的提示词生成\n{'-'*50}")
|
|
|
|
results = []
|
|
for i, topic in enumerate(test_topics, 1):
|
|
print(f"\n📝 测试主题 {i}: {topic}")
|
|
try:
|
|
start_time = datetime.now()
|
|
prompt = generate_prompt(topic)
|
|
end_time = datetime.now()
|
|
|
|
# 计算执行时间
|
|
execution_time = (end_time - start_time).total_seconds()
|
|
|
|
# 保存提示词
|
|
prefix = f"测试_{i}"
|
|
output_file = save_deepseek_output(prompt, prefix)
|
|
|
|
# 截断显示(如果太长)
|
|
display_prompt = prompt[:200] + "..." if len(prompt) > 200 else prompt
|
|
|
|
results.append({
|
|
"topic": topic,
|
|
"success": True,
|
|
"time": execution_time,
|
|
"output_file": output_file,
|
|
"prompt_length": len(prompt)
|
|
})
|
|
|
|
print(f"✅ 成功生成提示词 ({len(prompt)} 字符, {execution_time:.2f}秒)")
|
|
print(f"📄 预览: {display_prompt}")
|
|
print(f"💾 已保存到: {output_file}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ 生成失败: {str(e)}")
|
|
results.append({
|
|
"topic": topic,
|
|
"success": False,
|
|
"error": str(e)
|
|
})
|
|
|
|
# 打印汇总结果
|
|
print(f"\n{'-'*50}\n📊 测试结果汇总\n{'-'*50}")
|
|
success_count = sum(1 for r in results if r.get("success", False))
|
|
print(f"✅ 成功: {success_count}/{len(test_topics)}")
|
|
|
|
if success_count > 0:
|
|
avg_time = sum(r["time"] for r in results if r.get("success", False)) / success_count
|
|
avg_length = sum(r["prompt_length"] for r in results if r.get("success", False)) / success_count
|
|
print(f"⏱️ 平均执行时间: {avg_time:.2f}秒")
|
|
print(f"📏 平均提示词长度: {avg_length:.0f}字符")
|
|
|
|
return results
|
|
|
|
def test_api_configs():
|
|
"""测试所有API配置"""
|
|
print(f"{'-'*50}\n🧪 测试所有API配置\n{'-'*50}")
|
|
|
|
test_topic = "测试API配置的简单主题"
|
|
|
|
for i, config in enumerate(API_CONFIGS, 1):
|
|
print(f"\n🔌 测试API配置 {i}: {config['name']}")
|
|
print(f" 模型: {config['model']}")
|
|
print(f" URL: {config['base_url']}")
|
|
|
|
try:
|
|
# 构建提示词
|
|
full_prompt = SYSTEM_PROMPT_TEMPLATE + f"\n\nTopic: {test_topic}"
|
|
|
|
# 准备请求
|
|
endpoint = f"{config['base_url']}/chat/completions"
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {config['api_key']}"
|
|
}
|
|
payload = {
|
|
"model": config["model"],
|
|
"messages": [{"role": "user", "content": full_prompt}],
|
|
"temperature": 0.7,
|
|
"max_tokens": 100, # 减少token以加快测试
|
|
"stream": False
|
|
}
|
|
|
|
# 发送请求
|
|
start_time = datetime.now()
|
|
print(f" 🕒 发送请求...")
|
|
response = requests.post(endpoint, headers=headers, json=payload, timeout=10)
|
|
end_time = datetime.now()
|
|
execution_time = (end_time - start_time).total_seconds()
|
|
|
|
# 检查响应
|
|
response.raise_for_status()
|
|
result = response.json()
|
|
|
|
# 输出结果
|
|
print(f" ✅ API工作正常! 响应时间: {execution_time:.2f}秒")
|
|
print(f" 🔑 响应状态码: {response.status_code}")
|
|
print(f" 📦 模型回复: {result['choices'][0]['message']['content'][:50]}...")
|
|
|
|
except Exception as e:
|
|
print(f" ❌ API测试失败: {str(e)}")
|
|
|
|
def main():
|
|
"""主函数,运行多个测试"""
|
|
print(f"🚀 DeepSeek提示词生成器测试 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
|
|
# 运行标准测试
|
|
user_topic = "设计一张南开大学的海报,要求风格为卡通风格,包含南开大学的标志性建筑和校园元素。"
|
|
print(f"🔍 标准测试 - 主题: {user_topic}")
|
|
|
|
try:
|
|
prompt = generate_prompt(user_topic)
|
|
output_file = save_deepseek_output(prompt, "南开大学海报")
|
|
print(f"✅ 标准测试成功!")
|
|
print(f"📄 生成的提示词: {prompt[:100]}...")
|
|
print(f"💾 已保存到: {output_file}")
|
|
except Exception as e:
|
|
print(f"❌ 标准测试失败: {str(e)}")
|
|
|
|
# 询问用户是否运行更多测试
|
|
print("\n是否运行更多测试? (输入数字选择)")
|
|
print("1. 测试多个主题")
|
|
print("2. 测试API配置")
|
|
print("3. 运行所有测试")
|
|
print("0. 退出")
|
|
|
|
choice = input("请选择 (默认0): ").strip() or "0"
|
|
|
|
if choice == "1":
|
|
test_multiple_topics()
|
|
elif choice == "2":
|
|
test_api_configs()
|
|
elif choice == "3":
|
|
test_multiple_topics()
|
|
test_api_configs()
|
|
else:
|
|
print("退出测试。")
|
|
|
|
if __name__ == "__main__":
|
|
main() |