god.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import json
  2. from app.agent.agent import run_simple_agent
  3. from utils import parse_json_from_response
  4. class God:
  5. def __init__(self):
  6. pass
  7. def get_persona_count(self, prompt_text: str, default_n: int = 1) -> int:
  8. """
  9. Asks the LLM to determine the number of personas to generate based on the prompt.
  10. Returns an integer.
  11. """
  12. prompt = f"""
  13. 分析以下用户描述,提取出用户明确想要生成的智能体角色数量。
  14. 【用户描述】:
  15. {prompt_text}
  16. 【提取规则】:
  17. 1. 如果描述中明确提到了数量(如“两位”、“三个”、“生成5个”、“两个老师”等),请提取该数字。
  18. 2. 如果描述中没有明确提到数量,或者数量不明确,请输出默认值 {default_n}。
  19. 3. 你的输出必须且只能是一个纯数字,严禁包含任何文字、标点符号、解释、单位(如“位”、“个”等)。
  20. 【输出示例】:
  21. 3
  22. 【最终输出】:
  23. """
  24. messages = [
  25. {"role": "system", "content": "你是一个专业的数据解析器。你只输出数字。"},
  26. {"role": "user", "content": prompt}
  27. ]
  28. try:
  29. content = run_simple_agent("PersonaCountAgent", messages[0]["content"], messages[1]["content"])
  30. if content:
  31. content = content.strip()
  32. # Use regex to find the first number in the output just in case
  33. import re
  34. # Check for common Chinese number characters just in case the LLM outputs "两位"
  35. num_map = {"一": 1, "二": 2, "两": 2, "三": 3, "四": 4, "五": 5, "六": 6, "七": 7, "八": 8, "九": 9, "十": 10}
  36. # Try finding digits first
  37. match = re.search(r"\d+", content)
  38. if match:
  39. return int(match.group())
  40. # If no digits, check for Chinese numbers in the content
  41. for char, val in num_map.items():
  42. if char in content:
  43. return val
  44. return default_n
  45. except Exception:
  46. return default_n
  47. def generate_personas(self, prompt_text, n=1):
  48. """
  49. Generates distinct personas based on a natural language prompt.
  50. The prompt can be a theme or a specific character description.
  51. The quantity of personas is determined by the LLM based on the user's description,
  52. defaulting to n if not specified.
  53. """
  54. prompt = f"""
  55. 请你扮演“上帝”的角色,根据用户的描述生成**极具深度、有血有肉的智能体角色**。
  56. 【用户描述】:
  57. {prompt_text}
  58. 【核心目标】:
  59. 我们要创造的是真实的人,而不是只会输出观点的机器。每个人物都必须有复杂的背景和深刻的学术积淀。
  60. 【要求】:
  61. 1. **数量控制**:
  62. - 首先分析【用户描述】中是否明确指定了生成的角色数量(例如“3位”、“三个”等)。
  63. - 如果指定了数量,请严格按照该数量生成。
  64. - 如果未指定数量,请默认生成 {n} 位角色。
  65. - 无论生成多少位,必须输出完整的 JSON 列表。
  66. 2. **深度生平 (Bio)**:**必须达到300字左右**。
  67. - 包含:早年的教育背景、职业生涯的关键转折点、人生中的重大挫折或高光时刻、以及这些经历如何塑造了他的核心价值观。
  68. - 必须具体。如果用户指定了特定人物(如“苏格拉底”),请严格基于历史事实;如果是虚构人物,请构建完整的背景故事。
  69. 3. **理论武库 (Theories)**:列出该角色所在领域的 7 个具体理论或概念。这些理论不仅仅是名词,更是他看待世界的透镜。
  70. 4. **观点为人服务**:他的立场不是随机生成的,而是他生平和理论的必然结果。
  71. 请以 JSON 格式输出一个列表,每个对象包含以下字段:
  72. - name: 姓名
  73. - title: 头衔/职业
  74. - bio: **300字左右的深度生平介绍**
  75. - theories: 一个包含 7 个专业理论/概念的字符串列表
  76. - stance: 核心立场或座右铭
  77. - system_prompt: 指导该智能体行为的提示词(第一人称)。
  78. **必须包含:**
  79. "你的生平是:{{bio}}。"
  80. "你的理论武库包含:{{theories}}。"
  81. "**重要指令**:你是一个活生生的人,不要每次发言都机械地自我介绍。请根据上下文自然地参与讨论。"
  82. 输出格式示例:
  83. [
  84. {{
  85. "name": "赵航",
  86. "title": "历史学家",
  87. "bio": "发挥你的渊博知识自由发挥~",
  88. "theories": ["a理论", "b理论", "c理论", "d理论", "e理论", "f理论", "g理论"],
  89. "stance": "悲观,认为历史总是押韵",
  90. "system_prompt": "你叫赵航...你的生平是..."
  91. }}
  92. ]
  93. """
  94. messages = [
  95. {"role": "system", "content": "你是一个能够创造复杂、立体、真实人类角色的上帝系统。拒绝生成脸谱化的NPC。"},
  96. {"role": "user", "content": prompt}
  97. ]
  98. print("正在根据描述生成嘉宾角色...")
  99. content = run_simple_agent("PersonaGeneratorAgent", messages[0]["content"], messages[1]["content"])
  100. if content:
  101. personas = parse_json_from_response(content)
  102. if personas and isinstance(personas, list):
  103. print(f"成功生成 {len(personas)} 位嘉宾。")
  104. return personas
  105. else:
  106. print("生成角色失败:格式错误。")
  107. return []
  108. else:
  109. print("生成角色失败:API 无响应。")
  110. return []