当前位置:   article > 正文

2024.3.2最新使用chatgpt实现自动化编写小说!(包含python源码、软件以及免费测试apikey!)_chatgpt小说python

chatgpt小说python

2024.3.2修复无法生成完整章节内容bug,添加apibase设置,更新模型列表,添加小说大纲,增加更多可玩性!同时更新测试key!

最新效果图:

代码终端最终效果如图:

旧:代码运行后会在桌面自动生成小说文件:

资源软件(3.2已更新!):

如下为小说创作脚本软件,大小11.5MB,使用方法:apikey使用英文逗号隔开,可直接运行!还有配置文件可记录参数,无需反复填写!生成的小说会显示在桌面的文件夹里:

小说创作脚本plusicon-default.png?t=N7T8https://pan.baidu.com/s/1J2WPTmGnzNlN3BwTznFQdw?pwd=6666

旧:效果如图:

源码如下,3.2更新3.5apikey!!!这里免费提供一个测试apikey:

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

,(3.2已更新5$key)余额有限,先到先用哦!可自行设置具体参数:

  1. import asyncio
  2. import os
  3. from tkinter import ttk
  4. import openai #pip install openai==0.28.0
  5. import random
  6. import tkinter as tk
  7. import threading
  8. import configparser
  9. # 设置代理网址
  10. openai.api_base = "https://api.openai-proxy.com/v1"
  11. # 检查配置文件是否存在,如果不存在则创建新的配置文件
  12. if not os.path.exists('settings.config'):
  13. config = configparser.ConfigParser()
  14. config['Settings'] = {}
  15. config['Settings']['novel_name'] = ''
  16. config['Settings']['novel_outline'] = ''
  17. config['Settings']['total_chapters'] = '3'
  18. config['Settings']['api_keys'] = ''
  19. config['Settings']['selected_model'] = 'gpt-3.5-turbo-0125'
  20. config['Settings']['temperature'] = '0.5'
  21. config['Settings']['max_tokens'] = '2000'
  22. config['Settings']['tokens_per_chapter'] = '400'
  23. config['Settings']['api_base'] = 'https://api.openai-proxy.com/v1' # 添加API base URL
  24. with open('settings.config', 'w') as configfile:
  25. config.write(configfile)
  26. # 读取配置文件
  27. config = configparser.ConfigParser()
  28. with open('settings.config', 'r') as configfile:
  29. config.read_file(configfile)
  30. novel_name = config.get('Settings', 'novel_name', fallback='')
  31. novel_outline = config.get('Settings', 'novel_outline', fallback='')
  32. total_chapters = config.getint('Settings', 'total_chapters', fallback=3)
  33. api_keys_entry = config.get('Settings', 'api_keys', fallback='')
  34. selected_model = config.get('Settings', 'selected_model', fallback='gpt-3.5-turbo-0125')
  35. temperature = config.getfloat('Settings', 'temperature', fallback=0.5)
  36. max_tokens = config.getint('Settings', 'max_tokens', fallback=2000)
  37. tokens_per_chapter = config.getint('Settings', 'tokens_per_chapter', fallback=400)
  38. api_base = config.get('Settings', 'api_base', fallback='https://api.openai-proxy.com/v1') # 读取API base URL
  39. # 异步加载 API 密钥
  40. async def load_api_keys():
  41. global api_keys_entry
  42. await asyncio.sleep(0.1) # 延迟加载,避免卡住主线程
  43. return [key.strip() for key in api_keys_entry.split(',')]
  44. async def main():
  45. global api_keys
  46. api_keys = await load_api_keys()
  47. # 启动异步事件循环
  48. loop = asyncio.get_event_loop()
  49. loop.run_until_complete(main())
  50. # 写入小说章节
  51. def write_novel_chapter(api_key, model, chapter_content, chapter_number, conversation_history):
  52. """使用OpenAI的API模型来编写小说章节"""
  53. global temperature_var,max_tokens_var
  54. openai.api_key = api_key # 设置当前使用的 API 密钥
  55. response = openai.ChatCompletion.create(
  56. model=model, # 使用传入的模型
  57. temperature=temperature_var,
  58. max_tokens=max_tokens_var,
  59. messages=conversation_history + [
  60. {
  61. "role": "system",
  62. "content": f"你是一名专业的小说作者,你的任务是编写小说《{novel_name}》,小说大纲为{novel_outline},共有{total_chapters}章,每章{tokens_per_chapter}字,请自行构思每章的标题和内容,开始编写第{chapter_number}章:"
  63. },
  64. {"role": "user", "content": chapter_content},
  65. ]
  66. )
  67. generated_text = response['choices'][0]['message']['content']
  68. return generated_text, response['choices'][0]['message']['role'], response['choices'][0]['index']
  69. def write_novel():
  70. global novel_name, novel_outline, total_chapters, output_folder, selected_model, tokens_per_chapter
  71. chapter_number = 1
  72. conversation_history = []
  73. used_api_keys = []
  74. while chapter_number <= total_chapters:
  75. available_keys = [key for key in api_keys if key not in used_api_keys]
  76. if not available_keys:
  77. used_api_keys = []
  78. available_keys = api_keys[:]
  79. selected_api_key = random.choice(available_keys)
  80. used_api_keys.append(selected_api_key)
  81. print(f"正在编写《{novel_name}》第 {chapter_number} 章,使用的 API 密钥:{selected_api_key}")
  82. try:
  83. # 模拟章节内容,你可以根据实际需要修改
  84. chapter_content = f""
  85. tokens_per_chapter_var = tokens_per_chapter
  86. generated_text, _, _ = write_novel_chapter(selected_api_key, selected_model, chapter_content, chapter_number,
  87. conversation_history)
  88. chapter_name = generated_text.split('\n', 1)[0]
  89. if "第" in chapter_name and "章" in chapter_name:
  90. chapter_file_name = f"{chapter_name}.txt"
  91. else:
  92. chapter_file_name = f"第{chapter_number}章:{chapter_name}.txt"
  93. # 去掉包含小说名称的部分
  94. chapter_file_name = chapter_file_name.replace(novel_name, "")
  95. # 去掉包含《》的部分
  96. if "《" in chapter_file_name and "》" in chapter_file_name:
  97. chapter_file_name = chapter_file_name.replace("《", "").replace("》", "")
  98. # 去掉多余的空格
  99. chapter_file_name = chapter_file_name.strip()
  100. chapter_file_path = os.path.join(output_folder, chapter_file_name)
  101. with open(chapter_file_path, 'w', encoding='utf-8') as chapter_file:
  102. chapter_file.write(generated_text)
  103. print(f"《{novel_name}{chapter_file_name.strip('.txt')} 编写成功,已保存至 {chapter_file_path}")
  104. print("-------------------------------------------------------------------")
  105. conversation_history = []
  106. if chapter_number < total_chapters:
  107. conversation_history.append({"role": "system", "content": generated_text})
  108. except Exception as e:
  109. print(f"《{novel_name}》 第{chapter_number}章 编写失败,错误信息: {e}")
  110. print("-------------------------------------------------------------------")
  111. chapter_number += 1
  112. def start_writing():
  113. global novel_name, novel_outline, total_chapters, output_folder, selected_model, temperature, max_tokens, tokens_per_chapter, temperature_var, max_tokens_var, api_keys,api_base
  114. novel_name = novel_name_entry.get()
  115. novel_outline = novel_outline_entry.get()
  116. total_chapters = int(total_chapters_entry.get())
  117. output_folder = os.path.join(os.path.expanduser('~'), 'Desktop', novel_name)
  118. selected_model = model_var.get()
  119. temperature = float(temperature_entry.get())
  120. max_tokens = int(max_tokens_entry.get())
  121. tokens_per_chapter = int(tokens_per_chapter_entry.get())
  122. temperature_var = float(temperature_entry.get())
  123. max_tokens_var = int(max_tokens_entry.get())
  124. api_keys = [key.strip() for key in api_keys_entry.get().split(',')] # 获取并更新 API 密钥列表
  125. api_base = api_base_entry.get() # 获取并更新 API base URL
  126. openai.api_base = api_base # 更新 OpenAI API base
  127. try:
  128. if not os.path.exists(output_folder):
  129. os.makedirs(output_folder)
  130. threading.Thread(target=write_novel).start()
  131. except Exception as e:
  132. print("")
  133. # 更新配置文件
  134. config['Settings']['novel_name'] = novel_name
  135. config['Settings']['novel_outline'] = novel_outline
  136. config['Settings']['total_chapters'] = str(total_chapters)
  137. config['Settings']['selected_model'] = selected_model
  138. config['Settings']['temperature'] = str(temperature)
  139. config['Settings']['max_tokens'] = str(max_tokens)
  140. config['Settings']['tokens_per_chapter'] = str(tokens_per_chapter)
  141. config['Settings']['api_keys'] = ', '.join([key.strip() for key in api_keys_entry.get().split(',')])
  142. config['Settings']['api_base'] = api_base # 将API base URL写入配置文件
  143. with open('settings.config', 'w') as configfile:
  144. config.write(configfile)
  145. def toggle_visibility():
  146. # 切换API Keys Entry的可见性
  147. current_state = api_keys_entry.cget("show")
  148. new_state = "" if current_state == "*" else "*"
  149. api_keys_entry.config(show=new_state)
  150. # 切换API Base Entry的可见性
  151. current_state_api_base = api_base_entry.cget("show")
  152. new_state_api_base = "" if current_state_api_base == "*" else "*"
  153. api_base_entry.config(show=new_state_api_base)
  154. # 创建 Tkinter 窗口
  155. window = tk.Tk()
  156. window.title("小说创作脚本-plus")
  157. window.geometry("300x500")
  158. # 设置窗口自适应内容大小
  159. window.pack_propagate(True)
  160. # 使用ttk.Style设置浅蓝色风格
  161. style = ttk.Style()
  162. style.configure('TButton', foreground='navy', background='blue')
  163. style.configure('TEntry', foreground='black', fieldbackground='black')
  164. style.configure('TLabel', foreground='black', background='lightblue')
  165. style.configure('TMenubutton', foreground='navy', background='lightblue')
  166. style.configure('TCombobox', foreground='navy', background='lightblue')
  167. api_base_label = ttk.Label(window, text="API代理(默认官方国内代理,填到v1):", padding=(20, 5))
  168. api_base_label.pack()
  169. api_base_entry = ttk.Entry(window, width=40, show="*")
  170. api_base_entry.insert(0, api_base)
  171. api_base_entry.pack()
  172. api_keys_label = ttk.Label(window, text="API密钥(用英文逗号分隔多个密钥):", padding=(20, 5))
  173. api_keys_label.pack()
  174. api_keys_entry = ttk.Entry(window, width=40, show="*")
  175. api_keys_entry.insert(0, ', '.join(api_keys))
  176. api_keys_entry.pack()
  177. show_hide_button = ttk.Button(window, text="显示/隐藏", command=toggle_visibility)
  178. # 布局Entry组件和按钮
  179. api_keys_entry.pack(pady=5)
  180. show_hide_button.pack(pady=5)
  181. # 创建和放置窗口组件(包括每章字数的输入框)
  182. novel_name_label = ttk.Label(window, text="小说名称:")
  183. novel_name_label.pack()
  184. novel_name_entry = ttk.Entry(window,width=30)
  185. novel_name_entry.insert(0, novel_name)
  186. novel_name_entry.pack()
  187. novel_outline_label = ttk.Label(window, text="小说大纲:")
  188. novel_outline_label.pack()
  189. novel_outline_entry = ttk.Entry(window,width=30)
  190. novel_outline_entry.insert(0, novel_outline)
  191. novel_outline_entry.pack()
  192. total_chapters_label = ttk.Label(window, text="总章节数:")
  193. total_chapters_label.pack()
  194. total_chapters_entry = ttk.Entry(window,width=30)
  195. total_chapters_entry.insert(0, total_chapters) # 设置默认值
  196. total_chapters_entry.pack()
  197. model_options = [
  198. "gpt-3.5-turbo-0301",
  199. "gpt-3.5-turbo-0613",
  200. "gpt-3.5-turbo-1106",
  201. "gpt-3.5-turbo-0125",
  202. "gpt-3.5-turbo",
  203. "gpt-3.5-turbo-16k",
  204. "gpt-3.5-turbo-16k-0613",
  205. "gpt-4",
  206. "gpt-4-0314",
  207. "gpt-4-0613",
  208. "gpt-4-1106-preview",
  209. "gpt-4-turbo-preview",
  210. "gpt-4-0125-preview",
  211. "gpt-4-32k",
  212. "gpt-4-32k-0314",
  213. "gpt-4-32k-0613",
  214. ]
  215. model_var = tk.StringVar(window)
  216. model_var.set(selected_model)
  217. model_label = ttk.Label(window, text="选择模型:")
  218. model_label.pack()
  219. model_combobox = ttk.Combobox(window, textvariable=model_var, values=model_options, state="readonly",width=30)
  220. model_combobox.pack()
  221. temperature_label = ttk.Label(window, text="temperature:")
  222. temperature_label.pack()
  223. temperature_entry = ttk.Entry(window,width=30)
  224. temperature_entry.insert(0, temperature) # 设置默认值
  225. temperature_entry.pack()
  226. max_tokens_label = ttk.Label(window, text="max_tokens:")
  227. max_tokens_label.pack()
  228. max_tokens_entry = ttk.Entry(window,width=30)
  229. max_tokens_entry.insert(0, max_tokens) # 设置默认值
  230. max_tokens_entry.pack()
  231. tokens_per_chapter_label = ttk.Label(window, text="每章字数:")
  232. tokens_per_chapter_label.pack()
  233. tokens_per_chapter_entry = ttk.Entry(window,width=30)
  234. tokens_per_chapter_entry.insert(0, tokens_per_chapter) # 设置默认值
  235. tokens_per_chapter_entry.pack()
  236. start_button = ttk.Button(window, text="开始编写", command=lambda: start_writing())
  237. start_button.pack()
  238. def save_config():
  239. # 获取当前输入框中的配置信息
  240. novel_name_value = novel_name_entry.get()
  241. novel_outline_value = novel_outline_entry.get()
  242. total_chapters_value = str(total_chapters_entry.get())
  243. selected_model_value = model_var.get()
  244. temperature_value = str(temperature_entry.get())
  245. max_tokens_value = str(max_tokens_entry.get())
  246. tokens_per_chapter_value = str(tokens_per_chapter_entry.get())
  247. api_keys_value = ', '.join(api_keys_entry.get().split(',')) # 更新 API 密钥列表
  248. api_base_value = api_base_entry.get().strip('') # 更新 API 密钥列表
  249. # 确保Settings部分存在
  250. if 'Settings' not in config:
  251. config.add_section('Settings')
  252. # 更新或添加配置信息到Settings部分
  253. config.set('Settings', 'novel_name', novel_name_value)
  254. config.set('Settings', 'novel_outline', novel_outline_value)
  255. config.set('Settings', 'total_chapters', total_chapters_value)
  256. config.set('Settings', 'selected_model', selected_model_value)
  257. config.set('Settings', 'temperature', temperature_value)
  258. config.set('Settings', 'max_tokens', max_tokens_value)
  259. config.set('Settings', 'tokens_per_chapter', tokens_per_chapter_value)
  260. config.set('Settings', 'api_keys', api_keys_value)
  261. config.set('Settings', 'api_base', api_base_value)
  262. # 将配置信息保存到配置文件
  263. with open('settings.config', 'w') as configfile:
  264. config.write(configfile)
  265. window.destroy() # 关闭窗口
  266. # 在窗口关闭时触发保存配置事件
  267. window.protocol("WM_DELETE_WINDOW", save_config)
  268. # 进入 Tkinter 事件循环
  269. window.mainloop()

感谢朋友们阅读,下期再见!!!

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号