系统概述
游戏与故事人物对话模拟系统
此系统旨在模拟游戏或故事场景里人物的对话。它具备创建游戏与人物信息的功能,并且能借助输入游戏、人物、时间、地点、场景等信息,调用 OpenAI 格式的接口(通过One Api支持DeepSeek之类的其他AI)得到人物的对话内容。
文章目录
前言
在数字内容创作的世界里,角色对话是连接虚拟与现实的桥梁——它让游戏中的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 openai
app = 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: body
name: body
schema:
type: object
required:
- worldview
- year
- timeline
properties:
worldview:
type: string
description: 游戏的世界观
year:
type: integer
description: 游戏的年份
timeline:
type: string
description: 游戏的主要时间线
responses:
200:
description: 游戏创建成功
schema:
type: object
properties:
game_id:
type: integer
description: 游戏的唯一标识
"""
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: body
name: body
schema:
type: object
required:
- game_id
- name
- gender
- age
- relationships
- friendliness
- activity_area
- backstory
- timeline
- level
- life
- magic
- stamina
- health
- luck
- mystery
properties:
game_id:
type: integer
description: 关联的游戏 ID
name:
type: string
description: 人物姓名
gender:
type: string
description: 人物性别
age:
type: integer
description: 人物年龄
title:
type: string
description: 人物称号
relationships:
type: string
description: 与其他人物的关系
friendliness:
type: integer
description: 友好度
activity_area:
type: string
description: 活动区域
backstory:
type: string
description: 背景故事
timeline:
type: string
description: 人物的时间线
level:
type: integer
description: 人物等级
life:
type: integer
description: 人物生命值
magic:
type: integer
description: 人物魔法值
stamina:
type: integer
description: 人物体力值
health:
type: integer
description: 人物健康度
luck:
type: integer
description: 人物幸运值
mystery:
type: integer
description: 人物神秘属性值
responses:
200:
description: 人物创建成功
schema:
type: object
properties:
character_id:
type: integer
description: 人物的唯一标识
"""
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: body
name: body
schema:
type: object
required:
- game_id
- character_id
- time
- location
- scenario
properties:
game_id:
type: integer
description: 游戏的唯一标识
character_id:
type: integer
description: 人物的唯一标识
time:
type: string
description: 当前时间
location:
type: string
description: 地点
scenario:
type: string
description: 场景
responses:
200:
description: 成功返回人物对话
schema:
type: object
properties:
dialogue:
type: string
description: 人物的对话内容
"""
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 API
response = 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)}"}), 500
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)
总结
谁会需要它
- 游戏开发者:快速生成NPC在探索、战斗、支线任务中的差异化对话,让开放世界更具沉浸感;
- 剧本创作者:为小说、剧本杀、动画角色设计符合人设的台词,解决“角色ooc(脱离人设)”难题;
- 互动内容设计者:在教育模拟、心理咨询等场景中,快速构建动态变化的虚拟对话伙伴,实现个性化交互体验。
我们相信,每一个虚拟角色都值得被认真对待。这套系统不仅是工具,更是创作者的“对话助手”——它记住角色的每一段过往,理解场景的每一处细节,让每一次对话都成为角色性格的自然延伸。让虚拟角色的对话真正成为故事的“灵魂纽带”。
现在,让我们一起告别机械的对话模板,开启“让角色自己说话”的创作新体验——因为每个角色的声音,都值得被听见。
说了这么多,其实就是一个故事+人物内容管理+调api的系统....