系统概述
游戏与故事人物对话模拟系统
此系统旨在模拟游戏或故事场景里人物的对话。它具备创建游戏与人物信息的功能,并且能借助输入游戏、人物、时间、地点、场景等信息,调用 OpenAI 格式的接口(通过One Api支持DeepSeek之类的其他AI)得到人物的对话内容。
文章目录
- 系统概述
- 前言
- 一、功能模块分析
- 系统概述
- 功能模块分析
- 1. 游戏信息管理模块
- 2. 人物信息管理模块
- 3. 对话模拟模块
- 数据结构设计
- 1. 游戏表(games)
- 2. 人物表(characters)
- 系统流程
- 1. 游戏创建流程
- 2. 人物创建流程
- 3. 对话模拟流程
- 4. 整体系统流程图
- 技术实现考虑
- 1. 后端技术
- 2. API 调用
- 3. 前端技术(可选)
- 4. 对话生成逻辑:
- 二、示例代码
- 总结
- 谁会需要它
前言
在数字内容创作的世界里,角色对话是连接虚拟与现实的桥梁——它让游戏中的NPC拥有温度,让故事里的角色跃然纸上。无论是构建恢弘的游戏世界,还是打磨细腻的剧情剧本,贴合人设的对话永远是赋予角色灵魂的关键。然而,当开发者需要为数百个NPC设计千种场景对话,当作家需要为数十个角色编织上万句台词时,手动编写往往陷入“耗时低效”与“逻辑割裂”的困境:如何让酒馆老板的闲聊符合他隐藏的盗贼身份?如何让恋人的争吵既符合性格又推动剧情?这些细节挑战,正需要一套智能化工具来破局。
为此,我们打造了 “游戏与故事人物对话模拟系统”——这不是简单的对话生成工具,而是一个聚焦“角色灵魂塑造”的全链路创作平台。它通过 “结构化设定+智能化生成” 的双重引擎,让每一句对话都成为角色性格的延伸、场景逻辑的自然流露,助您彻底告别“对话脱离人设”的创作痛点,让虚拟角色的每一次开口都充满说服力。
一、功能模块分析
以下是对该系统的详细分析与细化:
系统概述
此系统旨在模拟游戏或故事场景里人物的对话。它具备创建游戏与人物信息的功能,并且能借助输入游戏、人物、时间、地点、场景等信息,调用 OpenAI 接口得到人物的对话内容。
功能模块分析
1. 游戏信息管理模块
- 功能描述:该模块用于创建和管理游戏的基本信息。
- 具体内容:
- 游戏创建:用户录入游戏的世界观,例如是奇幻、科幻还是现实题材;游戏的年份,像古代、未来;主要的时间线,例如关键事件的发生顺序。
- 游戏存储:将游戏信息存储在数据库中,以便后续查询和使用。
- 游戏查询与修改:用户能够依据游戏 ID 查询和修改游戏信息。
2. 人物信息管理模块
- 功能描述:负责创建和管理人物的详细信息。
- 具体内容:
- 人物创建:用户输入人物的姓名、性别、年龄、称号(可选)、与其他人物的关系、友好度、活动区域、背景故事、时间线以及各项属性(如力量、智力等)。
- 人物存储:把人物信息关联到对应的游戏 ID 并存储在数据库中。
- 人物查询与修改:用户可以根据人物 ID 查询和修改人物信息。
3. 对话模拟模块
- 功能描述:根据用户输入的游戏 ID、人物 ID、时间、地点、场景等信息,整合数据并调用 OpenAI 接口,获取人物的对话内容。
- 具体内容:
- 信息整合:从数据库中提取游戏和人物的相关信息,与用户输入的时间、地点、场景等信息进行整合。
- API 调用:将整合后的信息作为输入,调用 OpenAI 的接口。
- 结果返回:接收 OpenAI 的响应并返回给用户。
数据结构设计
1. 游戏表(games)
字段名 | 类型 | 描述 |
---|---|---|
game_id | 整数 | 游戏的唯一标识 |
worldview | 文本 | 游戏的世界观 |
year | 整数 | 游戏的年份 |
timeline | 文本 | 主要的时间线 |
2. 人物表(characters)
字段名 | 类型 | 描述 |
---|---|---|
character_id | 整数 | 人物的唯一标识 |
game_id | 整数 | 关联的游戏 ID |
name | 文本 | 人物姓名 |
gender | 文本 | 人物性别 |
age | 整数 | 人物年龄 |
title | 文本(可选) | 人物称号 |
relationships | 文本 | 与其他人物的关系 |
friendliness | 整数 | 友好度 |
activity_area | 文本 | 活动区域 |
backstory | 文本 | 背景故事 |
timeline | 文本 | 人物的时间线 |
attributes | 文本 | 各项属性(等级,生命,魔力,健康等) |
系统流程
1. 游戏创建流程
- 用户进入游戏创建界面。
- 输入游戏的世界观、年份和主要时间线。
- 系统生成唯一的游戏 ID,并将信息存储到数据库中。
2. 人物创建流程
- 用户选择要创建人物的游戏 ID。
- 输入人物的各项信息。
- 系统生成唯一的人物 ID,并将信息关联到对应的游戏 ID 存储到数据库中。
3. 对话模拟流程
- 用户输入游戏 ID、人物 ID、时间、地点和场景。
- 系统从数据库中提取游戏和人物的相关信息,并与用户输入的信息进行整合。
- 系统调用 OpenAI 的接口,将整合后的信息作为输入。
- 系统接收 OpenAI 的响应并返回给用户。
4. 整体系统流程图
技术实现考虑
1. 后端技术
- 编程语言:Python 是一个不错的选择,因为它有丰富的库和工具,如 Flask 或 Django 可用于构建 Web 服务。
- 数据库:可以使用 MySQL、PostgreSQL 等关系型数据库来存储游戏和人物信息。
2. API 调用
- 使用 OpenAI 的 Python 库
openai
来调用其 API。在调用前,需要获取 OpenAI 的 API 密钥,并进行身份验证。
3. 前端技术(可选)
如果需要开发一个用户界面,可以使用 HTML、CSS 和 JavaScript 来构建前端页面,通过 AJAX 与后端进行交互。现在阶段暂时用swagger文档做显示。
4. 对话生成逻辑:
- 将游戏世界观、人物背景、当前场景等信息整合成 Prompt,作为 OpenAI 的输入。 支持自定义 Prompt
- 模板(如包含人物属性、友好度、关系等细节,提升对话真实性)。
二、示例代码
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flasgger import Swagger
import os
import openaiapp = Flask(__name__)
# 配置 PostgreSQL 数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'postgresql://username:password@192.168.123.224:5435/postgres')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)# 配置 OpenAI API 密钥
openai.api_key = os.getenv('OPENAI_API_KEY')# Swagger 配置
swagger_template = {"swagger": "2.0","info": {"title": "游戏人物对话模拟系统","description": "一个用于模拟游戏或故事场景中人物对话的系统","version": "1.0"},"basePath": "/","schemes": ["http","https"]
}
swagger_config = {"headers": [],"specs": [{"endpoint": 'apispec_1',"route": '/apispec_1.json',"rule_filter": lambda rule: True,"model_filter": lambda tag: True,}],"static_url_path": "/flasgger_static","swagger_ui": True,"specs_route": "/swagger/"
}
swagger = Swagger(app, template=swagger_template, config=swagger_config)# 游戏实体类
class Game(db.Model):"""游戏实体类,对应数据库中的 games 表,用于存储游戏的基本信息。"""__tablename__ = 'games'# 游戏的唯一标识,作为主键game_id = db.Column(db.Integer, primary_key=True)# 游戏的世界观,如奇幻、科幻等,不能为空worldview = db.Column(db.Text, nullable=False)# 游戏的年份,不能为空year = db.Column(db.Integer, nullable=False)# 游戏的主要时间线,记录关键事件顺序,不能为空timeline = db.Column(db.Text, nullable=False)# 人物实体类
class Character(db.Model):"""人物实体类,对应数据库中的 characters 表,用于存储人物的详细信息。"""__tablename__ = 'characters'# 人物的唯一标识,作为主键character_id = db.Column(db.Integer, primary_key=True)# 关联的游戏 ID,外键,关联到 games 表的 game_id,不能为空game_id = db.Column(db.Integer, db.ForeignKey('games.game_id'), nullable=False)# 人物姓名,不能为空name = db.Column(db.Text, nullable=False)# 人物性别,不能为空gender = db.Column(db.Text, nullable=False)# 人物年龄,不能为空age = db.Column(db.Integer, nullable=False)# 人物称号,可选字段title = db.Column(db.Text)# 与其他人物的关系,不能为空relationships = db.Column(db.Text, nullable=False)# 友好度,不能为空friendliness = db.Column(db.Integer, nullable=False)# 活动区域,不能为空activity_area = db.Column(db.Text, nullable=False)# 背景故事,不能为空backstory = db.Column(db.Text, nullable=False)# 人物的时间线,不能为空timeline = db.Column(db.Text, nullable=False)# 人物等级level = db.Column(db.Integer, nullable=False)# 人物生命值life = db.Column(db.Integer, nullable=False)# 人物魔法值magic = db.Column(db.Integer, nullable=False)# 人物体力值stamina = db.Column(db.Integer, nullable=False)# 人物健康度health = db.Column(db.Integer, nullable=False)# 人物幸运值luck = db.Column(db.Integer, nullable=False)# 人物神秘属性值mystery = db.Column(db.Integer, nullable=False)# 与 Game 类建立关联,方便通过游戏对象访问其关联的人物列表game = db.relationship('Game', backref=db.backref('characters', lazy=True))# 创建游戏 API
@app.route('/create_game', methods=['POST'])
def create_game():"""创建游戏---tags:- 游戏管理parameters:- in: bodyname: bodyschema:type: objectrequired:- worldview- year- timelineproperties:worldview:type: stringdescription: 游戏的世界观year:type: integerdescription: 游戏的年份timeline:type: stringdescription: 游戏的主要时间线responses:200:description: 游戏创建成功schema:type: objectproperties:game_id:type: integerdescription: 游戏的唯一标识"""data = request.get_json()worldview = data.get('worldview')year = data.get('year')timeline = data.get('timeline')game = Game(worldview=worldview, year=year, timeline=timeline)db.session.add(game)db.session.commit()return jsonify({"game_id": game.game_id})# 创建人物 API
@app.route('/create_character', methods=['POST'])
def create_character():"""创建人物---tags:- 人物管理parameters:- in: bodyname: bodyschema:type: objectrequired:- game_id- name- gender- age- relationships- friendliness- activity_area- backstory- timeline- level- life- magic- stamina- health- luck- mysteryproperties:game_id:type: integerdescription: 关联的游戏 IDname:type: stringdescription: 人物姓名gender:type: stringdescription: 人物性别age:type: integerdescription: 人物年龄title:type: stringdescription: 人物称号relationships:type: stringdescription: 与其他人物的关系friendliness:type: integerdescription: 友好度activity_area:type: stringdescription: 活动区域backstory:type: stringdescription: 背景故事timeline:type: stringdescription: 人物的时间线level:type: integerdescription: 人物等级life:type: integerdescription: 人物生命值magic:type: integerdescription: 人物魔法值stamina:type: integerdescription: 人物体力值health:type: integerdescription: 人物健康度luck:type: integerdescription: 人物幸运值mystery:type: integerdescription: 人物神秘属性值responses:200:description: 人物创建成功schema:type: objectproperties:character_id:type: integerdescription: 人物的唯一标识"""data = request.get_json()game_id = data.get('game_id')name = data.get('name')gender = data.get('gender')age = data.get('age')title = data.get('title')relationships = data.get('relationships')friendliness = data.get('friendliness')activity_area = data.get('activity_area')backstory = data.get('backstory')timeline = data.get('timeline')level = data.get('level')life = data.get('life')magic = data.get('magic')stamina = data.get('stamina')health = data.get('health')luck = data.get('luck')mystery = data.get('mystery')character = Character(game_id=game_id,name=name,gender=gender,age=age,title=title,relationships=relationships,friendliness=friendliness,activity_area=activity_area,backstory=backstory,timeline=timeline,level=level,life=life,magic=magic,stamina=stamina,health=health,luck=luck,mystery=mystery)db.session.add(character)db.session.commit()return jsonify({"character_id": character.character_id})# 模拟对话 API
@app.route('/simulate_dialogue', methods=['POST'])
def simulate_dialogue():"""模拟对话---tags:- 对话模拟parameters:- in: bodyname: bodyschema:type: objectrequired:- game_id- character_id- time- location- scenarioproperties:game_id:type: integerdescription: 游戏的唯一标识character_id:type: integerdescription: 人物的唯一标识time:type: stringdescription: 当前时间location:type: stringdescription: 地点scenario:type: stringdescription: 场景responses:200:description: 成功返回人物对话schema:type: objectproperties:dialogue:type: stringdescription: 人物的对话内容"""data = request.get_json()game_id = data.get('game_id')character_id = data.get('character_id')time = data.get('time')location = data.get('location')scenario = data.get('scenario')game = Game.query.get(game_id)character = Character.query.get(character_id)if not game or not character:return jsonify({"error": "游戏或人物不存在"}), 404# 整合信息prompt = f"游戏世界观: {game.worldview}, 年份: {game.year}, 时间线: {game.timeline}. " \f"人物姓名: {character.name}, 性别: {character.gender}, 年龄: {character.age}, 称号: {character.title}, " \f"关系: {character.relationships}, 友好度: {character.friendliness}, 活动区域: {character.activity_area}, " \f"背景故事: {character.backstory}, 时间线: {character.timeline}, 等级: {character.level}, " \f"生命: {character.life}, 魔法: {character.magic}, 体力: {character.stamina}, " \f"健康度: {character.health}, 幸运: {character.luck}, 神秘: {character.mystery}. " \f"当前时间: {time}, 地点: {location}, 场景: {scenario}. 请模拟该人物的对话。"try:# 调用 OpenAI APIresponse = openai.Completion.create(engine="text-davinci-003",prompt=prompt,max_tokens=150)dialogue = response.choices[0].text.strip()return jsonify({"dialogue": dialogue})except Exception as e:return jsonify({"error": f"调用 OpenAI API 时出错: {str(e)}"}), 500if __name__ == '__main__':with app.app_context():db.create_all()app.run(debug=True)
总结
谁会需要它
- 游戏开发者:快速生成NPC在探索、战斗、支线任务中的差异化对话,让开放世界更具沉浸感;
- 剧本创作者:为小说、剧本杀、动画角色设计符合人设的台词,解决“角色ooc(脱离人设)”难题;
- 互动内容设计者:在教育模拟、心理咨询等场景中,快速构建动态变化的虚拟对话伙伴,实现个性化交互体验。
我们相信,每一个虚拟角色都值得被认真对待。这套系统不仅是工具,更是创作者的“对话助手”——它记住角色的每一段过往,理解场景的每一处细节,让每一次对话都成为角色性格的自然延伸。让虚拟角色的对话真正成为故事的“灵魂纽带”。
现在,让我们一起告别机械的对话模板,开启“让角色自己说话”的创作新体验——因为每个角色的声音,都值得被听见。
说了这么多,其实就是一个故事+人物内容管理+调api的系统....