跳到主要内容

JavaScript AI生态

目录

JavaScript已经成为AI应用开发的重要语言,拥有丰富的AI库、框架和工具链。本文将深入探讨JavaScript AI生态系统,帮助开发者选择合适的工具和技术栈。

JavaScript AI生态概览

生态系统架构

核心AI框架

1. TensorFlow.js

特点

  • Google开发的机器学习框架
  • 支持浏览器和Node.js
  • 预训练模型丰富
  • 支持自定义模型训练

核心功能实现

// TensorFlow.js核心功能封装
class TensorFlowManager {
constructor() {
this.models = new Map();
this.backend = 'webgl'; // 默认使用WebGL加速
this.initialized = false;
}

async initialize() {
if (this.initialized) return;

// 设置后端
await tf.setBackend(this.backend);
await tf.ready();

// 检查设备能力
const deviceInfo = this.getDeviceInfo();
console.log('TensorFlow.js initialized:', deviceInfo);

this.initialized = true;
}

getDeviceInfo() {
return {
backend: tf.getBackend(),
memory: tf.memory(),
environment: tf.env(),
flags: tf.env().flags
};
}

// 加载预训练模型
async loadPretrainedModel(modelName, modelUrl) {
if (this.models.has(modelName)) {
return this.models.get(modelName);
}

try {
const model = await tf.loadLayersModel(modelUrl);
this.models.set(modelName, {
model,
metadata: {
loadTime: Date.now(),
inputShape: model.inputs[0].shape,
outputShape: model.outputs[0].shape
}
});

return model;
} catch (error) {
console.error(`Failed to load model ${modelName}:`, error);
throw error;
}
}

// 图像分类示例
async classifyImage(modelName, imageElement) {
const modelInfo = this.models.get(modelName);
if (!modelInfo) {
throw new Error(`Model ${modelName} not loaded`);
}

const { model } = modelInfo;

// 预处理图像
const tensor = tf.browser.fromPixels(imageElement)
.resizeNearestNeighbor([224, 224])
.toFloat()
.div(255.0)
.expandDims();

// 执行推理
const predictions = await model.predict(tensor).data();

// 清理内存
tensor.dispose();

return this.postprocessPredictions(predictions);
}

// 自定义模型训练
async trainCustomModel(trainingData, modelConfig) {
const { inputs, outputs, architecture } = modelConfig;

// 构建模型架构
const model = tf.sequential();

architecture.forEach(layer => {
switch (layer.type) {
case 'dense':
model.add(tf.layers.dense({
units: layer.units,
activation: layer.activation,
inputShape: layer.inputShape
}));
break;
case 'conv2d':
model.add(tf.layers.conv2d({
filters: layer.filters,
kernelSize: layer.kernelSize,
activation: layer.activation
}));
break;
case 'maxPooling2d':
model.add(tf.layers.maxPooling2d({
poolSize: layer.poolSize
}));
break;
case 'flatten':
model.add(tf.layers.flatten());
break;
case 'dropout':
model.add(tf.layers.dropout({
rate: layer.rate
}));
break;
}
});

// 编译模型
model.compile({
optimizer: modelConfig.optimizer || 'adam',
loss: modelConfig.loss || 'categoricalCrossentropy',
metrics: modelConfig.metrics || ['accuracy']
});

// 准备训练数据
const xs = tf.tensor(inputs);
const ys = tf.tensor(outputs);

// 训练模型
const history = await model.fit(xs, ys, {
epochs: modelConfig.epochs || 100,
batchSize: modelConfig.batchSize || 32,
validationSplit: modelConfig.validationSplit || 0.2,
callbacks: {
onEpochEnd: (epoch, logs) => {
console.log(`Epoch ${epoch}: loss = ${logs.loss}, accuracy = ${logs.acc}`);
}
}
});

// 清理内存
xs.dispose();
ys.dispose();

return { model, history };
}

// 模型性能监控
monitorPerformance(modelName, callback) {
const modelInfo = this.models.get(modelName);
if (!modelInfo) return;

const monitor = {
startTime: null,
endTime: null,
memoryBefore: null,
memoryAfter: null
};

return {
start: () => {
monitor.startTime = performance.now();
monitor.memoryBefore = tf.memory();
},
end: () => {
monitor.endTime = performance.now();
monitor.memoryAfter = tf.memory();

const metrics = {
inferenceTime: monitor.endTime - monitor.startTime,
memoryUsage: {
before: monitor.memoryBefore,
after: monitor.memoryAfter,
delta: {
numTensors: monitor.memoryAfter.numTensors - monitor.memoryBefore.numTensors,
numBytes: monitor.memoryAfter.numBytes - monitor.memoryBefore.numBytes
}
}
};

callback(metrics);
}
};
}
}

2. Transformers.js

特点

  • Hugging Face的JavaScript实现
  • 支持多种预训练模型
  • 自然语言处理专用
  • 零配置使用

核心功能实现

// Transformers.js功能封装
class TransformersManager {
constructor() {
this.pipelines = new Map();
this.models = new Map();
this.tokenizers = new Map();
}

// 创建处理管道
async createPipeline(task, model = null, options = {}) {
const pipelineKey = `${task}-${model || 'default'}`;

if (this.pipelines.has(pipelineKey)) {
return this.pipelines.get(pipelineKey);
}

try {
const { pipeline } = await import('@xenova/transformers');

const pipe = await pipeline(task, model, {
...options,
progress_callback: (progress) => {
console.log(`Loading ${task} model: ${Math.round(progress.progress * 100)}%`);
}
});

this.pipelines.set(pipelineKey, pipe);
return pipe;
} catch (error) {
console.error(`Failed to create pipeline for ${task}:`, error);
throw error;
}
}

// 文本分类
async classifyText(text, model = 'Xenova/distilbert-base-uncased-finetuned-sst-2-english') {
const classifier = await this.createPipeline('sentiment-analysis', model);
return await classifier(text);
}

// 文本生成
async generateText(prompt, options = {}) {
const generator = await this.createPipeline(
'text-generation',
options.model || 'Xenova/gpt2'
);

return await generator(prompt, {
max_length: options.maxLength || 100,
num_return_sequences: options.numSequences || 1,
temperature: options.temperature || 0.7,
do_sample: options.doSample !== false,
...options
});
}

// 问答系统
async answerQuestion(question, context, model = 'Xenova/distilbert-base-cased-distilled-squad') {
const qa = await this.createPipeline('question-answering', model);

return await qa({
question,
context
});
}

// 文本摘要
async summarizeText(text, options = {}) {
const summarizer = await this.createPipeline(
'summarization',
options.model || 'Xenova/distilbart-cnn-12-6'
);

return await summarizer(text, {
max_length: options.maxLength || 130,
min_length: options.minLength || 30,
do_sample: options.doSample || false,
...options
});
}

// 翻译
async translateText(text, sourceLanguage, targetLanguage) {
const modelName = `Helsinki-NLP/opus-mt-${sourceLanguage}-${targetLanguage}`;
const translator = await this.createPipeline('translation', modelName);

return await translator(text);
}

// 特征提取
async extractFeatures(text, model = 'Xenova/all-MiniLM-L6-v2') {
const extractor = await this.createPipeline('feature-extraction', model);
return await extractor(text, { pooling: 'mean', normalize: true });
}

// 零样本分类
async zeroShotClassify(text, candidateLabels, model = 'Xenova/distilbert-base-uncased-mnli') {
const classifier = await this.createPipeline('zero-shot-classification', model);

return await classifier(text, candidateLabels);
}

// 批量处理
async batchProcess(texts, task, options = {}) {
const pipeline = await this.createPipeline(task, options.model);
const batchSize = options.batchSize || 10;
const results = [];

for (let i = 0; i < texts.length; i += batchSize) {
const batch = texts.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(text => pipeline(text, options))
);
results.push(...batchResults);

// 进度回调
if (options.onProgress) {
options.onProgress({
processed: Math.min(i + batchSize, texts.length),
total: texts.length,
progress: Math.min(i + batchSize, texts.length) / texts.length
});
}
}

return results;
}
}

3. Brain.js

特点

  • 轻量级神经网络库
  • 易于使用和理解
  • 支持多种网络类型
  • 适合快速原型开发

核心功能实现

// Brain.js功能封装
class BrainManager {
constructor() {
this.networks = new Map();
this.trainingData = new Map();
}

// 创建神经网络
createNetwork(name, type = 'feedforward', options = {}) {
let network;

switch (type) {
case 'feedforward':
network = new brain.NeuralNetwork({
hiddenLayers: options.hiddenLayers || [3],
activation: options.activation || 'sigmoid',
learningRate: options.learningRate || 0.3,
...options
});
break;

case 'lstm':
network = new brain.recurrent.LSTM({
hiddenLayers: options.hiddenLayers || [20],
learningRate: options.learningRate || 0.01,
...options
});
break;

case 'gru':
network = new brain.recurrent.GRU({
hiddenLayers: options.hiddenLayers || [20],
learningRate: options.learningRate || 0.01,
...options
});
break;

case 'rnn':
network = new brain.recurrent.RNN({
hiddenLayers: options.hiddenLayers || [20],
learningRate: options.learningRate || 0.01,
...options
});
break;

default:
throw new Error(`Unsupported network type: ${type}`);
}

this.networks.set(name, {
network,
type,
options,
trained: false,
createdAt: Date.now()
});

return network;
}

// 训练网络
async trainNetwork(name, trainingData, options = {}) {
const networkInfo = this.networks.get(name);
if (!networkInfo) {
throw new Error(`Network ${name} not found`);
}

const { network } = networkInfo;

// 保存训练数据
this.trainingData.set(name, trainingData);

const trainingOptions = {
iterations: options.iterations || 20000,
errorThresh: options.errorThresh || 0.005,
log: options.log || false,
logPeriod: options.logPeriod || 100,
learningRate: options.learningRate || 0.3,
momentum: options.momentum || 0.1,
callback: options.callback,
callbackPeriod: options.callbackPeriod || 10,
timeout: options.timeout || Infinity,
...options
};

const startTime = Date.now();

return new Promise((resolve, reject) => {
try {
const stats = network.train(trainingData, {
...trainingOptions,
callback: (stats) => {
if (options.onProgress) {
options.onProgress({
iterations: stats.iterations,
error: stats.error,
progress: stats.iterations / trainingOptions.iterations
});
}

if (options.callback) {
options.callback(stats);
}
}
});

networkInfo.trained = true;
networkInfo.trainingStats = {
...stats,
trainingTime: Date.now() - startTime
};

resolve(stats);
} catch (error) {
reject(error);
}
});
}

// 预测
predict(name, input) {
const networkInfo = this.networks.get(name);
if (!networkInfo) {
throw new Error(`Network ${name} not found`);
}

if (!networkInfo.trained) {
console.warn(`Network ${name} has not been trained yet`);
}

return networkInfo.network.run(input);
}

// 文本生成(LSTM示例)
async trainTextGenerator(name, text, options = {}) {
const network = this.createNetwork(name, 'lstm', {
hiddenLayers: options.hiddenLayers || [20],
learningRate: options.learningRate || 0.01
});

// 准备训练数据
const trainingData = this.prepareTextData(text, options.sequenceLength || 10);

await this.trainNetwork(name, trainingData, {
iterations: options.iterations || 2000,
errorThresh: options.errorThresh || 0.011,
log: true,
logPeriod: 100,
onProgress: options.onProgress
});

return network;
}

generateText(name, seed, length = 100) {
const networkInfo = this.networks.get(name);
if (!networkInfo || networkInfo.type !== 'lstm') {
throw new Error(`LSTM network ${name} not found`);
}

return networkInfo.network.run(seed, length);
}

// 时间序列预测
async trainTimeSeriesPredictor(name, data, options = {}) {
const network = this.createNetwork(name, 'lstm', {
hiddenLayers: options.hiddenLayers || [10, 10],
learningRate: options.learningRate || 0.005
});

// 准备时间序列数据
const trainingData = this.prepareTimeSeriesData(
data,
options.windowSize || 10,
options.predictionSteps || 1
);

await this.trainNetwork(name, trainingData, {
iterations: options.iterations || 1000,
errorThresh: options.errorThresh || 0.01,
onProgress: options.onProgress
});

return network;
}

predictTimeSeries(name, inputSequence) {
return this.predict(name, inputSequence);
}

// 数据预处理辅助方法
prepareTextData(text, sequenceLength) {
const data = [];
for (let i = 0; i < text.length - sequenceLength; i++) {
data.push({
input: text.substring(i, i + sequenceLength),
output: text.substring(i + 1, i + sequenceLength + 1)
});
}
return data;
}

prepareTimeSeriesData(data, windowSize, predictionSteps) {
const trainingData = [];

for (let i = 0; i < data.length - windowSize - predictionSteps + 1; i++) {
const input = data.slice(i, i + windowSize);
const output = data.slice(i + windowSize, i + windowSize + predictionSteps);

trainingData.push({ input, output });
}

return trainingData;
}

// 网络序列化
exportNetwork(name) {
const networkInfo = this.networks.get(name);
if (!networkInfo) {
throw new Error(`Network ${name} not found`);
}

return {
json: networkInfo.network.toJSON(),
function: networkInfo.network.toFunction().toString(),
metadata: {
type: networkInfo.type,
options: networkInfo.options,
trained: networkInfo.trained,
trainingStats: networkInfo.trainingStats
}
};
}

// 网络导入
importNetwork(name, exportedData) {
const network = new brain.NeuralNetwork();
network.fromJSON(exportedData.json);

this.networks.set(name, {
network,
type: exportedData.metadata.type,
options: exportedData.metadata.options,
trained: exportedData.metadata.trained,
trainingStats: exportedData.metadata.trainingStats,
importedAt: Date.now()
});

return network;
}
}

AI服务集成SDK

0. Vercel AI SDK(2026 首选)

接 LLM 别再从零封装 fetch/流式/重试了——Vercel AI SDK(ai 包)是 2026 年 JS 生态接大模型的事实标准:统一封装流式、工具调用、结构化输出、多 provider,换模型只改一行。

npm i ai @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/google zod
# 前端额外:npm i @ai-sdk/react streamdown

streamText:服务端流式

import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

const result = streamText({
model: openai('gpt-4o-mini'),
prompt: '用一句话解释 RAG',
});
// 服务端:return result.toUIMessageStreamResponse();
// 脚本里:for await (const chunk of result.textStream) process.stdout.write(chunk);

useChat:前端聊天(@ai-sdk/react

'use client';
import { useChat } from '@ai-sdk/react';
const { messages, sendMessage, status } = useChat();
// messages[i].parts 是结构化数组:text / tool 调用 / source / reasoning

generateObject:Zod 约束的结构化输出

import { generateObject } from 'ai';
import { z } from 'zod';
const { object } = await generateObject({
model: openai('gpt-4o-mini'),
schema: z.object({ sentiment: z.enum(['正', '负']), score: z.number() }),
prompt: '分析「这产品太好用了」',
});

tool():工具调用(多步)

import { tool, streamText, stepCountIs } from 'ai';
import { z } from 'zod';
streamText({
model: openai('gpt-4o'),
stopWhen: stepCountIs(5),
tools: {
getPrice: tool({
description: '查询商品价格',
inputSchema: z.object({ sku: z.string() }),
execute: async ({ sku }) => ({ sku, price: 99 }),
}),
},
messages,
});

配套:流式 Markdown 用 streamdown(自动补全未闭合语法,专为 AI 流式输出设计);Generative UI 让工具结果直接渲染成组件(message.parts 里匹配 tool-* part)。换 provider 只需把 openai('...') 换成 anthropic('claude-sonnet-4')google('gemini-2.5-flash'),业务代码不变。

1. OpenAI SDK

核心功能封装

// OpenAI SDK增强封装
class EnhancedOpenAI {
constructor(apiKey, options = {}) {
this.client = new OpenAI({
apiKey,
...options
});

this.rateLimiter = new RateLimiter({
requestsPerMinute: options.requestsPerMinute || 60,
tokensPerMinute: options.tokensPerMinute || 90000
});

this.cache = new ResponseCache({
ttl: options.cacheTTL || 3600000, // 1小时
maxSize: options.cacheMaxSize || 1000
});

this.retryConfig = {
maxRetries: options.maxRetries || 3,
backoffFactor: options.backoffFactor || 2,
initialDelay: options.initialDelay || 1000
};
}

// 智能聊天完成
async chatCompletion(messages, options = {}) {
const cacheKey = this.generateCacheKey('chat', { messages, ...options });

// 检查缓存
if (options.useCache !== false) {
const cached = await this.cache.get(cacheKey);
if (cached) {
return { ...cached, fromCache: true };
}
}

// 速率限制检查
await this.rateLimiter.checkLimit();

const requestOptions = {
model: options.model || 'gpt-4o-mini', // 2026 默认小模型
messages,
temperature: options.temperature ?? 0.7,
max_tokens: options.maxTokens,
top_p: options.topP,
frequency_penalty: options.frequencyPenalty,
presence_penalty: options.presencePenalty,
stop: options.stop,
stream: options.stream || false,
...options
};

try {
const response = await this.executeWithRetry(async () => {
return await this.client.chat.completions.create(requestOptions);
});

// 缓存响应
if (options.useCache !== false && !options.stream) {
await this.cache.set(cacheKey, response);
}

return response;
} catch (error) {
throw this.handleError(error);
}
}

// 流式聊天
async streamChatCompletion(messages, options = {}, onChunk) {
const stream = await this.chatCompletion(messages, {
...options,
stream: true
});

let fullContent = '';

for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta;
if (delta?.content) {
fullContent += delta.content;
onChunk({
content: delta.content,
fullContent,
chunk,
finished: false
});
}

if (chunk.choices[0]?.finish_reason) {
onChunk({
content: '',
fullContent,
chunk,
finished: true,
finishReason: chunk.choices[0].finish_reason
});
}
}

return fullContent;
}

// 文本嵌入
async createEmbedding(input, options = {}) {
const cacheKey = this.generateCacheKey('embedding', { input, ...options });

if (options.useCache !== false) {
const cached = await this.cache.get(cacheKey);
if (cached) return cached;
}

await this.rateLimiter.checkLimit();

try {
const response = await this.executeWithRetry(async () => {
return await this.client.embeddings.create({
model: options.model || 'text-embedding-3-small', // 2026 推荐,可降维
input,
...options
});
});

if (options.useCache !== false) {
await this.cache.set(cacheKey, response);
}

return response;
} catch (error) {
throw this.handleError(error);
}
}

// 图像生成
async generateImage(prompt, options = {}) {
await this.rateLimiter.checkLimit();

try {
return await this.executeWithRetry(async () => {
return await this.client.images.generate({
prompt,
model: options.model || 'dall-e-3',
n: options.n || 1,
size: options.size || '1024x1024',
quality: options.quality || 'standard',
style: options.style,
response_format: options.responseFormat || 'url',
...options
});
});
} catch (error) {
throw this.handleError(error);
}
}

// 语音转文字
async transcribeAudio(audioFile, options = {}) {
await this.rateLimiter.checkLimit();

try {
return await this.executeWithRetry(async () => {
return await this.client.audio.transcriptions.create({
file: audioFile,
model: options.model || 'whisper-1',
language: options.language,
prompt: options.prompt,
response_format: options.responseFormat || 'json',
temperature: options.temperature,
...options
});
});
} catch (error) {
throw this.handleError(error);
}
}

// 文字转语音
async generateSpeech(text, options = {}) {
await this.rateLimiter.checkLimit();

try {
return await this.executeWithRetry(async () => {
return await this.client.audio.speech.create({
model: options.model || 'tts-1',
input: text,
voice: options.voice || 'alloy',
response_format: options.responseFormat || 'mp3',
speed: options.speed || 1.0,
...options
});
});
} catch (error) {
throw this.handleError(error);
}
}

// 重试机制
async executeWithRetry(operation) {
let lastError;

for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;

if (attempt === this.retryConfig.maxRetries) {
break;
}

if (!this.isRetryableError(error)) {
break;
}

const delay = this.retryConfig.initialDelay *
Math.pow(this.retryConfig.backoffFactor, attempt);
await this.sleep(delay);
}
}

throw lastError;
}

isRetryableError(error) {
const retryableStatusCodes = [429, 500, 502, 503, 504];
return retryableStatusCodes.includes(error.status) ||
error.code === 'ECONNRESET' ||
error.code === 'ETIMEDOUT';
}

handleError(error) {
const enhancedError = new Error(error.message);
enhancedError.originalError = error;
enhancedError.status = error.status;
enhancedError.code = error.code;
enhancedError.type = error.type;

// 添加用户友好的错误信息
if (error.status === 429) {
enhancedError.userMessage = '请求过于频繁,请稍后再试';
} else if (error.status === 401) {
enhancedError.userMessage = 'API密钥无效或已过期';
} else if (error.status >= 500) {
enhancedError.userMessage = '服务暂时不可用,请稍后再试';
}

return enhancedError;
}

generateCacheKey(operation, params) {
return `${operation}:${JSON.stringify(params)}`;
}

sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}

2. LangChain.js

⚠️ 2026 重要变更:废弃 API 已迁移。 LangChain.js 0.1 时代的 RetrievalQAChainConversationChaininitializeAgentExecutorWithOptions 这些「预制 Chain/Agent」已被官方弃用。新写法是:

  • 包结构:核心拆成 @langchain/core(基础抽象 + LCEL 表达式语言)、@langchain/openai 等集成包;不再从 langchain/chains 这种大杂烩导入。
  • RAG 链 → 用 LCELRunnableSequence / pipe)手动组合 prompt | model | parser,而不是 RetrievalQAChain.fromLLM
  • Agent → 用 LangGraph.js@langchain/langgraphcreateReactAgent)构建有状态、可循环、可中断的 Agent,取代 initializeAgentExecutorWithOptions。LangGraph 也是实现上文 Agentic RAG 的推荐框架。

下面先给出现代写法,再保留旧封装作为「演进对照」(旧 API 已不推荐,仅供理解历史)。

现代写法(LCEL + LangGraph.js)

// RAG:用 LCEL 组合,而非 RetrievalQAChain
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { RunnableSequence, RunnablePassthrough } from '@langchain/core/runnables';

const model = new ChatOpenAI({ model: 'gpt-4o-mini' }); // 2026 默认
const embeddings = new OpenAIEmbeddings({ model: 'text-embedding-3-small' });
const retriever = vectorStore.asRetriever({ k: 4 });

const prompt = ChatPromptTemplate.fromTemplate(
`仅根据下面的上下文回答,查不到就说不知道。\n上下文:{context}\n问题:{question}`
);
const formatDocs = (docs) => docs.map(d => d.pageContent).join('\n\n');

// LCEL:用管道把「检索 → 填模板 → 调模型 → 解析」串起来
const ragChain = RunnableSequence.from([
{ context: async (input) => formatDocs(await retriever.invoke(input.question)),
question: new RunnablePassthrough() },
prompt,
model,
new StringOutputParser(),
]);
const answer = await ragChain.invoke({ question: '什么是 RAG?' });
// Agent:用 LangGraph.js 的 createReactAgent,取代 initializeAgentExecutorWithOptions
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { ChatOpenAI } from '@langchain/openai';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';

const search = tool(async ({ query }) => `${query}」的检索结果...`, {
name: 'search',
description: '搜索知识库',
schema: z.object({ query: z.string() }),
});

const agent = createReactAgent({
llm: new ChatOpenAI({ model: 'gpt-4o' }),
tools: [search],
});
const res = await agent.invoke({ messages: [{ role: 'user', content: '帮我查下 X' }] });

演进对照:旧版封装(已弃用,仅供理解)

// LangChain.js功能封装(注意:以下 RetrievalQAChain / initializeAgentExecutorWithOptions 等已被官方弃用)
class LangChainManager {
constructor() {
this.chains = new Map();
this.vectorStores = new Map();
this.retrievers = new Map();
this.agents = new Map();
}

// 创建对话链
async createConversationChain(name, llm, options = {}) {
const { ConversationChain } = await import('langchain/chains');
const { BufferMemory } = await import('langchain/memory');

const memory = new BufferMemory({
memoryKey: 'history',
inputKey: 'input',
outputKey: 'response',
...options.memory
});

const chain = new ConversationChain({
llm,
memory,
verbose: options.verbose || false,
...options
});

this.chains.set(name, {
chain,
type: 'conversation',
createdAt: Date.now()
});

return chain;
}

// 创建RAG链
async createRAGChain(name, llm, vectorStore, options = {}) {
const { RetrievalQAChain } = await import('langchain/chains');

const retriever = vectorStore.asRetriever({
k: options.topK || 4,
searchType: options.searchType || 'similarity',
...options.retriever
});

const chain = RetrievalQAChain.fromLLM(llm, retriever, {
returnSourceDocuments: options.returnSourceDocuments || true,
verbose: options.verbose || false,
...options
});

this.chains.set(name, {
chain,
type: 'rag',
retriever,
createdAt: Date.now()
});

return chain;
}

// 创建向量存储
async createVectorStore(name, documents, embeddings, storeType = 'memory') {
let vectorStore;

switch (storeType) {
case 'memory':
const { MemoryVectorStore } = await import('langchain/vectorstores/memory');
vectorStore = await MemoryVectorStore.fromDocuments(documents, embeddings);
break;

case 'chroma':
const { Chroma } = await import('langchain/vectorstores/chroma');
vectorStore = await Chroma.fromDocuments(documents, embeddings, {
collectionName: name
});
break;

case 'pinecone':
const { PineconeStore } = await import('langchain/vectorstores/pinecone');
vectorStore = await PineconeStore.fromDocuments(documents, embeddings, {
pineconeIndex: this.getPineconeIndex(name)
});
break;

default:
throw new Error(`Unsupported vector store type: ${storeType}`);
}

this.vectorStores.set(name, {
store: vectorStore,
type: storeType,
documentCount: documents.length,
createdAt: Date.now()
});

return vectorStore;
}

// 创建智能代理
async createAgent(name, llm, tools, options = {}) {
const { initializeAgentExecutorWithOptions } = await import('langchain/agents');

const executor = await initializeAgentExecutorWithOptions(tools, llm, {
agentType: options.agentType || 'zero-shot-react-description',
verbose: options.verbose || false,
maxIterations: options.maxIterations || 10,
earlyStoppingMethod: options.earlyStoppingMethod || 'generate',
...options
});

this.agents.set(name, {
executor,
tools,
createdAt: Date.now()
});

return executor;
}

// 文档处理和分割
async processDocuments(documents, options = {}) {
const { RecursiveCharacterTextSplitter } = await import('langchain/text_splitter');

const splitter = new RecursiveCharacterTextSplitter({
chunkSize: options.chunkSize || 1000,
chunkOverlap: options.chunkOverlap || 200,
separators: options.separators || ['\n\n', '\n', ' ', ''],
...options
});

const splitDocs = await splitter.splitDocuments(documents);

// 添加元数据
return splitDocs.map((doc, index) => ({
...doc,
metadata: {
...doc.metadata,
chunkIndex: index,
processedAt: Date.now()
}
}));
}

// 执行链
async runChain(name, input, options = {}) {
const chainInfo = this.chains.get(name);
if (!chainInfo) {
throw new Error(`Chain ${name} not found`);
}

const { chain } = chainInfo;

try {
const result = await chain.call(input, options);

// 记录使用统计
this.updateChainStats(name, {
inputTokens: this.estimateTokens(JSON.stringify(input)),
outputTokens: this.estimateTokens(JSON.stringify(result)),
executionTime: Date.now()
});

return result;
} catch (error) {
console.error(`Error running chain ${name}:`, error);
throw error;
}
}

// 批量处理
async batchProcess(chainName, inputs, options = {}) {
const batchSize = options.batchSize || 5;
const results = [];

for (let i = 0; i < inputs.length; i += batchSize) {
const batch = inputs.slice(i, i + batchSize);

const batchPromises = batch.map(input =>
this.runChain(chainName, input, options)
);

const batchResults = await Promise.allSettled(batchPromises);

results.push(...batchResults.map((result, index) => ({
index: i + index,
input: batch[index],
success: result.status === 'fulfilled',
result: result.status === 'fulfilled' ? result.value : null,
error: result.status === 'rejected' ? result.reason : null
})));

// 进度回调
if (options.onProgress) {
options.onProgress({
processed: Math.min(i + batchSize, inputs.length),
total: inputs.length,
progress: Math.min(i + batchSize, inputs.length) / inputs.length
});
}

// 批次间延迟
if (options.batchDelay && i + batchSize < inputs.length) {
await this.sleep(options.batchDelay);
}
}

return results;
}

// 链性能监控
updateChainStats(name, stats) {
const chainInfo = this.chains.get(name);
if (!chainInfo.stats) {
chainInfo.stats = {
totalCalls: 0,
totalInputTokens: 0,
totalOutputTokens: 0,
averageExecutionTime: 0,
lastUsed: null
};
}

const currentStats = chainInfo.stats;
currentStats.totalCalls++;
currentStats.totalInputTokens += stats.inputTokens;
currentStats.totalOutputTokens += stats.outputTokens;
currentStats.averageExecutionTime = (
(currentStats.averageExecutionTime * (currentStats.totalCalls - 1) +
stats.executionTime) / currentStats.totalCalls
);
currentStats.lastUsed = Date.now();
}

// 获取链统计信息
getChainStats(name) {
const chainInfo = this.chains.get(name);
return chainInfo ? chainInfo.stats : null;
}

// 工具方法
estimateTokens(text) {
// 简单的token估算,实际应用中可以使用更精确的方法
return Math.ceil(text.length / 4);
}

sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}

开发工具链

1. 构建工具配置

Webpack配置

// webpack.config.js for AI applications
const path = require('path');
const webpack = require('webpack');

module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
library: 'AIApp',
libraryTarget: 'umd'
},

resolve: {
fallback: {
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"buffer": require.resolve("buffer"),
"process": require.resolve("process/browser"),
"path": require.resolve("path-browserify"),
"fs": false,
"net": false,
"tls": false
}
},

module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime'
]
}
}
},
{
test: /\.wasm$/,
type: 'webassembly/async'
},
{
test: /\.(bin|onnx)$/,
type: 'asset/resource'
}
]
},

plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
],

experiments: {
asyncWebAssembly: true,
topLevelAwait: true
},

optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
ai: {
test: /[\\/]node_modules[\\/](@tensorflow|@xenova|brain\.js)/,
name: 'ai-libs',
chunks: 'all'
}
}
}
}
};

Vite配置

// vite.config.js for AI applications
import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
define: {
global: 'globalThis'
},

resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},

optimizeDeps: {
include: [
'@tensorflow/tfjs',
'@xenova/transformers',
'brain.js',
'openai'
],
exclude: [
'@tensorflow/tfjs-node'
]
},

build: {
rollupOptions: {
output: {
manualChunks: {
'ai-core': ['@tensorflow/tfjs', '@xenova/transformers'],
'ai-services': ['openai', 'langchain'],
'ai-utils': ['brain.js', 'ml5']
}
}
},
target: 'esnext',
minify: 'terser'
},

server: {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin'
}
}
});

2. 性能监控工具

// AI应用性能监控
class AIPerformanceMonitor {
constructor() {
this.metrics = new Map();
this.observers = [];
this.isMonitoring = false;
}

startMonitoring() {
if (this.isMonitoring) return;

this.isMonitoring = true;

// 监控内存使用
this.memoryObserver = setInterval(() => {
if (performance.memory) {
this.recordMetric('memory', {
used: performance.memory.usedJSHeapSize,
total: performance.memory.totalJSHeapSize,
limit: performance.memory.jsHeapSizeLimit,
timestamp: Date.now()
});
}
}, 1000);

// 监控网络请求
this.setupNetworkMonitoring();

// 监控AI模型性能
this.setupModelMonitoring();
}

recordMetric(category, data) {
if (!this.metrics.has(category)) {
this.metrics.set(category, []);
}

const categoryMetrics = this.metrics.get(category);
categoryMetrics.push(data);

// 保持最近1000条记录
if (categoryMetrics.length > 1000) {
categoryMetrics.shift();
}

// 通知观察者
this.notifyObservers(category, data);
}

getMetrics(category, timeRange = 60000) {
const categoryMetrics = this.metrics.get(category) || [];
const cutoff = Date.now() - timeRange;

return categoryMetrics.filter(metric => metric.timestamp > cutoff);
}

generateReport() {
const report = {
timestamp: Date.now(),
memory: this.analyzeMemoryUsage(),
network: this.analyzeNetworkPerformance(),
models: this.analyzeModelPerformance(),
recommendations: this.generateRecommendations()
};

return report;
}
}

学习检验

理论问题

  1. 生态系统比较

    • 比较TensorFlow.js、Brain.js和ML5.js的优缺点
    • 在什么场景下选择客户端AI vs 服务端AI?
    • 如何设计混合AI架构?
  2. 性能优化

    • JavaScript AI应用的主要性能瓶颈有哪些?
    • 如何优化模型加载和推理性能?
    • 设计一个AI应用的缓存策略
  3. 工具链选择

    • 如何为AI项目选择合适的构建工具?
    • 不同AI库的打包优化策略
    • 如何处理AI库的依赖冲突?

实践练习

  1. 环境搭建

    • 创建一个支持多种AI库的开发环境
    • 配置Webpack/Vite支持AI库打包
    • 实现AI库的懒加载机制
  2. 性能对比

    • 对比不同AI库在相同任务上的性能
    • 测试客户端vs服务端AI的响应时间
    • 分析内存使用和优化策略
  3. 集成开发

    • 创建一个统一的AI服务管理器
    • 实现多个AI提供商的负载均衡
    • 开发AI应用的监控和调试工具

实践项目建议

初级项目

  1. AI库性能测试工具 - 对比不同AI库的性能表现
  2. 统一AI接口封装 - 创建统一的AI服务调用接口
  3. AI应用脚手架 - 快速创建AI应用的项目模板

中级项目

  1. AI模型管理平台 - 模型版本管理和部署工具
  2. 多模态AI工具箱 - 集成多种AI能力的工具集
  3. AI应用性能监控 - 实时监控AI应用性能

高级项目

  1. AI开发框架 - 完整的AI应用开发框架
  2. 智能代码生成器 - 基于AI的代码生成工具
  3. AI应用商店 - AI能力的发现和集成平台

延伸阅读

官方文档

开源项目

社区资源


JavaScript AI生态系统正在快速发展,让我们一起探索这个充满创新的领域!