百度SEO

百度SEO

Products

当前位置:首页 > 百度SEO >

如何用React和Node.js构建AI聊天应用?

96SEO 2026-04-20 12:29 1


构建一个属于自己的 AI 聊天机器人Yi经不再是遥不可及的梦想。无论是为了提升工作效率,还是单纯为了探索技术的边界,React 与 Node.js 的组合无疑是全栈开发者的“黄金搭档”。今天我们就来一场硬核的实战演练,不搞那些虚头巴脑的理论,直接上手,kankan如何从零开始,搭建一个支持流式响应、多模型切换的现代化 AI 聊天应用。

如何用React和Node.js构建AI聊天应用?

架构设计:不仅仅是简单的请求与响应

在敲下第一行代码之前,我们得先搞清楚整个系统的运作逻辑。传统的 HTTP 请求-响应模式在 AI 对话场景下显得有些笨重——你发个请求,然后干等十几秒,Zui后才收到一大段文字。这种体验,说实话,有点像回到了拨号上网时代。

为了解决这个问题,我们引入了 Server-Sent Events 技术。简单来说就是后端像挤牙膏一样,把 AI 生成的文字一点一点“流”向前端。这样一来用户就Nengkan到 AI 正在“思考”和“打字”的过程,交互感瞬间拉满。

我们的技术选型非常明确:

前端React 18 + Vite。

后端Node.js + Express,负责对接大模型 API并转发流式数据。

部署前端扔给 Vercel,后端Ke以考虑阿里云函数计算或者 ECS,主打一个性价比。

后端实现:Node.js 作为智Neng中枢

后端的核心任务非常单纯:接收前端的消息,转发给 LLM,然后把模型的流式输出原封不动地转手给前端。但别小kan这个“转发”,里面有不少门道。

我们需要搭建一个 Express 服务器。为了支持多模型切换,我们需要在后端Zuo一个简单的配置映射。

环境配置与依赖安装

新建一个 `server` 目录,初始化项目并安装必要的依赖。这里我们需要 `express` 来起服务,`openai` 库来调用接口,以及 `cors` 和 `dotenv` 来处理跨域和环境变量。

mkdir ai-chat && cd ai-chat
mkdir server && cd server
npm init -y
npm install express openai cors dotenv

别忘了在 `package.json` 里加上 `"type": "module"`,毕竟现在是 ES Modules 的天下了。创建一个 `.env` 文件,把你的 API Key 妥善藏好:

DEEPSEEK_API_KEY=sk-xxx
DASHSCOPE_API_KEY=sk-xxx
核心路由与流式处理

接下来是重头戏。我们需要编写 `server/index.js`。这里的关键在于如何正确处理 SSE 流。我们要设置特定的 HTTP 头部,告诉前端“我要开始发流了别断开”。

import express from 'express';
import cors from 'cors';
import OpenAI from 'openai';
import 'dotenv/config';
const app = express;
app.use);
app.use);
// 多模型配置:key 是前端传来的 modelId
const MODEL_CONFIGS = {
  'deepseek-chat': {
    client: new OpenAI({
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseURL: 'https://api.deepseek.com/v1',
    }),
    model: 'deepseek-chat',
  },
  'deepseek-r1': {
    client: new OpenAI({
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseURL: 'https://api.deepseek.com/v1',
    }),
    model: 'deepseek-reasoner',
  },
  'qwen-max': {
    client: new OpenAI({
      apiKey: process.env.DASHSCOPE_API_KEY,
      baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
    }),
    model: 'qwen-max',
  },
  'qwen-turbo': {
    client: new OpenAI({
      apiKey: process.env.DASHSCOPE_API_KEY,
      baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
    }),
    model: 'qwen-turbo',
  },
};
// POST /api/chat — 返回 SSE 流式响应
app.post => {
  const { messages, modelId = 'deepseek-chat' } = req.body;
  const config = MODEL_CONFIGS;
  if  {
    return res.status.json;
  }
  // 设置 SSE headers
  res.setHeader;
  res.setHeader;
  res.setHeader;
  res.flushHeaders;
  try {
    const stream = await config.client.chat.completions.create({
      model: config.model,
      messages,
      stream: true,
      max_tokens: 2000,
    });
    for await  {
      const delta = chunk.choices?.delta?.content;
      if  {
        // SSE 格式:data: 

        res.write}

`);
      }
    }
    res.write;
  } catch  {
    console.error;
    res.write}

`);
  } finally {
    res.end;
  }
});
app.listen => console.log);
前端实现:React 打造丝滑交互

后端搞定后前端的工作就是把这些数据漂亮地展示出来。我们使用 Vite 来创建 React 项目,因为它比 Create React App 快太多了。

cd .. && npm create vite@latest client -- --template react
cd client
npm install
核心 Hook:useChat.js

这是整个前端的大脑。我们需要管理消息列表、处理流式数据的接收、以及自动滚动到底部。这里有个坑:网络传输的数据包可Neng会把一行 SSE 数据切断,或者把多行数据粘在一起。所以我们必须维护一个 `buffer` 来处理这种“分包”现象。

import { useState, useCallback, useRef } from 'react';
const API_BASE = import.meta.env.VITE_API_BASE || 'http://localhost:3000';
export function useChat {
  const  = useState => {
    // localStorage 持久化:加载历史对话
    try {
      const saved = localStorage.getItem;
      return saved ? JSON.parse : ;
    } catch {
      return ;
    }
  });
  const  = useState;
  const  = useState;
  const abortRef = useRef;
  // 持久化到 localStorage
  const saveHistory =  => {
    try {
      // 只保存Zui近 20 条,防止 localStorage 爆满
      localStorage.setItem));
    } catch {}
  };
  const sendMessage = useCallback => {
    if  || streaming) return;
    const userMsg = { role: 'user', content: userText };
    const newMessages = ;
    setMessages;
    // 添加一条空的 assistant 消息,稍后流式填充
    const assistantMsg = { role: 'assistant', content: '' };
    setMessages;
    setStreaming;
    const controller = new AbortController;
    abortRef.current = controller;
    try {
      const res = await fetch(`${API_BASE}/api/chat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify,
        signal: controller.signal,
      });
      if  throw new Error;
      const reader = res.body.getReader;
      const decoder = new TextDecoder;
      let buffer = ''; // 关键:处理分包的 buffer
      let accumulated = '';
      while  {
        const { done, value } = await reader.read;
        if  break;
        buffer += decoder.decode;
        const lines = buffer.split;
        buffer = lines.pop; // Zui后一行可Neng不完整,留到下次
        for  {
          if ) continue;
          const payload = line.slice;
          if  break;
          try {
            const { content, error } = JSON.parse;
            if  throw new Error;
            if  {
              accumulated += content;
              // 实时geng新Zui后一条 assistant 消息
              setMessages => {
                const updated = ;
                updated = {
                  role: 'assistant',
                  content: accumulated,
                };
                return updated;
              });
            }
          } catch  {
            console.error;
          }
        }
      }
      // 流结束后持久化
      const finalMessages = ;
      saveHistory;
    } catch  {
      if  {
        setMessages => {
          const updated = ;
          updated = {
            role: 'assistant',
            content: `请求失败:${err.message}`,
          };
          return updated;
        });
      }
    } finally {
      setStreaming;
    }
  }, );
  const stopStreaming =  => abortRef.current?.abort;
  const clearHistory =  => {
    setMessages;
    localStorage.removeItem;
  };
  return { messages, streaming, modelId, setModelId, sendMessage, stopStreaming, clearHistory };
}
UI 组件组装

有了 Hook,剩下的就是拼积木了。我们需要一个模型选择器、一个消息展示窗口,以及一个输入框。

这里强烈推荐使用 `react-markdown` 和 `react-syntax-highlighter`,不然 AI 输出的代码块会是一团乱麻,可读性极差。

import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
export function MessageItem {
  const isUser = role === 'user';
  return (
    
{isUser ? '你' : 'AI'}
{isUser ? (

{content}

) : ( {String.replace} ) : ( {children} ); }, }} > {content || '▋'} {/* 流式未完成时显示光标 */} )}
); }

至于 `App.jsx`,就是把 `useChat` 的状态和这些组件连起来加上一个自动滚动到底部的 `useEffect` 就大功告成了。

部署方案:从本地到云端

代码写完了总不Neng只在 localhost 上跑吧?

前端:Vercel

Vercel 部署 React 项目简直是傻瓜式的。在项目根目录运行:

cd client
npm run build
npx vercel --prod

记得在 Vercel 的环境变量里配置好 `VITE_API_BASE`,指向你后端的地址。

后端:阿里云函数计算

Ru果你不想一直开着个 ECS 服务器烧钱,阿里云函数计算是个绝佳选择。按量付费,平时没请求基本不花钱。

你需要写一个 `template.yml` 来定义服务:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  ai-chat-service:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: AI Chat Backend
    ai-chat-function:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: nodejs18
        Timeout: 60 # 流式响应需要较长超时
        EnvironmentVariables:
          DEEPSEEK_API_KEY: !Ref DEEPSEEK_API_KEY

注意:函数计算的流式响应需要开启 "HTTP 触发器" 并配置 `responseType: stream`。Ru果觉得 FC 配置太繁琐,直接用个便宜的 ECS + PM2 部署也是极好的,几十块钱一个月,图个安稳。

几个容易踩的坑

开发过程中,总有一些让人抓狂的瞬间。这里几个血泪经验,希望Neng帮你少掉几根头发。

1. React StrictMode 的双重渲染

在开发环境下React 18 的 StrictMode 会让 `useEffect` 执行两次。这通常没问题,但Ru果你的 `useEffect` 里直接触发了 API 请求,你就会发现消息莫名其妙发两次。虽然 `useCallback` 包裹的函数只有依赖变化才重建,但Zui好还是检查一下是否有未清理的副作用,或者干脆在生产环境构建测试。

2. 上下文窗口爆炸

随着对话越来越长,`messages` 数组会无限增长,Zui终超出模型的 Token 限制,导致报错。Zui简单的策略是“截断”:只保留Zui近的 N 轮对话,或者把Zui早的旧消息存到数据库里只给模型发“摘要”。

// 发送前裁剪:保留 system prompt + Zui近 N 轮
const MAX_TURNS = 10;
const contextMessages = ;
3. SSE 分包问题

这是Zui常见的新手坑。你以为 SSE 是一行一行发的,但网络层可Neng会把两行拼成一个 chunk 发过来或者把一行切成两半。Ru果不处理 `buffer`,你的 JSON 解析就会报错,前端界面就会卡住不动。一定要像上面 `useChat.js` 里那样,用 `buffer` 变量存一下不完整的行。

构建一个 AI 聊天应用,kan似复杂,实则只要理顺了数据流向——从用户输入,到 React 状态geng新,再到 Node.js 的流式转发,Zui后回到前端的实时渲染——一切dou会变得井井有条。这不仅仅是一次编程练习,geng是对现代 Web 全栈开发Neng力的一次综合体检。希望这篇文章Neng给你带来一些启发,别光kan不练,赶紧动手试试吧!有问题欢迎评论区交流,觉得有帮助的话点个赞 👍。


标签: 教程

SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback