游戏NPC对话AI生成的管理调用系统设计

系统概述

游戏与故事人物对话模拟系统
此系统旨在模拟游戏或故事场景里人物的对话。它具备创建游戏与人物信息的功能,并且能借助输入游戏、人物、时间、地点、场景等信息,调用 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. 游戏创建流程
  1. 用户进入游戏创建界面。
  2. 输入游戏的世界观、年份和主要时间线。
  3. 系统生成唯一的游戏 ID,并将信息存储到数据库中。
用户输入游戏信息
输入是否合法
生成唯一游戏ID
返回错误提示
将游戏信息存入数据库
返回游戏创建成功及game_id
2. 人物创建流程
  1. 用户选择要创建人物的游戏 ID。
  2. 输入人物的各项信息。
  3. 系统生成唯一的人物 ID,并将信息关联到对应的游戏 ID 存储到数据库中。
用户选择游戏ID并输入人物信息
游戏ID是否存在
返回游戏不存在错误
人物信息是否完整
返回必填字段缺失错误
生成唯一人物ID
将人物信息存入数据库
返回人物创建成功及character_id
3. 对话模拟流程
  1. 用户输入游戏 ID、人物 ID、时间、地点和场景。
  2. 系统从数据库中提取游戏和人物的相关信息,并与用户输入的信息进行整合。
  3. 系统调用 OpenAI 的接口,将整合后的信息作为输入。
  4. 系统接收 OpenAI 的响应并返回给用户。
用户输入:game_id,character_id,时间,地点,场景
验证id是否存在
返回游戏或人物不存在错误
从数据库查询游戏信息和人物信息
整合信息生成OpenAI对话Prompt
调用OpenAI API生成对话内容
API调用是否成功
返回API调用失败错误
返回人物对话内容
4. 整体系统流程图
外部接口
数据存储层
业务逻辑层
用户交互层
合法
OpenAI API
PostgreSQL数据库
games表
characters表
验证输入合法性
生成唯一ID
查询游戏人物信息
生成对话Prompt
调用OpenAI API
创建游戏
创建人物
模拟对话
返回对话结果

技术实现考虑

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的系统....

### 如何将ChatGPT集成到游戏NPC问答系统 #### 设计思路 为了使游戏中的非玩家角色(NPC)能够提供更加生动、自然的回答,可以利用像ChatGPT这样的大型语言模型(LLM)[^1]。这类模型由于其强大的文本生成能力,非常适合用于创建动态对话体验。 #### 技术准备 要实现这一目标,开发者应当掌握一定的自然语言处理基础知识以及深度学习框架的应用技能[^4]。具体来说: - **API接入**:首先需要获取访问ChatGPT API的权限,并设置好相应的环境变量以便安全地调用接口。 - **数据预处理**:考虑到游戏中可能存在特定领域的术语或背景设定,在向ChatGPT发送请求之前,应该先对输入的数据做一些必要的转换工作,比如标准化用户的提问格式等。 - **上下文管理**:为了让聊天更连贯,还需要设计一套机制来保存并传递之前的交流记录给ChatGPT,从而让每次回应都能基于完整的对话历史作出反应。 #### 实现步骤概述 下面是一个简单的Python脚本示例,展示了如何通过HTTP POST方法调用ChatGPT服务完成一次基本的游戏内互动查询: ```python import requests from dotenv import load_dotenv import os load_dotenv() def get_chatgpt_response(prompt, history=None): url = "https://api.openai.com/v1/chat/completions" headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {os.getenv("CHATGPT_API_KEY")}' } data = {"model": "gpt-3.5-turbo", "messages":[{"role":"user","content":prompt}]} if history is not None and isinstance(history,list): for item in reversed(history[-5:]): role,content=item.split(": ",1) data["messages"].insert(0,{"role":role,"content":content}) response=requests.post(url,json=data,headers=headers).json() return response['choices'][0]['message']['content'] # 测试函数 if __name__=="__main__": user_input="你好啊!能告诉我这个村庄的历史吗?" npc_reply=get_chatgpt_response(user_input) print(f"Npc says:{npc_reply}") ``` 此代码片段实现了与ChatGPT服务器通信的功能,并可以根据传入的不同`prompt`(即玩家的问题),返回由ChatGPT生成的回答字符串。同时支持携带一定长度的历史消息列表作为参数,以增强回复的相关性和连续性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值