当前位置:首页>PPT>如何让AI生成100页PPT

如何让AI生成100页PPT

  • 2026-04-16 13:51:33
如何让AI生成100页PPT

引言:打破 Vibe Coding 的"一键生成"神话

每个第一次尝试用 AI 做 HTML 演示文稿的人,几乎都会犯同一个错误。

他们打开对话框,输入一段雄心勃勃的 Prompt:

"请帮我生成一个完整的 HTML 演示文稿,共 100 页,主题是XX,要求有封面、目录、图文分栏、代码示例、数据图表,风格简洁现代,支持键盘翻页……"

然后按下回车,满怀期待地等待。

AI 开始输出。前几页看起来不错,HTML 结构清晰,样式也挺好看。但写到第 15 页左右,代码开始出现 <!-- 此处省略,样式同上 -->。写到第 30 页,翻页逻辑消失了。写到第 50 页,输出直接被截断。最终你得到的,是一个残缺的、样式混乱的、根本无法运行的代码堆。

这不是 AI 不够聪明,也不是你的 Prompt 写得不够好。这是一个物理限制问题,任何大语言模型都无法绕过。


真正的问题出在哪里?

我们习惯把"做一个 100 页 PPT"理解为一项写作任务——就像让 AI 写一篇长文章一样,只要给够指令,AI 应该能一气呵成输出全部内容。

但 100 页 HTML PPT 本质上不是一篇文章,它是一个软件工程项目

一篇文章可以从第一个字写到最后一个字,中间的每一句话都依赖前面的语境。但一个软件项目有架构、有模块、有数据、有渲染逻辑——这些东西不能被"顺序生成",它们必须被设计,然后被组装

把软件工程项目当成写作任务交给 AI,就像拿着一张食材清单,让厨师直接端出一桌满汉全席——不是厨师的问题,是你给错了任务单。


本文要解决的核心问题,只有一个:

如何把"生成 100 页 PPT"这件事,从一个写作任务重新定义为一个工程任务

一旦完成这个认知转变,AI 就不再是那个需要一口气输出所有内容的"全知作者",而是变成你流水线上的专项工程师——每次只做一件明确的事,每次的输出都能直接运行,最终由你把所有模块组装成完整的产品。

这就是 Vibe Coding 真正应该被使用的方式。


第一章:重塑认知 —— 为什么 100 页会让 AI "精神分裂"?


1.1 那堵看不见的墙:Token 限制

和 AI 对话,感觉像是在和一个无所不知的人聊天。但这个"人"有一个非常具体的生理限制:它的大脑在任意时刻只能容纳有限数量的文字

这个限制的单位叫做 Token

Token 不完全等于字符,也不完全等于单词。粗略地理解,一个英文单词大约是 1-2 个 Token,一个中文字大约是 1-2 个 Token。对于大多数主流模型来说,单次对话能处理的 Token 总量是有上限的——包括你输入的所有内容,加上 AI 需要输出的所有内容,加上系统的背景设定,全部加在一起,不能超过这个上限。

这带来两个直接后果。

第一个后果:输出被截断。

当你要求 AI 生成 100 页 HTML,AI 会在某个时刻触碰到输出长度的天花板,然后戛然而止。你看到的不是一个完整的文件,而是一个被硬生生切断的代码片段——有开头,没结尾,浏览器根本无法解析。

第二个后果:AI 主动压缩内容。

更隐蔽的问题是,AI 在生成过程中会"感知"到自己剩余的输出空间不多了,于是开始自动省略。第 20 页之后,你会看到这样的代码:

<!-- 第21页 - 结构同第20页,内容替换即可 -->
<!-- 第22页 - 同上 -->
<!-- ... 此处省略至第100页 -->

这不是 AI 在偷懒,这是它在用它认为"合理"的方式,在有限的输出空间内尽量覆盖你的需求。问题在于,这种"合理"对你毫无价值——你得到的是一堆注释,而不是可以运行的代码。


1.2 另一堵墙:注意力稀释

Token 限制是一个硬限制,碰到了就停。但还有另一个问题更加隐蔽,很多人遇到了却不知道原因——注意力稀释

要理解这个问题,先理解 AI 是怎么"记住"上下文的。

AI 在生成每一个新的字符时,都会回头看整个对话历史,计算"哪些之前说过的内容,和我现在要写的东西最相关"。这个计算过程叫做注意力机制。它不是简单地从头读到尾,而是对历史内容做加权——越相关的内容权重越高,越不相关的权重越低。

这套机制在短对话里表现完美。但当上下文变得非常长,问题就出现了。

权重被稀释了。

想象你在开头定义了一套完整的 CSS 设计规范:主色调、字体大小、间距系统、组件样式。这套规范写了大约 200 行。在生成第 1 页到第 10 页时,AI 能清楚地"看见"这套规范,输出的样式高度一致。

但当对话进行到第 80 页时,历史上下文已经积累了几万个 Token。开头那 200 行 CSS 规范,相对于整个上下文的比重变得极小。AI 的注意力被后面大量的内容分散,对最初规范的"记忆"开始模糊。

于是你会看到这样的现象:

没有任何报错,没有任何警告。代码完全可以运行。但视觉上,你的第 1 页和第 80 页看起来像是两个完全不同的人做的。


Token 限制和注意力稀释,本质上是同一件事的两面。

Token 限制说的是:AI 能处理的信息总量有上限。注意力稀释说的是:即使在上限之内,AI 对早期信息的把握也会随着上下文增长而衰减。

两者叠加的结果是:你越想一次性让 AI 做更多,AI 能做好的比例就越低。

这不是通过"写更好的 Prompt"能解决的问题。这是架构问题,需要架构层面的解法。

而这个解法,就是接下来整篇文章要讲的核心思路:不要让 AI 记住所有东西,而是把"需要记住的东西"从对话中剥离出去,变成代码和数据。


第二章:脚手架工程 —— 搭建零依赖的"主舞台"


2.1 只写壳子,不写内容

上一章说清楚了问题的根源:AI 的上下文是有限的,注意力是会稀释的。那么解法的第一步,就是把"内容"从"结构"里彻底剥离出去

什么叫"只写壳子"?

想象你在建一座剧院。剧院建好之后,今晚演莎士比亚,明晚演现代舞,后天办音乐会——舞台本身不需要为此改变任何结构。灯光、座位、音响系统,全部不动。变的只是上面演的内容。

我们要做的 HTML PPT,结构上应该是同一件事:一个稳定的舞台,加上可以随时替换的内容

这意味着,第二章要让 AI 写的这个"壳子",完成之后应该长这样:

  • 打开浏览器,页面是全黑的,或者显示一个空白的占位符
  • 按左右方向键,页面能响应,能翻页——哪怕现在还没有任何内容
  • 代码结构清晰,有一个明确的"插槽",后续的内容全部注入到这里

这个壳子一旦写好,就不再需要 AI 碰它了。

后续所有的对话,AI 只需要关心一件事:生成内容。翻页逻辑、全屏适配、键盘事件——这些东西只写一次,永久稳定。


2.2 用 Vibe Coding 写出这个壳子

这是你和 AI 的第一次实质性对话。Prompt 应该非常具体,边界非常清晰:

"请写一个零外部依赖的单页 HTML 文件,实现以下功能:

  1. 全屏自适应容器,始终占满视口,背景色 #0f0f0f
  2. 页面中央有一个 id="slide-mount" 的 div,作为幻灯片的挂载点,暂时为空
  3. 监听键盘左右方向键事件,分别触发 prevSlide() 和 nextSlide() 函数
  4. 维护一个 state 对象,包含 current(当前页索引)和 total(总页数)两个字段
  5. 不要写任何幻灯片内容,不要写任何样式组件,只写框架本身
  6. 完整输出所有代码,禁止使用任何注释替代真实代码"

注意最后两条指令。第 5 条划定了边界——这次对话只做这一件事。第 6 条是防压缩指令——明确告诉 AI 不能省略。

AI 应该输出类似这样的结构:

<!DOCTYPE html>
<htmllang="zh">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>Presentation</title>
<style>
    * { margin0padding0box-sizing: border-box; }

body {
width100vw;
height100vh;
background#0f0f0f;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
    }

#slide-mount {
width100%;
height100%;
position: relative;
    }
</style>
</head>
<body>
<divid="slide-mount"></div>

<script>
const state = {
current0,
total0
    };

functionprevSlide({
if (state.current > 0) {
        state.current--;
        renderCurrent();
      }
    }

functionnextSlide({
if (state.current < state.total - 1) {
        state.current++;
        renderCurrent();
      }
    }

functionrenderCurrent({
// 由 engine.js 实现,此处为占位
    }

document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft')  prevSlide();
if (e.key === 'ArrowRight') nextSlide();
    });
</script>
</body>
</html>

这段代码此刻什么都不显示。但它已经具备了一个完整 PPT 框架所需要的全部骨骼:状态管理、事件监听、挂载点。

这就够了。现在关掉这个对话窗口。

下一个对话,我们去做完全不同的一件事。


第三章:原子化设计 —— 打造你的"幻灯片组件库"


3.1 不要重复造轮子

现在你有了一个稳定的舞台。下一步,很多人会直接开始写内容——打开新对话,让 AI 开始生成第 1 页、第 2 页、第 3 页……

这是第二个常见陷阱。

100 页 PPT,看起来是 100 个独立的页面。但仔细观察任何一套专业的演示文稿,你会发现一个规律:页面的种类其实非常少

一套典型的技术分享 PPT,大概率只有这几种页面:

  • 封面页:大标题 + 副标题
  • 要点页:一个标题 + 若干条目
  • 图文页:左图右文,或左文右图
  • 代码页:标题 + 代码块
  • 图表页:标题 + 数据可视化

100 页内容,本质上是这 4-5 种模板的不同数据填充

这个认知非常重要。它意味着你不需要让 AI 写 100 段 HTML——你只需要让 AI 写 5 个模板函数,然后用数据驱动这 5 个函数生成 100 页。

这就是组件化思路的核心:把"页面"变成"模板 + 数据"。


3.2 先立规矩:全局 CSS 规范

在写任何组件之前,先用一次独立的对话,让 AI 输出一套全局 CSS 规范。

为什么要单独做这一步?

因为这套规范是所有组件的共同语言。字体大小、颜色系统、间距单位——如果这些东西在每个组件里各自定义,最终拼在一起必然视觉混乱。把它们提取成 CSS 变量,写在一个地方,所有组件只引用变量名,就从根本上消灭了这个风险。

给 AI 的 Prompt:

"请输出一套用于全屏 HTML 演示文稿的 CSS 全局规范,要求:

  1. 使用 CSS 自定义属性(变量)定义所有设计 token
  2. 包含:主色、辅助色、背景色、文字色(主次两级)
  3. 包含:字体大小系统(标题大、标题中、正文、注释四级)
  4. 包含:间距系统(4px 基准单位,定义 sm / md / lg / xl 四个档位)
  5. 包含:针对幻灯片的基础布局类(全屏居中、左右分栏、上下分栏)
  6. 不要写任何组件样式,只写设计 token 和布局工具类
  7. 完整输出,禁止省略"

AI 应该输出类似这样的内容:

:root {
/* 颜色系统 */
--color-primary:    #4F6EF7;
--color-accent:     #00D4AA;
--color-bg:         #0f0f0f;
--color-surface:    #1a1a1a;
--color-text:       #F0F0F0;
--color-text-muted#888888;

/* 字体大小系统 */
--text-display64px;
--text-heading40px;
--text-body:    20px;
--text-caption14px;

/* 间距系统 */
--space-sm:  8px;
--space-md16px;
--space-lg32px;
--space-xl64px;
}

/* 布局工具类 */
.slide-center {
width100%;
height100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
paddingvar(--space-xl);
}

.slide-split {
width100%;
height100%;
display: grid;
grid-template-columns1fr 1fr;
gapvar(--space-lg);
paddingvar(--space-xl);
}

.slide-stack {
width100%;
height100%;
display: flex;
flex-direction: column;
justify-content: center;
paddingvar(--space-xl);
gapvar(--space-md);
}

这个文件同样只写一次,之后不再修改。

所有组件的样式,都从这套变量里取值。改颜色?改一个变量,100 页同时生效。调间距?同理。这就是设计 token 的价值——让全局一致性变成一个系统保证,而不是靠人工检查。


3.3 开始写组件:Hero 与 Split

全局规范确立之后,现在可以开始写组件了。

每个组件用一次独立的对话完成。不要在同一个对话里让 AI 连续写多个组件——每次只做一件事,边界越清晰,输出质量越高。


第一个组件:Hero(封面页)

给 AI 的 Prompt:

"请写一个 JavaScript 函数 renderHero(data),用于渲染演示文稿的封面页。 要求:

  1. 接收一个 data 对象,结构为 { title, subtitle, eyebrow? }
  2. 返回一个 HTMLElement,不要直接操作 DOM,不要使用 innerHTML
  3. 使用已有的 CSS 工具类 slide-center,以及 :root 中定义的 CSS 变量
  4. eyebrow 是可选字段,有则显示在 title 上方,无则不渲染
  5. 完整输出函数体,禁止省略任何代码"

AI 应该输出:

functionrenderHero(data{
const { title, subtitle, eyebrow } = data;

const slide = document.createElement('div');
  slide.className = 'slide-center';
  slide.style.background = 'var(--color-bg)';
  slide.style.textAlign = 'center';

if (eyebrow) {
const eye = document.createElement('p');
    eye.textContent = eyebrow;
    eye.style.cssText = `
      font-size: var(--text-caption);
      color: var(--color-accent);
      letter-spacing: 0.15em;
      text-transform: uppercase;
      margin-bottom: var(--space-md);
    `
;
    slide.appendChild(eye);
  }

const h1 = document.createElement('h1');
  h1.textContent = title;
  h1.style.cssText = `
    font-size: var(--text-display);
    color: var(--color-text);
    font-weight: 700;
    line-height: 1.1;
    margin-bottom: var(--space-md);
  `
;

const sub = document.createElement('p');
  sub.textContent = subtitle;
  sub.style.cssText = `
    font-size: var(--text-body);
    color: var(--color-text-muted);
    max-width: 600px;
    line-height: 1.6;
  `
;

  slide.appendChild(h1);
  slide.appendChild(sub);

return slide;
}

拿到这个函数之后,做一件事:在浏览器里测试它。

// 在控制台里粘贴这两行
const el = renderHero({ title"测试标题"subtitle"这是副标题"eyebrow"Chapter 01" });
document.getElementById('slide-mount').appendChild(el);

如果封面页出现了,这个组件就完成了。关掉对话,开下一个。


第二个组件:Split(图文分栏页)

给 AI 的 Prompt:

"请写一个 JavaScript 函数 renderSplit(data),用于渲染图文分栏页。 要求:

  1. 接收 data 对象,结构为 { heading, body, image?, side }
  2. side 字段值为 "left" 或 "right",决定图片在哪一侧
  3. image 是可选字段,有则显示图片,无则该侧显示一个占位色块
  4. 返回 HTMLElement,使用 CSS 工具类 slide-split
  5. 完整输出,禁止省略"

AI 应该输出:

functionrenderSplit(data{
const { heading, body, image, side } = data;

const slide = document.createElement('div');
  slide.className = 'slide-split';
  slide.style.background = 'var(--color-bg)';

const textCol = document.createElement('div');
  textCol.style.cssText = `
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-md);
  `
;

const h2 = document.createElement('h2');
  h2.textContent = heading;
  h2.style.cssText = `
    font-size: var(--text-heading);
    color: var(--color-text);
    font-weight: 600;
    line-height: 1.2;
  `
;

const p = document.createElement('p');
  p.textContent = body;
  p.style.cssText = `
    font-size: var(--text-body);
    color: var(--color-text-muted);
    line-height: 1.7;
  `
;

  textCol.appendChild(h2);
  textCol.appendChild(p);

const mediaCol = document.createElement('div');
  mediaCol.style.cssText = `
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    overflow: hidden;
    background: var(--color-surface);
  `
;

if (image) {
const img = document.createElement('img');
    img.src = image;
    img.style.cssText = `
      width: 100%;
      height: 100%;
      object-fit: cover;
    `
;
    mediaCol.appendChild(img);
  }

if (side === 'left') {
    slide.appendChild(mediaCol);
    slide.appendChild(textCol);
  } else {
    slide.appendChild(textCol);
    slide.appendChild(mediaCol);
  }

return slide;
}

每个组件写完之后,立刻测试,立刻收工。

不要在同一个对话里追问"能不能加个动画"、"能不能改改颜色"。这些都是后续的事。现在的目标只有一个:让这个函数能跑通,返回正确的 DOM 结构。

组件库不需要一次写完。先写 Hero 和 Split,够用了就去做第四章。等到真正遇到需要 Code 组件或 Chart 组件的内容时,再回来补写。

不要提前造你现在不需要的轮子。


第四章:数据驱动 —— 内容与代码的终极解耦


4.1 为什么 JSON 是这道题的答案

先回想一下,如果不用数据驱动的方式,100 页 PPT 的内容是怎么存在于代码里的。

最直觉的做法,是让 AI 直接生成 100 个 <section> 标签:

<sectionid="slide-1">
<h1>第一页标题</h1>
<p>第一页内容……</p>
</section>

<sectionid="slide-2">
<h1>第二页标题</h1>
<p>第二页内容……</p>
</section>

<!-- 以此类推,直到第100页 -->

这个方案有三个致命问题。

第一,它根本无法生成。 100 个 <section>,加上每页的样式和内容,轻松超过任何模型的单次输出上限。你会在某一页被截断,然后不知道从哪里续写。

第二,修改成本极高。 第 73 页有个错别字,你需要在几千行 HTML 里找到那个位置,改完还要确保没有误碰到周围的代码。

第三,内容和表现完全耦合。 想把第 40 页从"要点列表"改成"图文分栏"?你需要重写整个 <section> 的 HTML 结构,而不是改一个字段。

JSON 数据驱动的方式,从根本上解决了这三个问题。

内容只是数据。代码只是模板。两者完全分离。


4.2 设计你的 JSON 数据结构

整个 PPT 的内容,存储为一个 JSON 数组。每个元素代表一页幻灯片,结构如下:

[
  {
"id"1,
"type""hero",
"theme""dark",
"data": {
"eyebrow""Vibe Coding 实战",
"title""用 AI 做 100 页 HTML PPT",
"subtitle""一套可复用的工程化方法论"
    }
  },
  {
"id"2,
"type""list",
"theme""dark",
"data": {
"heading""今天要解决的三个问题",
"items": [
"为什么 AI 无法一次生成 100 页",
"如何用工程化思维拆解这个任务",
"数据驱动渲染的完整实现方式"
      ]
    }
  },
  {
"id"3,
"type""split",
"theme""dark",
"data": {
"heading""Token 限制的本质",
"body""大语言模型在任意时刻能处理的信息总量是有上限的。超过这个上限,内容会被截断,或者被模型主动压缩省略。",
"side""right",
"image"null
    }
  }
]

这个结构有三个关键设计决策,每一个都有明确的理由。

决策一:用 type 字段决定渲染逻辑。

type 的值直接对应第三章写的组件函数名。"hero" 对应 renderHero()"split" 对应 renderSplit()。渲染引擎只需要一个简单的映射表,就能知道每一页该用哪个组件来渲染。

决策二:data 字段的结构由 type 决定。

不同类型的页面需要不同的数据字段。Hero 页需要 title 和 subtitle,Split 页需要 headingbody 和 side。把这些字段全部收进 data 对象,而不是平铺在顶层,是为了让顶层结构保持统一——无论什么类型的页面,顶层永远只有 idtypethemedata 四个字段。

决策三:内容修改只发生在 JSON 里。

第 73 页有错别字?打开 slides.json,找到 id: 73 的对象,改掉那个字符串,保存,刷新浏览器。整个过程不需要碰任何 JavaScript 或 HTML 文件。这是数据驱动最直接的价值体现。


这个 JSON 文件本身,也可以由 AI 来生成。

当你的 PPT 内容已经在脑子里,或者已经有一份大纲、一份 Word 文档时,可以直接把内容交给 AI,让它帮你转换成这个格式:

"请将以下 PPT 大纲转换为 JSON 数组,每页包含 id、type、theme、data 四个字段。type 只能是 hero、split、list、code、chart 五种之一。data 的字段结构根据 type 决定,规则如下:[粘贴字段规范]。只输出 JSON,不要输出任何解释。"

这是一个边界极清晰的任务——输入是大纲,输出是结构化数据,没有歧义,没有发挥空间。AI 在这类任务上的表现非常稳定,几乎不会出现幻觉。


4.3 渲染管道:让数据流动起来

有了 JSON 数据,有了组件函数,现在需要一个"调度中心"把它们连接起来。这就是渲染管道的职责。

渲染管道由两个函数组成,各自做一件事。


第一个函数:renderSlide()

它的职责只有一个:接收一个幻灯片的数据对象,判断它的类型,调用对应的组件函数,返回渲染好的 DOM 元素。

给 AI 的 Prompt:

"请写一个函数 renderSlide(slideData),作为组件库的调度入口。 要求:

  1. 接收单个幻灯片数据对象,结构为 { id, type, theme, data }
  2. 根据 type 字段,调用对应的组件函数:hero → renderHero,split → renderSplit,list → renderList,code → renderCode,chart → renderChart
  3. 如果 type 未知,返回一个显示错误信息的占位 div
  4. 返回 HTMLElement
  5. 完整输出,禁止省略"

AI 应该输出:

functionrenderSlide(slideData{
const { type, data } = slideData;

const renderers = {
hero:  renderHero,
split: renderSplit,
list:  renderList,
code:  renderCode,
chart: renderChart,
  };

const renderer = renderers[type];

if (!renderer) {
const fallback = document.createElement('div');
    fallback.className = 'slide-center';
    fallback.style.cssText = `
      background: var(--color-bg);
      color: var(--color-text-muted);
      font-size: var(--text-body);
    `
;
    fallback.textContent = `未知组件类型:${type}`;
return fallback;
  }

return renderer(data);
}

注意 renderers 这个映射表的设计。它把 type 字符串和函数引用绑定在一起,避免了冗长的 if-else 或 switch 语句。以后要新增一种组件类型,只需要在这个对象里加一行,其他代码完全不需要动。


第二个函数:mountSlides()

它的职责是加载 JSON 数据,初始化状态,渲染第一页,并把整个系统启动起来。

给 AI 的 Prompt:

"请写一个异步函数 mountSlides(),作为整个渲染系统的启动入口。 要求:

  1. 使用 fetch 加载 slides.json 文件
  2. 将数据存入 state.slides,将 state.total 设为数组长度
  3. 将 state.current 设为 0
  4. 调用 renderCurrent() 渲染第一页
  5. renderCurrent() 函数负责清空挂载点,渲染 state.slides[state.current],并将结果插入 id="slide-mount" 的容器
  6. 在 DOMContentLoaded 事件里调用 mountSlides()
  7. 完整输出,禁止省略"

AI 应该输出:

asyncfunctionmountSlides({
const response = await fetch('slides.json');
const slides = await response.json();

  state.slides = slides;
  state.total  = slides.length;
  state.current = 0;

  renderCurrent();
}

functionrenderCurrent({
const mount = document.getElementById('slide-mount');
  mount.innerHTML = '';

const slideData = state.slides[state.current];
const el = renderSlide(slideData);
  mount.appendChild(el);
}

document.addEventListener('DOMContentLoaded', mountSlides);

现在把所有部分连起来,验证整个管道是否跑通。

在 slides.json 里放三条测试数据:

[
  {
"id"1,
"type""hero",
"theme""dark",
"data": {
"eyebrow""测试",
"title""管道跑通了",
"subtitle""如果你能看到这行字,说明一切正常"
    }
  },
  {
"id"2,
"type""split",
"theme""dark",
"data": {
"heading""第二页",
"body""按左右方向键可以翻页",
"side""right",
"image"null
    }
  },
  {
"id"3,
"type""list",
"theme""dark",
"data": {
"heading""第三页",
"items": ["条目一""条目二""条目三"]
    }
  }
]

打开浏览器,按左右方向键。如果三页能正常切换,样式统一,没有报错——整个工程的核心管道就验证完毕了

此刻你拥有的,是一个可以承载任意数量页面的渲染引擎。把 slides.json 从 3 条数据扩展到 100 条,系统不需要做任何改变。

这就是数据驱动架构的核心价值:规模增长的成本趋近于零。


第五章:Vibe 操控术 —— 应对 AI 幻觉的 Prompt 范式


5.1 多轮对话的最大敌人:上下文漂移

前四章解决的是架构问题。但在实际操作过程中,你还会遇到另一类问题——不是代码跑不通,而是AI 在对话过程中悄悄偏离了你的要求

这种偏离有一个规律:它不会突然发生,而是缓慢累积的。

第一轮对话,AI 完全按你的要求输出。第三轮,它开始在函数里加入你没要求的"优化"。第五轮,它已经把你第一轮定义的接口改掉了,用了一套它自己觉得"更好"的结构。第八轮,你发现新输出的代码和之前的完全无法兼容。

这个现象叫做上下文漂移。原因很简单:随着对话轮次增加,早期的约束在注意力权重里越来越弱,AI 越来越倾向于根据最近几轮的对话来决定输出方向。

解决这个问题,不需要任何黑魔法。只需要一个习惯:每次对话开始时,主动把关键约束重新带入上下文。


5.2 上下文锚点:把约束钉死在对话开头

上下文锚点,就是在每次新对话的开头,用几句话重新声明当前的技术边界。

模板如下:

【当前项目约束】
- 技术栈:Vanilla JS,零外部依赖,4个文件(index.html / engine.js / components.js / slides.json)
- 组件接口:每个 render 函数接收 data 对象,返回 HTMLElement,不直接操作 DOM
- CSS:所有样式值使用 :root 中定义的 CSS 变量,不允许硬编码颜色或字号
- 状态管理:只通过 state 对象维护,不引入任何外部状态

【当前进度】
已完成:index.html 框架、全局 CSS 规范、renderHero()、renderSplit()、renderSlide()、mountSlides()
本次任务:写 renderList() 函数

【本次要求】
接收 data 对象,结构为 { heading, items: string[], note? }
返回 HTMLElement,使用 slide-stack 布局类
完整输出,禁止省略

这个模板做了三件事:

第一,重申约束。 把整个项目最核心的技术边界写在最前面,确保 AI 在生成任何内容之前,先读到这些约束。

第二,同步进度。 告诉 AI 已经存在哪些函数,避免它重复定义或者和已有代码产生冲突。

第三,限定任务。 本次对话只做一件事,边界清晰,没有歧义。

这三个部分缺一不可。只有任务没有约束,AI 会自由发挥。只有约束没有进度,AI 不知道哪些东西已经存在。只有约束和进度没有任务,AI 不知道这次要输出什么。


5.3 防压缩指令:逼 AI 交出完整代码

上下文锚点解决的是"方向跑偏"的问题。防压缩指令解决的是另一个问题:AI 输出了正确的结构,但省略了关键细节。

最常见的省略形式有三种:

// 第一种:用注释替代代码
functionrenderChart(data{
// 此处实现图表渲染逻辑
// 使用 Canvas API 绘制柱状图
}

// 第二种:用 TODO 占位
functionrenderCode(data{
const el = document.createElement('div');
// TODO: 添加语法高亮
return el;
}

// 第三种:声称"同上"
functionrenderList(data{
// 结构与 renderSplit 类似,此处省略,请参考上文
}

这三种省略,表面上看是 AI 在节省 token,实际上是把工作甩给了你。你需要自己去补全这些空洞,而补全的过程往往会引入新的不一致。

防压缩指令的核心,是在 Prompt 里明确声明"省略"是不可接受的输出:

"请完整输出 renderList 函数的全部代码。 以下行为视为输出无效,需要重新生成:

  • 使用注释替代任何真实代码
  • 出现 TODO、省略号、'同上'、'参考上文'等字样
  • 函数体未完整实现,无法直接运行"

把"无效输出"的定义写清楚,AI 就有了明确的约束边界。大多数情况下,这类指令能有效减少省略行为。


5.4 局部隔离:当 AI 搞砸了一个组件

有时候问题不是 AI 省略了代码,而是它把某个组件写错了——逻辑有 bug,或者样式和其他组件不一致。

这时候很多人会在原来的对话里继续追问,让 AI 修复。这是一个容易让问题变得更复杂的选择。

原因在于:原来的对话上下文里已经积累了大量的"错误信息"——AI 之前输出的错误代码、你的报错反馈、AI 的解释。这些内容会干扰 AI 对问题的判断,它在修复时很容易引入新的错误,或者把之前正确的部分也改掉。

更好的做法是局部隔离

第一步,开一个全新的对话窗口。

新对话没有任何历史包袱,AI 的注意力完全集中在你即将给出的信息上。

第二步,只带入必要的上下文。

【背景】
我有一个 renderList(data) 函数需要重写。

【接口约束】
接收:{ heading, items: string[], note? }
返回:HTMLElement
使用 CSS 变量:--color-text、--color-text-muted、--text-heading、--text-body、--space-md、--space-lg
使用布局类:slide-stack

【当前问题】
items 超过 5 条时,内容溢出容器底部,没有做截断或滚动处理。

【要求】
重新实现这个函数,完整输出,禁止省略。

第三步,拿到新代码后,直接替换旧代码。

不需要合并,不需要对比差异,直接用新函数覆盖旧函数。因为接口没有变(输入输出一致),替换之后整个系统依然能正常运行。

这就是局部隔离的价值:把一个组件的修复工作,完全限定在一次干净的对话里,不污染其他任何东西。


第六章:组装与热修复 —— 优雅的 Debug 流程


6.1 最终拼图:把四个文件缝合在一起

经过前五章,你手里已经有了所有的零件:

  • index.html:主舞台框架,带挂载点和键盘事件
  • components.js:五个组件渲染函数
  • engine.jsrenderSlide()renderCurrent()mountSlides()
  • slides.json:所有页面的内容数据

现在要做的,是把它们组装成一个可以运行的整体。

在 index.html 的 <head> 里,按顺序引入 CSS 变量文件和 JS 文件:

<!DOCTYPE html>
<htmllang="zh">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>Presentation</title>
<linkrel="stylesheet"href="styles.css">
</head>
<body>
<divid="slide-mount"></div>

<scriptsrc="components.js"></script>
<scriptsrc="engine.js"></script>
</body>
</html>

加载顺序很关键。components.js 必须在 engine.js 之前加载,因为 engine.js 里的 renderSlide() 依赖 components.js 里定义的五个渲染函数。如果顺序反了,浏览器会报"函数未定义"的错误。

slides.json 不需要在 HTML 里引入,它由 engine.js 里的 fetch() 在运行时动态加载。

组装完成后,用本地服务器打开 index.html。注意:不能直接双击打开文件,因为 fetch() 在本地文件协议下会被浏览器安全策略拦截。最简单的启动方式:

# 如果安装了 Python
python3 -m http.server 8080

# 如果安装了 Node.js
npx serve .

打开 http://localhost:8080,如果第一页正常显示,方向键能够翻页,说明组装成功。


6.2 DevTools 辅助:所见即所得的微调

真正让 Vibe Coding 效率倍增的,不只是 AI,还有浏览器的开发者工具。两者配合使用,能让调试速度大幅提升。

场景一:样式微调。

第 12 页的标题字号看起来太大了。不要立刻去找 AI,先打开 DevTools 的 Elements 面板,直接在 CSS 变量或行内样式上改数值。DevTools 里的改动实时生效,你能立刻看到效果。

确认满意之后,把改动同步回代码。这个过程可能只需要 30 秒,而如果去找 AI,来回一两轮对话可能要 5 分钟。

场景二:定位 Bug。

某一页渲染出来是空白的。打开 DevTools 的 Console 面板,看有没有报错信息。大多数情况下,错误信息会直接告诉你问题所在:

Uncaught TypeError: Cannot read properties of undefined (reading 'heading')
    at renderList (components.js:47)

这条报错告诉你:renderList 函数在第 47 行试图读取 heading 属性,但传入的 data 对象是 undefined

回去检查 slides.json,找到对应页面的数据,很可能是 type 写成了 "lists" 而不是 "list",导致 renderSlide() 找不到对应的渲染函数,传入了 undefined

改掉 JSON 里的一个字母,刷新,问题消失。

场景三:把 DevTools 的发现交给 AI 处理。

遇到复杂的 Bug,自己看不出原因,这时候再去找 AI。但不要只说"第 12 页显示不对",而是把 DevTools 里的完整报错信息一起带过去:

"renderList 函数报错如下:[粘贴完整报错堆栈] 当前传入的 data 对象是:[粘贴 JSON] 函数代码如下:[粘贴函数代码] 请找出问题并给出修复后的完整函数,禁止省略。"

信息越完整,AI 定位问题越准确,输出的修复代码越可靠。


6.3 内容扩展:从 3 页到 100 页

验证管道跑通之后,正式开始填充内容。

这个阶段的工作几乎完全在 slides.json 里进行,和 AI 的交互模式也变得非常简单:

"请将以下内容转换为 slides.json 格式的 JSON 数组。每个对象包含 id、type、theme、data 四个字段,type 只能是 hero、split、list、code、chart 五种之一。只输出 JSON,不要输出任何解释文字。

[粘贴你的 PPT 大纲或内容文稿]"

这是一个纯粹的格式转换任务,没有逻辑推理,没有代码生成,AI 的输出非常稳定。即使某几条数据格式有误,也只影响那几页的渲染,不会波及整个系统。

逐段转换,逐段验证,每次处理 10-20 页,保持每次任务的粒度可控。全部转换完成后,slides.json 就是你的 100 页内容,整个 PPT 自动渲染完毕。


结语:Vibe Coding 需要更强的架构直觉,不是更弱的

回顾整篇文章走过的路:

我们没有试图让 AI 一次性生成所有东西。我们做的恰恰相反——把一个看起来庞大的任务,拆解成一系列有明确边界的小任务,每次只让 AI 做一件事,每次的输出都可以独立验证。

这套方法背后有一个核心洞察:

AI 的能力上限,取决于你给它的任务有多清晰。

任务越模糊,AI 需要做的假设就越多,出错的概率就越高。任务越具体,AI 的输出就越稳定,越可预期。

Vibe Coding 这个词,容易让人联想到一种随性的、直觉驱动的创作方式——感觉对了就行,不需要想太多。但本文展示的实践告诉我们,真正高效的 Vibe Coding 恰恰相反:

它需要你在动手之前,想清楚整个系统的架构。它需要你知道哪些东西只需要写一次,哪些东西需要反复复用。它需要你理解 AI 的局限,并在任务设计层面绕开这些局限,而不是在出了问题之后再去修补。

换句话说:越强大的 AI 工具,越需要使用者具备清晰的工程化思维。 AI 负责执行,你负责设计。这个分工不会因为 AI 变得更强而改变——它只会变得更加重要。

100 页 PPT 只是一个具体的例子。这套思路可以迁移到任何需要用 AI 完成的复杂任务:长篇文档、自动化脚本、数据处理管道……只要你能把任务拆解清楚,AI 就能成为你真正意义上的协作者。

工具从来不是瓶颈。思维方式才是。


全文完。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-17 18:46:11 HTTP/2.0 GET : https://h.sjds.net/a/490985.html
  2. 运行时间 : 0.155709s [ 吞吐率:6.42req/s ] 内存消耗:4,545.45kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=96b5d7bad24694194722b53faa72b585
  1. /yingpanguazai/ssd/ssd1/www/h.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/h.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/h.sjds.net/runtime/temp/ad153693ed39fba6d1bda2fe72512cde.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000458s ] mysql:host=127.0.0.1;port=3306;dbname=h_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000730s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000331s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000247s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000514s ]
  6. SELECT * FROM `set` [ RunTime:0.000200s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000508s ]
  8. SELECT * FROM `article` WHERE `id` = 490985 LIMIT 1 [ RunTime:0.000649s ]
  9. UPDATE `article` SET `lasttime` = 1776422771 WHERE `id` = 490985 [ RunTime:0.003645s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000294s ]
  11. SELECT * FROM `article` WHERE `id` < 490985 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000455s ]
  12. SELECT * FROM `article` WHERE `id` > 490985 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002463s ]
  13. SELECT * FROM `article` WHERE `id` < 490985 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001905s ]
  14. SELECT * FROM `article` WHERE `id` < 490985 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000708s ]
  15. SELECT * FROM `article` WHERE `id` < 490985 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001548s ]
0.157247s