feat: 大小标题支持智能生成

后端:
- 新增 POST /script/generate-title API
- 新增提示词模板 title_system.txt / title.txt(文件管理)
- 根据脚本内容调用 LLM 生成大标题(≤8字)/小标题(≤30字)

前端:
- 大标题/小标题输入框右侧新增【智能生成】按钮
- 点击后根据 utterances 拼接脚本内容调用 API
- 添加 title-input-row / title-generate-btn CSS 样式
This commit is contained in:
小鱼开发
2026-04-30 12:09:56 +08:00
parent de0fb0949c
commit 475758beed
7 changed files with 218 additions and 17 deletions
+64 -1
View File
@@ -15,10 +15,13 @@ from fastapi import APIRouter, Request
from fastapi.responses import StreamingResponse
from app.schemas.common import ApiResponse, success_response
from app.ai.prompts import list_categories
from app.ai.model_router import get_model_router
from app.ai.prompts import list_categories, load_prompt, render_template
from app.schemas.script import (
CategoryItem,
GenerateScriptRequest,
GenerateTitleRequest,
GenerateTitleResponse,
ModelHealthResponse,
PolishRequest,
ScriptGenerationEvent,
@@ -202,3 +205,63 @@ async def test_model(request: TestModelRequest):
data=TestModelResponse(**result),
message="模型测试完成" if result["success"] else f"模型测试失败: {result.get('error')}",
)
@router.post("/generate-title", response_model=ApiResponse[GenerateTitleResponse])
async def generate_title(request: GenerateTitleRequest):
"""
根据脚本内容智能生成标题
调用 LLM 根据脚本内容生成大标题或小标题。
提示词从文件加载,支持热更新。
"""
model_router = await get_model_router()
# 加载提示词
system_prompt = load_prompt("user/title_system")
user_template = load_prompt("user/title")
if not system_prompt or not user_template:
return success_response(
code=500,
message="标题生成提示词文件缺失",
data=None,
)
# 渲染用户提示词
title_type_desc = "大标题(主标题,提炼核心卖点,吸睛)" if request.title_type == "main" else "小标题(副标题,补充说明或制造悬念)"
user_prompt = render_template(
user_template,
title_type=request.title_type,
title_type_desc=title_type_desc,
script_content=request.script_content,
max_length=request.max_length,
)
try:
result = await model_router.generate(
prompt=user_prompt,
system_prompt=system_prompt,
task_type="script",
temperature=0.8,
max_tokens=64,
)
title = result.content.strip() if result.content else ""
# 去除可能的引号
title = title.strip('"').strip("'").strip('「」').strip('『』').strip('《》')
# 截断到最大长度
if len(title) > request.max_length:
title = title[:request.max_length]
return success_response(
data=GenerateTitleResponse(title=title),
message="标题生成成功",
)
except Exception as e:
logger.error(f"[generate_title] 标题生成失败: {e}")
return success_response(
code=500,
message=f"标题生成失败: {str(e)}",
data=None,
)