206 lines
6.9 KiB
Python
206 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
提示词API路由
|
||
"""
|
||
|
||
import logging
|
||
from typing import Dict, Any, Optional
|
||
from fastapi import APIRouter, Depends, HTTPException
|
||
from pydantic import BaseModel, Field
|
||
|
||
from api.services.prompt_service import PromptService
|
||
from api.services.prompt_builder import PromptBuilderService
|
||
from api.dependencies import get_config, get_tweet_service
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 创建路由
|
||
router = APIRouter(
|
||
tags=["prompt"],
|
||
responses={404: {"description": "Not found"}},
|
||
)
|
||
|
||
# 依赖注入函数
|
||
def get_prompt_service():
|
||
"""获取提示词服务"""
|
||
from core.config import get_config_manager
|
||
return PromptService(get_config_manager())
|
||
|
||
def get_prompt_builder():
|
||
"""获取提示词构建器服务"""
|
||
from core.config import get_config_manager
|
||
config_manager = get_config_manager()
|
||
prompt_service = PromptService(config_manager)
|
||
return PromptBuilderService(config_manager, prompt_service)
|
||
|
||
|
||
# 请求和响应模型
|
||
class PromptRequest(BaseModel):
|
||
"""提示词请求模型"""
|
||
style: str = Field(..., description="内容风格")
|
||
audience: str = Field(..., description="目标受众")
|
||
|
||
class Config:
|
||
schema_extra = {
|
||
"example": {
|
||
"style": "攻略风",
|
||
"audience": "亲子向"
|
||
}
|
||
}
|
||
|
||
|
||
class PromptResponse(BaseModel):
|
||
"""提示词响应模型"""
|
||
style_content: str = Field(..., description="风格提示词")
|
||
audience_content: str = Field(..., description="受众提示词")
|
||
|
||
class Config:
|
||
schema_extra = {
|
||
"example": {
|
||
"style_content": "以实用信息为主,包含详细的游玩路线...",
|
||
"audience_content": "家庭出游,有小孩同行,关注安全性..."
|
||
}
|
||
}
|
||
|
||
|
||
class PromptBuilderRequest(BaseModel):
|
||
"""提示词构建器请求模型"""
|
||
topic: Dict[str, Any] = Field(..., description="选题信息")
|
||
step: Optional[str] = Field(None, description="步骤,如topic、content、judge等")
|
||
|
||
class Config:
|
||
schema_extra = {
|
||
"example": {
|
||
"topic": {
|
||
"index": "1",
|
||
"date": "2023-07-15",
|
||
"object": "北京故宫",
|
||
"product": "故宫门票",
|
||
"style": "攻略风",
|
||
"targetAudience": "亲子向",
|
||
"logic": "暑期旅游热门景点推荐"
|
||
},
|
||
"step": "content"
|
||
}
|
||
}
|
||
|
||
|
||
class PromptBuilderResponse(BaseModel):
|
||
"""提示词构建器响应模型"""
|
||
system_prompt: str = Field(..., description="系统提示词")
|
||
user_prompt: str = Field(..., description="用户提示词")
|
||
|
||
class Config:
|
||
schema_extra = {
|
||
"example": {
|
||
"system_prompt": "你是一位专业的旅游内容创作者...",
|
||
"user_prompt": "请为北京故宫创作一篇旅游攻略..."
|
||
}
|
||
}
|
||
|
||
|
||
class GenerateContentResponse(BaseModel):
|
||
"""生成内容响应模型"""
|
||
request_id: str = Field(..., description="请求ID")
|
||
topic_index: str = Field(..., description="选题索引")
|
||
content: Dict[str, Any] = Field(..., description="生成的内容")
|
||
|
||
class Config:
|
||
schema_extra = {
|
||
"example": {
|
||
"request_id": "content-20240715-123456-a1b2c3d4",
|
||
"topic_index": "1",
|
||
"content": {
|
||
"title": "【北京故宫】避开人潮的秘密路线,90%的人都不知道!",
|
||
"content": "故宫,作为中国最著名的文化遗产之一...",
|
||
"tag": ["北京旅游", "故宫", "旅游攻略", "避暑胜地"]
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
@router.post("/get-style-audience", response_model=PromptResponse)
|
||
async def get_style_audience(
|
||
request: PromptRequest,
|
||
prompt_service: PromptService = Depends(get_prompt_service)
|
||
):
|
||
"""获取风格和受众提示词"""
|
||
try:
|
||
style_content = prompt_service.get_style_content(request.style)
|
||
audience_content = prompt_service.get_audience_content(request.audience)
|
||
|
||
return PromptResponse(
|
||
style_content=style_content,
|
||
audience_content=audience_content
|
||
)
|
||
except Exception as e:
|
||
logger.error(f"获取提示词失败: {e}")
|
||
raise HTTPException(status_code=500, detail=f"获取提示词失败: {str(e)}")
|
||
|
||
|
||
@router.post("/build-prompt", response_model=PromptBuilderResponse)
|
||
async def build_prompt(
|
||
request: PromptBuilderRequest,
|
||
prompt_builder: PromptBuilderService = Depends(get_prompt_builder)
|
||
):
|
||
"""构建完整提示词"""
|
||
try:
|
||
# 根据请求中的step确定构建哪种类型的提示词
|
||
step = request.step or "content"
|
||
|
||
if step == "topic":
|
||
# 构建选题提示词
|
||
# 从topic中提取必要的参数
|
||
numTopics = request.topic.get("numTopics", 5)
|
||
month = request.topic.get("month", "7")
|
||
system_prompt, user_prompt = prompt_builder.build_topic_prompt(
|
||
dates=month,
|
||
numTopics=numTopics
|
||
)
|
||
elif step == "judge":
|
||
# 构建审核提示词
|
||
# 需要提供生成的内容
|
||
content = request.topic.get("content", {})
|
||
system_prompt, user_prompt = prompt_builder.build_judge_prompt(request.topic, content)
|
||
else:
|
||
# 默认构建内容生成提示词
|
||
system_prompt, user_prompt = prompt_builder.build_content_prompt(request.topic, step)
|
||
|
||
return PromptBuilderResponse(
|
||
system_prompt=system_prompt,
|
||
user_prompt=user_prompt
|
||
)
|
||
except Exception as e:
|
||
logger.error(f"构建提示词失败: {e}")
|
||
raise HTTPException(status_code=500, detail=f"构建提示词失败: {str(e)}")
|
||
|
||
|
||
@router.post("/generate-content", response_model=GenerateContentResponse)
|
||
async def generate_content(
|
||
request: PromptBuilderRequest,
|
||
prompt_builder: PromptBuilderService = Depends(get_prompt_builder),
|
||
tweet_service = Depends(get_tweet_service)
|
||
):
|
||
"""使用构建的提示词生成内容"""
|
||
try:
|
||
# 构建提示词
|
||
step = request.step or "content"
|
||
system_prompt, user_prompt = prompt_builder.build_content_prompt(request.topic, step)
|
||
|
||
# 使用提示词生成内容
|
||
request_id, topic_index, content = await tweet_service.generate_content_with_prompt(
|
||
topic=request.topic,
|
||
system_prompt=system_prompt,
|
||
user_prompt=user_prompt
|
||
)
|
||
|
||
return GenerateContentResponse(
|
||
request_id=request_id,
|
||
topic_index=topic_index,
|
||
content=content
|
||
)
|
||
except Exception as e:
|
||
logger.error(f"生成内容失败: {e}")
|
||
raise HTTPException(status_code=500, detail=f"生成内容失败: {str(e)}") |