【开源】灵魂讲述者:基于魔珐星云的AI交互式分支叙事应用,免费体验啦!

人们眼中的天才之所以卓越非凡,并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。------------ 马尔科姆·格拉德威尔

🌟 Hello,我是Xxtaoaooo!

🌈 "代码是逻辑的诗篇,架构是思想的交响"


项目简介

大家好!今天给大家分享我最近做的一个开源项目------ 灵魂讲述者(Soul Teller)

这是一个基于魔珐星云具身智能平台的AI交互式叙事应用。简单来说:你选择一个故事世界,3D数字人实时给你讲故事,你可以通过对话和分支选择影响剧情走向,每一条选择都会带来不同的结局。

和传统的文字冒险游戏不同,这个故事没有预设脚本------所有剧情都由AI实时生成,每一次体验都是独一无二的。

新用户注册魔珐星云可以填写邀请码:J36AKZEFMK,可免费获取积分体验数字人,快来试试吧!

魔法星云地址: https://xingyun3d.com/

GitHub 项目地址: https://github.com/xtdexw/soul-teller


一、效果展示

1.1 故事世界选择

用户进入应用后,首先选择一个故事世界。目前支持赛博朋克、奇幻森林、悬疑推理等多种风格。

1.2 互动播放室

进入故事后,界面分为两个区域:

  • 左侧:3D数字人实时渲染,配合语音讲述剧情
  • 右侧:1. 分支选项面板,AI生成3个分支供选择 2. 剧情面板,展示当前剧情内容 3. Ai对话面板:实时沟通改变分支、剧情走向

同时支持故事剧情导出。

1.3 设置面板

所有API密钥都在页面内配置,密钥存储在浏览器本地,支持掩码显示,安全开箱即用。


二、核心功能

2.1 3D数字人实时讲述

通过魔珐星云SDK实现数字人实时渲染与语音合成:

复制代码
// 数字人初始化
const sdk = new XmovAvatar({
  containerId: '#avatar-container',
  appId: config.appId,
  appSecret: config.appSecret,
  gatewayServer: config.gatewayServer,
});

数字人支持:

  • 流式语音合成(TTS),边生成边朗读
  • 文本分块朗读与状态同步
  • 手动/自动连接控制

2.2 AI分支剧情系统

这是整个项目最核心的部分。一次API调用同时获取:续写内容(200-400字)+ 3个分支选项

复制代码
// 统一故事生成API
async generateStory(context: StoryContext): Promise<StoryNode> {
  const response = await fetch(config.apiUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${config.apiKey}`,
    },
    body: JSON.stringify({
      model: 'qwen2.5-72b-instruct',
      messages: this.buildPrompt(context),
    }),
  });
  // 同时返回剧情续写 + 3个分支选项
  return this.parseStoryResponse(response);
}

用户选择任意一个分支,AI会基于你的选择继续生成下一段剧情,形成真正的分支叙事体验。

2.3 智能上下文管理

为了让AI记住之前的剧情走向,我实现了一套混合上下文策略:

复制代码
// 混合上下文策略
buildContext(currentNode: StoryNode): string {
  return [
    this.getRecentStory(10),      // 最近10段剧情
    this.vectorSearch(2),         // 语义检索2个最相关历史节点
    this.getUserDialogue(),       // 用户的实时对话输入
  ].join('\n');
}
  • 最近剧情:内存中保存最近10段,保证连贯性
  • 向量检索:基于IndexedDB实现的本地向量存储,语义检索最相关的历史节点
  • 用户对话:实时纳入用户的对话输入

这套机制确保AI在长篇故事中也能"记住"之前的情节和伏笔。

2.4 动态背景系统

根据故事进展自动切换背景,10张背景图片循环使用,配合1秒淡入淡出的平滑过渡:

复制代码
// 根据节点序号切换背景
const bgIndex = (nodeIndex % 10) + 1;
setBackgroundWithTransition(`/images/back${bgIndex}.webp`);

2.5 智能连接状态管理

未连接数字人时,AI对话和分支选择会被禁用,避免用户在未就绪时操作:

复制代码
// 连接状态控制
const isConnected = useStore(state => state.isConnected);
// 未连接时禁用交互
disabled={!isConnected}

三、技术架构

3.1 技术栈

|------------|--------------------------------------------|
| 技术 | 说明 |
| 前端框架 | React 18 + TypeScript |
| 构建工具 | Vite |
| 状态管理 | Zustand + persist(持久化) |
| 样式方案 | TailwindCSS |
| 数字人SDK | 魔珐星云具身驱动SDK (xmovAvatar) |
| 大语言模型 | 通义千问 Qwen2.5-72B-Instruct (ModelScope API) |
| 向量模型 | 通义千问 Embedding-8B |
| 向量存储 | 自研轻量级向量存储(基于IndexedDB) |

3.2 项目结构

复制代码
soul-teller/
├── src/
│   ├── components/          # UI组件
│   │   ├── StoryHub/        # 故事世界选择
│   │   ├── PlayRoom/        # 互动播放室(核心页面)
│   │   ├── Settings/        # 设置面板
│   │   ├── Dialogue/        # AI对话面板
│   │   └── StoryTeller/     # 数字人容器
│   ├── services/            # 服务层
│   │   ├── StoryEngine.ts       # 故事引擎(核心调度)
│   │   ├── StoryGenerator.ts    # 故事生成器(AI调用)
│   │   ├── VectorStore.ts       # 向量存储(IndexedDB)
│   │   └── XingyunSDK.ts        # 星云SDK封装
│   ├── hooks/               # 自定义Hooks
│   │   └── useAvatar.ts         # 数字人生命周期管理
│   ├── store/               # Zustand状态管理
│   │   └── useStore.ts          # 全局状态(含persist)
│   ├── utils/               # 工具函数
│   │   ├── secureStorage.ts     # 安全存储(密钥掩码)
│   │   └── textChunker.ts       # 文本分块(TTS朗读)
│   ├── types/               # TypeScript类型定义
│   │   ├── story.ts             # 故事节点、分支类型
│   │   └── interaction.ts       # 交互事件类型
│   └── App.tsx
├── public/                  # 静态资源(背景图片等)
└── package.json

3.3 核心架构图

复制代码
flowchart TB
    %%{init: {'theme':'base', 'themeVariables':{'primaryColor':'#7c3aed'}}}%%
    subgraph UI ["UI Layer"]
        A["StoryHub<br/>故事世界选择"]:::ui
        B["PlayRoom<br/>互动播放室"]:::ui
        C["Dialogue<br/>AI对话面板"]:::ui
        D["StoryTeller<br/>数字人容器"]:::ui
    end

    subgraph Service ["Service Layer"]
        E["StoryEngine<br/>故事引擎"]:::svc
        F["StoryGenerator<br/>AI故事生成"]:::svc
        G["VectorStore<br/>向量存储"]:::svc
    end

    subgraph External ["External APIs"]
        H["魔珐星云SDK<br/>3D数字人"]:::ext
        I["通义千问API<br/>Qwen2.5-72B"]:::ext
        J["IndexedDB<br/>本地存储"]:::ext
    end

    B --> E
    C --> E
    D --> H
    E --> F
    E --> G
    F --> I
    G --> J

    classDef ui fill:#ede9fe,stroke:#7c3aed,stroke-width:2px
    classDef svc fill:#dbeafe,stroke:#2563eb,stroke-width:2px
    classDef ext fill:#fef3c7,stroke:#d97706,stroke-width:2px

图1:灵魂讲述者系统架构图


四、快速开始

4.1 克隆项目

复制代码
git clone https://github.com/xtdexw/soul-teller.git
cd soul-teller

4.2 安装依赖

复制代码
npm install

4.3 启动开发服务器

复制代码
npm run dev

4.4 配置API密钥

打开应用后,点击右上角设置按钮:

通义千问配置:

  1. 访问 ModelScope
  2. 注册并获取API Key
  3. 在设置面板的"API密钥"标签中填入密钥

魔珐星云配置:

  1. 访问 魔珐星云官网
  2. 注册账号(填写邀请码 J36AKZEFMK 可免费获取积分体验数字人!)
  3. 创建应用,获取App ID和App Secret
  4. 在设置面板的"数字人连接"标签中配置

4.5 开始体验

连接数字人 → 选择故事世界 → 点击"开始冒险" → 选择分支或对话推动剧情


五、项目亮点

5.1 一个API调用搞定剧情 + 分支

传统做法是分两次调用------先生成剧情,再生成选项。我把这两步合并成一次调用,既减少了延迟,又保证了选项和剧情的语义连贯性。

5.2 本地向量存储,零服务端依赖

基于IndexedDB自研了一套轻量级向量存储,不需要部署Pinecone或Milvus这类向量数据库,全部在浏览器本地完成。对于这种中小规模的上下文检索场景,完全够用。

5.3 密钥安全设计

  • 所有API密钥存储在浏览器localStorage中,不上传任何服务器
  • 设置面板中密钥仅显示前4位和后4位,防止泄露
  • 用户完全控制数字人的连接与断开

六、使用流程

复制代码
flowchart TD
    %%{init: {'theme':'base', 'themeVariables':{'primaryColor':'#059669'}}}%%
    A["启动应用"]:::step --> B["连接数字人"]:::step
    B --> C["选择故事世界"]:::step
    C --> D["点击开始冒险"]:::step
    D --> E["数字人朗读开场剧情"]:::step
    E --> F{"选择分支 or AI对话?"}:::choice
    F -->|选择分支| G["AI生成新剧情"]:::step
    F -->|自由对话| H["AI调整分支选项"]:::step
    G --> E
    H --> E

    classDef step fill:#d1fae5,stroke:#059669,stroke-width:2px
    classDef choice fill:#fef3c7,stroke:#d97706,stroke-width:2px

图2:用户使用流程图


七、写在最后

这个项目探索了一种新的互动叙事形式------不是预设脚本的选择题,而是AI实时生成的开放世界故事。每一次对话、每一个选择,都会让故事走向不同的方向。

如果你对AI叙事、数字人、向量存储这些方向感兴趣,欢迎一起交流贡献!

如果觉得这个项目对你有帮助,欢迎给个Star ️!

GitHub地址: https://github.com/xtdexw/soul-teller


🌟 嗨,我是Xxtaoaooo!
⚙️ 【点赞】让更多同行看见深度干货
🚀 【关注】持续获取行业前沿技术与经验
🧩 【评论】分享你的实战经验或技术困惑
作为一名技术实践者,我始终相信:
每一次技术探讨都是认知升级的契机,期待在评论区与你碰撞灵感火花🔥

相关推荐
2401_865382502 小时前
AI询价与传统询价平台的区别
人工智能·信息化项目·政务信息化·信息化造价
liu_zhiyi2 小时前
生成式 AI 交互规范:提示词工程(Prompt Engineering)技术指南
人工智能·prompt·交互
前端不太难2 小时前
开源驱动的 AI 构建与治理
人工智能·开源
QYR_112 小时前
2026年全球寡核苷酸合成用固相载体行业深度洞察与展望
大数据·人工智能
CS创新实验室2 小时前
CS实验室行业报告:自动驾驶领域就业分析报告
人工智能·自动驾驶·unix
泰迪智能科技012 小时前
分享|人工智能方向职业技术培训:从入门到进阶,11个方向可选
人工智能
慧知AI2 小时前
【技术深度】苹果换帅后的端侧AI技术架构详解
人工智能
coderyi3 小时前
LLM Agent 浅析
前端·javascript·人工智能