上一篇 下一篇 分享链接 返回 返回顶部

AI搜索上线后网站变慢?一次生产环境提速实测记录

发布人:慈云数据-客服中心 发布时间:20小时前 阅读量:8

AI搜索 如何提高网站速度|生产环境实测

在过去一年里,越来越多企业站、内容站和工具型网站开始从“传统搜索”转向“AI搜索”:用户不再只输入关键词,而是直接提出自然语言问题,例如“适合跨境电商独立站的支付方案有哪些”“某款产品和竞品相比有什么优势”“帮我找一篇关于网站性能优化的实战文章”。
AI搜索带来的体验提升很明显,但它也引入了一个新的问题:网站速度变慢了

传统站内搜索通常依赖数据库 LIKE 查询、Elasticsearch、Meilisearch 或 Algolia 等搜索服务,返回的是一组链接或结果列表。而AI搜索往往还会涉及向量检索、语义召回、重排序、上下文拼接、LLM生成回答、权限过滤、缓存命中判断等流程。任何一个环节处理不好,都会让页面加载时间明显增加,甚至出现首屏长时间空白、回答生成缓慢、接口超时等问题。

本文结合一个生产环境项目的实测经验,系统梳理:在接入AI搜索后,如何提高网站速度。文章会从性能指标、问题定位、架构优化、前端优化、后端优化、缓存策略、向量检索优化、LLM响应优化以及上线监控等角度展开。


一、生产环境背景说明

为了便于说明,先介绍本次优化的生产环境背景。

该网站是一个中文内容型网站,主要包含:

  • 文章内容约 12 万篇;
  • 日均访问量约 8 万 PV;
  • 高峰期并发请求约 300~600;
  • 用户可以使用站内普通搜索,也可以使用AI搜索;
  • AI搜索支持自然语言提问,并基于网站内容生成答案;
  • 后端主要使用 Node.js + PostgreSQL + Redis;
  • 向量数据库使用 PostgreSQL pgvector;
  • 前端使用 Next.js;
  • LLM调用外部大模型API。

优化前,AI搜索接口的平均响应时间偏高。部分问题在高峰期甚至会出现 8~15 秒的等待时间,严重影响用户体验。

优化前关键指标

指标 优化前表现
首页 LCP 3.8s
搜索页首屏加载 2.9s
普通搜索接口 P95 850ms
AI搜索接口平均响应 6.4s
AI搜索接口 P95 13.2s
AI回答首字输出时间 5.1s
Redis缓存命中率 28%
向量检索平均耗时 1.7s
LLM调用平均耗时 3.8s

可以看到,真正拖慢体验的并不只是页面加载,而是AI搜索完整链路太长。用户点击搜索后,需要等待很久才能看到AI回答,导致跳出率上升。


二、AI搜索为什么容易拖慢网站?

很多团队在接入AI搜索时,会低估它对网站性能的影响。原因在于,AI搜索不是一个单接口问题,而是一条复杂链路。

一个典型AI搜索流程如下:

  1. 用户输入问题;
  2. 前端发送请求到后端;
  3. 后端进行用户权限校验;
  4. 对问题进行清洗、改写或意图识别;
  5. 将问题转换为向量;
  6. 在向量库中做相似度检索;
  7. 根据关键词、时间、分类、权限等条件过滤结果;
  8. 对召回结果进行重排序;
  9. 拼接上下文;
  10. 调用大模型生成答案;
  11. 以流式或普通方式返回前端;
  12. 前端渲染答案、引用来源、推荐内容等。

其中任何一步过慢,都会影响最终体验。

尤其是以下几个环节最容易成为瓶颈:

  • 向量检索没有索引;
  • 每次请求都实时生成Embedding;
  • 检索结果过多,重排序成本太高;
  • 上下文拼接过长,导致LLM响应变慢;
  • 没有流式输出,用户必须等完整答案;
  • 缓存策略不合理,重复问题无法复用结果;
  • 前端首屏资源过大,页面还没加载完接口已经等待;
  • 后端请求串行执行,链路被无谓拉长。

三、先定义性能目标,而不是盲目优化

性能优化不能只凭感觉。生产环境优化的第一步,是定义清晰指标。

本次优化目标如下:

指标 目标
AI搜索首字输出时间 小于 1.5s
AI搜索完整回答时间 小于 5s
AI搜索接口 P95 小于 6s
搜索页 LCP 小于 2.5s
向量检索平均耗时 小于 300ms
Redis缓存命中率 大于 60%
页面 JS 首包体积 降低 30%以上

这里重点说明一个指标:首字输出时间

对于AI搜索来说,用户并不一定要求完整答案瞬间返回。如果能在 1~2 秒内看到回答开始生成,用户的等待感会明显降低。因此,优化AI搜索时,不应只关注“完整响应耗时”,还要关注“首字返回时间”。


四、前端优化:先让页面快起来

很多AI搜索项目一开始就把优化重点放在模型和后端上,但忽略了前端。实际上,如果搜索页本身加载慢,用户在输入问题之前就已经产生负面体验。

1. 拆分搜索页首屏资源

优化前,搜索页加载了大量非首屏组件,包括:

  • 热门文章列表;
  • 推荐专题;
  • 历史搜索记录;
  • 用户反馈组件;
  • Markdown渲染器;
  • 代码高亮库;
  • 图表组件。

这些组件并不一定需要在首屏同步加载。

优化方式:

import dynamic from "next/dynamic";

const MarkdownRenderer = dynamic(() => import("@/components/MarkdownRenderer"), {
  ssr: false,
  loading: () => 
正在加载回答组件...
, }); const FeedbackPanel = dynamic(() => import("@/components/FeedbackPanel"), { ssr: false, });

将非关键组件动态加载后,搜索页首屏JS体积明显下降。

2. 搜索框优先渲染

搜索页最重要的元素是搜索框。我们把搜索框、标题、简单说明作为首屏核心内容,其他模块延迟加载。

优化前页面结构大致是:


  

优化后调整为:


  
  
  
  

这样用户进入页面后可以更快开始搜索,而不是等待整页资源加载。

3. 减少阻塞渲染资源

对CSS、字体和第三方脚本进行检查后,发现一些统计脚本和客服脚本会阻塞页面加载。处理方式:

  • 统计脚本延迟加载;
  • 字体使用 font-display: swap
  • 首屏图片使用压缩后的WebP;
  • 非必要第三方SDK只在用户交互后加载;
  • 减少全局CSS体积。

优化后,搜索页 LCP 从 2.9s 降到 1.9s,用户进入页面的速度明显提升。


五、后端优化:拆解AI搜索链路

前端优化只能解决页面体验的一部分。真正决定AI搜索速度的,是后端链路。

优化前,AI搜索接口是一个典型串行流程:

接收问题
  ↓
权限校验
  ↓
生成Embedding
  ↓
向量检索
  ↓
数据库查询文章详情
  ↓
结果重排序
  ↓
拼接Prompt
  ↓
调用LLM
  ↓
返回完整答案

问题在于:所有步骤都串行执行,且必须等LLM完整生成后才返回给用户。

优化后,我们将链路拆成两部分:

  1. 快速响应链路:尽快完成检索并开始流式输出;
  2. 异步增强链路:记录日志、更新搜索热度、用户行为分析、推荐内容计算等放到异步队列。

六、使用流式输出降低等待感

AI搜索最关键的优化之一,是使用流式输出。

优化前,后端等待LLM生成完整答案后才返回:

用户提问 → 后端处理 → LLM完整生成 → 一次性返回

这种方式下,用户可能等待 5~10 秒都看不到任何内容。

优化后,采用 Server-Sent Events 或 Stream Response:

用户提问 → 检索 → LLM开始生成 → 边生成边返回

示例代码:

export async function POST(req: Request) {
  const { question } = await req.json();

  const stream = new ReadableStream({
    async start(controller) {
      const encoder = new TextEncoder();

      const contexts = await retrieveContexts(question);

      const llmStream = await callLLMStream({
        question,
        contexts,
      });

      for await (const chunk of llmStream) {
        controller.enqueue(encoder.encode(chunk));
      }

      controller.close();
    },
  });

  return new Response(stream, {
    headers: {
      "Content-Type": "text/event-stream; charset=utf-8",
      "Cache-Control": "no-cache",
      "Connection": "keep-alive",
    },
  });
}

上线后,AI回答首字输出时间从 5.1s 降到 1.4s。虽然完整答案生成时间仍然需要几秒,但用户能立即看到内容开始输出,感知速度大幅提升。


七、缓存策略:不要让相似问题反复计算

AI搜索的成本和耗时都比较高。如果每个问题都从头走一遍完整链路,系统压力会很大。

我们采用了三层缓存。

1. 精确问题缓存

对用户原始问题进行标准化处理:

  • 去除首尾空格;
  • 统一标点;
  • 繁简转换;
  • 小写化;
  • 去除无意义语气词。

例如:

“怎么提高网站速度?”
“如何提升网站速度”
“网站速度怎么优化?”

这些问题虽然文字不同,但意图相似。对于完全一致的问题,可以直接走精确缓存。

缓存Key示例:

const cacheKey = `ai_search:answer:${hash(normalizedQuestion)}`;

缓存内容包括:

  • 最终答案;
  • 引用文章;
  • 推荐链接;
  • 生成时间;
  • 使用的模型版本。

2. 语义缓存

精确缓存只能命中完全相同的问题,而AI搜索中大量问题是语义相近但表达不同。因此我们引入语义缓存。

基本思路是:

  1. 将用户问题转换为向量;
  2. 在“历史问题向量库”中查找相似问题;
  3. 如果相似度高于阈值,例如 0.92;
  4. 直接返回历史答案,或者基于历史答案轻量改写。

这样可以避免大量重复调用LLM。

不过语义缓存要注意风险:相似问题不一定等价。比如:

  • “苹果手机怎么提高速度”
  • “苹果电脑怎么提高速度”

这两个问题有相似词,但答案不同。因此语义缓存不能只看相似度,还要结合意图分类和实体识别。

3. 检索结果缓存

除了最终答案,检索结果也可以缓存。比如某些热门问题,每次都需要查向量库和文章表,成本较高。我们将 Top K 文档ID缓存起来:

ai_search:retrieval:{question_hash} → [docId1, docId2, docId3]

这样即使不缓存最终答案,也可以减少检索耗时。

优化后,Redis缓存命中率从 28% 提升到 67%,AI搜索平均响应时间明显下降。


八、向量检索优化:从1.7秒降到260毫秒

本次生产环境中,向量检索一开始是最大的瓶颈之一。

1. 为向量字段建立索引

使用 pgvector 时,如果没有合理索引,数据量上来后查询会变慢。

优化前查询:

SELECT id, title, content
FROM articles
ORDER BY embedding <-> $1
LIMIT 10;

在 12 万篇文章数据下,该查询平均耗时约 1.7s。

优化后,为向量字段建立 HNSW 索引:

CREATE INDEX articles_embedding_hnsw_idx
ON articles
USING hnsw (embedding vector_cosine_ops);

如果使用 IVFFlat,也可以:

CREATE INDEX articles_embedding_ivfflat_idx
ON articles
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

对于读多写少的内容站,HNSW查询表现更稳定,适合生产使用。

2. 控制候选数量

很多团队为了“答案更准”,会把 Top K 设置得很大,比如一次召回 100 条甚至 200 条。实际上,候选越多,后续数据库查询、重排序、Prompt拼接都会更慢。

我们实测后发现:

Top K 检索耗时 答案质量
5 180ms 偶尔信息不足
10 260ms 较稳定
20 430ms 略有提升
50 970ms 提升不明显

最终生产环境选择默认 Top K = 10,复杂问题才动态提升到 20。

3. 文档切片要适中

AI搜索通常不是直接对整篇文章做向量化,而是对文章切片。切片太长会影响召回精度,切片太短会导致数量膨胀。

我们测试过三种方案:

切片长度 优点 缺点
300字 精细,召回准确 切片数量太多
800字 平衡较好 需要处理上下文衔接
1500字 数量少 召回不够精准

最终采用约 700~900 中文字的切片,并保留 100~150 字重叠内容。这样既能保证语义完整,也不会导致向量数量过大。


九、Prompt优化:上下文越长不代表答案越好

AI搜索还有一个常见误区:把尽可能多的内容塞给大模型。
结果是Prompt越来越长,模型响应越来越慢,费用也越来越高。

优化前,我们会把检索到的 10 篇文章摘要和部分正文全部拼接进Prompt,平均上下文长度超过 7000 tokens。LLM响应时间平均 3.8s。

优化后做了三点调整:

1. 只保留高相关片段

不再把整篇文章传给模型,而是只传与问题最相关的段落。

2. 对上下文进行压缩

对于较长内容,先用规则方式提取标题、摘要、核心段落,而不是原样传入。

示例结构:

资料1:
标题:网站速度优化实战
相关内容:介绍了图片压缩、缓存、CDN、数据库索引等方法。
来源:https://example.com/a

资料2:
标题:Next.js 性能优化
相关内容:介绍了动态导入、SSR缓存、边缘渲染等方案。
来源:https://example.com/b

3. 限制最大上下文长度

生产环境中设置了硬限制:普通问题上下文不超过 3000 tokens,复杂问题不超过 5000 tokens。

优化后,LLM平均调用耗时从 3.8s 降到 2.6s,同时答案质量没有明显下降。


十、并行处理:能同时做的不要串行做

优化前,后端很多步骤都是串行执行。例如:

  • 记录搜索日志;
  • 查询用户信息;
  • 获取推荐问题;
  • 查询热门文章;
  • 写入搜索历史。

这些操作并不都依赖主链路结果。如果全部串行等待,就会拖慢AI搜索。

优化方式是将非核心任务异步化:

const answerPromise = generateAnswer(question);

queue.add("search_log", {
  userId,
  question,
  createdAt: Date.now(),
});

queue.add("update_hot_keyword", {
  question,
});

return streamAnswer(answerPromise);

核心原则是:用户当前必须看到的内容同步处理,不影响当前结果的任务全部异步处理

经过调整,后端主链路减少了约 400~700ms 的无效等待。


十一、数据库查询优化:不要在AI链路里做重查询

AI搜索检索出文档ID后,通常还需要查询文章标题、URL、摘要、发布时间等信息。优化前我们直接查文章主表,并且有一些字段不必要:

SELECT *
FROM articles
WHERE id IN (...);

这会取出大量无关字段,比如正文、作者扩展信息、统计字段等。

优化后改为只查询必要字段:

SELECT id, title, slug, summary, published_at
FROM articles
WHERE id = ANY($1);

并为常用过滤条件加索引:

CREATE INDEX idx_articles_status_published
ON articles(status, published_at DESC);

同时,将文章基础信息写入Redis缓存:

article:meta:{id}

这样向量检索返回ID后,可以优先从缓存批量获取文章元数据,减少数据库压力。


十二、CDN与边缘缓存:静态资源必须离用户更近

AI搜索接口本身很难完全静态化,但页面资源、文章页、图片、CSS、JS都可以通过CDN优化。

本次优化中,我们做了以下处理:

  • 所有图片走CDN;
  • WebP/AVIF格式自动转换;
  • 静态资源设置长期缓存;
  • HTML页面根据业务设置短缓存;
  • 热门文章页启用边缘缓存;
  • 搜索页骨架屏和基础HTML尽量边缘返回。

静态资源缓存示例:

Cache-Control: public, max-age=31536000, immutable

对于内容页:

Cache-Control: public, s-maxage=600, stale-while-revalidate=86400

这样即使源站压力较高,用户访问文章页和搜索页基础内容时仍然能保持较快速度。


十三、生产环境实测结果

经过多轮优化后,生产环境指标变化如下:

指标 优化前 优化后
首页 LCP 3.8s 2.1s
搜索页首屏加载 2.9s 1.7s
普通搜索接口 P95 850ms 420ms
AI搜索接口平均响应 6.4s 3.2s
AI搜索接口 P95 13.2s 5.8s
AI回答首字输出时间 5.1s 1.4s
Redis缓存命中率 28% 67%
向量检索平均耗时 1.7s 260ms
LLM调用平均耗时 3.8s 2.6s

从结果看,最大的收益来自四个方面:

  1. 流式输出:显著降低用户等待感;
  2. 向量索引:大幅降低检索耗时;
  3. 缓存策略:减少重复计算;
  4. Prompt压缩:降低LLM响应时间和调用成本。

十四、上线后的监控不能省

性能优化不是一次性工作。AI搜索上线后,必须持续监控。

建议至少监控以下指标:

  • AI搜索请求量;
  • 平均响应时间;
  • P90、P95、P99耗时;
  • 首字输出时间;
  • 向量检索耗时;
  • Embedding生成耗时;
  • LLM调用耗时;
  • 缓存命中率;
  • 错误率;
  • 超时率;
  • 用户中断率;
  • 每次回答平均Token数;
  • 单次请求平均成本。

尤其要关注 P95 和 P99,而不是只看平均值。平均值很好看,并不代表用户体验好。很多生产问题都藏在长尾请求里。


十五、最终建议:AI搜索提速的优先级

如果你的站点已经接入AI搜索,但速度不理想,可以按以下优先级优化:

  1. 先接入流式输出,让用户尽快看到回答;
  2. 检查向量库是否有索引,避免全表扫描;
  3. 减少Prompt上下文长度,不要盲目塞内容;
  4. 增加Redis缓存,优先缓存热门问题和检索结果;
  5. 前端搜索页拆包,保证搜索框快速可用;
  6. 异步化非核心任务,缩短主链路;
  7. 优化数据库查询字段和索引
  8. 使用CDN缓存静态资源和热门页面
  9. 建立监控面板,持续观察长尾性能;
  10. 根据问题复杂度动态调整检索和模型策略

结语

AI搜索确实能提升网站体验,但如果没有做好性能优化,它也可能成为网站速度的最大瓶颈。生产环境中的优化经验表明,AI搜索提速并不只是“换一个更快的模型”这么简单,而是一个系统工程。

真正有效的优化,通常来自链路拆解:前端让页面先快起来,后端让主链路更短,向量检索加索引,缓存减少重复计算,Prompt减少无效上下文,LLM使用流式输出,非核心任务全部异步化。

从本次实测结果看,经过优化后,AI搜索接口 P95 从 13.2 秒降到 5.8 秒,首字输出时间从 5.1 秒降到 1.4 秒,用户等待感明显降低,搜索转化率和停留时间也随之提升。

如果你正在做AI搜索,建议不要等到用户反馈“太慢”之后再优化。性能设计应该从第一天就纳入架构方案。因为在AI搜索时代,网站速度不仅影响SEO和转化率,也直接影响用户是否愿意继续与你的网站对话。

目录结构
全文