Skip to content

自定义集成

AnythingLLM 提供灵活的集成能力,让开发者能够将 AI 对话功能无缝集成到现有系统中。本指南将详细介绍各种集成方式、最佳实践和实际案例。

集成概述

集成方式

AnythingLLM 支持多种集成方式:

  • API 集成:通过 RESTful API 进行集成
  • 嵌入式组件:直接嵌入到网页中
  • Webhook 集成:通过 Webhook 接收事件通知
  • SSO 集成:单点登录集成
  • 数据库集成:直接数据库连接
  • 第三方平台集成:与其他平台的集成

集成场景

企业应用:
- 客户服务系统:集成到客服平台
- 知识管理系统:增强知识检索能力
- 内部工具:为内部工具添加 AI 功能
- 培训平台:智能培训助手

Web 应用:
- 电商网站:智能客服和产品推荐
- 内容平台:智能内容生成和问答
- 教育平台:智能学习助手
- 社交平台:智能对话功能

移动应用:
- 移动客服:移动端智能客服
- 学习应用:移动学习助手
- 生产力工具:智能助手功能
- 游戏应用:智能 NPC 对话

API 集成

基础 API 集成

最简单的集成方式是通过 RESTful API:

javascript
// 基础聊天集成
class AnythingLLMIntegration {
  constructor(apiKey, baseURL) {
    this.apiKey = apiKey;
    this.baseURL = baseURL;
  }

  async sendMessage(workspaceId, message) {
    const response = await fetch(`${this.baseURL}/api/v1/workspaces/${workspaceId}/chat`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        message: message,
        mode: 'chat',
        include_sources: true
      })
    });

    if (!response.ok) {
      throw new Error(`API 请求失败: ${response.status}`);
    }

    return await response.json();
  }

  async getWorkspaces() {
    const response = await fetch(`${this.baseURL}/api/v1/workspaces`, {
      headers: {
        'Authorization': `Bearer ${this.apiKey}`
      }
    });

    return await response.json();
  }
}

// 使用示例
const llm = new AnythingLLMIntegration('your-api-key', 'https://your-instance.com');
const result = await llm.sendMessage('workspace-id', '你好,请帮我分析这个文档');

高级 API 集成

包含错误处理、重试机制和缓存的高级集成:

javascript
class AdvancedAnythingLLMIntegration {
  constructor(config) {
    this.apiKey = config.apiKey;
    this.baseURL = config.baseURL;
    this.retryAttempts = config.retryAttempts || 3;
    this.retryDelay = config.retryDelay || 1000;
    this.cache = new Map();
    this.cacheTimeout = config.cacheTimeout || 300000; // 5分钟
  }

  async makeRequest(endpoint, options = {}) {
    const url = `${this.baseURL}${endpoint}`;
    const requestOptions = {
      ...options,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
        ...options.headers
      }
    };

    for (let attempt = 1; attempt <= this.retryAttempts; attempt++) {
      try {
        const response = await fetch(url, requestOptions);
        
        if (response.status === 429) {
          // 处理速率限制
          const resetTime = response.headers.get('X-RateLimit-Reset');
          const waitTime = (resetTime * 1000) - Date.now();
          await this.sleep(Math.max(waitTime, this.retryDelay * attempt));
          continue;
        }

        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        return await response.json();
      } catch (error) {
        if (attempt === this.retryAttempts) {
          throw error;
        }
        await this.sleep(this.retryDelay * attempt);
      }
    }
  }

  async sendMessageWithCache(workspaceId, message) {
    const cacheKey = `${workspaceId}:${message}`;
    const cached = this.cache.get(cacheKey);
    
    if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
      return cached.data;
    }

    const result = await this.makeRequest(`/api/v1/workspaces/${workspaceId}/chat`, {
      method: 'POST',
      body: JSON.stringify({
        message: message,
        mode: 'chat',
        include_sources: true
      })
    });

    this.cache.set(cacheKey, {
      data: result,
      timestamp: Date.now()
    });

    return result;
  }

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

嵌入式集成

网页嵌入

将 AnythingLLM 聊天界面直接嵌入到网页中:

html
<!-- 基础嵌入 -->
<div id="anythingllm-chat"></div>
<script>
  window.AnythingLLMConfig = {
    apiKey: 'your-api-key',
    baseURL: 'https://your-instance.com',
    workspaceId: 'your-workspace-id',
    theme: 'light',
    position: 'bottom-right'
  };
</script>
<script src="https://your-instance.com/embed.js"></script>

React 组件集成

创建 React 组件来集成 AnythingLLM:

jsx
import React, { useState, useEffect } from 'react';

const AnythingLLMChat = ({ apiKey, baseURL, workspaceId }) => {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);

  const sendMessage = async () => {
    if (!input.trim()) return;

    const userMessage = { role: 'user', content: input };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setLoading(true);

    try {
      const response = await fetch(`${baseURL}/api/v1/workspaces/${workspaceId}/chat`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          message: input,
          mode: 'chat'
        })
      });

      const data = await response.json();
      const aiMessage = { role: 'assistant', content: data.data.response };
      setMessages(prev => [...prev, aiMessage]);
    } catch (error) {
      console.error('发送消息失败:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="anythingllm-chat">
      <div className="messages">
        {messages.map((message, index) => (
          <div key={index} className={`message ${message.role}`}>
            {message.content}
          </div>
        ))}
        {loading && <div className="loading">AI 正在思考...</div>}
      </div>
      <div className="input-area">
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
          placeholder="输入您的消息..."
        />
        <button onClick={sendMessage} disabled={loading}>
          发送
        </button>
      </div>
    </div>
  );
};

export default AnythingLLMChat;

Vue.js 组件集成

vue
<template>
  <div class="anythingllm-chat">
    <div class="messages">
      <div 
        v-for="(message, index) in messages" 
        :key="index" 
        :class="`message ${message.role}`"
      >
        {{ message.content }}
      </div>
      <div v-if="loading" class="loading">AI 正在思考...</div>
    </div>
    <div class="input-area">
      <input
        v-model="input"
        @keyup.enter="sendMessage"
        placeholder="输入您的消息..."
        :disabled="loading"
      />
      <button @click="sendMessage" :disabled="loading">
        发送
      </button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'AnythingLLMChat',
  props: {
    apiKey: String,
    baseURL: String,
    workspaceId: String
  },
  data() {
    return {
      messages: [],
      input: '',
      loading: false
    };
  },
  methods: {
    async sendMessage() {
      if (!this.input.trim()) return;

      this.messages.push({ role: 'user', content: this.input });
      const message = this.input;
      this.input = '';
      this.loading = true;

      try {
        const response = await fetch(`${this.baseURL}/api/v1/workspaces/${this.workspaceId}/chat`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            message: message,
            mode: 'chat'
          })
        });

        const data = await response.json();
        this.messages.push({ role: 'assistant', content: data.data.response });
      } catch (error) {
        console.error('发送消息失败:', error);
      } finally {
        this.loading = false;
      }
    }
  }
};
</script>

Webhook 集成

设置 Webhook

配置 Webhook 来接收 AnythingLLM 的事件通知:

javascript
// Express.js Webhook 处理器
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

// Webhook 签名验证
function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

// Webhook 端点
app.post('/webhook/anythingllm', (req, res) => {
  const signature = req.headers['x-anythingllm-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Unauthorized');
  }

  const event = req.body;
  
  switch (event.type) {
    case 'chat.message.created':
      handleNewMessage(event.data);
      break;
    case 'workspace.created':
      handleWorkspaceCreated(event.data);
      break;
    case 'document.uploaded':
      handleDocumentUploaded(event.data);
      break;
    default:
      console.log('未知事件类型:', event.type);
  }

  res.status(200).send('OK');
});

function handleNewMessage(data) {
  console.log('新消息:', data.message);
  // 处理新消息事件
}

function handleWorkspaceCreated(data) {
  console.log('新工作空间:', data.workspace.name);
  // 处理工作空间创建事件
}

function handleDocumentUploaded(data) {
  console.log('文档上传:', data.document.name);
  // 处理文档上传事件
}

app.listen(3000, () => {
  console.log('Webhook 服务器运行在端口 3000');
});

Webhook 事件类型

用户事件:
- user.created: 用户创建
- user.updated: 用户更新
- user.deleted: 用户删除

工作空间事件:
- workspace.created: 工作空间创建
- workspace.updated: 工作空间更新
- workspace.deleted: 工作空间删除

对话事件:
- chat.message.created: 新消息创建
- chat.session.started: 对话会话开始
- chat.session.ended: 对话会话结束

文档事件:
- document.uploaded: 文档上传
- document.processed: 文档处理完成
- document.deleted: 文档删除

系统事件:
- system.health.check: 系统健康检查
- system.backup.completed: 备份完成
- system.error.occurred: 系统错误

SSO 集成

SAML 集成

配置 SAML 单点登录:

javascript
// SAML 配置示例
const samlConfig = {
  issuer: 'https://your-app.com',
  callbackUrl: 'https://your-app.com/auth/saml/callback',
  entryPoint: 'https://your-idp.com/saml/sso',
  cert: process.env.SAML_CERT,
  identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
  attributeConsumingServiceIndex: false,
  disableRequestedAuthnContext: true,
  signatureAlgorithm: 'sha256'
};

// 用户属性映射
const attributeMapping = {
  'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress': 'email',
  'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name': 'name',
  'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role': 'role'
};

OAuth 2.0 集成

javascript
// OAuth 2.0 配置
const oauthConfig = {
  clientId: process.env.OAUTH_CLIENT_ID,
  clientSecret: process.env.OAUTH_CLIENT_SECRET,
  redirectUri: 'https://your-app.com/auth/oauth/callback',
  authorizationURL: 'https://provider.com/oauth/authorize',
  tokenURL: 'https://provider.com/oauth/token',
  userInfoURL: 'https://provider.com/oauth/userinfo',
  scope: ['openid', 'profile', 'email']
};

// OAuth 流程处理
async function handleOAuthCallback(code) {
  // 交换授权码获取访问令牌
  const tokenResponse = await fetch(oauthConfig.tokenURL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: oauthConfig.clientId,
      client_secret: oauthConfig.clientSecret,
      code: code,
      redirect_uri: oauthConfig.redirectUri
    })
  });

  const tokens = await tokenResponse.json();
  
  // 获取用户信息
  const userResponse = await fetch(oauthConfig.userInfoURL, {
    headers: {
      'Authorization': `Bearer ${tokens.access_token}`
    }
  });

  const userInfo = await userResponse.json();
  
  // 创建或更新用户
  return await createOrUpdateUser(userInfo);
}

数据库集成

直接数据库连接

javascript
// 数据库集成示例
const mysql = require('mysql2/promise');

class DatabaseIntegration {
  constructor(dbConfig) {
    this.pool = mysql.createPool(dbConfig);
  }

  async syncUserData() {
    // 从 AnythingLLM 获取用户数据
    const users = await this.getAnythingLLMUsers();
    
    // 同步到本地数据库
    for (const user of users) {
      await this.upsertUser(user);
    }
  }

  async getAnythingLLMUsers() {
    const response = await fetch(`${this.baseURL}/api/v1/users`, {
      headers: {
        'Authorization': `Bearer ${this.apiKey}`
      }
    });
    
    return await response.json();
  }

  async upsertUser(userData) {
    const connection = await this.pool.getConnection();
    
    try {
      await connection.execute(
        `INSERT INTO users (id, email, name, role, created_at) 
         VALUES (?, ?, ?, ?, ?) 
         ON DUPLICATE KEY UPDATE 
         email = VALUES(email), 
         name = VALUES(name), 
         role = VALUES(role)`,
        [userData.id, userData.email, userData.name, userData.role, userData.created_at]
      );
    } finally {
      connection.release();
    }
  }

  async logChatActivity(workspaceId, userId, message, response) {
    const connection = await this.pool.getConnection();
    
    try {
      await connection.execute(
        `INSERT INTO chat_logs (workspace_id, user_id, message, response, timestamp) 
         VALUES (?, ?, ?, ?, NOW())`,
        [workspaceId, userId, message, response]
      );
    } finally {
      connection.release();
    }
  }
}

数据同步策略

javascript
// 实时同步
class RealTimeSync {
  constructor(dbIntegration, webhookHandler) {
    this.db = dbIntegration;
    this.webhook = webhookHandler;
    
    // 监听 Webhook 事件
    this.webhook.on('user.created', this.handleUserCreated.bind(this));
    this.webhook.on('chat.message.created', this.handleMessageCreated.bind(this));
  }

  async handleUserCreated(event) {
    await this.db.upsertUser(event.data.user);
  }

  async handleMessageCreated(event) {
    await this.db.logChatActivity(
      event.data.workspace_id,
      event.data.user_id,
      event.data.message,
      event.data.response
    );
  }
}

// 批量同步
class BatchSync {
  constructor(dbIntegration) {
    this.db = dbIntegration;
    this.syncInterval = 5 * 60 * 1000; // 5分钟
  }

  start() {
    setInterval(async () => {
      try {
        await this.syncAllData();
      } catch (error) {
        console.error('批量同步失败:', error);
      }
    }, this.syncInterval);
  }

  async syncAllData() {
    await Promise.all([
      this.db.syncUserData(),
      this.db.syncWorkspaceData(),
      this.db.syncChatData()
    ]);
  }
}

第三方平台集成

Slack 集成

javascript
// Slack Bot 集成
const { App } = require('@slack/bolt');

const slackApp = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// 监听消息事件
slackApp.message(async ({ message, say }) => {
  if (message.text && !message.bot_id) {
    try {
      // 发送到 AnythingLLM
      const response = await sendToAnythingLLM(message.text);
      
      // 回复到 Slack
      await say({
        text: response.data.response,
        thread_ts: message.ts
      });
    } catch (error) {
      await say('抱歉,处理您的消息时出现了错误。');
    }
  }
});

async function sendToAnythingLLM(message) {
  return await fetch(`${process.env.ANYTHINGLLM_URL}/api/v1/workspaces/${process.env.WORKSPACE_ID}/chat`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.ANYTHINGLLM_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      message: message,
      mode: 'chat'
    })
  });
}

slackApp.start(process.env.PORT || 3000);

Discord 集成

javascript
// Discord Bot 集成
const { Client, GatewayIntentBits } = require('discord.js');

const discordClient = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent
  ]
});

discordClient.on('messageCreate', async (message) => {
  if (message.author.bot) return;
  
  // 检查是否是对 Bot 的提及
  if (message.mentions.has(discordClient.user)) {
    try {
      const userMessage = message.content.replace(`<@${discordClient.user.id}>`, '').trim();
      
      // 发送到 AnythingLLM
      const response = await sendToAnythingLLM(userMessage);
      
      // 回复到 Discord
      await message.reply(response.data.response);
    } catch (error) {
      await message.reply('抱歉,处理您的消息时出现了错误。');
    }
  }
});

discordClient.login(process.env.DISCORD_BOT_TOKEN);

Microsoft Teams 集成

javascript
// Microsoft Teams Bot 集成
const { TeamsActivityHandler, CardFactory } = require('botbuilder');

class AnythingLLMTeamsBot extends TeamsActivityHandler {
  constructor() {
    super();

    this.onMessage(async (context, next) => {
      const userMessage = context.activity.text;
      
      try {
        // 发送到 AnythingLLM
        const response = await this.sendToAnythingLLM(userMessage);
        
        // 创建自适应卡片响应
        const card = CardFactory.adaptiveCard({
          type: 'AdaptiveCard',
          version: '1.2',
          body: [
            {
              type: 'TextBlock',
              text: response.data.response,
              wrap: true
            }
          ]
        });

        await context.sendActivity({ attachments: [card] });
      } catch (error) {
        await context.sendActivity('抱歉,处理您的消息时出现了错误。');
      }

      await next();
    });
  }

  async sendToAnythingLLM(message) {
    // 实现 AnythingLLM API 调用
  }
}

module.exports.AnythingLLMTeamsBot = AnythingLLMTeamsBot;

移动应用集成

React Native 集成

javascript
// React Native 组件
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView } from 'react-native';

const AnythingLLMChat = ({ apiKey, baseURL, workspaceId }) => {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);

  const sendMessage = async () => {
    if (!input.trim()) return;

    const userMessage = { role: 'user', content: input, id: Date.now() };
    setMessages(prev => [...prev, userMessage]);
    setInput('');
    setLoading(true);

    try {
      const response = await fetch(`${baseURL}/api/v1/workspaces/${workspaceId}/chat`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          message: input,
          mode: 'chat'
        })
      });

      const data = await response.json();
      const aiMessage = { 
        role: 'assistant', 
        content: data.data.response, 
        id: Date.now() + 1 
      };
      setMessages(prev => [...prev, aiMessage]);
    } catch (error) {
      console.error('发送消息失败:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <View style={{ flex: 1, padding: 16 }}>
      <ScrollView style={{ flex: 1 }}>
        {messages.map((message) => (
          <View 
            key={message.id} 
            style={{
              alignSelf: message.role === 'user' ? 'flex-end' : 'flex-start',
              backgroundColor: message.role === 'user' ? '#007AFF' : '#E5E5EA',
              padding: 12,
              borderRadius: 16,
              marginVertical: 4,
              maxWidth: '80%'
            }}
          >
            <Text style={{ 
              color: message.role === 'user' ? 'white' : 'black' 
            }}>
              {message.content}
            </Text>
          </View>
        ))}
        {loading && (
          <View style={{ alignSelf: 'flex-start' }}>
            <Text>AI 正在思考...</Text>
          </View>
        )}
      </ScrollView>
      
      <View style={{ flexDirection: 'row', alignItems: 'center' }}>
        <TextInput
          style={{
            flex: 1,
            borderWidth: 1,
            borderColor: '#ccc',
            borderRadius: 20,
            paddingHorizontal: 16,
            paddingVertical: 8,
            marginRight: 8
          }}
          value={input}
          onChangeText={setInput}
          placeholder="输入您的消息..."
          multiline
        />
        <TouchableOpacity
          onPress={sendMessage}
          disabled={loading}
          style={{
            backgroundColor: '#007AFF',
            borderRadius: 20,
            paddingHorizontal: 16,
            paddingVertical: 8
          }}
        >
          <Text style={{ color: 'white' }}>发送</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default AnythingLLMChat;

Flutter 集成

dart
// Flutter 集成示例
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class AnythingLLMChat extends StatefulWidget {
  final String apiKey;
  final String baseURL;
  final String workspaceId;

  const AnythingLLMChat({
    Key? key,
    required this.apiKey,
    required this.baseURL,
    required this.workspaceId,
  }) : super(key: key);

  @override
  _AnythingLLMChatState createState() => _AnythingLLMChatState();
}

class _AnythingLLMChatState extends State<AnythingLLMChat> {
  final List<Message> _messages = [];
  final TextEditingController _controller = TextEditingController();
  bool _isLoading = false;

  Future<void> _sendMessage() async {
    if (_controller.text.trim().isEmpty) return;

    final userMessage = Message(
      content: _controller.text,
      isUser: true,
      timestamp: DateTime.now(),
    );

    setState(() {
      _messages.add(userMessage);
      _isLoading = true;
    });

    final messageText = _controller.text;
    _controller.clear();

    try {
      final response = await http.post(
        Uri.parse('${widget.baseURL}/api/v1/workspaces/${widget.workspaceId}/chat'),
        headers: {
          'Authorization': 'Bearer ${widget.apiKey}',
          'Content-Type': 'application/json',
        },
        body: jsonEncode({
          'message': messageText,
          'mode': 'chat',
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        final aiMessage = Message(
          content: data['data']['response'],
          isUser: false,
          timestamp: DateTime.now(),
        );

        setState(() {
          _messages.add(aiMessage);
        });
      }
    } catch (error) {
      print('发送消息失败: $error');
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AnythingLLM Chat')),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: _messages.length,
              itemBuilder: (context, index) {
                final message = _messages[index];
                return Container(
                  margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
                  child: Row(
                    mainAxisAlignment: message.isUser 
                        ? MainAxisAlignment.end 
                        : MainAxisAlignment.start,
                    children: [
                      Container(
                        constraints: BoxConstraints(
                          maxWidth: MediaQuery.of(context).size.width * 0.8,
                        ),
                        padding: EdgeInsets.all(12),
                        decoration: BoxDecoration(
                          color: message.isUser ? Colors.blue : Colors.grey[300],
                          borderRadius: BorderRadius.circular(16),
                        ),
                        child: Text(
                          message.content,
                          style: TextStyle(
                            color: message.isUser ? Colors.white : Colors.black,
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
          if (_isLoading)
            Padding(
              padding: EdgeInsets.all(8),
              child: Text('AI 正在思考...'),
            ),
          Container(
            padding: EdgeInsets.all(8),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: InputDecoration(
                      hintText: '输入您的消息...',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20),
                      ),
                    ),
                    maxLines: null,
                  ),
                ),
                SizedBox(width: 8),
                FloatingActionButton(
                  onPressed: _isLoading ? null : _sendMessage,
                  child: Icon(Icons.send),
                  mini: true,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class Message {
  final String content;
  final bool isUser;
  final DateTime timestamp;

  Message({
    required this.content,
    required this.isUser,
    required this.timestamp,
  });
}

监控和分析

集成监控

javascript
// 集成监控类
class IntegrationMonitor {
  constructor(config) {
    this.metrics = new Map();
    this.alerts = [];
    this.config = config;
  }

  // 记录 API 调用
  recordAPICall(endpoint, duration, success) {
    const key = `api_${endpoint}`;
    const metric = this.metrics.get(key) || {
      calls: 0,
      totalDuration: 0,
      errors: 0,
      lastCall: null
    };

    metric.calls++;
    metric.totalDuration += duration;
    metric.lastCall = new Date();
    
    if (!success) {
      metric.errors++;
    }

    this.metrics.set(key, metric);
    
    // 检查是否需要发送警报
    this.checkAlerts(key, metric);
  }

  // 检查警报条件
  checkAlerts(key, metric) {
    const errorRate = metric.errors / metric.calls;
    const avgDuration = metric.totalDuration / metric.calls;

    if (errorRate > this.config.errorThreshold) {
      this.sendAlert(`高错误率警报: ${key} 错误率 ${(errorRate * 100).toFixed(2)}%`);
    }

    if (avgDuration > this.config.durationThreshold) {
      this.sendAlert(`响应时间警报: ${key} 平均响应时间 ${avgDuration.toFixed(2)}ms`);
    }
  }

  // 发送警报
  sendAlert(message) {
    console.warn(`[ALERT] ${message}`);
    this.alerts.push({
      message,
      timestamp: new Date()
    });

    // 可以集成到 Slack、邮件等通知系统
    if (this.config.webhookURL) {
      this.sendWebhookAlert(message);
    }
  }

  // 获取监控报告
  getReport() {
    const report = {
      timestamp: new Date(),
      metrics: {},
      alerts: this.alerts.slice(-10) // 最近 10 个警报
    };

    for (const [key, metric] of this.metrics) {
      report.metrics[key] = {
        ...metric,
        avgDuration: metric.totalDuration / metric.calls,
        errorRate: metric.errors / metric.calls
      };
    }

    return report;
  }
}

// 使用监控
const monitor = new IntegrationMonitor({
  errorThreshold: 0.05, // 5% 错误率阈值
  durationThreshold: 5000, // 5秒响应时间阈值
  webhookURL: process.env.ALERT_WEBHOOK_URL
});

// 在 API 调用中使用监控
async function monitoredAPICall(endpoint, requestFn) {
  const startTime = Date.now();
  let success = false;

  try {
    const result = await requestFn();
    success = true;
    return result;
  } catch (error) {
    throw error;
  } finally {
    const duration = Date.now() - startTime;
    monitor.recordAPICall(endpoint, duration, success);
  }
}

最佳实践

安全最佳实践

javascript
// 安全配置示例
const securityConfig = {
  // API 密钥管理
  apiKey: {
    rotation: true,
    rotationInterval: 30 * 24 * 60 * 60 * 1000, // 30天
    storage: 'encrypted', // 加密存储
    environment: 'production' // 环境隔离
  },

  // 请求验证
  validation: {
    inputSanitization: true,
    rateLimiting: true,
    requestSigning: true,
    timestampValidation: true
  },

  // 网络安全
  network: {
    httpsOnly: true,
    certificatePinning: true,
    ipWhitelist: ['192.168.1.0/24'],
    cors: {
      origin: ['https://yourdomain.com'],
      credentials: true
    }
  }
};

// 输入验证和清理
function sanitizeInput(input) {
  // 移除潜在的恶意内容
  return input
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/javascript:/gi, '')
    .trim();
}

// 请求签名验证
function verifyRequestSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

性能优化

javascript
// 性能优化策略
class PerformanceOptimizer {
  constructor() {
    this.cache = new Map();
    this.requestQueue = [];
    this.batchSize = 10;
    this.batchTimeout = 1000;
  }

  // 请求批处理
  async batchRequests(requests) {
    return new Promise((resolve) => {
      this.requestQueue.push(...requests.map(req => ({ ...req, resolve })));
      
      if (this.requestQueue.length >= this.batchSize) {
        this.processBatch();
      } else {
        setTimeout(() => this.processBatch(), this.batchTimeout);
      }
    });
  }

  async processBatch() {
    if (this.requestQueue.length === 0) return;

    const batch = this.requestQueue.splice(0, this.batchSize);
    
    try {
      const results = await Promise.all(
        batch.map(req => this.makeRequest(req))
      );
      
      batch.forEach((req, index) => {
        req.resolve(results[index]);
      });
    } catch (error) {
      batch.forEach(req => req.resolve({ error }));
    }
  }

  // 智能缓存
  async getCachedResponse(key, fetchFn, ttl = 300000) {
    const cached = this.cache.get(key);
    
    if (cached && Date.now() - cached.timestamp < ttl) {
      return cached.data;
    }

    const data = await fetchFn();
    this.cache.set(key, {
      data,
      timestamp: Date.now()
    });

    return data;
  }

  // 连接池管理
  createConnectionPool(maxConnections = 10) {
    const pool = {
      connections: [],
      available: [],
      waiting: []
    };

    for (let i = 0; i < maxConnections; i++) {
      const connection = this.createConnection();
      pool.connections.push(connection);
      pool.available.push(connection);
    }

    return pool;
  }
}

错误处理和重试

javascript
// 高级错误处理
class ErrorHandler {
  constructor(config = {}) {
    this.maxRetries = config.maxRetries || 3;
    this.baseDelay = config.baseDelay || 1000;
    this.maxDelay = config.maxDelay || 30000;
    this.retryableErrors = config.retryableErrors || [
      'NETWORK_ERROR',
      'TIMEOUT',
      'RATE_LIMIT',
      'SERVER_ERROR'
    ];
  }

  async executeWithRetry(operation, context = {}) {
    let lastError;
    
    for (let attempt = 1; attempt <= this.maxRetries + 1; attempt++) {
      try {
        return await operation();
      } catch (error) {
        lastError = error;
        
        if (attempt > this.maxRetries || !this.isRetryable(error)) {
          break;
        }

        const delay = this.calculateDelay(attempt);
        console.warn(`操作失败,${delay}ms 后重试 (${attempt}/${this.maxRetries}):`, error.message);
        
        await this.sleep(delay);
      }
    }

    throw new Error(`操作在 ${this.maxRetries} 次重试后仍然失败: ${lastError.message}`);
  }

  isRetryable(error) {
    return this.retryableErrors.some(type => 
      error.code === type || error.message.includes(type)
    );
  }

  calculateDelay(attempt) {
    // 指数退避算法
    const delay = this.baseDelay * Math.pow(2, attempt - 1);
    return Math.min(delay, this.maxDelay);
  }

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

自定义集成让 AnythingLLM 能够无缝融入您的现有系统,提供强大的 AI 能力。选择合适的集成方式并遵循最佳实践,可以确保集成的稳定性和性能。

AnythingLLM 是一个功能强大的开源 AI 知识管理平台,支持多种 LLM 模型,让您轻松构建智能对话系统和知识库。