码道:让大模型做你的游戏主持人——AI 对话式交互文字冒险「无尽回廊」开发全记录

用 HTML5 + CSS3 + JavaScript 从零搭建一个由 DeepSeek 驱动的无限叙事文字冒险游戏,不依赖任何框架与构建工具,纯前端拥抱大模型。本文完整记录了项目从灵感到落地、从 Python 参考实现到 JavaScript 流式重写的全过程。


一、前言:一次"即兴叙事"的冲动

你有没有过这样的时刻:读完一本小说,恨不得自己就是主角;玩完一款游戏,却对每个选项的走向烂熟于心;看完一部电影,惋惜分支剧情只能存在于导演的剪辑室。传统媒介里的故事总是"写完即定稿",玩家能做的不过是在有限的选项里挑一个,游戏的终点早已被设计者埋好。

但大模型的出现改变了一切。当语言模型拥有数以百亿计的参数、足够强的上下文理解能力与丰富的世界知识时,"生成式叙事"不再是科幻。AI 可以即时理解你的一句话行动指令,并根据设定好的世界观与角色逻辑,即时编织出下一段剧情——你向左转,它为你描绘左侧走廊里的烛台与蛛网;你选择驻足倾听,它让黑暗中传来低沉的呼吸声。

正是这种"无限可能性",让我决定亲手做一个项目。它既不是传统的视觉小说脚本,也不是套壳 Chatbot,而是一个真正意义上由 AI 主持、完全开放、可持续数小时也不会重复的交互式文字冒险游戏——我把它命名为「无尽回廊」。

这个项目的技术选型出人意料地保守:HTML5、CSS3、JavaScript,零第三方依赖、零构建工具、零后端服务。而支撑它运行的核心,是 DeepSeek-V4-Flash 模型的一次次流式推理调用。

本文将从设计动机、技术选型、核心实现、落地过程与踩坑经验几个维度,完整复盘这个项目的开发旅程。文章会比较长,因为我想把每一个值得分享的细节都记录下来,也希望给同样想用"大模型做产品"的开发者一些可复用的经验。


在这里插入图片描述

二、项目缘起:为什么做一款 AI 文字冒险

2.1 传统文字冒险的痛点

文字冒险游戏(Text Adventure / Interactive Fiction)历史悠久,从早期的 Zork 到如今的各类视觉小说,其核心矛盾始终存在:

  • 内容成本极高:一条剧情线需要策划、文案、测试反复打磨,制作一个十小时体量的作品往往需要团队数月投入。
  • 分支呈指数爆炸:两个选项就分裂出两条线,三个选项就分裂出三条线,想覆盖所有可能的行动组合几乎不可能。绝大多数游戏只能"假分支"——选项长得不一样,结局通向同一处。
  • 玩家创造力受限:玩家输入"把蜡烛放到窗台上",系统若没有预设这个交互,就只能回复"你无法这样做"。这种挫败感是传统引擎的硬伤。

2.2 大模型给出的解法

大模型恰好同时解决了上述三个问题:

  • 零边际内容成本:剧情由模型动态生成,世界无限大,不存在"内容用完"的概念。
  • 分支天然收敛:无论玩家输入什么,模型都能依据当前状态输出合理的续写,既包容了想象,又不至于让开发维护爆炸。
  • 自由输入自然语言:抛弃预设选项的枷锁,玩家可以直接键入任何行动,“让蜡烛发光”“回头看看脚印”“对着黑暗大喊”——模型都能理解语义并给出合理回应。

这正是"对话式交互"与"文字冒险"结合的意义所在。大模型不只是一个会聊天的机器人,它是一个可以承载世界观、维护状态、推进叙事的游戏主持人(Game Master)

2.3 为什么采用对话式界面

我特意选择了"对话/聊天"式的交互形态,而非传统游戏的按钮式 UI。理由有三:

  1. 亲切感:聊天界面是当下用户最熟悉的交互范式,学习成本几乎为零。
  2. 叙事连续:聊天记录天然形成"事件流",玩家回看上一条行动与对应反馈,故事脉络一目了然。
  3. 契合创作:写作本身就是一个对话过程——策划与作者、作者与角色、角色与读者。将聊天界面用作叙事舞台,语义上严丝合缝。

于是「无尽回廊」的形态就此确定:左侧是玩家角色状态面板,中间是剧情舞台,底部是自由输入框。你打字,AI 编织命运。


三、技术选型:纯前端的三重考量

确定了产品形态,接下来是技术栈。很多人可能会下意识选择 React/Vue + Node 后端 + 数据库,但我最终选定了纯静态三件套。这并非保守,而是一种刻意的取舍。

3.1 零依赖,零门槛

  • 无需 Node 环境:整个项目只有四个文件,任何一个装有现代浏览器的设备都能直接运行。
  • 无需构建流程:没有 webpack、vite、npm install,改完代码刷新即可看到效果,对初学者极度友好。
  • 部署即复制:把文件扔到任何静态文件服务器(Nginx、GitHub Pages、对象存储)就能上线,不需要运维任何后端进程。

3.2 浏览器原生能力已足够

过去"纯前端调大模型"最大的障碍是跨域(CORS)问题。好消息是,很多大模型服务商(包括本项目使用的 GitCode 开放 API)已经开放了浏览器直连许可。现代浏览器原生提供的 fetch + ReadableStream 足以实现完整的流式通信,连 EventSource 的 SSE 协议都无需依赖(因为需要 POST 请求,且要携带鉴权头)。

3.3 聚焦产品本身

去掉框架,反而让我把注意力放在了两件真正重要的事上,那就是提示词设计渲染体验。项目的价值不在于某个炫酷的组件库,而在于那一纸"系统提示词"——它定义了 AI 的行为边界与输出契约,是整个产品心智的核心。

当然,纯前端方案也有代价:API 密钥暴露在浏览器端,无法做到真正的服务端鉴权。这一点的应对策略我会在安全章节详细说明。


四、从 Python 参考实现到 JavaScript:一次流式改写之旅

项目的 API 调用部分最初拿到的是 Python 参考代码。利用 Python 生态中的 requests 库,流式接收大模型响应几乎是开箱即用的体验。但我们的目标是纯前端,因此必须将其完整翻译为浏览器端的 JavaScript。这趟"翻译"看似机械,实际上躲着几个不深不浅的坑。

4.1 Python 参考实现长什么样

参考代码的核心逻辑大致如下:

def query(payload):
    response = requests.post(API_URL, headers=headers, json=payload, stream=True)
    for line in response.iter_lines():
        if not line.startswith(b"data:"):
            continue
        if line.strip() in (b"data:[DONE]", b"data: [DONE]"):
            return
        yield json.loads(line.decode("utf-8").lstrip("data:").rstrip("/n"))

几个值得注意的细节:

  1. stream=True:开启 HTTP 流式传输,服务端分批返回,客户端逐行消费。
  2. iter_lines():按行迭代字节流。
  3. 前缀过滤:只处理以 data: 开头的事件行(SSE 协议格式)。
  4. 结束哨兵:遇到 data: [DONE] 终止迭代。
  5. 生成器(yield):逐块产出解析后的 JSON,调用方可以实时消费。

4.2 浏览器端对应的写法

JavaScript 没有 iter_lines(),但浏览器提供了一套等价的机制——Response.body.getReader() 配合 TextDecoder

const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
let buffer = "";

while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });

    const lines = buffer.split("\n");
    buffer = lines.pop(); // 保留可能被截断的残行

    for (const rawLine of lines) {
        const line = rawLine.trim();
        if (!line.startsWith("data:")) continue;
        if (line === "data:[DONE]" || line === "data: [DONE]") continue;
        const json = JSON.parse(line.slice(5).trim());
        const delta = json.choices?.[0]?.delta?.content;
        if (delta) fullText += delta;
    }
}

4.3 翻译过程中的三个关键坑

坑一:半行问题(频段边界)。网络块(chunk)的边界与 SSE 行的边界不一致,一行可能被切到两个 chunk 中。解决方案是维护一个 buffer,每次先把残行拼接完整再逐行处理。这正是 Python iter_lines() 内部帮我们做掉的事情,浏览器端需要自己实现一次。

坑二:多字节字符的分裂。中文 UTF-8 编码占 3 字节,一个汉字可能被一个 chunk 截成两半。TextDecoder(..., { stream: true }) 专门解决了这个问题——它会保存上一个块未完成的字节,等下一块到来时拼成完整的字符。千万不能省略 stream: true,否则会出现乱码。

**坑三:python 与 javascript 的行尾差异**。参考代码中的 rstrip(“/n”)(反斜杠 n 字符串)其实是原文笔误,Python 的 strip() 已经足够。在 JavaScript 侧,line.slice(5).trim()才是更稳妥的做法,它同时兼容data:` 后是否带空格两种情况。

4.4 请求体的参数对齐

请求体与参考实现保持一致,并在独立配置文件 config.js 中统一管理:

const CONFIG = {
    API_URL: "https://api-ai.gitcode.com/v1/chat/completions",
    MODEL: "deepseek-ai/DeepSeek-V4-Flash",
    MAX_TOKENS: 2048,
    TEMPERATURE: 0.6,       // 温度:略低,保证叙事稳定
    TOP_P: 0.95,            // 核采样:保留一定的多样性
    FREQUENCY_PENALTY: 0,   // 不做重复惩罚,让语气自然
    THINKING_BUDGET: 2048
};

把这些参数单独抽到配置文件而不是散落在代码里的好处是:非技术人员也可以直接改配置文件来调整游戏风格,而不需要碰业务代码。


五、系统提示词:让大模型化身"游戏主持人"

这是整个项目含金量最高的部分。同样的 API,写给聊天机器人看的系统提示词和写给游戏主持人看的提示词,效果天差地别。

5.1 角色设定:Game Master

系统提示词的开头必须一句话锁定角色:

你是「无尽回廊」文字冒险游戏的叙事引擎与游戏主持人(Game Master)。玩家正身处于一个充满神秘与危机的奇幻世界中,一切将由你实时生成。

“游戏主持人"这个角色定义极其重要,它同时约束了三点:叙事口吻(第二人称"你”)、行为边界(只输出剧情相关内容)、职责范围(负责世界运行与状态管理)。一旦角色确立,模型就会自动"入戏",极少再跳脱出框架输出无关内容。

5.2 结构契约:让 HTML 更好显示的 JSON

大多数 AI 应用失败在"返回值自由发挥"。为了让前端 HTML 稳定渲染,我在系统提示词中硬性规定了输出格式——一个固定的 JSON 结构,包含 8 个字段:

{
  "scene_title": "场景小标题,例如「尘封的回廊」",
  "location": "当前所处地点名称,例如「旧图书馆 · 一层」",
  "narration": "对该场景的沉浸式描写,3~6 句话,第二人称“你”……",
  "event_summary": "玩家上一回合行动产生的直接后果……",
  "hp": 100,
  "stamina": 100,
  "inventory": ["物品A", "物品B"],
  "options": [
    {"text": "简短动作选项", "hint": "给玩家的私密提示"}
  ]
}

在提示词中,我不只是列出结构,还针对每个字段写了类型要求、取值范围、取值语义和示例。比如:

  • hp / stamina 必须为 0~100 的整数,依剧情合理增减;
  • options 固定 3~4 个,必须是"具体的行动"而非抽象描述;
  • inventory 每回合完整给出(增删物品都要在列表里体现);
  • 结局时 options 置空数组。

为什么这么详细?因为语言模型遵循的"规则"就是提示词中出现的每一个约束。约束写得越具体、越可验证,模型输出的越稳定。实践下来,模型几乎可以 100% 输出结构正确的 JSON。

5.3 状态一致性协议

游戏的主持人必须"记住"玩家状态,但 LLM 是无状态的——每次调用都得把历史上下文完整喂回去。我的协议是:

  1. 每一次玩家行动后,模型返回上述 JSON;
  2. 前端把模型的原始 JSON 文本原样记录为 assistant 消息,追加进消息历史;
  3. 下次请求时携带完整历史;模型从历史中读取当前 hp、背包、场景,继续演进。

采用"JSON 即上下文"的设计,避免了前端自行维护状态的结构漂移:模型读取的、与前端渲染的,是同一份数据,两边永远不会对不上。

5.4 上下文长度治理

游戏玩久了,历史消息会越来越长,最终击穿模型的上下文窗口。我在前端做了滑动窗口策略:保留最近 16 条消息(system 提示词单独拼装),更早的历史自然截断。对于强调沉浸式连续性的文字冒险来说,16 条通常足够覆盖"最近发生的事",既能维持连贯叙事,又能稳定控制 token 成本。


六、结构化数据契约:前端渲染的基石

传统聊天应用的返回是纯文本,前端只能整段展示。而在文字冒险里,我们需要的是一套结构化状态:场景标题、地点、血量、精力、背包、选项。这些数据只有被精确解析,UI 才能做到"健康条增减、背包增删、选项按钮化"。

6.1 JSON 解析的容错武器

即使提示词约束得再严格,也不能完全信任模型的输出。现实中可能遇到这些情况:

  • 模型输出了 markdown 代码围栏(```json);
  • 模型在 JSON 前后加了"好的,这是你的场景:"之类的杂质文本;
  • 流式拼接时个别字符损坏导致整段 JSON 无法直接解析。

因此我实现了一个多重兜底的解析函数 extractJson()

  1. 先剥离 ```json 围栏与首尾空白;
  2. 尝试直接 JSON.parse
  3. 失败则截取第一个 { 到最后一个 } 之间的子串再解析;
  4. 仍失败则返回 null,触发上层重试逻辑。

这个"截最大花括号区间"的手法朴实但极其有效,实测能救回绝大部分杂质输出。

6.2 字段规范化:脏数据的最后防线

即使 JSON 结构正确,字段值也可能"越界"。例如模型返回 hp: 150stamina: -20inventory: "金币"(字符串而非数组)。normalizeScene() 负责把所有字段收编为安全值:

  • 数值字段做 0~100 钳制;
  • 数组字段校验并映射为字符串数组;
  • 选项过滤掉空文本,避免渲染出空按钮;
  • 缺失字段回退到当前游戏状态的默认值。

经过这两层处理,前端渲染逻辑就可以"信任数据",不需要到处写防御性分支。

6.3 数据契约带来的 UI 收益

正因为有了结构化数据,渲染层才能轻松实现:

  • 健康条动画:hp 变化时宽度过渡动画,直观呈现战斗/休息反馈;
  • 背包列表:新增物品自动出现在面板,丢失物品自动消失;
  • 选项按钮化:点击选项即发送该行动,一步直达;
  • 提示气泡hint 字段作为 title tooltip,玩家悬停可窥探"直觉",但不直白剧透。

这些体验,是纯文本聊天界面完全做不到的。


七、前端渲染引擎与交互设计

7.1 页面布局:三区结构

围绕"游戏化"目标,页面采用三区布局:

  1. 左侧状态面板:生命值、精力条、地点、背包。信息密度高、常驻可见,让玩家时刻掌握角色处境。
  2. 中间剧情舞台:聊天式滚动区,承载事件反馈、场景标题、叙述文本与行动选项。
  3. 底部输入区:自由输入框 + 发送按钮,Enter 快捷发送。

7.2 打字机效果:叙事节奏的艺术

文字冒险的沉浸感,很大程度上来自文本的"呼吸感"。瞬时显示一大段文本会让玩家失去节奏,我因此为叙述文本实现了打字机逐字效果:

  • 每帧输出 2 个字符(观感更流畅且不过分缓慢);
  • 显示一个闪烁的光标作为"AI 正在书写"的可视锚点;
  • 长文本自动加快速度,避免等待焦躁;
  • 自动滚动到屏幕底部,保证最新内容始终可见。

打字机效果不只是"炫技",它对叙事体验有实质增益:玩家被动地跟随 AI 的叙述节奏,悬念被拉开、情绪被酝酿,这恰恰是文字冒险最需要的"临场感"。

7.3 事件反馈与历史留存设计

每一轮交互,界面会依次呈现:

  1. 玩家行动气泡(如果是自由输入);
  2. 上回合后果反馈(event_summary,金色高亮);
  3. 场景标题;
  4. 叙述正文(打字机);
  5. 本轮选项按钮。

关键设计决策是:每一轮都创建全新的 DOM 节点追加到历史区,而不是复用固定元素。这个细节避免了一个隐蔽 bug——如果复用同一个事件框节点,后一轮的内容会覆盖前一轮,玩家回看历史时只能看到最后一回合的只言片语。独立节点让整个剧情在 DOM 中形成一条永不消逝的时间线,任何时候向上滚动都能复盘之前的奇遇。

7.4 视觉风格:暗黑奇幻的构成要素

用 CSS 变量统一管理设计令牌:

:root {
    --bg-deep: #0b0f1a;      /* 深邃底色 */
    --gold:   #d4af37;       /* 主题金色 */
    --hp:     #e0605f;       /* 生命条 */
    --sta:    #57b8ff;       /* 精力条 */
}

氛围营造采用了几个关键手法:

  • 径向渐变模拟暗夜中的微光(顶部偏蓝、角落透金);
  • 毛玻璃(backdrop-filter)面板呈现"魔法书页"质感;
  • 金色作为唯一强调色,点缀标题、装饰符、选项图标;
  • 柔和 glitch 感不易实现,改用"辉光"(box-shadow)营造神秘层次;
  • 开场动画的浮动城堡图标,暗示"门扉之后的世界"。

响应式布局保证了移动端也能完整体验:窄屏下状态面板自动转为横向并排。


在这里插入图片描述

八、游戏主流程与状态管理

8.1 一回合请求的完整生命周期

以玩家点击选项为例,一次完整交互的生命周期为:

点击选项按钮
   ↓
组装 user 消息并 push 进历史
   ↓
构造 payload = [system, ...历史消息]
   ↓
流式请求(loading 遮罩显示"命运之书正在书写...(N字)")
   ↓
收到完整文本 → extractJson → normalizeScene
   ↓
失败则重试(最多 MAX_RETRY 次)
   ↓
成功:把模型原始 JSON 作为 assistant 消息入历史
   ↓
渲染:事件反馈 / 标题 / 打字机叙述 / 选项
   ↓
更新状态面板 → 等待玩家下一次输入

8.2 并发与输入防护

游戏进行中必须禁止玩家重复发送请求,否则消息历史会被并发请求搅乱。我引入 game.busy 标志位:请求期间禁用发送按钮、禁用输入框、隐藏选项区;渲染完本轮才恢复。这个"单飞"模型(同一时刻最多一个在途请求)虽然简单,却彻底杜绝了乱序响应的可能性。

8.3 加载文案的巧思

加载遮罩的提示文案是"命运之书正在书写…",并且我在流式解析时实时更新 (已收到 N 字)。这不仅是装饰——当用户在窄带宽下等待大段生成时,这在视觉和心理上给了用户"有东西正在产生"的正反馈,极大地降低了等待焦虑。


九、里程碑:从第一行代码到完整游玩的收获

9.1 关于"严格模式"与健壮性

我在 script.js 顶部声明了 "use strict"。严格模式不是可选项——它能提前暴露许多潜在的编码错误(比如误用未声明变量),对单人、小团队维护的成长型项目尤其重要。

9.2 关于错误的重试观

AI 返回质量不佳(解析失败)时的自动重试,我做了带指数的重试策略:最多 MAX_RETRY(默认 2)次,每次间隔 600ms,失败提示 (重试 N 次)。值得一提的细节是:重试时不需要清空或修改历史消息——因为模型是概率性的,同样的输入再次生成,结果往往就正常了。这与传统系统的"重试幂等"思维不同,是 LLM 应用特有的工程经验。

9.3 关于可读性:注释与文档

整个项目文件虽少,但都有清晰的区块注释:配置、DOM 引用、游戏状态、提示词、解析、渲染、主流程。因为这类项目天然适合被初学者复制学习,代码即文档是对读者最大的尊重。配套的 README 更是包含了完整的部署说明、Python↔JavaScript 对照表、数据契约说明与 FAQ。


十、安全实践:密钥不入库

纯前端项目最大的安全短板是 API 密钥的暴露问题。任何用户打开浏览器开发者工具都能看到请求头里的 Authorization: Bearer xxx。因此安全策略必须"以会泄露为前提"来设计:

10.1 三个层次的风险控制

  1. 开发期:密钥写在 config.js,但默认为空占位。克隆者必须自行申请并填入密钥,任何人都无法直接偷用别人的配额。
  2. 发布期:如果必须公开展示,配置密钥交给服务端代理(如 Cloudflare Workers、云函数)转发,浏览器只与同源代理通信。
  3. 运营期:密钥设置用量上限,定期轮换;日志脱敏,严禁将完整密钥写入日志或错误上报。

10.2 Git 提交的止血法

我特别避免将真实密钥提交进 git 历史——git 历史中的密钥视为永久泄露,即使后来删除,攻击者仍可从历史记录中提取。因此代码提交时,密钥位置始终是占位符,并借 README 醒目警告。这是我认为所有开源 AI 应用都应坚守的底线。


十一、本地验证与真实 Agent 的端到端测试

项目并非"写完就提交",我在交付前执行了四层验证,确保交付物可靠:

11.1 语法与静态检查

node --check script.js 校验 JS 语法零错误;逐一核对 HTML 中所有 id 与 JS 中 document.getElementById 的引用完全对应,杜绝"元素找不到"的空指针。

11.2 纯函数单元测试

针对 extractJson() 写了四组用例:纯净 JSON、含 markdown 围栏、前后夹杂质文本、纯垃圾文本。前三组应正确提取,第四组应返回 null。全部通过。

11.3 真实 API 流式端到端测试

用真实的 DeepSeek-V4-Flash 接口发起流式请求,验证:

  • SSE 帧按行正确切分;
  • data:[DONE] 哨兵正确终止;
  • 47 个增量 chunk 正确拼接为完整 JSON;
  • 完整游戏提示词下,模型对 8 个契约字段全部正确填充。

实测返回的 scene_title 为"尘封的回廊",叙述文本自然、选项 4 个、状态数值合法,说明提示词契约质量过硬。

11.4 本地 HTTP 服务资源巡检

启动静态文件服务器,轮询五个交付文件(HTML/CSS/JS/Config/README)全部返回 200,字节数与预期一致,确认部署无缺漏。


十二、如何运行这个项目

如果你也想体验一把由 AI 主持的冒险,步骤非常简单:

# 1. 克隆仓库
git clone https://atomgit.com/2601_94918285/AI_Adventur1.git
cd AI_Adventur1

# 2. 配置密钥:编辑 config.js,填入你的 API Key
#    API_KEY: "your_api_key_here"

# 3. 用任意本地静态服务启动
python -m http.server 8080
# 或 npx serve .

# 4. 浏览器打开
#    http://localhost:8080

点击"进入冒险",AI 立刻为你生成第一个场景。之后你可以:

  • 点击选项按钮推进剧情;
  • 在底部输入框自由输入任何行动;
  • 随时点击"⟲ 新游戏"开启全新剧情线。

十三、你还可以这样做:二次开发的方向

这个项目刻意保持了极简,留出了大量可扩展空间:

13.1 玩法维度

  • 多角色共存:给每个 NPC 独立的 system 角色,实现"同伴系统";
  • 时间与天气系统:在 JSON 契约中增加 dayweather 字段,让世界随时间推移而演化;
  • 任务与倒计时:加入 queststimer 字段,AI 可在限定回合内制造紧迫感;
  • 多语言:修改 system 提示词即可让 AI 用英文、日文等语言主持冒险。

13.2 技术维度

  • 服务端代理层:接一层轻量后端(Node/Go/云函数),把密钥迁移到服务端,开放限流与统计;
  • 存档系统:把消息历史 + 游戏状态序列化为 JSON,存入 localStorage 或导出文件,实现"读档重玩";
  • 音效与图片:根据 mood 字段接 TTS 朗读叙述、生成场景插画,升级为"多模态叙事";
  • 记忆持久化:引入向量数据库存储"玩家已探索的世界",让游戏世界跨会话延续。

13.3 模式启发

这个"系统提示词定义数据结构 → 前端结构化解构渲染"的架构,其实可以泛化到很多应用:

  • AI 表格填写助手:让模型返回结构化行数据,前端渲染成表格;
  • AI 表单生成器:模型返回字段 schema,前端动态生成表单;
  • AI 数据看板:让模型直接返回图表所需的 dataconfig,前端交给图表库渲染。

把"模型输出"从自由文本进化为"结构化契约",是 LLM 应用走向工程化的关键一步,远比反复调 prompt 更有杠杆。


十四、结语:让代码替你讲故事

回望整个项目,最令我感慨的并不是代码量——它只有区区一千多行——而是架构的轻盈与体验的厚重之间的反差。四个静态文件,撑起了一个理论上可以无限延续的世界。没有数据库,却有会流血、会疲惫、会捡起背包里每一件战利品的角色;没有服务端,却有实时流式生成的叙事;没有策划团队,却有每次运行都不重样的剧情。

这正是大模型时代最迷人的一面:当模型足够聪明,产品的最小可行形态可以小到极致,而体验的上限却由想象力决定。

「无尽回廊」是这扇门的一个入口。如果你也想亲手推开它,仓库就在这里:

仓库地址:https://atomgit.com/2601_94918285/AI_Adventur1
技术栈:HTML5 + CSS3 + JavaScript + DeepSeek-V4-Flash(OpenAI 兼容 Chat Completions 流式接口)

愿你的每一段冒险,都由大模型温柔相待。


*本文为「码道」系列技术分享文章,欢迎转载,注明出处即可。*在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐