news 2026/9/6 4:08:06

用大语言模型做网页文字游戏:Agent 架构、提示词工程与流式输出实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用大语言模型做网页文字游戏:Agent 架构、提示词工程与流式输出实战

“LPAI:用 AI 做一款简单、好玩的网页文字游戏”——这个项目名字是我自己起的,LPAI 就是“Little Personal AI”的缩写,意思是做一个轻量的、个人化的 AI 文字游戏。整体思路很简单:让大语言模型当游戏引擎,玩家用自然语言输入指令,AI 负责推进剧情、判断结果、维护状态,网页只做展示和交互。这篇文章就把我从零到一把它做出来的完整过程拆开讲,包括方案选型、提示词设计、状态管理、前后端联动,以及中间踩过的各种坑,给同样想用 AI 做交互应用的朋友一条可以直接抄的路线。

先交代一下背景。我平时喜欢玩文字冒险游戏,老式的 MUD、互动小说、跑团都接触过不少。这类游戏最大的魅力是“自由”,但最大的痛点也是“自由”——传统文字游戏的剧情分支是写死的,你要么选择一个选项,要么输入一个命令,系统能理解的东西极其有限。而大语言模型天然适合干这事:它懂自然语言,能理解意图,能生成文本,还能保持上下文。把 LLM 塞进文字游戏里,理论上玩家想干什么都行,不用再受限于预定义的选项。LPAI 就是奔着这个方向做的。

这篇文章适合谁看?如果你是做 AI 应用开发的,想了解怎么把大模型接到真实产品里,怎么处理流式输出、状态持久化、提示词稳定性这些问题,这篇能给你一套完整的落地参考。如果你是个游戏爱好者,想自己做个小游戏但不会写复杂逻辑,这篇也能让你明白,用 AI 做游戏的核心不是编程,而是设计“规则”和“交互”。我尽量把每一步都写清楚,包括为什么这么做、不这么做会出什么问题。

1. 项目整体设计与方案选型

1.1 为什么选择“LLM 即引擎”的架构

先说一个最核心的决策:游戏逻辑到底由谁承担。

传统方案是自己写规则引擎。比如玩家输入“拿起剑”,你需要在代码里解析意图、匹配物体、判断背包、更新状态,每一步都要写逻辑。这套方案的缺点是工作量爆炸——一个稍微像样的互动游戏,状态组合是天文数字,你根本写不完所有可能性。

LPAI 换了一个思路:把游戏世界描述交给大模型,让模型根据当前状态和玩家输入,决定“这个世界发生了什么”。我的角色不是“实现每个动作”,而是“定义世界的规则和边界”。比如我告诉模型:你是一个游戏主持人,玩家在一个废弃的太空站里,你负责描述场景、处理玩家的行动、判定成功失败。然后玩家说“我想撬开那扇门”,模型就会自己生成结果——可能成功,可能失败,可能触发警报,完全不用我提前写这些分支。

这个架构的好处很明显:开发量小,灵活度极高,玩家体验是真正“自由输入”而不是“选 A/B/C”。但也有代价:模型输出不稳定,可能胡说八道,可能无视规则,需要做大量约束和校验。这个权衡在我看来是值得的,因为它的下限很高——模型再乱也不会比“我输入了词组但系统完全听不懂”更糟糕。

1.2 技术栈的选择逻辑

技术栈我最终定为:前端纯 HTML/JavaScript,后端 Node.js + Express,LLM 通过 API 调用。为什么这么选,逐一说。

前端不搞框架。文字游戏的核心界面就是“一段历史消息 + 一个输入框”,React/Vue 在这种场景下没有优势,反而引入构建工具的复杂度。我直接用原生 HTML + CSS + 少量 JS,一个文件搞定,任意浏览器打开就能用。如果你想做得更美观,后期再加框架也不迟,核心逻辑和 UI 是解耦的。

后端用 Node.js 是因为它对流式响应支持自然。大模型生成文本是逐个 token 往外蹦的,如果你等全部生成完再一次性返回,玩家要等好几秒,体验很差。用 SSE(Server-Sent Events)或简单的 chunked response,可以把模型吐出来的文字实时推到前端,配合打字机效果,体验接近 ChatGPT 那种流式输出。这一点用 Python 做也不是不行,但 Node 的异步模型写起来更顺手。

LLM 的选择上,我建议优先考虑支持 OpenAI 兼容接口的模型,不管是商业 API 还是本地部署的,兼容性最好。LPAI 里我做了可配置的 baseURL 和 model 字段,方便切换。实际测试中我用过通用对话模型和代码模型,效果差异不大,关键不在模型大小,而在提示词设计——后面专门讲。

1.3 为什么这个项目适合用 Agent 的方式做

现在 AI 圈特别流行“Agent”的概念,LPAI 本质上就是一个单 Agent 的文字交互应用。Agent 在这里的定义很朴素:一个能感知输入、调用工具、决策行动、产生输出的循环。

LPAI 的 Agent 循环大概是这样的:

  1. 接收玩家文字输入。
  2. 拼接完整上下文:世界观设定 + 当前状态 + 历史摘要 + 玩家输入。
  3. 调用 LLM,让模型输出一段结构化结果(包含剧情文本、状态更新、判定结果)。
  4. 解析模型输出,更新游戏状态,把剧情文本推送回前端。
  5. 回到步骤 1,等待下一次玩家输入。

这个循环里没有复杂的工具调用,也不需要多 Agent 协作,但它已经具备 Agent 的基础特征:感知(读输入)、记忆(历史摘要)、决策(LLM 生成)、行动(更新状态与输出文本)。你在做更复杂的 AI 应用时,比如让 AI 替你订机票、写邮件,也是同样一套骨架,只是换掉“行动”的具体实现。这也是为什么我说 LPAI 不只是一个游戏,更是一个 AI 交互应用的最小可行范例。

2. 核心细节解析与实现要点

2.1 提示词工程:让模型学会“当主持人”

LPAI 里最重要的不是代码,是提示词。我把它叫做“主持人系统提示词”,份量最重。这个提示词不是简单说“你是游戏主持人,请描述剧情”,而是要把规则、输出格式、边界条件全都塞进去。

我的系统提示词分成四层。第一层定义身份和世界观:你是一个文字冒险游戏的主持人,游戏背景是一次太空站探索任务,玩家是唯一的幸存者。第二层定义任务目标:根据玩家的行动描述结果,推动剧情发展,制造悬念和挑战。第三层定义交互规则:尊重玩家的自主选择,不要替玩家做决定,不能让玩家角色无故死亡(除非玩家主动作死),要维持游戏的一致性——之前出现过的物品、角色、事件不能凭空消失或改变。第四层最重要:输出格式必须是 JSON,包含三个字段:narrative(给玩家看的剧情文本)、state_update(需要更新的游戏状态)、events(触发的事件列表,比如获得物品、生命值减少)。

为什么强调 JSON 格式?因为如果不规定输出结构,模型会自由发挥,一会输出纯文本,一会输出带 Markdown 的文本,你解析起来非常痛苦。JSON 相当于给模型的输出加了一道围栏,把它的创造力限制在“内容”层面,而不是“形式”层面。实测下来,只要清晰说明 JSON 结构并给出示例,主流模型基本都能稳定输出。偶尔出格式错误,靠解析失败重试一次就能解决。

提示词还有一个细节:给一个示例输出,哪怕只有一个字段也行。这招非常管用,模型看到示例后,模仿能力会显著增强。我建议系统提示词里至少放这样一个小示例:

{ "narrative": "你走上前去,门上的指示灯闪烁着微弱的红光。", "state_update": {"location": "airlock", "tension": 1}, "events": [] }

2.2 状态管理的艺术:既要完整,又要省 token

文字游戏必须有状态,比如玩家位置、生命值、物品、NPC 好感度。但状态到底怎么存,是个值得琢磨的问题。

最简单粗暴的方式是每次请求都把完整状态塞给模型,让它在 JSON 里返回全部更新后的状态。缺点是 token 消耗巨大,而且模型偶尔会遗漏某个字段,导致状态悄悄丢失。玩家上一秒还拿着手电筒,下一秒就没了,这种体验很糟糕。

我的方案是“服务端状态 + 增量更新”。游戏状态存在后端内存里(正式产品可以存数据库),每次请求时我把当前状态精简成一句摘要塞给模型,而不是把所有字段堆给它。模型只需要在 state_update 里返回“变动了的东西”,后端负责合并。

比如当前状态是“位置:airlock,生命值:80,背包:[手电筒]”,我传给模型的不是这段原始结构,而是一句话“当前玩家位置是气闸舱,生命值 80,身上带着一个手电筒”。模型理解了上下文,输出 state_update: {"tension": 2},后端就把 tension 从 1 更新到 2,其他字段原样不动。这样省 token,也避免模型误改无关字段。

合并更新时需要处理一个问题:有些字段是数组(比如背包),模型可能只返回新增物品,但我需要的是“添加操作”而不是“覆盖操作”。我的做法是在 state_update 里约定:如果字段是数组,则默认追加;如果要覆盖,则显式加一个 clear 标记。规则有点绕,但在代码里实现也就十几行,效果好过让模型每次输出完整背包。

2.3 上下文管理:用摘要对抗长对话

文字游戏玩久了,对话轮次会非常多,上下文窗口迟早会被撑爆。直接把所有历史消息都塞给模型,不仅浪费 token,而且模型容易“记错”——注意力分散在大量早期内容上,反而忽略最新的关键信息。

LPAI 用了一个简单有效的方案:滑动窗口 + 历史摘要。每次请求只带最近的三轮对话,更早的内容压缩成一段固定格式的摘要。摘要是怎么生成的?也是让模型做——在每轮对话结束时,我把当前轮次的剧情、玩家的关键行动、重要状态变化提炼成三四句话,追加到 summary 字段里。

这样做的效果是:无论游戏进行了多少轮,我传给模型的 tokens 基本恒定。模型既能通过摘要记住主线(比如“玩家已经拿到了逃生舱钥匙”),又能通过最近对话感知当下情境(比如“玩家正被怪物追赶”),两全其美。代价是摘要本身可能遗漏细节,但它带来的稳定性收益远大于损失。

2.4 流式输出的前端联动

我前面提到用 SSE 做流式输出,这里详细说一下体验细节。当后端接收到 LLM 返回的流式内容时,数据是分块到达的。后端不能直接把 JSON 结构流式传给前端——因为 JSON 是在模型完整生成之后才能解析的,如果一边生成一边传,前端拿到的是一堆碎片,没法渲染。

这里的解法是“双轨输出”:模型产出的 narrative 字段(剧情文本)流式转发给前端,让玩家看到文字一个一个字蹦出来,产生“AI 正在写作”的沉浸感。而 state_update 和 events 这两个结构化字段,等模型生成完毕、后端解析完成后再一次性提交。也就是说,前端先看到文字,再看到状态变化,顺序上是:剧情描述 → 状态栏刷新。实际体验就像翻页小说加了一个即时的数值面板,非常顺滑。

前端的渲染我做了一个“打字机”效果:收到一个 chunk,就往消息区的当前段落追加一段文字,并自动滚动到底部。实现不复杂,关键在于处理中断——玩家在 AI 还没说完话时就输入了下一个指令,旧请求要取消,新请求要覆盖旧的状态。我用了 AbortController 来终止未完成的请求,避免出现两条剧情同时输出的错乱。

3. 实操过程与核心环节实现

3.1 搭一个最小可运行的 Agent 核心

先看后端最核心的一个函数——处理玩家输入并联动模型:

const express = require("express"); const app = express(); app.use(express.json()); // 游戏状态,正式场景应持久化 const gameState = { location: "太空站入口", hp: 100, inventory: ["身份卡"], flags: { alarmRaised: false } }; // 系统提示词:定义身份、规则、输出格式 const SYSTEM_PROMPT = ` 你是一个文字冒险游戏的主持人,游戏背景是废弃太空站。 你必须遵守以下规则: 1. 根据玩家行为和当前状态推进剧情,绝不代替玩家做决定。 2. 保持世界的一致性,已出现的物品和事件不能凭空消失。 3. 输出必须是 JSON 格式,包含 narrative、state_update、events 三个字段。 4. narrative 长度控制在 100-200 字之间,用第二人称描写。 示例输出: {"narrative": "你走上前去,门上的指示灯闪烁着微弱的红光。", "state_update": {"tension": 1}, "events": []} `; app.post("/api/act", async (req, res) => { const { input, history, summary } = req.body; const messages = [ { role: "system", content: SYSTEM_PROMPT }, { role: "system", content: `当前状态摘要:${JSON.stringify(gameState)}` }, { role: "system", content: `历史摘要:${summary ?? "暂无"}` }, ...history.slice(-6), // 只携带最近六条消息 { role: "user", content: input } ]; const response = await fetch(process.env.LLM_API_URL, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${process.env.LLM_API_KEY}` }, body: JSON.stringify({ model: process.env.LLM_MODEL, messages, temperature: 0.8 }) }); const data = await response.json(); const content = data.choices[0].message.content; // 解析 JSON,失败则重试一次 let parsed; try { parsed = JSON.parse(content); } catch (e) { return res.status(500).json({ error: "模型输出格式异常,请重试" }); } mergeState(gameState, parsed.state_update); res.json({ narrative: parsed.narrative, state: gameState, events: parsed.events }); }); app.listen(3000, () => console.log("LPAI backend running on 3000"));

这段代码是最小闭环,已经能跑通“输入行动 → 模型生成 → 更新状态 → 返回剧情”的完整循环。mergeState 就是那个做增量合并的函数,注意数组字段要追加而不是覆盖:

function mergeState(state, update) { if (!update) return; for (const [key, value] of Object.entries(update)) { if (Array.isArray(value)) { state[key] = [...(state[key] || []), ...value]; } else { state[key] = value; } } }

3.2 让状态更新更可控:增加“意图操作”

但直接让模型返回 state_update 有一个隐患:模型可能把玩家背包物品写丢,比如玩家说“把手电筒扔掉”,模型只返回 narrative 而忘记更新背包。这就要在提示词里加操作语义。

我在 state_update 基础上增加了一个可选字段 intent_ops,专门处理对数组和数值的操作,比如:

{ "narrative": "你把手电筒扔进了通风管道。", "state_update": {}, "intent_ops": { "inventory": {"op": "remove", "item": "手电筒"}, "hp": {"op": "add", "value": -10} } }

后端先处理 intent_ops,再处理 state_update。这样模型不需要知道“背包当前长什么样”,只需要告诉系统“删掉什么、加多少”,就不会出现覆盖整个背包的问题。数值变更也由此变得稳定——玩家受到伤害、回血、获得经验,都是显式的加减操作,而不是直接赋值。

这个设计是从实际踩坑里逼出来的。早期版本我让模型直接返回 hp: 80,结果有一次模型把 100 写成 200,玩家直接从满血变成了不死之身。改成操作语义后,这种离谱错误就很少发生了,因为“当前值是多少”由后端算,模型只描述“产生了什么影响”。

3.3 前端:如何把流式输出做成“有手感”的交互

前端的核心是渲染消息区和处理流式输出。我直接贴一个简化版的核心逻辑:

async function sendAction(input) { const controller = new AbortController(); activeController = controller; // 追加玩家消息到界面 appendMessage("player", input); const resp = await fetch("/api/act/stream", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ input, history: msgHistory, summary: currentSummary }), signal: controller.signal }); // 读取 SSE 流 const reader = resp.body.getReader(); const decoder = new TextDecoder(); let narrativeBlock = appendMessage("ai", ""); while (true) { const { done, value } = await reader.read(); if (done) break; const text = decoder.decode(value); narrativeBlock.textContent += text; // 滚动到底部 container.scrollTop = container.scrollHeight; } // 流结束后取回结构化状态 const stateResp = await fetch("/api/act/state"); const stateData = await stateResp.json(); renderStatePanel(stateData.state); }

注意这里后端要把生成过程拆成两个接口:/api/act/stream 负责流式返回剧情文本,/api/act/state 负责返回解析后的状态。实际实现要保证这两个接口共享同一状态实例,避免中间状态不一致。

前端界面我故意做得很素——黑色背景、等宽字体、绿色文字,有点老式终端的感觉。输入框默认聚焦,回车即发送。界面要素只有三个:消息区、状态栏(生命值/位置/背包)、输入框。对于文字游戏来说,一个干净的界面反而能增强沉浸感,复杂的 UI 会分散玩家注意力。

3.4 玩起来有意思是关键:随机性与正反馈

光有技术不行,游戏得好玩。这是我整个项目里反思最深的地方。最早版本我跑通技术流程后,自己玩了两轮就腻了——因为模型只会描述场景,玩家做什么都能成功,没有任何张力。

解决之道是给模型施加“戏剧性压力”。我在系统提示词里加了这几条:

  • 不要轻易让玩家成功,给每个行动设置合理的成功率,失败也要导向有趣的结果。
  • 每隔 3-5 轮,主动引入一个新事件:警报声、新线索、角色登场、危机发生。
  • 玩家的选择要产生实际影响,并在后续剧情中被提及或引用——让玩家感到自己的行动有意义。

举一个实际例子。玩家说“我要搜索控制台”,模型如果直接给“你找到了一张纸条”,这就很无聊。更好的输出是:“你在控制台的键盘夹缝里发现一张被揉皱的纸条,但与此同时,走廊传来脚步声,越来越近。”这样一来,玩家必须立刻做下一个决定:继续读纸条,还是找地方躲起来。游戏的节奏感和张力就出来了。

想让模型稳定产出这种内容,需要给提示词加“戏剧性规则”,本质上就是调教模型像一个有经验的主持人而不是一个被动应答的秘书。要明确告诉它:你的任务是制造有趣的决策,而不是满足玩家的一切愿望。这个思维转变对 AI 游戏开发来说非常关键。

3.5 后端部署的几个注意点

LPAI 的后端可以部署在任何支持 Node.js 的环境,我用的是 Docker + 一个简单的 Linux 服务器,配置大概是这样的:

FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install --production COPY . . EXPOSE 3000 CMD ["node", "src/index.js"]

部署时有两个坑值得说。第一个是环境变量管理:API 密钥绝对不能写死在代码里,我用 dotenv 加载 .env 文件,这个文件不进 Git。第二个是进程守护:Node 进程崩了得能自动重启,我在容器里用了 PM2 做进程管理,宿主机配置了 Docker 的 restart 策略。文字游戏用户量不大,这样已经非常可靠。

另外要特别注意 API 的流式连接超时问题。有些 LLM API 对连接时间有限制,如果你的提示词很长,模型生成时间又长,连接可能被切断。我在后端设置了超时重试机制,并且在前端做了提示“AI 正在思考中”,避免玩家误以为卡死。

4. 常见问题与排查技巧实录

4.1 JSON 解析失败:让模型“闭嘴”不乱说

这是最容易遇到的问题。模型输出 JSON 时偶尔会在前后加额外的文字,比如“好的!这是你的结果:{...}”。解析直接失败。

我的排查策略有三层。第一层:在后端捕获 JSON.parse 异常后,先尝试用正则把第一个 { 到最后一个 } 之间的内容截出来再解析。这个办法能解决八成问题。第二层:给模型 redo,把上一次的输出拼上提示词“请仅输出 JSON,不要包含任何其他文字”,再调用一次。第三层:在系统提示词里强调“不要输出 JSON 之外的任何字符”,并在示例里明确展示纯 JSON 的样子。

三层下来,解析失败率基本降到了 1% 以下。剩余那 1% 就交给用户重试一次,作为 AI 应用的容错设计,完全可以接受。

4.2 模型无视规则,擅自控制玩家角色

文字游戏最忌讳“NPC 式 AI”替玩家做决定。我早期测试时,输入“我要逃跑”,模型竟然直接写“你逃跑了”,没有给玩家任何选择余地。这就像跑团 DM 把你的人物卡抢过来替你行动,体验非常差。

我加了两条很硬性的提示词约束:“严禁替玩家做出选择或行动,玩家的行动必须由玩家亲自发出指令。”以及“如果玩家没有明确行动,你只能描述环境和氛围,不能推进事件。”同时,我让模型在 narrative 里输出时,尽量以“你看到了……”“你感到……”这样的感知性描写为主,把决策权留给玩家。

还有一种更精细的调法:给忽略规则的输出一个惩罚式反馈。如果检测到 narrative 里出现了“你做了某件事”的表述,后端可以把这次输出标记为“规则违反”,把错误信息反馈给模型,让它重新生成。这需要额外的检测逻辑,但也不算复杂,我用字符串匹配加规则引擎勉强实现了,效果不错。

4.3 输出太长或太短,节奏不对

模型生成的剧情文本长度很难控制。太长了像流水账,太短了像干巴巴的播报。我在提示词里写了“narrative 长度控制在 100-200 字之间”,但模型有时候还是会抽风,输出个 500 字的小作文。

后来我用了一个后处理方案:在后端对 narrative 做长度裁剪。超过 250 字就截断到最近的句号;如果低于 50 字,则把 history 里的上下文重新强调一下,再次请求让模型基于上一段展开。这样虽然多花一次 API 调用,但保证了玩家体验。

当然,长度控制也不是越短越好。如果一段剧情描述少于 50 字,玩家根本没法建立画面感。关键阈值是 80-150 字,这个长度足够描绘环境、给出信息、抛出钩子,又不会让玩家失去耐心。我个人实测后定的目标值就是这个区间。

4.4 历史摘要越滚越乱,主线丢失

游戏进行到二十轮以后,摘要可能长达几百字,而且越早的信息越模糊。玩家可能在第 5 轮捡到的钥匙,到第 30 轮模型已经忘了,导致明明有钥匙却写“门打不开”。

针对这个问题,我在摘要生成时让模型额外输出一个“关键物品清单”,每轮都更新一次,确保核心道具永远不会被遗忘。摘要变成两个部分:情节摘要 + 关键物品/事件清单。后者虽然是纯列表,但对维持一致性帮助巨大。

还有一个更简单的兜底方案:把玩家的背包和关键 flag 直接放进系统提示词的“当前状态摘要”里,而且是硬编码拼进去的,不走模型摘要。也就是说,背包丢了什么东西,系统是真实存着的,模型只是“使用者”而不是“记忆体”。只要模型每次决策前都看到背包清单,就不会出现“有钥匙不用”的蠢事。

4.5 常见问题速查表

现象可能原因解决方案
模型输出带额外文字导致 JSON 解析失败提示词约束不够正则截取 + 重试 + 强化格式规则
玩家输入后没有反应流式连接超时后端超时重试,前端显示思考中状态
状态字段变成 null增量更新合并出错检查 mergeState,数组和对象要深拷贝
剧情前后矛盾摘要丢失关键信息增加关键物品清单 + 硬编码状态摘要
模型代替玩家做决定提示词未明确边界加入严禁行为条款 + 感知性描写约束
游戏玩一会儿就无聊缺少事件推动力设置戏剧性压力规则,3-5 轮引入新事件

4.6 独家避坑心得

最后分享几个不好归类的经验。第一,LLM 的作用域要尽量窄。每一次调用,模型只需要关心“当前回合发生了什么”,不要让它管理全局进度、分支状态这类复杂信息,那些应该放在后端的数据库或文件里。模型越专注,输出越稳定。

第二,永远准备一个离线兜底方案。有一次 LLM API 服务商出故障,我的游戏直接没法玩。后来我给后端加了一个“本地规则模式”:当 API 调用失败时,自动切换到一套关键词匹配的简易回应逻辑,虽然笨但至少能让玩家继续玩。对于个人项目来说,这种降级处理是必要的心态:你不是在做一个依赖单一服务的产品,而是在做一个有韧性的系统。

第三,别把“模型的创造力”当成“游戏的设计力”。模型能生成文本,但它不知道什么好玩。游戏好不好玩,取决于你在提示词里嵌入了多少设计思考。我花了大量时间在调整“戏剧性规则”上,而不是在调模型参数上。真正让 LPAI 变好玩的关键修改,是加了“不要轻易让玩家成功”这一条,它让游戏从“记事本”变成了“冒险”。

我在写这个项目的过程中最大的感受是:用 AI 做应用,核心能力已经从“写代码”变成了“写规则”。你需要清楚地定义:AI 能做什么、不能做什么、输出结构是什么、状态如何流转、失败怎么处理。这些规则写好了,代码反而是最轻松的部分。LPAI 算是我在 AI 应用开发上的一次完整练兵,从模型调用、流式输出、状态管理到部署运维全走了一遍,也让我对 AI 产品经理口中的“提示词策略”有了实打实的体感。如果你也想做点什么,建议不要只停留在调 API 玩一玩,试着把一个完整的小应用跑起来——哪怕是这种简单文字游戏,做完之后你对 AI 应用的理解都会完全不同。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 4:07:00

智能手表技术拆解:从BLE通信到消息推送的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 3:57:38

RK3588边缘盒子周期性掉线排查:电源、散热与AI负载的隐性坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 3:52:28

微信小程序课堂考勤系统开发:毕业设计实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 3:49:22

魔女的魔法小木屋 THreeJS 开源

GitHub - YIBI2333/line-art-style-magic-cabin GitHub 魔女的魔法小木屋 一个线稿风格的 3D 魔法小屋。 页面预览 操控一只软软的史莱姆在魔法小屋里生活 使用 HTML—— 单HTML页面实现Three.js r128—— 场景、相机、几何体与渲染原生 JavaScript —— 单个 HTML 文件、单个…

作者头像 李华
网站建设 2026/9/6 3:47:44

FPSO孤岛电网稳定性分析与PMS电源管理系统优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华