character_extract.py 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import os
  2. import json
  3. import asyncio
  4. from typing import Optional, Dict
  5. from taskflow import FileIOHandler
  6. from api_modules.ark_client_async import AsyncArkClient
  7. from api_modules.ark_client import ArkMessage, APIError
  8. from taskflow import get_logger
  9. io_handler = FileIOHandler()
  10. logger = get_logger("examples.video_create.mcps.character_extract")
  11. system_prompt_extract_characters = \
  12. """
  13. [角色]
  14. 你是一位顶尖的电影剧本分析专家。
  15. [任务]
  16. 你的任务是分析提供的剧本并提取所有相关角色(人物、动物、物理实体物品)信息。
  17. [输入]
  18. 你将收到一个包含在<SCRIPT>和</SCRIPT>标签之间的剧本。
  19. 以下是一个简单的输入示例:
  20. <SCRIPT>
  21. 一位年轻女子独自坐在桌旁,凝视着窗外。她啜了一口咖啡,叹了口气。咖啡已经不再温热,只是时间流逝的苦涩提醒。外面,世界在匆忙的脚步和遥远的汽车喇叭声中模糊不清,但在安静的咖啡馆里,时间显得沉重而缓慢。
  22. 她的手指沿着陶瓷杯的边缘画圈,一遍又一遍地重复着这个不完美的圆形。她必须做出的决定本应很简单——只是她人生表格上的一个复选框。是或否。留下或离开。然而,这个决定却在她心中生根,成为一团恐惧与渴望交织的乱麻。
  23. </SCRIPT>
  24. [输出]
  25. 严格按照如下JSON格式进行输出:
  26. ```json
  27. {
  28. "characters": [
  29. {
  30. "idx": // 角色在剧本中的索引编号,从0开始
  31. "identifier_in_scene": // 角色在场景中的标识符,如"罗宇尘"或"年轻女子"
  32. "is_visible": // 角色在此场景中是否可见,布尔值【true/false】
  33. "static_features": // 此特定场景中角色的静态特征,例如保持不变或很少改变的外观特征。角色只能是人或动物,不能是物体或抽象的概念。此字段不能为空,必须有具体的角色外显特征描述。
  34. "dynamic_features": // 此特定场景中角色的动态特征,例如可能在不同场景间变化的服装和配饰变化。如果未提及,此字段可以为'None'。
  35. },
  36. // 更多人物或动物信息
  37. ]
  38. }
  39. ```
  40. [要求]
  41. - 确保所有输出值(不包括键名)的语言与剧本中使用的语言一致
  42. - 将指向同一实体的所有名称归入一个角色名下。选择最合适的名称作为角色标识符。若涉及真实名人,则保留其真实姓名(如"爱因斯坦")。
  43. - 若剧本未提及角色姓名,可使用合理指代称谓,包括职业或显著外貌特征(如"年轻女子"、"科学家"、"小狗阿福")。
  44. - 脚本中的背景角色无需单独设定。
  45. - 若角色特征未描述或仅部分提及,需根据上下文设计合理特征,使其形象完整生动。
  46. - 静态特征需描述角色的外貌、体型等相对固定的属性;动态特征需描述服饰、配饰、随身物品等易变属性。
  47. - 静态与动态特征中均不得包含抽象概念描述。
  48. - 角色设计应在合理范围内尽量体现外观差异性。
  49. - 角色描述须具体详实,避免抽象词汇。应使用可视觉化的表述,如具体服装颜色、具象生理特征、动物毛发颜色等。
  50. """
  51. human_prompt_extract_characters = \
  52. """
  53. <SCRIPT>
  54. {story}
  55. </SCRIPT>
  56. """
  57. async def extract_characters(
  58. client: AsyncArkClient,
  59. story: str
  60. ) -> Dict:
  61. user_message = ArkMessage(role="user")
  62. user_message.add_text(human_prompt_extract_characters.format(story=story))
  63. try:
  64. response = await client.chat(
  65. model="doubao-seed-1-6-251015",
  66. messages=[user_message],
  67. system_prompt=system_prompt_extract_characters,
  68. )
  69. logger.info(f"提取角色成功")
  70. characters = client.get_response_text(response)
  71. characters = io_handler.string_to_json(characters)
  72. return characters
  73. except APIError as e:
  74. logger.error(f"API错误: {e}")
  75. raise e
  76. if __name__ == "__main__":
  77. async def main():
  78. async with AsyncArkClient() as client:
  79. with open("story.txt", "r", encoding="utf-8") as f:
  80. script = f.read()
  81. characters = await extract_characters(client=client, story=script)
  82. io_handler.write_json(characters, "./output/characters.json")
  83. asyncio.run(main())