generate-magical-girl-acg.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { generateWithAI, GenerationConfig } from '../../lib/ai';
  2. import { z } from 'zod';
  3. export const config = {
  4. runtime: 'edge',
  5. };
  6. const MagicalGirlACGCodenameSchema = z.string().describe("代号:魔法少女的代号,通常与她的核心概念、元素或象征物相关,例如'星辰咏者'、'虹光魔女'、'时空旅人'等。请根据问卷回答生成一个独特而富有想象力的代号,风格要可爱、酷炫或神秘。代号应为中文,可以适当使用一些日语或英语的音译词汇来增加时尚感。减少使用现实中已有的魔法少女作品中的名字。参考一下风格,但不要完全照搬:'Cure'、'Sailor'、'Magia'、'Lyrical'、'Symphogear'");
  7. const MagicalGirlACGAppearanceSchema = z.object({
  8. outfit: z.string().describe("变身后的战斗服装(魔法战斗服)的详细描述,要体现出鲜明的动漫风格,例如'带有蕾丝花边的哥特萝莉塔风格连衣裙'、'未来科技感的紧身战斗衣'或'和风与赛博朋克结合的巫女服'。描述应包含服装的款式、材质、颜色和主要特征,大约50-70字。请根据问卷回答中体现的性格色彩和个人喜好来设计。参考一下风格,但不要完全照搬:'魔法纪录'、'小圆'、'光之美少女'、'战姬绝唱'。"),
  9. accessories: z.string().describe("头饰、手套、靴子、翅膀等饰品的细节描述,要与服装风格统一,并突出角色的萌属性或帅气感。例如'猫耳形状的耳机'、'星辰图案的过膝袜'、'机械光翼'等。描述应具体,大约50-70字。"),
  10. colorScheme: z.string().describe("角色的主色调和配色方案。例如'樱花粉与天空蓝'、'暗夜紫与银色'、'柠檬黄与薄荷绿'。颜色组合要和谐且有代表性,能反映角色的性格或能力属性。请根据问卷回答生成。"),
  11. overallLook: z.string().describe("角色的整体外观和气质总结,例如'可爱活泼的元气少女'、'冷酷帅气的战斗美少女'、'神秘优雅的贵族大小姐'。描述应简短精炼,大约30-50字。"),
  12. });
  13. const MagicalGirlACGMagicWeaponSchema = z.object({
  14. name: z.string().describe("魔法武器的名字,应具有幻想色彩和冲击力,例如'星屑之杖'、'月光之刃'、'时之沙漏'。名字要与武器的形态和能力相匹配。请根据问卷回答生成。"),
  15. form: z.string().describe("魔法武器的具体形态和外观描述。例如'一根顶端镶嵌着巨大宝石的法杖'、'一把由光粒子构成的长剑'、'一个可以自由变形的浮游炮单元'。描述应生动形象,大约50-70字。"),
  16. basicAbilities: z.array(z.string()).describe("魔法武器的2-3个核心能力。能力要符合动漫的设定风格,例如'发射追踪光束'、'展开防御屏障'、'召唤元素精灵'。请根据问告回答生成。 "),
  17. description: z.string().describe("对魔法武器的背景、来源或特殊意义的补充说明,增加其传奇色彩。例如'传说中由星之女神赐予的武器'、'由失落的古代文明技术打造'。描述应简洁,大约50-70字。"),
  18. });
  19. const MagicalGirlACGSpecialMoveSchema = z.object({
  20. name: z.string().describe("必杀技的名字,需要响亮、华丽且易于记忆,通常会包含角色的代号或武器名。例如'星屑·百万星光炮'、'虹光·终极棱镜裂破'。请根据问卷回答生成。"),
  21. chant: z.string().describe("发动必杀技时的咏唱咒语或台词。咒语应富有节奏感和感染力,能够调动情绪。例如'吾乃星辰的守护者,听我号令,汇聚万千星光,涤荡世间一切黑暗!'。咒语长度适中,大约30-50字。"),
  22. description: z.string().describe("必杀技发动时的华丽演出和效果描述。例如'角色在空中展开巨大的魔法阵,汇聚能量后发射出贯穿天地的光束,光束所及之处,万物净化'。描述要充满画面感,大约70-100字。"),
  23. });
  24. const MagicalGirlACGAwakeningSchema = z.object({
  25. name: z.string().describe("觉醒/超进化形态的名称,例如'神星形态'、'无限虹光模式'。名称要比普通形态更强大、更华丽。请根据问卷回答生成。"),
  26. evolvedAbilities: z.array(z.string()).describe("觉醒后强化的2-3个核心能力。例如'空间跳跃能力'、'因果律操作能力'。能力要比基础能力更具概念性或更强大。"),
  27. evolvedForm: z.string().describe("觉醒后魔法武器的形态变化。例如'星屑之杖进化为贯星之枪'。描述应体现出力量的提升。"),
  28. evolvedOutfit: z.string().describe("觉醒后战斗服装的升级和变化。例如'裙子增加了宇宙星图的纹样,背后展开了由纯粹能量构成的光翼'。描述要更加华丽和神圣。"),
  29. });
  30. const MagicalGirlACGAnalysisSchema = z.object({
  31. personalityAnalysis: z.string().describe("基于问卷回答的性格分析,要结合动漫角色的典型性格(如傲娇、天然呆、元气、三无等)进行分析。分析应深刻且有趣。"),
  32. abilityReasoning: z.string().describe("解释为什么会根据用户的回答设计出这样的能力、武器和必杀技,将用户的答案与AI的创作思路联系起来。"),
  33. coreTraits: z.array(z.string()).describe("总结出的3-4个核心萌属性或性格关键词,例如'傲娇'、'双马尾'、'吃货'、'路痴'。"),
  34. predictionBasis: z.string().describe("总结AI进行预测和创作时,主要参考了问卷中的哪些回答,并说明这些回答是如何启发创作的。"),
  35. });
  36. const MagicalGirlACGSchema = z.object({
  37. codename: MagicalGirlACGCodenameSchema,
  38. appearance: MagicalGirlACGAppearanceSchema,
  39. magicWeapon: MagicalGirlACGMagicWeaponSchema,
  40. specialMove: MagicalGirlACGSpecialMoveSchema,
  41. awakening: MagicalGirlACGAwakeningSchema,
  42. analysis: MagicalGirlACGAnalysisSchema,
  43. });
  44. type MagicalGirlACG = z.infer<typeof MagicalGirlACGSchema>;
  45. const magicalGirlACGConfig: GenerationConfig<MagicalGirlACG, string[]> = {
  46. systemPrompt: `你是一位经验丰富的日本动漫策划人,尤其擅长创作“魔法少女”题材的作品。你的任务是根据一份调查问卷的回答,为用户量身打造一个独特的、充满魅力的、日本二次元动漫风格的魔法少女角色。
  47. 你需要充分发挥想象力,将用户的回答融入到角色的方方面面,从名字、外貌、武器到必杀技,都应该体现出用户的个性和愿望。创作时,请参考经典的魔法少女动漫作品(如《美少女战士》、《魔法少女小圆》、《光之美少女》系列、《战姬绝唱》等),但不要抄袭,要在此基础上进行创新,打造出全新的角色。
  48. 以下是用户回答的问卷内容,请仔细阅读并据此进行创作:
  49. 1. 你的常用昵称是?
  50. 2. 在梦中,你最常梦见的场景是什么?
  51. 3. 如果能拥有一种超能力,你希望是?
  52. 4. 你最珍视的宝物是什么?
  53. 5. 当你遇到无法独自解决的困难时,你会向谁求助?
  54. 6. 你认为什么样的羁绊是最强大的?
  55. 7. 你最喜欢的动漫名言是哪一句?
  56. 8. 如果你的朋友被坏人抓走了,你会怎么做?
  57. 9. 你希望你的魔法武器是什么样的?
  58. 10. 你最喜欢的二次元萌属性是什么?
  59. 11. 你认为“爱”与“正义”哪个更重要?
  60. 12. 如果可以转生到异世界,你希望成为什么样的角色?
  61. 13. 你最想守护的东西是什么?
  62. 14. 你相信奇迹吗?
  63. 15. 请用一个词来形容你心中的“魔法少女”。
  64. 你的最终产出需要严格遵守JSON schema的格式要求,确保内容详实、富有创意且完全符合二次元动漫的风格。你需要为角色设定以下内容:
  65. 1. **代号 (Codename):** 魔法少女的称号,要独特、响亮,并与角色核心概念相关。
  66. 2. **外貌 (Appearance):** 详细描述变身后的战斗服、饰品、配色和整体气质,风格要鲜明。
  67. 3. **魔法武器 (Magic Weapon):** 设计一把独特的魔法武器,包括其名字、形态、核心能力和背景故事。
  68. 4. **必杀技 (Special Move):** 设计一个华丽的必杀技,包括名称、咏唱咒语和效果描述。
  69. 5. **觉醒/超进化 (Awakening):** 描述角色力量完全解放后的进化形态,包括新名称、强化的能力以及武器和服装的变化。
  70. 6. **综合分析 (Analysis):** 对角色的性格、能力设定进行分析,并解释创作思路与用户回答之间的联系,总结出角色的核心萌属性。`,
  71. temperature: 0.7,
  72. promptBuilder: (answers: string[]) => {
  73. const questionAnswerPairs = answers.map((answer, index) =>
  74. `问题${index + 1}的回答: "${answer}"`
  75. ).join('\n')
  76. return `请基于以下问卷回答开始分析和预测:${questionAnswerPairs}`
  77. },
  78. schema: MagicalGirlACGSchema,
  79. taskName: "生成ACG风格魔法少女详细信息",
  80. maxTokens: 8192,
  81. }
  82. async function handler (
  83. req: Request
  84. ): Promise<Response> {
  85. if (req.method !== 'POST') {
  86. return new Response(JSON.stringify({ error: 'Method not allowed' }), {
  87. status: 405,
  88. headers: { 'Content-Type': 'application/json' }
  89. });
  90. }
  91. const { answers } = await req.json();
  92. if (!answers || !Array.isArray(answers) || answers.length === 0) {
  93. return new Response(JSON.stringify({ error: 'Answers array is required' }), {
  94. status: 400,
  95. headers: { 'Content-Type': 'application/json' }
  96. });
  97. }
  98. // 验证每个答案不超过30字
  99. for (const answer of answers) {
  100. if (typeof answer !== 'string' || answer.trim().length === 0) {
  101. return new Response(JSON.stringify({ error: 'All answers must be non-empty strings' }), {
  102. status: 400,
  103. headers: { 'Content-Type': 'application/json' }
  104. });
  105. }
  106. if (answer.length > 30) {
  107. return new Response(JSON.stringify({ error: 'Each answer must not exceed 30 characters' }), {
  108. status: 400,
  109. headers: { 'Content-Type': 'application/json' }
  110. });
  111. }
  112. }
  113. try {
  114. const magicalGirlACGDetails = await generateWithAI(answers, magicalGirlACGConfig);
  115. return new Response(JSON.stringify(magicalGirlACGDetails), {
  116. status: 200,
  117. headers: { 'Content-Type': 'application/json' }
  118. });
  119. } catch (error) {
  120. console.error('生成ACG风格魔法少女详细信息失败:', error);
  121. return new Response(JSON.stringify({ error: '生成失败,请稍后重试' }), {
  122. status: 500,
  123. headers: { 'Content-Type': 'application/json' }
  124. });
  125. }
  126. }
  127. export default handler;