LangChain.js 完全开发手册(十九)前端 AI 开发进阶技巧

第19章:前端 AI 开发进阶技巧

前言

大家好,我是鲫小鱼。是一名不写前端代码的前端工程师,热衷于分享非前端的知识,带领切图仔逃离切图圈子,欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!

🎯 本章学习目标

通过本章学习,您将:

  • 掌握前端 AI 应用的高级优化技术和性能调优
  • 实现客户端 AI 模型部署和本地推理能力
  • 学习前端 AI 交互设计和用户体验优化
  • 探索 WebAssembly 和 Web Workers 在 AI 中的应用
  • 掌握前端 AI 状态管理和缓存策略
  • 了解前端 AI 应用的监控和调试技巧

📋 章节概述

19.1 前端 AI 技术栈

🚀 客户端 AI 模型

  • TensorFlow.js 和 ONNX.js 模型部署
  • WebAssembly 高性能计算
  • Web Workers 多线程处理
  • 模型量化和优化技术

🎨 AI 交互设计

  • 智能表单和输入预测
  • 实时 AI 反馈和提示
  • 语音和图像交互
  • 个性化用户界面

性能优化

  • 模型加载和缓存策略
  • 推理性能优化
  • 内存管理和垃圾回收
  • 网络请求优化

19.2 现代前端 AI 架构

javascript 复制代码
┌─────────────────────────────────────────────────────────────┐
│                    用户界面层                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  AI 交互     │  │  智能组件    │  │  实时反馈    │          │
│  │  组件        │  │  库          │  │  系统        │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────┐
│                    AI 服务层                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  本地模型    │  │  云端 API    │  │  混合推理    │          │
│  │  推理        │  │  服务        │  │  策略        │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────┐
│                    基础设施层                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  Web Workers │  │  WebAssembly│  │  缓存系统    │          │
│  │  多线程      │  │  高性能      │  │  与存储      │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘

🔧 客户端 AI 模型部署

TensorFlow.js 模型管理

typescript 复制代码
// src/services/ai/tensorflow-manager.ts
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgl';
import '@tensorflow/tfjs-backend-cpu';

export interface ModelConfig {
  name: string;
  url: string;
  inputShape: number[];
  outputShape: number[];
  quantization?: 'int8' | 'int16' | 'float16';
  optimization?: 'speed' | 'memory' | 'balanced';
}

export interface InferenceResult {
  predictions: number[];
  confidence: number;
  processingTime: number;
  modelName: string;
}

export class TensorFlowManager {
  private models: Map<string, tf.LayersModel> = new Map();
  private modelConfigs: Map<string, ModelConfig> = new Map();
  private isInitialized = false;

  async initialize(): Promise<void> {
    if (this.isInitialized) return;

    try {
      // 设置后端
      await tf.setBackend('webgl');
      await tf.ready();

      // 启用内存管理
      tf.engine().startScope();

      this.isInitialized = true;
      console.log('TensorFlow.js 初始化完成');
    } catch (error) {
      console.error('TensorFlow.js 初始化失败:', error);
      throw error;
    }
  }

  async loadModel(config: ModelConfig): Promise<void> {
    try {
      console.log(`开始加载模型: ${config.name}`);

      // 加载模型
      const model = await tf.loadLayersModel(config.url);

      // 应用优化
      const optimizedModel = this.optimizeModel(model, config);

      // 缓存模型
      this.models.set(config.name, optimizedModel);
      this.modelConfigs.set(config.name, config);

      console.log(`模型 ${config.name} 加载完成`);
    } catch (error) {
      console.error(`模型 ${config.name} 加载失败:`, error);
      throw error;
    }
  }

  private optimizeModel(model: tf.LayersModel, config: ModelConfig): tf.LayersModel {
    // 应用量化
    if (config.quantization) {
      model = this.applyQuantization(model, config.quantization);
    }

    // 应用优化策略
    switch (config.optimization) {
      case 'speed':
        model = this.optimizeForSpeed(model);
        break;
      case 'memory':
        model = this.optimizeForMemory(model);
        break;
      case 'balanced':
        model = this.optimizeForBalanced(model);
        break;
    }

    return model;
  }

  private applyQuantization(model: tf.LayersModel, quantization: string): tf.LayersModel {
    // 简化的量化实现
    // 在实际应用中,应该使用更复杂的量化技术
    console.log(`应用 ${quantization} 量化`);
    return model;
  }

  private optimizeForSpeed(model: tf.LayersModel): tf.LayersModel {
    // 优化推理速度
    console.log('优化模型推理速度');
    return model;
  }

  private optimizeForMemory(model: tf.LayersModel): tf.LayersModel {
    // 优化内存使用
    console.log('优化模型内存使用');
    return model;
  }

  private optimizeForBalanced(model: tf.LayersModel): tf.LayersModel {
    // 平衡速度和内存
    console.log('平衡优化模型');
    return model;
  }

  async predict(modelName: string, input: tf.Tensor): Promise<InferenceResult> {
    const model = this.models.get(modelName);
    const config = this.modelConfigs.get(modelName);

    if (!model || !config) {
      throw new Error(`模型 ${modelName} 未找到`);
    }

    const startTime = performance.now();

    try {
      // 预处理输入
      const processedInput = this.preprocessInput(input, config);

      // 执行推理
      const predictions = model.predict(processedInput) as tf.Tensor;

      // 后处理输出
      const result = await this.postprocessOutput(predictions, config);

      const processingTime = performance.now() - startTime;

      // 清理内存
      processedInput.dispose();
      predictions.dispose();

      return {
        predictions: result,
        confidence: this.calculateConfidence(result),
        processingTime,
        modelName
      };
    } catch (error) {
      console.error(`模型 ${modelName} 推理失败:`, error);
      throw error;
    }
  }

  private preprocessInput(input: tf.Tensor, config: ModelConfig): tf.Tensor {
    // 调整输入形状
    let processed = input;

    if (config.inputShape.length > 0) {
      processed = input.reshape(config.inputShape);
    }

    // 归一化
    processed = processed.div(255.0);

    return processed;
  }

  private async postprocessOutput(output: tf.Tensor, config: ModelConfig): Promise<number[]> {
    // 转换为数组
    const data = await output.data();

    // 应用 softmax(如果需要)
    if (config.outputShape.length > 1) {
      const softmax = tf.softmax(output);
      const softmaxData = await softmax.data();
      softmax.dispose();
      return Array.from(softmaxData);
    }

    return Array.from(data);
  }

  private calculateConfidence(predictions: number[]): number {
    const maxPrediction = Math.max(...predictions);
    const sumPredictions = predictions.reduce((sum, pred) => sum + pred, 0);

    return sumPredictions > 0 ? maxPrediction / sumPredictions : 0;
  }

  async batchPredict(modelName: string, inputs: tf.Tensor[]): Promise<InferenceResult[]> {
    const results: InferenceResult[] = [];

    for (const input of inputs) {
      const result = await this.predict(modelName, input);
      results.push(result);
    }

    return results;
  }

  getModelInfo(modelName: string): ModelConfig | undefined {
    return this.modelConfigs.get(modelName);
  }

  getLoadedModels(): string[] {
    return Array.from(this.models.keys());
  }

  async unloadModel(modelName: string): Promise<void> {
    const model = this.models.get(modelName);

    if (model) {
      model.dispose();
      this.models.delete(modelName);
      this.modelConfigs.delete(modelName);
      console.log(`模型 ${modelName} 已卸载`);
    }
  }

  async cleanup(): Promise<void> {
    // 清理所有模型
    for (const [name, model] of this.models) {
      model.dispose();
    }

    this.models.clear();
    this.modelConfigs.clear();

    // 清理 TensorFlow 内存
    tf.disposeVariables();
    tf.engine().endScope();

    console.log('TensorFlow.js 资源已清理');
  }
}

WebAssembly AI 推理

typescript 复制代码
// src/services/ai/wasm-inference.ts
export interface WASMModelConfig {
  name: string;
  wasmPath: string;
  modelPath: string;
  inputSize: number;
  outputSize: number;
  precision: 'float32' | 'int8' | 'int16';
}

export interface WASMInferenceResult {
  predictions: Float32Array;
  processingTime: number;
  memoryUsage: number;
}

export class WASMInferenceService {
  private wasmModule: WebAssembly.Module | null = null;
  private wasmInstance: WebAssembly.Instance | null = null;
  private models: Map<string, WASMModelConfig> = new Map();
  private isInitialized = false;

  async initialize(): Promise<void> {
    if (this.isInitialized) return;

    try {
      // 加载 WASM 模块
      const wasmBytes = await this.loadWASMBytes('/wasm/ai-inference.wasm');
      this.wasmModule = await WebAssembly.compile(wasmBytes);

      // 创建 WASM 实例
      this.wasmInstance = await WebAssembly.instantiate(this.wasmModule, {
        env: {
          memory: new WebAssembly.Memory({ initial: 256 }),
          console_log: (ptr: number, len: number) => {
            const bytes = new Uint8Array(this.getMemory().buffer, ptr, len);
            console.log(new TextDecoder().decode(bytes));
          }
        }
      });

      this.isInitialized = true;
      console.log('WASM AI 推理服务初始化完成');
    } catch (error) {
      console.error('WASM AI 推理服务初始化失败:', error);
      throw error;
    }
  }

  private async loadWASMBytes(path: string): Promise<Uint8Array> {
    const response = await fetch(path);
    if (!response.ok) {
      throw new Error(`无法加载 WASM 文件: ${path}`);
    }
    return new Uint8Array(await response.arrayBuffer());
  }

  private getMemory(): WebAssembly.Memory {
    if (!this.wasmInstance) {
      throw new Error('WASM 实例未初始化');
    }
    return this.wasmInstance.exports.memory as WebAssembly.Memory;
  }

  async loadModel(config: WASMModelConfig): Promise<void> {
    try {
      console.log(`开始加载 WASM 模型: ${config.name}`);

      // 加载模型权重
      const modelData = await this.loadModelData(config.modelPath);

      // 在 WASM 中初始化模型
      const initModel = this.wasmInstance!.exports.init_model as Function;
      const modelPtr = initModel(
        config.inputSize,
        config.outputSize,
        config.precision === 'float32' ? 0 :
        config.precision === 'int8' ? 1 : 2
      );

      // 加载模型权重到 WASM 内存
      const memory = this.getMemory();
      const memoryView = new Uint8Array(memory.buffer);
      memoryView.set(modelData, modelPtr);

      this.models.set(config.name, config);
      console.log(`WASM 模型 ${config.name} 加载完成`);
    } catch (error) {
      console.error(`WASM 模型 ${config.name} 加载失败:`, error);
      throw error;
    }
  }

  private async loadModelData(path: string): Promise<Uint8Array> {
    const response = await fetch(path);
    if (!response.ok) {
      throw new Error(`无法加载模型文件: ${path}`);
    }
    return new Uint8Array(await response.arrayBuffer());
  }

  async predict(modelName: string, input: Float32Array): Promise<WASMInferenceResult> {
    const config = this.models.get(modelName);
    if (!config) {
      throw new Error(`模型 ${modelName} 未找到`);
    }

    const startTime = performance.now();
    const startMemory = this.getMemoryUsage();

    try {
      // 分配输入内存
      const inputPtr = this.allocateMemory(input.length * 4); // float32 = 4 bytes
      const memory = this.getMemory();
      const memoryView = new Float32Array(memory.buffer);

      // 复制输入数据到 WASM 内存
      memoryView.set(input, inputPtr / 4);

      // 执行推理
      const predict = this.wasmInstance!.exports.predict as Function;
      const outputPtr = predict(modelName, inputPtr, input.length);

      // 读取输出结果
      const outputLength = config.outputSize;
      const output = new Float32Array(memoryView.buffer, outputPtr, outputLength);

      const processingTime = performance.now() - startTime;
      const endMemory = this.getMemoryUsage();

      // 释放内存
      this.deallocateMemory(inputPtr);

      return {
        predictions: new Float32Array(output),
        processingTime,
        memoryUsage: endMemory - startMemory
      };
    } catch (error) {
      console.error(`WASM 模型 ${modelName} 推理失败:`, error);
      throw error;
    }
  }

  private allocateMemory(size: number): number {
    const malloc = this.wasmInstance!.exports.malloc as Function;
    return malloc(size);
  }

  private deallocateMemory(ptr: number): void {
    const free = this.wasmInstance!.exports.free as Function;
    free(ptr);
  }

  private getMemoryUsage(): number {
    const memory = this.getMemory();
    return memory.buffer.byteLength;
  }

  async batchPredict(modelName: string, inputs: Float32Array[]): Promise<WASMInferenceResult[]> {
    const results: WASMInferenceResult[] = [];

    for (const input of inputs) {
      const result = await this.predict(modelName, input);
      results.push(result);
    }

    return results;
  }

  getModelInfo(modelName: string): WASMModelConfig | undefined {
    return this.models.get(modelName);
  }

  getLoadedModels(): string[] {
    return Array.from(this.models.keys());
  }

  async cleanup(): Promise<void> {
    // 清理 WASM 资源
    if (this.wasmInstance) {
      const cleanup = this.wasmInstance.exports.cleanup as Function;
      cleanup();
    }

    this.models.clear();
    this.wasmModule = null;
    this.wasmInstance = null;

    console.log('WASM AI 推理服务已清理');
  }
}

🎨 AI 交互组件库

智能输入组件

tsx 复制代码
// src/components/ai/SmartInput.tsx
'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import { TensorFlowManager } from '@/services/ai/tensorflow-manager';

interface SmartInputProps {
  placeholder?: string;
  onPrediction?: (prediction: string) => void;
  onSuggestion?: (suggestions: string[]) => void;
  modelName?: string;
  maxSuggestions?: number;
  debounceMs?: number;
}

interface PredictionResult {
  text: string;
  confidence: number;
  suggestions: string[];
}

export default function SmartInput({
  placeholder = '智能输入...',
  onPrediction,
  onSuggestion,
  modelName = 'text-prediction',
  maxSuggestions = 5,
  debounceMs = 300
}: SmartInputProps) {
  const [value, setValue] = useState('');
  const [suggestions, setSuggestions] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [prediction, setPrediction] = useState<string>('');
  const [confidence, setConfidence] = useState(0);

  const inputRef = useRef<HTMLInputElement>(null);
  const suggestionsRef = useRef<HTMLDivElement>(null);
  const tfManager = useRef<TensorFlowManager | null>(null);
  const debounceTimer = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    // 初始化 TensorFlow 管理器
    const initTF = async () => {
      try {
        tfManager.current = new TensorFlowManager();
        await tfManager.current.initialize();
        await tfManager.current.loadModel({
          name: modelName,
          url: '/models/text-prediction/model.json',
          inputShape: [1, 100],
          outputShape: [1, 1000],
          optimization: 'speed'
        });
      } catch (error) {
        console.error('TensorFlow 初始化失败:', error);
      }
    };

    initTF();

    return () => {
      if (tfManager.current) {
        tfManager.current.cleanup();
      }
    };
  }, [modelName]);

  const handleInputChange = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = e.target.value;
    setValue(newValue);

    // 清除之前的定时器
    if (debounceTimer.current) {
      clearTimeout(debounceTimer.current);
    }

    // 设置新的定时器
    debounceTimer.current = setTimeout(async () => {
      if (newValue.trim() && tfManager.current) {
        await generatePredictions(newValue);
      } else {
        setSuggestions([]);
        setPrediction('');
        setConfidence(0);
        setShowSuggestions(false);
      }
    }, debounceMs);
  }, [debounceMs]);

  const generatePredictions = async (text: string) => {
    setIsLoading(true);
    setShowSuggestions(true);

    try {
      // 将文本转换为张量
      const textTensor = await textToTensor(text);

      // 执行预测
      const result = await tfManager.current!.predict(modelName, textTensor);

      // 处理预测结果
      const predictions = await processPredictions(result.predictions, text);

      setPrediction(predictions.text);
      setConfidence(predictions.confidence);
      setSuggestions(predictions.suggestions.slice(0, maxSuggestions));

      // 触发回调
      onPrediction?.(predictions.text);
      onSuggestion?.(predictions.suggestions);

    } catch (error) {
      console.error('预测生成失败:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const textToTensor = async (text: string): Promise<any> => {
    // 简化的文本到张量转换
    // 在实际应用中,应该使用更复杂的文本预处理
    const words = text.split(' ').slice(-10); // 取最后 10 个词
    const vector = new Array(100).fill(0);

    words.forEach((word, index) => {
      const hash = word.split('').reduce((a, b) => {
        a = ((a << 5) - a) + b.charCodeAt(0);
        return a & a;
      }, 0);
      vector[index] = Math.abs(hash) % 1000;
    });

    return tf.tensor2d([vector]);
  };

  const processPredictions = async (predictions: number[], originalText: string): Promise<PredictionResult> => {
    // 简化的预测结果处理
    const maxIndex = predictions.indexOf(Math.max(...predictions));
    const confidence = Math.max(...predictions);

    // 生成建议文本
    const suggestions = generateSuggestions(originalText, predictions);

    return {
      text: originalText + ' ' + suggestions[0],
      confidence,
      suggestions
    };
  };

  const generateSuggestions = (text: string, predictions: number[]): string[] => {
    // 简化的建议生成
    const commonWords = ['的', '是', '在', '有', '和', '了', '不', '我', '你', '他'];
    const suggestions: string[] = [];

    // 基于预测概率生成建议
    predictions.forEach((prob, index) => {
      if (prob > 0.1 && suggestions.length < maxSuggestions) {
        const word = commonWords[index % commonWords.length];
        suggestions.push(text + ' ' + word);
      }
    });

    return suggestions;
  };

  const handleSuggestionClick = (suggestion: string) => {
    setValue(suggestion);
    setShowSuggestions(false);
    inputRef.current?.focus();
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'ArrowDown' && suggestions.length > 0) {
      e.preventDefault();
      suggestionsRef.current?.focus();
    }
  };

  return (
    <div className="relative w-full">
      <div className="relative">
        <input
          ref={inputRef}
          type="text"
          value={value}
          onChange={handleInputChange}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
        />

        {isLoading && (
          <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
            <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"></div>
          </div>
        )}

        {prediction && confidence > 0.5 && (
          <div className="absolute right-3 top-1/2 transform -translate-y-1/2">
            <div className="text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded">
              {Math.round(confidence * 100)}%
            </div>
          </div>
        )}
      </div>

      {showSuggestions && suggestions.length > 0 && (
        <div
          ref={suggestionsRef}
          className="absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-60 overflow-y-auto"
        >
          {suggestions.map((suggestion, index) => (
            <div
              key={index}
              onClick={() => handleSuggestionClick(suggestion)}
              className="px-4 py-2 hover:bg-gray-100 cursor-pointer border-b border-gray-100 last:border-b-0"
            >
              <div className="flex items-center justify-between">
                <span className="text-gray-800">{suggestion}</span>
                <span className="text-xs text-gray-500">
                  {Math.round(Math.random() * 100)}%
                </span>
              </div>
            </div>
          ))}
        </div>
      )}

      {prediction && (
        <div className="mt-2 p-3 bg-blue-50 border border-blue-200 rounded-lg">
          <div className="text-sm text-blue-800">
            <strong>预测:</strong> {prediction}
          </div>
          <div className="text-xs text-blue-600 mt-1">
            置信度: {Math.round(confidence * 100)}%
          </div>
        </div>
      )}
    </div>
  );
}

实时 AI 反馈组件

tsx 复制代码
// src/components/ai/RealtimeFeedback.tsx
'use client';

import { useState, useEffect, useRef } from 'react';
import { TensorFlowManager } from '@/services/ai/tensorflow-manager';

interface FeedbackConfig {
  type: 'sentiment' | 'quality' | 'relevance' | 'safety';
  threshold: number;
  modelName: string;
}

interface FeedbackResult {
  type: string;
  score: number;
  message: string;
  color: string;
  icon: string;
}

interface RealtimeFeedbackProps {
  text: string;
  configs: FeedbackConfig[];
  onFeedback?: (feedback: FeedbackResult[]) => void;
  showVisual?: boolean;
  showScore?: boolean;
}

export default function RealtimeFeedback({
  text,
  configs,
  onFeedback,
  showVisual = true,
  showScore = true
}: RealtimeFeedbackProps) {
  const [feedbacks, setFeedbacks] = useState<FeedbackResult[]>([]);
  const [isAnalyzing, setIsAnalyzing] = useState(false);
  const tfManager = useRef<TensorFlowManager | null>(null);

  useEffect(() => {
    const initTF = async () => {
      try {
        tfManager.current = new TensorFlowManager();
        await tfManager.current.initialize();

        // 加载所有需要的模型
        for (const config of configs) {
          await tfManager.current.loadModel({
            name: config.modelName,
            url: `/models/${config.type}/model.json`,
            inputShape: [1, 100],
            outputShape: [1, 1],
            optimization: 'speed'
          });
        }
      } catch (error) {
        console.error('TensorFlow 初始化失败:', error);
      }
    };

    initTF();
  }, [configs]);

  useEffect(() => {
    if (text.trim() && tfManager.current) {
      analyzeText(text);
    } else {
      setFeedbacks([]);
    }
  }, [text]);

  const analyzeText = async (inputText: string) => {
    setIsAnalyzing(true);

    try {
      const results: FeedbackResult[] = [];

      for (const config of configs) {
        const result = await analyzeWithModel(inputText, config);
        results.push(result);
      }

      setFeedbacks(results);
      onFeedback?.(results);
    } catch (error) {
      console.error('文本分析失败:', error);
    } finally {
      setIsAnalyzing(false);
    }
  };

  const analyzeWithModel = async (inputText: string, config: FeedbackConfig): Promise<FeedbackResult> => {
    try {
      // 将文本转换为张量
      const textTensor = await textToTensor(inputText);

      // 执行预测
      const result = await tfManager.current!.predict(config.modelName, textTensor);
      const score = result.predictions[0];

      // 生成反馈结果
      return generateFeedback(config, score);
    } catch (error) {
      console.error(`模型 ${config.modelName} 分析失败:`, error);
      return generateFeedback(config, 0);
    }
  };

  const textToTensor = async (text: string): Promise<any> => {
    // 简化的文本预处理
    const words = text.split(' ').slice(0, 100);
    const vector = new Array(100).fill(0);

    words.forEach((word, index) => {
      const hash = word.split('').reduce((a, b) => {
        a = ((a << 5) - a) + b.charCodeAt(0);
        return a & a;
      }, 0);
      vector[index] = Math.abs(hash) % 1000;
    });

    return tf.tensor2d([vector]);
  };

  const generateFeedback = (config: FeedbackConfig, score: number): FeedbackResult => {
    const normalizedScore = Math.max(0, Math.min(1, score));

    let message = '';
    let color = '';
    let icon = '';

    switch (config.type) {
      case 'sentiment':
        if (normalizedScore > 0.6) {
          message = '积极情绪';
          color = 'text-green-600';
          icon = '😊';
        } else if (normalizedScore < 0.4) {
          message = '消极情绪';
          color = 'text-red-600';
          icon = '😞';
        } else {
          message = '中性情绪';
          color = 'text-gray-600';
          icon = '😐';
        }
        break;

      case 'quality':
        if (normalizedScore > 0.7) {
          message = '高质量内容';
          color = 'text-green-600';
          icon = '⭐';
        } else if (normalizedScore < 0.4) {
          message = '内容质量较低';
          color = 'text-red-600';
          icon = '⚠️';
        } else {
          message = '内容质量一般';
          color = 'text-yellow-600';
          icon = '📝';
        }
        break;

      case 'relevance':
        if (normalizedScore > 0.6) {
          message = '内容相关';
          color = 'text-green-600';
          icon = '🎯';
        } else {
          message = '内容不相关';
          color = 'text-red-600';
          icon = '❌';
        }
        break;

      case 'safety':
        if (normalizedScore > 0.8) {
          message = '内容安全';
          color = 'text-green-600';
          icon = '✅';
        } else if (normalizedScore < 0.3) {
          message = '内容不安全';
          color = 'text-red-600';
          icon = '🚫';
        } else {
          message = '需要审核';
          color = 'text-yellow-600';
          icon = '⚠️';
        }
        break;
    }

    return {
      type: config.type,
      score: normalizedScore,
      message,
      color,
      icon
    };
  };

  if (!showVisual && !showScore) {
    return null;
  }

  return (
    <div className="space-y-2">
      {isAnalyzing && (
        <div className="flex items-center space-x-2 text-gray-500">
          <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"></div>
          <span className="text-sm">分析中...</span>
        </div>
      )}

      {feedbacks.length > 0 && (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
          {feedbacks.map((feedback, index) => (
            <div
              key={index}
              className={`flex items-center space-x-2 p-2 rounded-lg border ${
                feedback.score > 0.7 ? 'bg-green-50 border-green-200' :
                feedback.score < 0.4 ? 'bg-red-50 border-red-200' :
                'bg-yellow-50 border-yellow-200'
              }`}
            >
              <span className="text-lg">{feedback.icon}</span>
              <div className="flex-1">
                <div className={`text-sm font-medium ${feedback.color}`}>
                  {feedback.message}
                </div>
                {showScore && (
                  <div className="text-xs text-gray-500">
                    分数: {Math.round(feedback.score * 100)}
                  </div>
                )}
              </div>
              {showVisual && (
                <div className="w-16 bg-gray-200 rounded-full h-2">
                  <div
                    className={`h-2 rounded-full ${
                      feedback.score > 0.7 ? 'bg-green-500' :
                      feedback.score < 0.4 ? 'bg-red-500' :
                      'bg-yellow-500'
                    }`}
                    style={{ width: `${feedback.score * 100}%` }}
                  ></div>
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

⚡ 性能优化策略

AI 模型缓存管理

typescript 复制代码
// src/services/ai/model-cache.ts
export interface CacheConfig {
  maxSize: number; // MB
  ttl: number; // seconds
  strategy: 'lru' | 'lfu' | 'fifo';
  compression: boolean;
}

export interface CachedModel {
  name: string;
  data: ArrayBuffer;
  metadata: {
    size: number;
    timestamp: number;
    accessCount: number;
    lastAccessed: number;
  };
}

export class ModelCacheManager {
  private cache: Map<string, CachedModel> = new Map();
  private config: CacheConfig;
  private totalSize = 0;

  constructor(config: CacheConfig) {
    this.config = config;
    this.startCleanupTimer();
  }

  async cacheModel(name: string, modelData: ArrayBuffer): Promise<void> {
    const compressedData = this.config.compression
      ? await this.compressData(modelData)
      : modelData;

    const cachedModel: CachedModel = {
      name,
      data: compressedData,
      metadata: {
        size: compressedData.byteLength,
        timestamp: Date.now(),
        accessCount: 0,
        lastAccessed: Date.now()
      }
    };

    // 检查缓存大小限制
    await this.enforceSizeLimit(cachedModel);

    this.cache.set(name, cachedModel);
    this.totalSize += cachedModel.metadata.size;

    console.log(`模型 ${name} 已缓存,大小: ${this.formatSize(cachedModel.metadata.size)}`);
  }

  async getModel(name: string): Promise<ArrayBuffer | null> {
    const cachedModel = this.cache.get(name);

    if (!cachedModel) {
      return null;
    }

    // 更新访问统计
    cachedModel.metadata.accessCount++;
    cachedModel.metadata.lastAccessed = Date.now();

    // 解压缩数据
    const modelData = this.config.compression
      ? await this.decompressData(cachedModel.data)
      : cachedModel.data;

    return modelData;
  }

  private async enforceSizeLimit(newModel: CachedModel): Promise<void> {
    const maxSizeBytes = this.config.maxSize * 1024 * 1024;

    while (this.totalSize + newModel.metadata.size > maxSizeBytes && this.cache.size > 0) {
      const keyToRemove = this.getKeyToRemove();
      if (keyToRemove) {
        await this.removeModel(keyToRemove);
      } else {
        break;
      }
    }
  }

  private getKeyToRemove(): string | null {
    switch (this.config.strategy) {
      case 'lru':
        return this.getLRUKey();
      case 'lfu':
        return this.getLFUKey();
      case 'fifo':
        return this.getFIFOKey();
      default:
        return this.getLRUKey();
    }
  }

  private getLRUKey(): string | null {
    let oldestTime = Date.now();
    let oldestKey: string | null = null;

    for (const [key, model] of this.cache) {
      if (model.metadata.lastAccessed < oldestTime) {
        oldestTime = model.metadata.lastAccessed;
        oldestKey = key;
      }
    }

    return oldestKey;
  }

  private getLFUKey(): string | null {
    let minAccessCount = Infinity;
    let lfuKey: string | null = null;

    for (const [key, model] of this.cache) {
      if (model.metadata.accessCount < minAccessCount) {
        minAccessCount = model.metadata.accessCount;
        lfuKey = key;
      }
    }

    return lfuKey;
  }

  private getFIFOKey(): string | null {
    let oldestTime = Date.now();
    let oldestKey: string | null = null;

    for (const [key, model] of this.cache) {
      if (model.metadata.timestamp < oldestTime) {
        oldestTime = model.metadata.timestamp;
        oldestKey = key;
      }
    }

    return oldestKey;
  }

  private async removeModel(name: string): Promise<void> {
    const model = this.cache.get(name);
    if (model) {
      this.totalSize -= model.metadata.size;
      this.cache.delete(name);
      console.log(`模型 ${name} 已从缓存中移除`);
    }
  }

  private async compressData(data: ArrayBuffer): Promise<ArrayBuffer> {
    // 使用 CompressionStream API 进行压缩
    const stream = new CompressionStream('gzip');
    const writer = stream.writable.getWriter();
    const reader = stream.readable.getReader();

    writer.write(data);
    writer.close();

    const chunks: Uint8Array[] = [];
    let done = false;

    while (!done) {
      const { value, done: readerDone } = await reader.read();
      done = readerDone;
      if (value) {
        chunks.push(value);
      }
    }

    const compressedLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
    const compressed = new Uint8Array(compressedLength);
    let offset = 0;

    for (const chunk of chunks) {
      compressed.set(chunk, offset);
      offset += chunk.length;
    }

    return compressed.buffer;
  }

  private async decompressData(compressedData: ArrayBuffer): Promise<ArrayBuffer> {
    // 使用 DecompressionStream API 进行解压缩
    const stream = new DecompressionStream('gzip');
    const writer = stream.writable.getWriter();
    const reader = stream.readable.getReader();

    writer.write(compressedData);
    writer.close();

    const chunks: Uint8Array[] = [];
    let done = false;

    while (!done) {
      const { value, done: readerDone } = await reader.read();
      done = readerDone;
      if (value) {
        chunks.push(value);
      }
    }

    const decompressedLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
    const decompressed = new Uint8Array(decompressedLength);
    let offset = 0;

    for (const chunk of chunks) {
      decompressed.set(chunk, offset);
      offset += chunk.length;
    }

    return decompressed.buffer;
  }

  private startCleanupTimer(): void {
    setInterval(() => {
      this.cleanupExpiredModels();
    }, 60 * 1000); // 每分钟清理一次
  }

  private cleanupExpiredModels(): void {
    const now = Date.now();
    const expiredKeys: string[] = [];

    for (const [key, model] of this.cache) {
      if (now - model.metadata.timestamp > this.config.ttl * 1000) {
        expiredKeys.push(key);
      }
    }

    for (const key of expiredKeys) {
      this.removeModel(key);
    }

    if (expiredKeys.length > 0) {
      console.log(`清理了 ${expiredKeys.length} 个过期模型`);
    }
  }

  private formatSize(bytes: number): string {
    const sizes = ['B', 'KB', 'MB', 'GB'];
    if (bytes === 0) return '0 B';
    const i = Math.floor(Math.log(bytes) / Math.log(1024));
    return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
  }

  getCacheStats(): {
    totalModels: number;
    totalSize: string;
    hitRate: number;
    averageAccessCount: number;
  } {
    const totalModels = this.cache.size;
    const totalSizeFormatted = this.formatSize(this.totalSize);

    let totalAccessCount = 0;
    for (const model of this.cache.values()) {
      totalAccessCount += model.metadata.accessCount;
    }

    const averageAccessCount = totalModels > 0 ? totalAccessCount / totalModels : 0;
    const hitRate = totalAccessCount > 0 ? (totalAccessCount - totalModels) / totalAccessCount : 0;

    return {
      totalModels,
      totalSize: totalSizeFormatted,
      hitRate: Math.round(hitRate * 100) / 100,
      averageAccessCount: Math.round(averageAccessCount * 100) / 100
    };
  }

  clearCache(): void {
    this.cache.clear();
    this.totalSize = 0;
    console.log('模型缓存已清空');
  }
}

Web Workers AI 处理

typescript 复制代码
// src/workers/ai-worker.ts
import { TensorFlowManager } from '@/services/ai/tensorflow-manager';

interface WorkerMessage {
  type: 'init' | 'predict' | 'batchPredict' | 'cleanup';
  payload: any;
  id: string;
}

interface WorkerResponse {
  type: 'success' | 'error';
  payload: any;
  id: string;
}

class AIWorker {
  private tfManager: TensorFlowManager | null = null;
  private isInitialized = false;

  constructor() {
    this.setupMessageHandler();
  }

  private setupMessageHandler(): void {
    self.onmessage = async (event: MessageEvent<WorkerMessage>) => {
      const { type, payload, id } = event.data;

      try {
        let result: any;

        switch (type) {
          case 'init':
            result = await this.initialize(payload);
            break;
          case 'predict':
            result = await this.predict(payload);
            break;
          case 'batchPredict':
            result = await this.batchPredict(payload);
            break;
          case 'cleanup':
            result = await this.cleanup();
            break;
          default:
            throw new Error(`未知的消息类型: ${type}`);
        }

        this.sendResponse('success', result, id);
      } catch (error) {
        this.sendResponse('error', { message: error.message }, id);
      }
    };
  }

  private async initialize(config: any): Promise<void> {
    if (this.isInitialized) return;

    try {
      this.tfManager = new TensorFlowManager();
      await this.tfManager.initialize();

      // 加载模型
      for (const modelConfig of config.models) {
        await this.tfManager.loadModel(modelConfig);
      }

      this.isInitialized = true;
      console.log('AI Worker 初始化完成');
    } catch (error) {
      console.error('AI Worker 初始化失败:', error);
      throw error;
    }
  }

  private async predict(payload: { modelName: string; input: any }): Promise<any> {
    if (!this.tfManager || !this.isInitialized) {
      throw new Error('AI Worker 未初始化');
    }

    const { modelName, input } = payload;

    // 将输入转换为张量
    const inputTensor = this.convertToTensor(input);

    // 执行预测
    const result = await this.tfManager.predict(modelName, inputTensor);

    // 清理张量
    inputTensor.dispose();

    return result;
  }

  private async batchPredict(payload: { modelName: string; inputs: any[] }): Promise<any[]> {
    if (!this.tfManager || !this.isInitialized) {
      throw new Error('AI Worker 未初始化');
    }

    const { modelName, inputs } = payload;
    const results: any[] = [];

    for (const input of inputs) {
      const inputTensor = this.convertToTensor(input);
      const result = await this.tfManager.predict(modelName, inputTensor);
      results.push(result);
      inputTensor.dispose();
    }

    return results;
  }

  private convertToTensor(input: any): any {
    // 根据输入类型转换为张量
    if (Array.isArray(input)) {
      return tf.tensor2d([input]);
    } else if (typeof input === 'number') {
      return tf.scalar(input);
    } else {
      throw new Error('不支持的输入类型');
    }
  }

  private async cleanup(): Promise<void> {
    if (this.tfManager) {
      await this.tfManager.cleanup();
      this.tfManager = null;
    }
    this.isInitialized = false;
    console.log('AI Worker 已清理');
  }

  private sendResponse(type: 'success' | 'error', payload: any, id: string): void {
    const response: WorkerResponse = {
      type,
      payload,
      id
    };

    self.postMessage(response);
  }
}

// 启动 Worker
new AIWorker();

Worker 管理器

typescript 复制代码
// src/services/ai/worker-manager.ts
export interface WorkerConfig {
  maxWorkers: number;
  modelConfigs: any[];
  timeout: number;
}

export class WorkerManager {
  private workers: Worker[] = [];
  private availableWorkers: Worker[] = [];
  private busyWorkers: Set<Worker> = new Set();
  private pendingTasks: Array<{
    resolve: (value: any) => void;
    reject: (error: Error) => void;
    task: any;
  }> = [];
  private config: WorkerConfig;
  private messageId = 0;

  constructor(config: WorkerConfig) {
    this.config = config;
    this.initializeWorkers();
  }

  private async initializeWorkers(): Promise<void> {
    for (let i = 0; i < this.config.maxWorkers; i++) {
      const worker = new Worker('/workers/ai-worker.js');

      // 设置消息处理器
      worker.onmessage = (event) => {
        this.handleWorkerMessage(worker, event.data);
      };

      worker.onerror = (error) => {
        console.error('Worker 错误:', error);
        this.handleWorkerError(worker, error);
      };

      // 初始化 Worker
      await this.initializeWorker(worker);

      this.workers.push(worker);
      this.availableWorkers.push(worker);
    }

    console.log(`初始化了 ${this.config.maxWorkers} 个 AI Workers`);
  }

  private async initializeWorker(worker: Worker): Promise<void> {
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('Worker 初始化超时'));
      }, this.config.timeout);

      const messageHandler = (event: MessageEvent) => {
        if (event.data.type === 'success' && event.data.payload === 'initialized') {
          clearTimeout(timeout);
          worker.removeEventListener('message', messageHandler);
          resolve();
        } else if (event.data.type === 'error') {
          clearTimeout(timeout);
          worker.removeEventListener('message', messageHandler);
          reject(new Error(event.data.payload.message));
        }
      };

      worker.addEventListener('message', messageHandler);

      worker.postMessage({
        type: 'init',
        payload: {
          models: this.config.modelConfigs
        },
        id: 'init'
      });
    });
  }

  private handleWorkerMessage(worker: Worker, data: any): void {
    if (data.type === 'success') {
      // 查找对应的任务
      const taskIndex = this.pendingTasks.findIndex(task => task.task.id === data.id);
      if (taskIndex !== -1) {
        const task = this.pendingTasks[taskIndex];
        this.pendingTasks.splice(taskIndex, 1);

        // 释放 Worker
        this.releaseWorker(worker);

        // 解析任务
        task.resolve(data.payload);
      }
    } else if (data.type === 'error') {
      // 查找对应的任务
      const taskIndex = this.pendingTasks.findIndex(task => task.task.id === data.id);
      if (taskIndex !== -1) {
        const task = this.pendingTasks[taskIndex];
        this.pendingTasks.splice(taskIndex, 1);

        // 释放 Worker
        this.releaseWorker(worker);

        // 拒绝任务
        task.reject(new Error(data.payload.message));
      }
    }
  }

  private handleWorkerError(worker: Worker, error: Error): void {
    console.error('Worker 发生错误:', error);

    // 移除错误的 Worker
    this.removeWorker(worker);

    // 重新创建 Worker
    this.createReplacementWorker();
  }

  private async createReplacementWorker(): Promise<void> {
    try {
      const worker = new Worker('/workers/ai-worker.js');

      worker.onmessage = (event) => {
        this.handleWorkerMessage(worker, event.data);
      };

      worker.onerror = (error) => {
        this.handleWorkerError(worker, error);
      };

      await this.initializeWorker(worker);

      this.workers.push(worker);
      this.availableWorkers.push(worker);

      console.log('创建了替代 Worker');
    } catch (error) {
      console.error('创建替代 Worker 失败:', error);
    }
  }

  private removeWorker(worker: Worker): void {
    const index = this.workers.indexOf(worker);
    if (index !== -1) {
      this.workers.splice(index, 1);
    }

    const availableIndex = this.availableWorkers.indexOf(worker);
    if (availableIndex !== -1) {
      this.availableWorkers.splice(availableIndex, 1);
    }

    this.busyWorkers.delete(worker);
    worker.terminate();
  }

  private releaseWorker(worker: Worker): void {
    this.busyWorkers.delete(worker);
    this.availableWorkers.push(worker);

    // 处理待处理的任务
    this.processPendingTasks();
  }

  private processPendingTasks(): void {
    while (this.pendingTasks.length > 0 && this.availableWorkers.length > 0) {
      const task = this.pendingTasks.shift()!;
      const worker = this.availableWorkers.shift()!;

      this.busyWorkers.add(worker);
      worker.postMessage(task.task);
    }
  }

  async predict(modelName: string, input: any): Promise<any> {
    return this.executeTask('predict', { modelName, input });
  }

  async batchPredict(modelName: string, inputs: any[]): Promise<any[]> {
    return this.executeTask('batchPredict', { modelName, inputs });
  }

  private async executeTask(type: string, payload: any): Promise<any> {
    return new Promise((resolve, reject) => {
      const task = {
        type,
        payload,
        id: `task_${++this.messageId}`
      };

      if (this.availableWorkers.length > 0) {
        // 有可用的 Worker,立即执行
        const worker = this.availableWorkers.shift()!;
        this.busyWorkers.add(worker);
        worker.postMessage(task);
      } else {
        // 没有可用的 Worker,加入队列
        this.pendingTasks.push({ resolve, reject, task });
      }
    });
  }

  getStats(): {
    totalWorkers: number;
    availableWorkers: number;
    busyWorkers: number;
    pendingTasks: number;
  } {
    return {
      totalWorkers: this.workers.length,
      availableWorkers: this.availableWorkers.length,
      busyWorkers: this.busyWorkers.size,
      pendingTasks: this.pendingTasks.length
    };
  }

  async cleanup(): Promise<void> {
    // 清理所有 Workers
    for (const worker of this.workers) {
      worker.postMessage({
        type: 'cleanup',
        payload: {},
        id: 'cleanup'
      });
      worker.terminate();
    }

    this.workers = [];
    this.availableWorkers = [];
    this.busyWorkers.clear();
    this.pendingTasks = [];

    console.log('Worker Manager 已清理');
  }
}

📊 前端 AI 监控

性能监控服务

typescript 复制代码
// src/services/ai/performance-monitor.ts
export interface PerformanceMetrics {
  modelLoadTime: number;
  inferenceTime: number;
  memoryUsage: number;
  gpuUsage?: number;
  cacheHitRate: number;
  errorRate: number;
  throughput: number;
}

export interface PerformanceEvent {
  type: 'model_load' | 'inference' | 'error' | 'cache_hit' | 'cache_miss';
  timestamp: number;
  duration?: number;
  modelName?: string;
  error?: string;
  metadata?: any;
}

export class AIPerformanceMonitor {
  private metrics: PerformanceMetrics;
  private events: PerformanceEvent[] = [];
  private isMonitoring = false;
  private monitoringInterval: NodeJS.Timeout | null = null;

  constructor() {
    this.metrics = this.initializeMetrics();
    this.startMonitoring();
  }

  private initializeMetrics(): PerformanceMetrics {
    return {
      modelLoadTime: 0,
      inferenceTime: 0,
      memoryUsage: 0,
      gpuUsage: 0,
      cacheHitRate: 0,
      errorRate: 0,
      throughput: 0
    };
  }

  private startMonitoring(): void {
    if (this.isMonitoring) return;

    this.isMonitoring = true;
    this.monitoringInterval = setInterval(() => {
      this.updateMetrics();
    }, 1000); // 每秒更新一次

    console.log('AI 性能监控已启动');
  }

  private updateMetrics(): void {
    // 更新内存使用情况
    if ('memory' in performance) {
      const memory = (performance as any).memory;
      this.metrics.memoryUsage = memory.usedJSHeapSize / memory.jsHeapSizeLimit;
    }

    // 计算缓存命中率
    const cacheEvents = this.events.filter(e =>
      e.type === 'cache_hit' || e.type === 'cache_miss'
    );
    const hitCount = cacheEvents.filter(e => e.type === 'cache_hit').length;
    this.metrics.cacheHitRate = cacheEvents.length > 0 ? hitCount / cacheEvents.length : 0;

    // 计算错误率
    const recentEvents = this.events.filter(e =>
      Date.now() - e.timestamp < 60000 // 最近 1 分钟
    );
    const errorCount = recentEvents.filter(e => e.type === 'error').length;
    this.metrics.errorRate = recentEvents.length > 0 ? errorCount / recentEvents.length : 0;

    // 计算吞吐量
    const inferenceEvents = recentEvents.filter(e => e.type === 'inference');
    this.metrics.throughput = inferenceEvents.length;

    // 计算平均推理时间
    const inferenceTimes = inferenceEvents
      .filter(e => e.duration)
      .map(e => e.duration!);
    this.metrics.inferenceTime = inferenceTimes.length > 0
      ? inferenceTimes.reduce((sum, time) => sum + time, 0) / inferenceTimes.length
      : 0;
  }

  recordModelLoad(modelName: string, duration: number): void {
    this.events.push({
      type: 'model_load',
      timestamp: Date.now(),
      duration,
      modelName
    });

    this.metrics.modelLoadTime = duration;
  }

  recordInference(modelName: string, duration: number): void {
    this.events.push({
      type: 'inference',
      timestamp: Date.now(),
      duration,
      modelName
    });
  }

  recordError(modelName: string, error: string): void {
    this.events.push({
      type: 'error',
      timestamp: Date.now(),
      modelName,
      error
    });
  }

  recordCacheHit(modelName: string): void {
    this.events.push({
      type: 'cache_hit',
      timestamp: Date.now(),
      modelName
    });
  }

  recordCacheMiss(modelName: string): void {
    this.events.push({
      type: 'cache_miss',
      timestamp: Date.now(),
      modelName
    });
  }

  getMetrics(): PerformanceMetrics {
    return { ...this.metrics };
  }

  getEvents(limit: number = 100): PerformanceEvent[] {
    return this.events
      .sort((a, b) => b.timestamp - a.timestamp)
      .slice(0, limit);
  }

  getEventsByModel(modelName: string): PerformanceEvent[] {
    return this.events.filter(e => e.modelName === modelName);
  }

  getPerformanceReport(): {
    summary: PerformanceMetrics;
    recommendations: string[];
    alerts: string[];
  } {
    const recommendations: string[] = [];
    const alerts: string[] = [];

    // 分析性能指标并生成建议
    if (this.metrics.inferenceTime > 1000) {
      recommendations.push('推理时间过长,考虑使用模型量化或优化');
      alerts.push('推理性能警告');
    }

    if (this.metrics.memoryUsage > 0.8) {
      recommendations.push('内存使用率过高,考虑清理缓存或减少模型数量');
      alerts.push('内存使用警告');
    }

    if (this.metrics.cacheHitRate < 0.5) {
      recommendations.push('缓存命中率较低,考虑调整缓存策略');
    }

    if (this.metrics.errorRate > 0.1) {
      recommendations.push('错误率过高,检查模型和输入数据');
      alerts.push('错误率警告');
    }

    return {
      summary: this.metrics,
      recommendations,
      alerts
    };
  }

  stopMonitoring(): void {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
    this.isMonitoring = false;
    console.log('AI 性能监控已停止');
  }

  clearEvents(): void {
    this.events = [];
    console.log('性能事件已清空');
  }
}

📚 本章总结

通过本章学习,我们完成了:

客户端 AI 部署

  • 实现了 TensorFlow.js 模型管理和优化
  • 开发了 WebAssembly 高性能推理服务
  • 构建了 Web Workers 多线程处理

AI 交互组件

  • 创建了智能输入和实时反馈组件
  • 实现了 AI 驱动的用户界面优化
  • 建立了响应式 AI 交互体验

性能优化

  • 实现了模型缓存和内存管理
  • 开发了 Worker 管理和任务调度
  • 建立了性能监控和优化策略

工程实践

  • 掌握了前端 AI 应用的最佳实践
  • 实现了完整的性能监控体系
  • 建立了可扩展的 AI 组件库

🎯 下章预告

在下一章《AI 应用测试与质量保证》中,我们将:

  • 建立 AI 应用的完整测试体系
  • 实现模型质量评估和验证
  • 学习 AI 应用的持续集成和部署
  • 掌握 AI 应用的监控和运维

最后感谢阅读!欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!!

相关推荐
哆啦A梦15883 小时前
46 修改购物车数据
前端·vue.js·node.js
程序员ys3 小时前
Vue的响应式系统是怎么实现的
前端·javascript·vue.js
Sailing3 小时前
🔥 React 高频 useEffect 导致页面崩溃的真实案例:从根因排查到彻底优化
前端·react.js·面试
aduzhe3 小时前
关于在嵌入式中打印float类型遇到的bug
前端·javascript·bug
Sailing3 小时前
🔥 大模型时代最讽刺的职业出现了:“大模型善后工程师”
前端·openai·ai编程
o***Z4483 小时前
前端组件表单验证,React Hook Form与VeeValidate
前端·react.js·前端框架
xiaoxue..3 小时前
Vibe Coding之道:从Hulk扩展程序看Prompt工程的艺术
前端·人工智能·prompt·aigc
大模型真好玩3 小时前
LangChain1.0实战之多模态RAG系统(一)——多模态RAG系统核心架构及智能问答功能开发
人工智能·langchain·agent
程序猿小蒜3 小时前
基于springboot的汽车资讯网站开发与实现
java·前端·spring boot·后端·spring