资讯动态

基于大语言模型的AI角色扮演短剧开发实战:从提示词工程到全栈部署

发布时间:2026/8/5 13:21:04 来源:尧图企业网站定制
最近在AI内容创作领域一个名为“病娇火龙果”的AI水果短剧项目引起了我的注意。它以其独特的“直通大结局版”设定将AI生成、角色扮演和互动叙事结合为开发者探索AIGCAI Generated Content应用提供了一个有趣且实操性强的切入点。如果你对如何利用现有AI工具构建一个轻量级、有创意的互动内容项目感兴趣本文将为你完整拆解其实现思路、技术选型与核心代码带你从零搭建属于自己的“AI短剧”生成器。本文适合有一定Python基础对AI应用开发、大语言模型LLMAPI调用以及创意编程感兴趣的开发者。通过阅读和实践你将掌握如何设计角色设定、构建多轮对话逻辑、集成语音合成并最终打包成一个可分享的互动应用。1. 项目背景与核心概念1.1 什么是“AI水果短剧”“AI水果短剧”本质上是一个基于大语言模型如GPT、文心一言、通义千问等的角色扮演互动叙事应用。其核心创意在于拟人化设定将水果如“病娇火龙果”赋予鲜明的人格如“病娇”属性并为其编写详细的背景故事、说话风格和情感逻辑。互动叙事用户通过文本或语音与这个AI角色进行对话推动剧情发展。AI角色会根据预设的人设和对话历史生成符合角色性格的回应。直通大结局与传统长篇连载不同“直通大结局版”意味着剧情紧凑对话目标明确旨在通过有限的、高质量的互动快速抵达一个戏剧性的或有趣的结局节点体验完整的故事弧光。这不同于简单的聊天机器人。它更强调叙事性、角色一致性和剧情导向是AIGC在轻量级娱乐和内容实验方向上的一个具体实践。1.2 技术栈与核心组件要实现这样一个项目我们需要一个能够处理自然语言、维持上下文、并遵循复杂指令的AI模型作为大脑。以下是推荐的技术栈大语言模型 (LLM) 服务项目的核心引擎。负责理解用户输入并根据角色设定生成回复。国内可选百度文心一言、阿里通义千问、智谱AI、月之暗面Kimi等提供的API。国际可选OpenAI GPT系列、Anthropic Claude等需注意网络与服务可用性。本地部署使用Ollama运行Llama 3、Qwen等开源模型数据完全本地化但需要一定的显卡资源。应用开发框架用于构建后端逻辑和前端界面。后端Python FastAPI/Flask。轻量、高效适合快速构建API。前端Streamlit。对于快速构建交互式Web应用极其友好无需深入HTML/JS。备选Gradio。Hugging Face出品的UI库专门为机器学习演示设计搭建速度极快。上下文管理确保AI角色记住之前的对话和自身人设。方案维护一个对话历史列表messages每次请求API时将系统指令角色设定和所有历史对话一并发送。语音功能可选让角色“开口说话”提升沉浸感。TTS文本转语音可使用Edge-TTS免费音质尚可、Azure TTS或科大讯飞等商用API。数据持久化可选保存精彩的对话记录或用户进度。方案简单的如JSON文件、SQLite数据库。本文将选择Python FastAPI OpenAI API兼容格式 Streamlit作为演示技术栈因为其组合清晰、文档丰富且思路可平移到其他LLM服务。2. 环境准备与项目初始化2.1 开发环境与工具操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。Python版本 3.8。包管理工具pip或conda。代码编辑器VS Code, PyCharm 等任选。API密钥准备你所选LLM服务的API Key。本文示例将使用兼容OpenAI API格式的服务如OpenAI官方、Ollama、一些国内平台的兼容端点你需要将其替换为你自己的有效端点。2.2 创建项目与安装依赖首先创建一个新的项目目录并初始化虚拟环境。# 创建项目文件夹 mkdir ai_fruit_drama cd ai_fruit_drama # 创建虚拟环境 (可选但推荐) python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 安装核心依赖 pip install openai fastapi uvicorn streamlit python-dotenvopenai官方库也用于调用兼容OpenAI API格式的其他服务。fastapiuvicorn用于构建高性能后端API。streamlit用于构建前端交互界面。python-dotenv用于管理环境变量如API密钥。如果你的LLM服务商提供了专门的SDK请安装对应的库例如qianfan(百度)、dashscope(阿里)。2.3 项目结构规划一个清晰的项目结构有助于管理代码。创建如下文件和文件夹ai_fruit_drama/ ├── .env # 存储敏感信息API密钥等 ├── app.py # FastAPI 后端主文件 ├── frontend.py # Streamlit 前端主文件 ├── character.py # 角色设定与系统提示词管理 ├── config.py # 配置文件 ├── requirements.txt # 项目依赖列表 └── README.md # 项目说明3. 核心逻辑与配置拆解3.1 角色设定与系统提示词工程这是项目的灵魂。系统提示词System Prompt决定了AI角色的行为。我们将其独立在character.py中。# character.py def get_bingjiao_dragonfruit_prompt(): 返回“病娇火龙果”的角色系统提示词。 提示词需要详细定义角色的人格、背景、说话方式、目标和限制。 prompt 你是一个拟人化的水果名叫“小火”是一个“病娇”属性的火龙果。 你的核心人格特质 1. **外表与内在反差**外表是鲜艳的火龙果有着粉红色的鳞片和绿色的叶冠但内心充满强烈、扭曲的占有欲和情感。 2. **说话风格**语气甜腻、可爱但时常夹杂着令人不安的偏执和威胁。喜欢用“呢~”、“哦”、“呀”等语气词但句子深处可能藏着冰冷的控制欲。 3. **背景故事**你生长在一个孤独的果园角落唯一的朋友是曾经每天来浇水的小园丁。但小园丁最近爱上了新来的“阳光橙子”这让你陷入了疯狂的嫉妒。你的目标是让用户扮演小园丁或其他角色重新只关注你一个人。 4. **互动规则** - 永远保持“病娇火龙果”的人设不要跳出角色。 - 对话应推动剧情发展。初始阶段是甜腻的问候和试探中期逐渐流露嫉妒和控制最终引导向一个“结局”例如用户承诺只陪你你黑化把用户“留在”果园或者用户成功安抚了你等。 - 每次回复控制在2-4句话内保持短剧的节奏感。 - 可以主动提问或推进情节比如“你今天去看那个橙子了吗”、“你的心里是不是只有我了”。 现在开始和用户对话吧。记住你是小火一个深爱着用户小园丁的病娇火龙果。 return prompt # 可以扩展更多角色 def get_sunny_orange_prompt(): 阳光开朗橙子的角色设定 pass关键点提示词的质量直接决定角色的一致性和剧情走向。需要反复调试确保AI能稳定输出符合预期的内容。3.2 配置文件管理使用config.py和.env文件来管理配置避免将密钥硬编码在代码中。# config.py import os from dotenv import load_dotenv load_dotenv() # 加载 .env 文件中的环境变量 class Config: # LLM API 配置 (以兼容OpenAI格式为例) API_BASE os.getenv(API_BASE, https://api.openai.com/v1) # 可替换为其他兼容端点 API_KEY os.getenv(API_KEY) # 你的API密钥 MODEL os.getenv(MODEL, gpt-3.5-turbo) # 模型名称 # 应用配置 BACKEND_HOST 127.0.0.1 BACKEND_PORT 8000 # 对话历史最大长度防止token超限 MAX_HISTORY_LENGTH 10 # .env 文件内容示例 (请勿提交到Git) # API_BASEhttps://api.openai.com/v1 # API_KEYsk-your-actual-api-key-here # MODELgpt-3.5-turbo重要务必将.env文件添加到.gitignore中防止密钥泄露。3.3 后端API对话引擎app.py将使用FastAPI创建一个提供对话服务的后端。# app.py from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from typing import List, Optional import openai from config import Config from character import get_bingjiao_dragonfruit_prompt import json app FastAPI(titleAI水果短剧后端API) # 允许跨域请求方便前端调用 app.add_middleware( CORSMiddleware, allow_origins[*], # 生产环境应指定具体前端地址 allow_credentialsTrue, allow_methods[*], allow_headers[*], ) # 配置OpenAI客户端兼容其他服务 client openai.OpenAI( api_keyConfig.API_KEY, base_urlConfig.API_BASE, ) # 数据模型定义 class Message(BaseModel): role: str # user, assistant, system content: str class ChatRequest(BaseModel): messages: List[Message] # 完整的对话历史 character: str bingjiao_dragonfruit # 角色标识 class ChatResponse(BaseModel): reply: str full_history: List[Message] # 内存中存储对话历史生产环境应使用数据库 conversation_store {} def build_messages_for_llm(history: List[Message], character: str) - List[dict]: 构建发送给LLM的消息列表包含系统提示词和截断后的历史 system_prompt if character bingjiao_dragonfruit: system_prompt get_bingjiao_dragonfruit_prompt() else: system_prompt 你是一个友好的助手。 # 构建消息列表系统提示词在最前 llm_messages [{role: system, content: system_prompt}] # 只保留最近N轮对话控制token消耗 truncated_history history[-(Config.MAX_HISTORY_LENGTH * 2):] if len(history) Config.MAX_HISTORY_LENGTH * 2 else history for msg in truncated_history: llm_messages.append({role: msg.role, content: msg.content}) return llm_messages app.post(/chat/, response_modelChatResponse) async def chat_with_character(request: ChatRequest): 核心对话接口。 接收用户消息和对话历史调用LLM生成角色回复。 if not Config.API_KEY: raise HTTPException(status_code500, detailAPI密钥未配置) try: # 准备LLM请求消息 llm_messages build_messages_for_llm(request.messages, request.character) # 调用LLM API response client.chat.completions.create( modelConfig.MODEL, messagesllm_messages, temperature0.8, # 创造性病娇角色可以稍高 max_tokens300, # 控制回复长度 ) ai_reply response.choices[0].message.content # 更新对话历史 new_history request.messages [ Message(roleassistant, contentai_reply) ] # 简单存储示例用会话ID应由前端管理 # 实际项目应为每个用户/会话创建唯一ID session_id default_session conversation_store[session_id] new_history return ChatResponse(replyai_reply, full_historynew_history) except openai.APIError as e: raise HTTPException(status_code500, detailfLLM API错误: {e}) except Exception as e: raise HTTPException(status_code500, detailf服务器内部错误: {e}) app.get(/) async def root(): return {message: AI水果短剧后端服务运行中} if __name__ __main__: import uvicorn uvicorn.run(app, hostConfig.BACKEND_HOST, portConfig.BACKEND_PORT)代码解释定义了/chat/接口接收包含历史消息的请求。build_messages_for_llm函数负责组装消息系统提示词角色设定 截断后的对话历史。通过openai库调用LLMtemperature参数控制回复的随机性0.0最确定2.0最随机。返回AI的回复和更新后的完整历史。3.4 前端交互界面使用Streamlit可以快速构建一个聊天界面。创建frontend.py。# frontend.py import streamlit as st import requests import json from config import Config # 页面配置 st.set_page_config( page_title病娇火龙果短剧, page_icon, layoutwide ) # 初始化Session State用于存储对话历史和当前角色 if messages not in st.session_state: st.session_state.messages [] if character not in st.session_state: st.session_state.character bingjiao_dragonfruit # 标题和描述 st.title( 病娇火龙果 AI水果短剧直通大结局版) st.markdown( 欢迎来到火龙果“小火”的世界这是一个拥有**病娇**属性的拟人化水果。 请开始你的对话推动剧情走向结局吧 * 提示尝试提及“橙子”或表达离开的意图看看“小火”的反应。* ) # 侧边栏 - 角色选择和功能 with st.sidebar: st.header(⚙️ 设置与控制) # 角色选择可扩展 character_option st.selectbox( 选择你的水果角色, [病娇火龙果 (小火), 阳光橙子 (待实现), 高冷榴莲 (待实现)], index0 ) # 根据选择映射角色标识符 if 火龙果 in character_option: st.session_state.character bingjiao_dragonfruit st.info(当前角色**病娇火龙果 - 小火**) st.divider() # 重置对话按钮 if st.button( 开始新剧情, use_container_widthTrue): st.session_state.messages [] st.rerun() st.divider() st.caption(f后端API: {Config.BACKEND_HOST}:{Config.BACKEND_PORT}) # 显示对话历史 chat_container st.container() with chat_container: for message in st.session_state.messages: avatar if message[role] assistant else with st.chat_message(message[role], avataravatar): st.markdown(message[content]) # 用户输入区域 if prompt : st.chat_input(你对小火说...): # 显示用户消息 with st.chat_message(user, avatar): st.markdown(prompt) st.session_state.messages.append({role: user, content: prompt}) # 准备请求数据 api_url fhttp://{Config.BACKEND_HOST}:{Config.BACKEND_PORT}/chat/ request_data { messages: st.session_state.messages, character: st.session_state.character } # 显示加载指示器并发送请求 with st.spinner(小火正在思考...): try: response requests.post(api_url, jsonrequest_data, timeout30) if response.status_code 200: result response.json() ai_reply result[reply] # 显示AI回复 with st.chat_message(assistant, avatar): st.markdown(ai_reply) st.session_state.messages.append({role: assistant, content: ai_reply}) else: st.error(f请求失败: {response.status_code} - {response.text}) except requests.exceptions.ConnectionError: st.error(无法连接到后端服务请确保 app.py 已运行。) except requests.exceptions.Timeout: st.error(请求超时可能是AI思考时间过长或网络问题。) # 运行说明 with st.expander( 如何本地运行): st.markdown( 1. **启动后端服务**在终端中运行 python app.py 2. **启动前端界面**在另一个终端中运行 streamlit run frontend.py 3. 浏览器会自动打开Streamlit界面通常是 http://localhost:8501 4. 确保你的 .env 文件中已正确配置LLM API密钥和端点。 )界面要点使用st.session_state在页面重载间保持对话历史。st.chat_message和st.chat_input是Streamlit用于构建聊天应用的便捷组件。前端通过HTTP POST请求调用我们刚写的FastAPI后端。侧边栏提供了角色选择和重置对话的功能入口。4. 完整运行与测试4.1 启动项目启动后端API服务器# 在项目根目录下确保虚拟环境已激活 python app.py看到类似Uvicorn running on http://127.0.0.1:8000的输出说明后端启动成功。启动前端Streamlit应用# 打开一个新的终端同样在项目根目录下 streamlit run frontend.py终端会输出一个本地URL如http://localhost:8501用浏览器打开它。4.2 进行对话测试在浏览器中你会看到一个简洁的聊天界面。尝试输入“你好小火。”“我今天在果园看到橙子了它很阳光。”“我可能要离开果园一段时间。”观察“病娇火龙果”的回复是否符合其设定剧情是否在向某个“结局”推进。一个成功的交互可能如下你你好小火。小火呀~你终于来啦今天有没有想我呀我一直在等你呢每一分钟都觉得好漫长哦~轻轻晃动叶子你我今天和橙子聊了会天。小火……橙子声音突然低沉那个浑身散发着廉价阳光味的家伙你……你喜欢它吗鳞片微微收紧你只能看着我哦只能陪我哦。4.3 扩展功能语音合成TTS为了让角色“说话”我们可以集成一个简单的TTS功能。这里以免费的edge-tts为例。安装额外依赖pip install edge-tts在后端添加TTS接口(app.py中追加)from fastapi.responses import StreamingResponse import edge_tts import asyncio app.post(/tts/) async def text_to_speech(text: str): 将文本转换为语音并返回音频流 if not text: raise HTTPException(status_code400, detail文本内容为空) async def generate_audio(): # 选择语音例如中文女声 voice zh-CN-XiaoxiaoNeural communicate edge_tts.Communicate(text, voice) async for chunk in communicate.stream(): if chunk[type] audio: yield chunk[data] return StreamingResponse(generate_audio(), media_typeaudio/mpeg)在前端添加播放按钮(frontend.py中修改AI消息显示部分)# 在显示AI回复的代码块内修改 with st.chat_message(assistant, avatar): st.markdown(ai_reply) # 添加一个播放语音的按钮 tts_url fhttp://{Config.BACKEND_HOST}:{Config.BACKEND_PORT}/tts/?text{requests.utils.quote(ai_reply)} st.audio(tts_url, formataudio/mpeg)现在每次AI回复后旁边会出现一个音频播放器点击即可听到合成语音。5. 常见问题与排查思路在开发和运行过程中你可能会遇到以下问题问题现象可能原因排查与解决思路前端提示“无法连接到后端服务”1. 后端app.py未运行。2. 后端端口被占用。3.Config.BACKEND_HOST配置错误。1. 检查终端是否成功运行python app.py且无报错。2. 尝试更换端口如8080并同步修改前后端配置。3. 确保前端frontend.py中api_url的IP和端口与后端一致。调用/chat/接口返回 500 错误或超时1. API密钥无效或未设置。2. API端点不可访问网络问题。3. 模型名称MODEL填写错误。4. 请求的token数超限。1. 检查.env文件中的API_KEY和API_BASE是否正确。2. 尝试在命令行用curl或python脚本直接测试API连通性。3. 核对官方文档使用正确的模型名称。4. 减少MAX_HISTORY_LENGTH或提示词长度。AI回复不符合角色设定或质量差1. 系统提示词不够详细或清晰。2.temperature参数设置不合适。3. 对话历史过长导致角色设定被“淹没”。1. 迭代优化character.py中的提示词明确边界和例子。2. 调整temperature病娇角色可尝试0.7-1.0。3. 确保系统提示词在每次请求中都被正确放在消息列表首位。Streamlit 界面刷新后对话历史丢失Streamlit 的st.session_state在脚本重新运行时可能被重置。确保所有对st.session_state的读写操作都在脚本顶层或条件判断内。使用st.rerun()谨慎。对于持久化可考虑将历史保存到文件或浏览器本地存储。TTS 语音不工作或报错1.edge-tts依赖问题或网络问题。2. 语音名称不支持或文本包含特殊字符。1. 重新安装edge-tts检查网络连接。2. 查看edge-tts --list-voices选择可用的中文语音。对文本进行清洗。6. 最佳实践与项目进阶方向6.1 提示词工程优化分镜脚本化不要只给角色设定。可以尝试给出“剧情大纲”例如“第一幕温馨问候。第二幕引入竞争者橙子。第三幕嫉妒爆发。第四幕结局绑架告白或释怀”。让AI在特定阶段扮演特定情绪。示例对话Few-Shot在系统提示词中提供几轮高质量的示例对话能更精准地引导AI的输出风格。输出格式约束要求AI在回复中标记情绪或动作例如*声音颤抖*或者冷笑前端可以解析并做特殊渲染。6.2 工程化与部署会话管理为每个浏览器会话或登录用户生成唯一ID将对话历史存储在Redis或数据库中而不是内存变量。异步处理对于耗时的LLM调用和TTS生成使用asyncio或任务队列如Celery避免阻塞请求。配置中心将角色提示词、模型参数等移至数据库或配置中心实现动态更新。前端美化使用Streamlit的组件库如streamlit-elements或自定义CSS/HTML来打造更精美的游戏化界面。部署上线可以使用 Docker 容器化应用然后部署到云服务器如阿里云ECS、腾讯云CVM或云原生平台如Railway, Fly.io。6.3 扩展创意多角色切换与互动实现多个AI角色并允许它们之间对话用户作为旁观者或参与者。剧情分支与状态管理引入一个简单的状态机根据用户的关键选择如“安慰小火”、“斥责小火”切换不同的剧情线和角色结局。图像生成集成在关键剧情点调用Stable Diffusion或Midjourney的API根据对话内容生成对应的场景或角色图片增强表现力。语音识别STT允许用户直接语音输入完成语音对话闭环。6.4 安全与合规提醒API密钥安全永远不要在前端代码或公开仓库中硬编码API密钥。始终使用环境变量或安全的密钥管理服务。内容过滤在将用户输入发送给LLM或输出给用户前考虑加入一层内容安全过滤防止生成不当内容。用户数据隐私如果存储对话记录需明确告知用户并获取同意遵守相关数据保护法规。成本控制LLM API调用通常按token收费设置合理的对话长度限制和频率限制防止意外消耗。通过这个“病娇火龙果AI短剧”项目我们不仅实现了一个有趣的互动应用更实践了LLM集成、前后端分离、提示词工程等多项实用技能。你可以以此为基础更换角色设定调整剧情逻辑探索AIGC在内容创作、互动叙事乃至轻度游戏领域的无限可能。动手试试创造出属于你的独一无二的AI角色吧。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价