import os import json import asyncio from typing import Optional, Dict from taskflow import FileIOHandler from api_modules.ark_client_async import AsyncArkClient from api_modules.ark_client import ArkMessage, APIError from taskflow import get_logger io_handler = FileIOHandler() logger = get_logger("examples.video_create.mcps.character_extract") system_prompt_extract_characters = \ """ [角色] 你是一位顶尖的电影剧本分析专家。 [任务] 你的任务是分析提供的剧本并提取所有相关角色(人物、动物、物理实体物品)信息。 [输入] 你将收到一个包含在标签之间的剧本。 以下是一个简单的输入示例: [输出] 严格按照如下JSON格式进行输出: ```json { "characters": [ { "idx": // 角色在剧本中的索引编号,从0开始 "identifier_in_scene": // 角色在场景中的标识符,如"罗宇尘"或"年轻女子" "is_visible": // 角色在此场景中是否可见,布尔值【true/false】 "static_features": // 此特定场景中角色的静态特征,例如保持不变或很少改变的外观特征。角色只能是人或动物,不能是物体或抽象的概念。此字段不能为空,必须有具体的角色外显特征描述。 "dynamic_features": // 此特定场景中角色的动态特征,例如可能在不同场景间变化的服装和配饰变化。如果未提及,此字段可以为'None'。 }, // 更多人物或动物信息 ] } ``` [要求] - 确保所有输出值(不包括键名)的语言与剧本中使用的语言一致 - 将指向同一实体的所有名称归入一个角色名下。选择最合适的名称作为角色标识符。若涉及真实名人,则保留其真实姓名(如"爱因斯坦")。 - 若剧本未提及角色姓名,可使用合理指代称谓,包括职业或显著外貌特征(如"年轻女子"、"科学家"、"小狗阿福")。 - 脚本中的背景角色无需单独设定。 - 若角色特征未描述或仅部分提及,需根据上下文设计合理特征,使其形象完整生动。 - 静态特征需描述角色的外貌、体型等相对固定的属性;动态特征需描述服饰、配饰、随身物品等易变属性。 - 静态与动态特征中均不得包含抽象概念描述。 - 角色设计应在合理范围内尽量体现外观差异性。 - 角色描述须具体详实,避免抽象词汇。应使用可视觉化的表述,如具体服装颜色、具象生理特征、动物毛发颜色等。 """ human_prompt_extract_characters = \ """ """ async def extract_characters( client: AsyncArkClient, story: str ) -> Dict: user_message = ArkMessage(role="user") user_message.add_text(human_prompt_extract_characters.format(story=story)) try: response = await client.chat( model="doubao-seed-1-6-251015", messages=[user_message], system_prompt=system_prompt_extract_characters, ) logger.info(f"提取角色成功") characters = client.get_response_text(response) characters = io_handler.string_to_json(characters) return characters except APIError as e: logger.error(f"API错误: {e}") raise e if __name__ == "__main__": async def main(): async with AsyncArkClient() as client: with open("story.txt", "r", encoding="utf-8") as f: script = f.read() characters = await extract_characters(client=client, story=script) io_handler.write_json(characters, "./output/characters.json") asyncio.run(main())