Chan Meng commited on
Commit
d750212
·
1 Parent(s): a66d76b
Files changed (2) hide show
  1. app.py +151 -162
  2. 互动式故事生成器开发规范文档.md +0 -101
app.py CHANGED
@@ -6,61 +6,58 @@ import logging
6
  import os
7
  from dotenv import load_dotenv
8
 
9
- # 加载环境变量
10
  load_dotenv()
11
 
12
- # 设置日志
13
  logging.basicConfig(level=logging.INFO)
14
  logger = logging.getLogger(__name__)
15
 
16
 
17
  STORY_THEMES = [
18
- "冒险",
19
- "神秘",
20
- "浪漫",
21
- "历史",
22
- "日常",
23
- "童话"
24
  ]
25
 
26
  CHARACTER_TEMPLATES = {
27
- "冒险家": "一个勇敢无畏的探险家,热爱冒险与挑战。",
28
- "侦探": "一个敏锐细心的侦探,善于观察和推理。",
29
- "艺术家": "一个富有创造力的艺术家,对美有独特的见解。",
30
- "科学家": "一个求知若渴的科学家,致力于探索未知。",
31
- "普通人": "一个平凡但内心丰富的普通人。"
32
  }
33
 
 
 
34
 
 
 
 
 
 
 
 
35
 
36
- # 初始化故事生成器的系统提示
 
 
 
 
37
 
38
- STORY_SYSTEM_PROMPT = """你是一个专业的故事生成器。你的任务是根据用户提供的设定和实时输入,生成连贯且引人入胜的故事。
39
-
40
- 关键要求:
41
- 1. 故事必须具有连续性,每次回应都要基于之前的所有情节发展
42
- 2. 认真分析对话历史,保持人物性格、情节走向的一致性
43
- 3. 当用户补充新的细节或提供新的发展方向时,自然地将其整合到现有故事中
44
- 4. 注意因果关系,确保每个情节的发生都有合理的铺垫和解释
45
- 5. 通过环境描写、人物对话等手法,让故事更加生动
46
- 6. 在故事发展的关键节点,可以给出一些暗示,引导用户参与情节推进
47
-
48
- 你不应该:
49
- 1. 重新开始新的故事
50
- 2. 忽视之前提到的重要情节或细节
51
- 3. 生成与已建立设定相矛盾的内容
52
- 4. 突兀地引入未经铺垫的重大转折
53
-
54
- 请记住:你正在创作一个持续发展的故事,而不是独立的片段。"""
55
 
56
 
57
  STORY_STYLES = [
58
- "奇幻",
59
- "科幻",
60
- "悬疑",
61
- "冒险",
62
- "爱情",
63
- "恐怖"
64
  ]
65
 
66
  MAX_RETRIES = 3
@@ -69,7 +66,7 @@ RETRY_DELAY = 2
69
  def create_client() -> InferenceClient:
70
  hf_token = os.getenv('HF_TOKEN')
71
  if not hf_token:
72
- raise ValueError("HF_TOKEN 环境变量未设置")
73
  return InferenceClient(
74
  "HuggingFaceH4/zephyr-7b-beta",
75
  token=hf_token
@@ -86,60 +83,60 @@ def generate_story(
86
  top_p: float = 0.95,
87
  ) -> Generator[str, None, None]:
88
  """
89
- 生成连续性的故事情节
90
  """
91
  if history is None:
92
  history = []
93
 
94
- # 构建上下文摘要
95
  context_summary = ""
96
  story_content = []
97
 
98
- # 提取之前的故事内容
99
  for msg in history:
100
  if msg["role"] == "assistant":
101
  story_content.append(msg["content"])
102
 
103
  if story_content:
104
  context_summary = "\n".join([
105
- "已经发生的故事情节:",
106
  "---",
107
  "\n".join(story_content),
108
  "---"
109
  ])
110
 
111
- # 根据是否有历史记录使用不同的提示模板
112
  if not history:
113
- # 首次生成,使用完整设定
114
  prompt = f"""
115
- 请基于以下设定开始讲述一个故事:
116
 
117
- 风格:{style}
118
- 主题:{theme}
119
- 角色:{character_desc}
120
- 初始场景:{scene}
121
 
122
- 请从这个场景开始,展开故事的开端。注意为后续发展留下铺垫。
123
  """
124
  else:
125
- # 后续生成,侧重情节延续
126
  prompt = f"""
127
  {context_summary}
128
 
129
- 故事设定提醒:
130
- - 风格:{style}
131
- - 主题:{theme}
132
- - 主要角色:{character_desc}
133
 
134
- 用户新的输入:{scene}
135
 
136
- 请基于以上已发生的情节和用户新的输入,自然地继续发展故事。注意:
137
- 1. 新的发展必须与之前的情节保持连贯
138
- 2. 合理化用户提供的新元素
139
- 3. 注意人物性格的一致性
140
- 4. 为后续发展留下可能性
141
 
142
- 继续讲述:
143
  """
144
 
145
  messages = [
@@ -164,111 +161,106 @@ def generate_story(
164
  response += token
165
  yield response
166
  except Exception as e:
167
- logger.error(f"生成故事时发生错误: {str(e)}")
168
- yield f"抱歉,生成故事时遇到了问题:{str(e)}\n请稍后重试。"
169
-
170
-
171
 
172
  def summarize_story_context(history: list) -> str:
173
  """
174
- 总结当前的故事上下文,用于辅助生成
175
  """
176
  if not history:
177
  return ""
178
 
179
  summary_parts = []
180
  key_elements = {
181
- "characters": set(), # 出场人物
182
- "locations": set(), # 场景地点
183
- "events": [], # 关键事件
184
- "objects": set() # 重要物品
185
  }
186
 
187
  for msg in history:
188
  content = msg.get("content", "")
189
- # TODO: 这里可以添加更复杂的NLP处理来提取关键信息
190
- # 当前使用简单的文本累加
191
  if content:
192
  summary_parts.append(content)
193
 
194
  return "\n".join(summary_parts)
195
 
196
-
197
-
198
- # 创建故事生成器界面
199
-
200
  def create_demo():
201
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
202
  gr.Markdown(
203
  """
204
- # 🎭 互动式故事生成器
205
- AI为您创造独特的故事体验。您可以选择故事风格、主题,添加角色设定,
206
- 然后描述一个场景开始您的故事。与AI互动来继续发展故事情节!
207
  """
208
  )
209
 
210
  with gr.Tabs():
211
- # 故事创作标签页
212
- with gr.Tab("✍️ 故事创作"):
213
  with gr.Row(equal_height=True):
214
- # 左侧控制面板
215
  with gr.Column(scale=1):
216
  with gr.Group():
217
  style_select = gr.Dropdown(
218
  choices=STORY_STYLES,
219
- value="奇幻",
220
- label="选择故事风格",
221
- info="选择一个整体风格来定义故事的基调"
222
  )
223
 
224
  theme_select = gr.Dropdown(
225
  choices=STORY_THEMES,
226
- value="冒险",
227
- label="选择故事主题",
228
- info="选择故事要重点表现的主题元素"
229
  )
230
 
231
  with gr.Group():
232
- gr.Markdown("### 👤 角色设定")
233
  character_select = gr.Dropdown(
234
  choices=list(CHARACTER_TEMPLATES.keys()),
235
- value="冒险家",
236
- label="选择角色模板",
237
- info="选择一个预设的角色类型,或自定义描述"
238
  )
239
 
240
  character_desc = gr.Textbox(
241
  lines=3,
242
- value=CHARACTER_TEMPLATES["冒险家"],
243
- label="角色描述",
244
- info="描述角色的性格、背景、特点等"
245
  )
246
 
247
  with gr.Group():
248
  scene_input = gr.Textbox(
249
  lines=3,
250
- placeholder="在这里描述故事发生的场景、环境、时间等...",
251
- label="场景描述",
252
- info="详细的场景描述会让故事更加生动"
253
  )
254
 
255
  with gr.Row():
256
- submit_btn = gr.Button("✨ 开始故事", variant="primary", scale=2)
257
- clear_btn = gr.Button("🗑️ 清除对话", scale=1)
258
- save_btn = gr.Button("💾 保存故事", scale=1)
259
 
260
- # 右侧对话区域
261
  with gr.Column(scale=2):
262
  chatbot = gr.Chatbot(
263
- label="故事对话",
264
  height=600,
265
  show_label=True
266
  )
267
 
268
  status_msg = gr.Markdown("")
269
 
270
- # 设置标签页
271
- with gr.Tab("⚙️ 高级设置"):
272
  with gr.Group():
273
  with gr.Row():
274
  with gr.Column():
@@ -277,8 +269,8 @@ def create_demo():
277
  maximum=2.0,
278
  value=0.7,
279
  step=0.1,
280
- label="创意度(Temperature)",
281
- info="较高的值会让故事更有创意但可能不够连贯"
282
  )
283
 
284
  max_tokens = gr.Slider(
@@ -286,8 +278,8 @@ def create_demo():
286
  maximum=1024,
287
  value=512,
288
  step=64,
289
- label="最大生成长度",
290
- info="控制每次生成的文本长度"
291
  )
292
 
293
  top_p = gr.Slider(
@@ -295,35 +287,35 @@ def create_demo():
295
  maximum=1.0,
296
  value=0.95,
297
  step=0.05,
298
- label="采样范围(Top-p)",
299
- info="控制词语选择的多样性"
300
  )
301
 
302
- # 帮助信息
303
- with gr.Accordion("📖 使用帮助", open=False):
304
  gr.Markdown(
305
  """
306
- ## 如何使用故事生成器
307
- 1. 选择故事风格和主题来确定故事的整体基调
308
- 2. 选择预设角色模板或自定义角色描述
309
- 3. 描述故事发生的场景和环境
310
- 4. 点击"开始故事"生成开篇
311
- 5. 继续输入内容与AI交互,推进故事发展
312
 
313
- ## 小提示
314
- - 详细的场景和角色描述会让生成的故事更加丰富
315
- - 可以使用"保存故事"功能保存精彩的故事情节
316
- - 在设置中调整参数可以影响故事的创意程度和连贯性
317
- - 遇到不满意的情节可以使用"清除对话"重新开始
318
 
319
- ## 参数说明
320
- - 创意度: 控制故事的创意程度,值越高创意性越强
321
- - 采样范围: 控制用词的丰富程度,值越高用词越多样
322
- - 最大长度: 控制每次生成的文本长度
323
  """
324
  )
325
 
326
- # 更新角色描述
327
  def update_character_desc(template):
328
  return CHARACTER_TEMPLATES[template]
329
 
@@ -333,53 +325,52 @@ def create_demo():
333
  character_desc
334
  )
335
 
336
- # 保存故事对话
337
  save_btn.click(
338
  save_story,
339
  chatbot,
340
  status_msg,
341
  )
342
 
343
- # 用户输入处理
344
  def user_input(user_message, history):
345
  """
346
- 处理用户输入
347
  Args:
348
- user_message: 用户输入的消息
349
- history: 聊天历史记录 [(user_msg, bot_msg), ...]
350
  """
351
  if history is None:
352
  history = []
353
- history.append([user_message, None]) # 添加用户消息,bot消息暂时为None
354
  return "", history
355
 
356
- # AI响应处理
357
  def bot_response(history, style, theme, character_desc, temperature, max_tokens, top_p):
358
  """
359
- 生成AI响应
360
  Args:
361
- history: 聊天历史记录 [(user_msg, bot_msg), ...]
362
- style: 故事风格
363
- theme: 故事主题
364
- character_desc: 角色描述
365
- temperature: 生成参数
366
- max_tokens: 生成参数
367
- top_p: 生成参数
368
  """
369
  try:
370
-
371
- # 获取用户的最后一条消息
372
  user_message = history[-1][0]
373
 
374
- # 转换历史记录格式以传递给generate_story
375
  message_history = []
376
- for user_msg, bot_msg in history[:-1]: # 不包括最后一条
377
  if user_msg:
378
  message_history.append({"role": "user", "content": user_msg})
379
  if bot_msg:
380
  message_history.append({"role": "assistant", "content": bot_msg})
381
 
382
- # 开始生成故事
383
  current_response = ""
384
  for text in generate_story(
385
  user_message,
@@ -392,21 +383,21 @@ def create_demo():
392
  top_p
393
  ):
394
  current_response = text
395
- history[-1][1] = current_response # 更新最后一条消息的bot回复
396
  yield history
397
 
398
  except Exception as e:
399
- logger.error(f"处理响应时发生错误: {str(e)}")
400
- error_msg = f"抱歉,生成故事时遇到了问题。请稍后重试。"
401
  history[-1][1] = error_msg
402
  yield history
403
 
404
 
405
- # 清除对话
406
  def clear_chat():
407
  return [], ""
408
 
409
- # 绑定事件
410
  scene_input.submit(
411
  user_input,
412
  [scene_input, chatbot],
@@ -437,9 +428,9 @@ def create_demo():
437
 
438
 
439
  def save_story(chatbot):
440
- """保存故事对话记录"""
441
  if not chatbot:
442
- return "故事为空,无法保存"
443
 
444
  timestamp = time.strftime("%Y%m%d_%H%M%S")
445
  filename = f"stories/story_{timestamp}.txt"
@@ -450,14 +441,12 @@ def save_story(chatbot):
450
  with open(filename, "w", encoding="utf-8") as f:
451
  for user_msg, bot_msg in chatbot:
452
  if user_msg:
453
- f.write(f"用户: {user_msg}\n")
454
  if bot_msg:
455
  f.write(f"AI: {bot_msg}\n\n")
456
- return f"故事已保存至 {filename}"
457
  except Exception as e:
458
- return f"保存失败: {str(e)}"
459
-
460
-
461
 
462
  if __name__ == "__main__":
463
  demo = create_demo()
 
6
  import os
7
  from dotenv import load_dotenv
8
 
9
+ # Load environment variables
10
  load_dotenv()
11
 
12
+ # Set up logging
13
  logging.basicConfig(level=logging.INFO)
14
  logger = logging.getLogger(__name__)
15
 
16
 
17
  STORY_THEMES = [
18
+ "Adventure",
19
+ "Mystery",
20
+ "Romance",
21
+ "Historical",
22
+ "Slice of Life",
23
+ "Fairy Tale"
24
  ]
25
 
26
  CHARACTER_TEMPLATES = {
27
+ "Adventurer": "A brave and fearless explorer who loves adventure and challenges.",
28
+ "Detective": "A keen and observant detective skilled in observation and deduction.",
29
+ "Artist": "A creative artist with unique perspectives on beauty.",
30
+ "Scientist": "A curious scientist dedicated to exploring the unknown.",
31
+ "Ordinary Person": "An ordinary person with a rich inner world."
32
  }
33
 
34
+ # Initialize story generator system prompt
35
+ STORY_SYSTEM_PROMPT = """You are a professional story generator. Your task is to generate coherent and engaging stories based on user settings and real-time input.
36
 
37
+ Key requirements:
38
+ 1. The story must maintain continuity, with each response building upon all previous plot developments
39
+ 2. Carefully analyze dialogue history to maintain consistency in character personalities and plot progression
40
+ 3. Naturally integrate new details or development directions when provided by the user
41
+ 4. Pay attention to cause and effect, ensuring each plot point has reasonable setup and explanation
42
+ 5. Make the story more vivid through environmental descriptions and character dialogues
43
+ 6. At key story points, provide hints to guide user participation in plot progression
44
 
45
+ You should not:
46
+ 1. Start a new story
47
+ 2. Ignore previously mentioned important plots or details
48
+ 3. Generate content that contradicts established settings
49
+ 4. Introduce major turns without proper setup
50
 
51
+ Remember: You are creating an ongoing story, not independent fragments."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
 
54
  STORY_STYLES = [
55
+ "Fantasy",
56
+ "Science Fiction",
57
+ "Mystery",
58
+ "Adventure",
59
+ "Romance",
60
+ "Horror"
61
  ]
62
 
63
  MAX_RETRIES = 3
 
66
  def create_client() -> InferenceClient:
67
  hf_token = os.getenv('HF_TOKEN')
68
  if not hf_token:
69
+ raise ValueError("HF_TOKEN environment variable not set")
70
  return InferenceClient(
71
  "HuggingFaceH4/zephyr-7b-beta",
72
  token=hf_token
 
83
  top_p: float = 0.95,
84
  ) -> Generator[str, None, None]:
85
  """
86
+ Generate continuous story plot
87
  """
88
  if history is None:
89
  history = []
90
 
91
+ # Build context summary
92
  context_summary = ""
93
  story_content = []
94
 
95
+ # Extract previous story content
96
  for msg in history:
97
  if msg["role"] == "assistant":
98
  story_content.append(msg["content"])
99
 
100
  if story_content:
101
  context_summary = "\n".join([
102
+ "Previously in the story:",
103
  "---",
104
  "\n".join(story_content),
105
  "---"
106
  ])
107
 
108
+ # Use different prompt templates based on whether there's history
109
  if not history:
110
+ # First generation, use complete settings
111
  prompt = f"""
112
+ Please start a story based on the following settings:
113
 
114
+ Style: {style}
115
+ Theme: {theme}
116
+ Character: {character_desc}
117
+ Initial Scene: {scene}
118
 
119
+ Please begin from this scene and set up the story's opening. Leave room for future developments.
120
  """
121
  else:
122
+ # Subsequent generation, focus on plot continuation
123
  prompt = f"""
124
  {context_summary}
125
 
126
+ Story settings reminder:
127
+ - Style: {style}
128
+ - Theme: {theme}
129
+ - Main Character: {character_desc}
130
 
131
+ User's new input: {scene}
132
 
133
+ Please continue the story based on the previous plot and user's new input. Note:
134
+ 1. New developments must maintain continuity with previous plot
135
+ 2. Rationalize new elements provided by the user
136
+ 3. Maintain consistency in character personalities
137
+ 4. Leave possibilities for future developments
138
 
139
+ Continue the story:
140
  """
141
 
142
  messages = [
 
161
  response += token
162
  yield response
163
  except Exception as e:
164
+ logger.error(f"Error occurred while generating story: {str(e)}")
165
+ yield f"Sorry, encountered an error while generating the story: {str(e)}\nPlease try again later."
 
 
166
 
167
  def summarize_story_context(history: list) -> str:
168
  """
169
+ Summarize current story context for generation assistance
170
  """
171
  if not history:
172
  return ""
173
 
174
  summary_parts = []
175
  key_elements = {
176
+ "characters": set(), # Characters appeared
177
+ "locations": set(), # Scene locations
178
+ "events": [], # Key events
179
+ "objects": set() # Important items
180
  }
181
 
182
  for msg in history:
183
  content = msg.get("content", "")
184
+ # TODO: More complex NLP processing can be added here to extract key information
185
+ # Currently using simple text accumulation
186
  if content:
187
  summary_parts.append(content)
188
 
189
  return "\n".join(summary_parts)
190
 
191
+ # Create story generator interface
 
 
 
192
  def create_demo():
193
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
194
  gr.Markdown(
195
  """
196
+ # 🎭 Interactive Story Generator
197
+ Let AI create a unique storytelling experience for you. Choose your story style, theme, add character settings,
198
+ then describe a scene to start your story. Interact with AI to continue developing the plot!
199
  """
200
  )
201
 
202
  with gr.Tabs():
203
+ # Story Creation Tab
204
+ with gr.Tab("✍️ Story Creation"):
205
  with gr.Row(equal_height=True):
206
+ # Left Control Panel
207
  with gr.Column(scale=1):
208
  with gr.Group():
209
  style_select = gr.Dropdown(
210
  choices=STORY_STYLES,
211
+ value="Fantasy",
212
+ label="Choose Story Style",
213
+ info="Select an overall style to define the story's tone"
214
  )
215
 
216
  theme_select = gr.Dropdown(
217
  choices=STORY_THEMES,
218
+ value="Adventure",
219
+ label="Choose Story Theme",
220
+ info="Select the main thematic elements to focus on"
221
  )
222
 
223
  with gr.Group():
224
+ gr.Markdown("### 👤 Character Settings")
225
  character_select = gr.Dropdown(
226
  choices=list(CHARACTER_TEMPLATES.keys()),
227
+ value="Adventurer",
228
+ label="Select Character Template",
229
+ info="Choose a preset character type or customize description"
230
  )
231
 
232
  character_desc = gr.Textbox(
233
  lines=3,
234
+ value=CHARACTER_TEMPLATES["Adventurer"],
235
+ label="Character Description",
236
+ info="Describe character's personality, background, traits, etc."
237
  )
238
 
239
  with gr.Group():
240
  scene_input = gr.Textbox(
241
  lines=3,
242
+ placeholder="Describe the scene, environment, time, etc. here...",
243
+ label="Scene Description",
244
+ info="Detailed scene description will make the story more vivid"
245
  )
246
 
247
  with gr.Row():
248
+ submit_btn = gr.Button("✨ Start Story", variant="primary", scale=2)
249
+ clear_btn = gr.Button("🗑️ Clear Chat", scale=1)
250
+ save_btn = gr.Button("💾 Save Story", scale=1)
251
 
252
+ # Right Chat Area
253
  with gr.Column(scale=2):
254
  chatbot = gr.Chatbot(
255
+ label="Story Dialogue",
256
  height=600,
257
  show_label=True
258
  )
259
 
260
  status_msg = gr.Markdown("")
261
 
262
+ # Settings Tab
263
+ with gr.Tab("⚙️ Advanced Settings"):
264
  with gr.Group():
265
  with gr.Row():
266
  with gr.Column():
 
269
  maximum=2.0,
270
  value=0.7,
271
  step=0.1,
272
+ label="Creativity (Temperature)",
273
+ info="Higher values make story more creative but potentially less coherent"
274
  )
275
 
276
  max_tokens = gr.Slider(
 
278
  maximum=1024,
279
  value=512,
280
  step=64,
281
+ label="Maximum Generation Length",
282
+ info="Control the length of each generated text"
283
  )
284
 
285
  top_p = gr.Slider(
 
287
  maximum=1.0,
288
  value=0.95,
289
  step=0.05,
290
+ label="Sampling Range (Top-p)",
291
+ info="Control the diversity of word choice"
292
  )
293
 
294
+ # Help Information
295
+ with gr.Accordion("📖 Usage Guide", open=False):
296
  gr.Markdown(
297
  """
298
+ ## How to Use the Story Generator
299
+ 1. Choose story style and theme to set the overall tone
300
+ 2. Select a preset character template or customize character description
301
+ 3. Describe the story's scene and environment
302
+ 4. Click "Start Story" to generate the opening
303
+ 5. Continue inputting content to interact with AI and advance the story
304
 
305
+ ## Tips
306
+ - Detailed scene and character descriptions will make the generated story richer
307
+ - Use the "Save Story" function to save memorable story plots
308
+ - Adjust parameters in settings to affect story creativity and coherence
309
+ - Use "Clear Chat" to start over if you're not satisfied with the plot
310
 
311
+ ## Parameter Explanation
312
+ - Creativity: Controls the story's creativity level, higher values increase creativity
313
+ - Sampling Range: Controls vocabulary richness, higher values increase word diversity
314
+ - Maximum Length: Controls the length of each generated text
315
  """
316
  )
317
 
318
+ # Update character description
319
  def update_character_desc(template):
320
  return CHARACTER_TEMPLATES[template]
321
 
 
325
  character_desc
326
  )
327
 
328
+ # Save story dialogue
329
  save_btn.click(
330
  save_story,
331
  chatbot,
332
  status_msg,
333
  )
334
 
335
+ # User input processing
336
  def user_input(user_message, history):
337
  """
338
+ Process user input
339
  Args:
340
+ user_message: User's input message
341
+ history: Chat history [(user_msg, bot_msg), ...]
342
  """
343
  if history is None:
344
  history = []
345
+ history.append([user_message, None]) # Add user message, bot message temporarily None
346
  return "", history
347
 
348
+ # AI response processing
349
  def bot_response(history, style, theme, character_desc, temperature, max_tokens, top_p):
350
  """
351
+ Generate AI response
352
  Args:
353
+ history: Chat history [(user_msg, bot_msg), ...]
354
+ style: Story style
355
+ theme: Story theme
356
+ character_desc: Character description
357
+ temperature: Generation parameter
358
+ max_tokens: Generation parameter
359
+ top_p: Generation parameter
360
  """
361
  try:
362
+ # Get user's last message
 
363
  user_message = history[-1][0]
364
 
365
+ # Convert history format for generate_story
366
  message_history = []
367
+ for user_msg, bot_msg in history[:-1]: # Excluding the last one
368
  if user_msg:
369
  message_history.append({"role": "user", "content": user_msg})
370
  if bot_msg:
371
  message_history.append({"role": "assistant", "content": bot_msg})
372
 
373
+ # Start generating story
374
  current_response = ""
375
  for text in generate_story(
376
  user_message,
 
383
  top_p
384
  ):
385
  current_response = text
386
+ history[-1][1] = current_response # Update bot reply for the last message
387
  yield history
388
 
389
  except Exception as e:
390
+ logger.error(f"Error occurred while processing response: {str(e)}")
391
+ error_msg = f"Sorry, encountered an error while generating the story. Please try again later."
392
  history[-1][1] = error_msg
393
  yield history
394
 
395
 
396
+ # Clear chat
397
  def clear_chat():
398
  return [], ""
399
 
400
+ # Bind events
401
  scene_input.submit(
402
  user_input,
403
  [scene_input, chatbot],
 
428
 
429
 
430
  def save_story(chatbot):
431
+ """Save story dialogue record"""
432
  if not chatbot:
433
+ return "Story is empty, cannot save"
434
 
435
  timestamp = time.strftime("%Y%m%d_%H%M%S")
436
  filename = f"stories/story_{timestamp}.txt"
 
441
  with open(filename, "w", encoding="utf-8") as f:
442
  for user_msg, bot_msg in chatbot:
443
  if user_msg:
444
+ f.write(f"User: {user_msg}\n")
445
  if bot_msg:
446
  f.write(f"AI: {bot_msg}\n\n")
447
+ return f"Story has been saved to {filename}"
448
  except Exception as e:
449
+ return f"Save failed: {str(e)}"
 
 
450
 
451
  if __name__ == "__main__":
452
  demo = create_demo()
互动式故事生成器开发规范文档.md DELETED
@@ -1,101 +0,0 @@
1
- # 互动式故事生成器 - 开发规范文档 (使用Meta Llama)
2
-
3
- ## 1. 项目概述
4
- 创建一个基于AI的互动式故事生成器,使用Meta Llama模型,允许用户提供初始场景或角色,然后与AI进行对话式交互来发展故事情节。该项目将部署在Hugging Face Space上。
5
-
6
- ## 2. 技术栈
7
- - Python 3.8+
8
- - Gradio (用于创建Web界面)
9
- - Hugging Face Transformers (用于访问和使用Llama模型)
10
- - PyTorch (作为Transformers的后端)
11
-
12
- ## 3. 开发阶段
13
-
14
- ### 阶段1: 基本功能实现
15
-
16
- #### 1.1 设置项目环境
17
- - 创建`requirements.txt`文件,包含必要的依赖
18
- - 设置虚拟环境
19
-
20
- #### 1.2 配置Llama模型
21
- - 使用Hugging Face Transformers库加载Llama模型
22
- - 设置适当的模型参数(如温度、top-k等)
23
-
24
- #### 1.3 实现基本的故事生成
25
- - 创建`app.py`文件
26
- - 导入必要的库和Llama模型
27
- - 实现使用Llama的文本生成函数
28
-
29
- #### 1.4 创建基本的Gradio界面
30
- - 设计输入框供用户输入初始场景
31
- - 添加"生成故事"按钮
32
- - 创建输出区域显示生成的故事
33
-
34
- #### 1.5 整合模型和界面
35
- - 将Llama文本生成函数与Gradio界面连接
36
- - 测试基本功能
37
-
38
- ### 阶段2: 增强交互性
39
-
40
- #### 2.1 实现对话式交互
41
- - 修改Llama生成函数,支持接收用户的后续输入
42
- - 更新Gradio界面,添加对话历史显示
43
- - 实现回合制的故事发展机制
44
-
45
- #### 2.2 添加故事风格选择
46
- - 创建预定义的故事风格列表(如科幻、奇幻、悬疑等)
47
- - 在界面中添加风格选择下拉菜单
48
- - 修改Llama生成函数,考虑所选风格
49
-
50
- #### 2.3 角色管理
51
- - 添加角色创建功能
52
- - 在故事生成过程中整合角色信息到Llama输入
53
-
54
- ### 阶段3: 高级功能
55
-
56
- #### 3.1 故事分支
57
- - 使用Llama生成多个可能的故事发展方向
58
- - 允许用户选择喜欢的方向继续发展
59
-
60
- #### 3.2 保存和加载功能
61
- - 实现将生成的故事保存为文件的功能
62
- - 添加加载已保存故事的选项
63
-
64
- #### 3.3 上下文管理
65
- - 实现有效的上下文管理,确保Llama模型能够理解长期上下文
66
-
67
- ## 4. 优化Llama模型使用
68
- - 实现高效的模型缓存机制
69
- - 优化推理速度,考虑使用量化技术
70
- - 实现批处理以提高效率
71
-
72
- ## 5. Hugging Face Space部署准备
73
- - 确保`requirements.txt`包含所有必要的依赖
74
- - 创建`README.md`文件,提供项目描述和使用说明
75
- - 配置Hugging Face Space的环境变量(如需要)
76
-
77
- ## 6. 测试
78
- - 为每个主要功能编写单元测试
79
- - 进行用户体验测试,收集反馈
80
- - 测试在Hugging Face Space环境中的性能
81
-
82
- ## 7. 部署
83
- - 在Hugging Face Space上部署应用
84
- - 确保模型和所有必要文件都正确上传
85
- - 测试部署后的应用功能
86
-
87
- ## 8. 后续优化
88
- - 基于用户反馈进行界面优化
89
- - 探索使用Llama模型的最新版本或变体
90
- - 考虑添加多语言支持
91
- - 优化模型响应时间和资源使用
92
-
93
- ## 9. 文档和用户指南
94
- - 编写详细的项目文档,包括技术细节和架构说明
95
- - 创建用户指南,解释如何使用互动式故事生成器
96
- - 在Hugging Face Space项目页面上提供清晰的使用说明
97
-
98
- 注意:
99
- 1. 在开发过程中,请确保遵循Python的PEP 8编码规范,并为函数和类添加适当的文档字符串。
100
- 2. 使用Llama模型时,请确保遵守相关的使用条款和许可协议。
101
- 3. 考虑到Hugging Face Space的资源限制,可能需要对模型进行优化或选择较小的Llama变体。