From 8f9f7824cdf30a57697ce90772090c42b8b7cc24 Mon Sep 17 00:00:00 2001 From: repair-agent Date: Mon, 2 Mar 2026 15:42:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=81=E9=9D=A2=E5=9B=BE=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E8=AF=8D=E6=94=B9=E4=B8=BA=E7=94=A8=20LLM=20=E4=BB=8E?= =?UTF-8?q?=E6=95=85=E4=BA=8B=E5=86=85=E5=AE=B9=E6=8F=90=E7=82=BC=20?= =?UTF-8?q?=E2=89=A450=20=E5=AD=97=E7=94=BB=E9=9D=A2=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 _extract_image_description:调用豆包 LLM 提取故事的主体、 场景与核心事件,串联成一幅画的描述(≤50字),再拼接风格前缀后 送入 Seedream 4.5 文生图模型,生成更贴合故事内容的封面。 Co-Authored-By: Claude Sonnet 4.6 --- apps/stories/services/llm_service.py | 55 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/apps/stories/services/llm_service.py b/apps/stories/services/llm_service.py index c165914..71a1cd4 100644 --- a/apps/stories/services/llm_service.py +++ b/apps/stories/services/llm_service.py @@ -132,7 +132,7 @@ def generate_story_stream(characters, scenes, props): cover_url = '' try: cover_url = _generate_and_upload_cover( - result['title'], characters, scenes, props, config + result['title'], result['content'], config ) except Exception as cover_err: logger.warning(f'Cover generation failed (non-fatal): {cover_err}') @@ -173,7 +173,32 @@ def _parse_story_json(text): } -def _generate_and_upload_cover(title, characters, scenes, props, config): +def _extract_image_description(title, content, client, model_name): + """ + 用 LLM 从故事内容中提炼 ≤50 字的画面描述:主体 + 场景 + 事件。 + 返回纯文本描述字符串。 + """ + system = ( + "你是图像提示词专家。从给定的儿童故事中,提取主体、场景与核心事件," + "串联成一幅画的中文描述。要求:\n" + "1. 不超过50个汉字\n" + "2. 只输出描述本身,不加任何解释、前缀或多余标点\n" + "3. 描述需具体生动,适合儿童绘本插画" + ) + user = f"故事标题:{title}\n故事内容:{content[:800]}" + resp = client.chat.completions.create( + model=model_name, + messages=[ + {'role': 'system', 'content': system}, + {'role': 'user', 'content': user}, + ], + max_tokens=80, + stream=False, + ) + return resp.choices[0].message.content.strip() + + +def _generate_and_upload_cover(title, content, config): """ 使用豆包文生图模型生成故事封面,上传到 OSS 并返回 URL。 失败时抛出异常(由调用方捕获,不影响主流程)。 @@ -184,24 +209,18 @@ def _generate_and_upload_cover(title, characters, scenes, props, config): from django.conf import settings from volcenginesdkarkruntime import Ark - # Build a concise Chinese image prompt - elements = [] - if characters: - elements.append('、'.join(characters)) - if scenes: - elements.append('、'.join(scenes)) - if props: - elements.append('、'.join(props)) - - element_str = ','.join(elements) if elements else title - image_prompt = ( - f"儿童绘本封面插画,{title},{element_str}," - "卡通可爱风格,色彩明亮鲜艳,温馨有趣,适合3-8岁儿童,高质量插画" - ) - client = Ark(api_key=config['API_KEY']) + + # 用 LLM 从故事内容提炼 ≤50 字画面描述 + scene_desc = _extract_image_description( + title, content, client, config['MODEL_NAME'] + ) + logger.info(f'Cover image description: {scene_desc}') + + image_prompt = f"儿童绘本封面插画,{scene_desc},卡通可爱风格,色彩明亮鲜艳,高质量插画" + image_model = config.get('IMAGE_MODEL_NAME', 'doubao-seedream-4-5-251128') - image_size = config.get('IMAGE_SIZE', '1920x1920') + image_size = config.get('IMAGE_SIZE', '2560x1440') result = client.images.generate( model=image_model,