精华 XIUNOX AIService 核心文档

AIService 核心文档

适用项目:XIUNOX(XIUNO BBS X重构版) 源文件:xiunobbs-master/lib/AIService.php 最后更新:2026-07-03

一、概述

AIService 是 XIUNOX 的 AI 调用中台,统一管理所有 AI 功能的调用入口。核心职责:

  1. 多 provider 调用:支持 failover/round_robin/random/concurrent 四种模式

  2. 健康检查:kv 持久化 provider 在线/离线状态,自动故障转移

  3. 功能注册:插件通过 registerFeature() 注册新 AI 功能

  4. 内容后处理:插件通过 registerPostFilter() 注册回调过滤 AI 返回内容

  5. 配置解析:按 mode(global/user_key/both)合并全局与用户配置

二、配置结构

2.1 全局配置 conf.aiconf/conf.php

'ai' => array (
    // 全局提供商库(管理员维护,含 api_key)
    'providers' => array (
        array(
            'name'    => 'openai',           // 唯一标识
            'type'    => 'text',             // text/image/video/audio/transcription
            'url'     => 'https://api.openai.com',
            'api_key' => 'sk-xxx',
            'models'  => array(              // 模型列表
                array('name' => 'gpt-4o', 'enabled' => 1),
                array('name' => 'gpt-4o-mini', 'enabled' => 1),
            ),
        ),
    ),
    // 功能配置(每个 AI 功能一项)
    'features' => array (
        'editor' => array (
            'name'             => 'AIeditor',
            'type'             => 'text',
            'mode'             => 'user_key',   // global/user_key/both
            'call_method'      => 'frontend',   // frontend/proxy
            'default_provider' => '',
            'default_model'    => '',
            'allowed_providers' => array('openai', 'deepseek'),
        ),
    ),
    // 编辑器专属配置(可选)
    'promptContinue' => '请根据上下文续写内容',
    'promptImprove'  => '请优化以下文本的表达',
),

2.2 用户配置 user.ai_config

// 存储在 user 表 ai_config 字段(JSON)
// 新版结构:{featureKey: {apiKey, model, url, provider_name}}
array(
    'editor' => array(
        'apiKey'        => 'sk-xxx',
        'model'         => 'gpt-4o-mini',
        'url'           => 'https://api.openai.com',
        'provider_name' => 'openai',
    ),
)

2.3 健康状态(kv 持久化)

  • kv 键ai_provider_health

  • 结构{provider_name: {online: bool, last_check: int}}

  • 写入时机:仅状态变化时写 kv(减少写开销)

  • 读取:请求内 static 缓存,避免重复读 kv

2.4 轮询状态(kv 持久化)

  • kv 键ai_roundrobin_last_{feature}

  • 作用:round_robin 模式记录上次使用的 provider,下次从下一个开始

三、API 参考

3.1 静态方法(功能注册)

registerFeature($key, $config)

注册新 AI 功能。插件应在 model_inc_start.php 钩子中调用,先注册者胜(已注册不覆盖)。

AIService::registerFeature('xnx_ai_reply', array(
    'name'             => 'AI 自动回复',
    'type'             => 'text',
    'mode'             => 'global',
    'call_method'      => 'proxy',
    'default_provider' => '',
    'default_model'    => '',
    'allowed_providers' => array(),
));

字段

类型

必填

说明

name

string

功能名称(显示用)

type

string

provider 类型:text/image/video/audio/transcription

mode

string

global(用全局配置)/ user_key(用用户配置)/ both(优先用户,回退全局)

call_method

string

frontend(前端直连)/ proxy(服务端代理)

default_provider

string

默认 provider 名

default_model

string

默认模型名

allowed_providers

array

允许的 provider 名数组

registerPostFilter($key, $callback)

注册内容后处理过滤器。call()callWithFailover() 成功后会自动调用。

AIService::registerPostFilter('xnx_ai_reply', function($content, $context) {
    // $context = ['key', 'messages', 'provider_name', 'options']
    return trim($content);
});

getRegisteredFeatures()

返回所有已注册功能(核心 editor + 插件注册的)。

3.2 实例方法(配置解析)

getFeatureConfig($key)

返回功能配置(合并注册默认值 + conf.ai.features.$key,conf 覆盖注册默认值)。

getEffectiveConfig($key, $uid = null)

按 mode 合并全局/用户配置,返回最终生效配置。配置不完整时返回空数组。

$ai = new AIService($db, $conf);
$config = $ai->getEffectiveConfig('editor', $uid);
// 返回:['apiKey', 'model', 'url', 'provider_name', 'promptContinue'(可选), 'promptImprove'(可选)]

3.3 实例方法(AI 调用)

call($key, $messages, $options = [])

单 provider 调用(按功能 key 解析配置后调用)。

$result = $ai->call('editor', $messages, array(
    'uid'         => $uid,
    'temperature' => 0.7,
    'max_tokens'  => 1024,
    'timeout'     => 30,
    'source'      => 'core',
));

返回结构

array(
    'code'    => 0,           // 0成功 / 1失败
    'message' => '',          // 错误信息
    'data'    => array(
        'content'       => 'AI 回复文本',
        'usage'         => array('prompt_tokens', 'completion_tokens', 'total_tokens'),
        'provider_name' => 'openai',
        'model'         => 'gpt-4o-mini',
        'time_ms'       => 1234,
    ),
)

callWithFailover($key, $messages, $options = [])

多 provider 调用,支持四种模式。插件复用此方法实现轮询、故障转移、并发竞速。

$result = $ai->callWithFailover('xnx_ai_reply', $messages, array(
    'mode'              => 'failover',   // failover/round_robin/random/concurrent
    'retry'             => 2,            // 每个 provider 重试次数
    'providers'         => array('openai', 'deepseek'),  // 可选,覆盖 feature.allowed_providers
    'uid'               => $uid,
    'temperature'       => 0.7,
    'max_tokens'        => 1024,
    'timeout'           => 30,
    'source'            => 'xnx_ai_reply',
    'recover_threshold' => 600,          // 离线恢复阈值秒数
));

provider 来源优先级

  1. options.providers 显式指定

  2. feature.allowed_providers

  3. feature.default_provider

四种模式

模式

行为

适用场景

failover

顺序故障转移,每个 provider retry 次后切下一个

默认,高可用

round_robin

轮询,从上次使用的下一个开始(kv 持久化)

负载均衡

random

shuffle 后顺序 fallback

随机分散

concurrent

curl_multi 前 3 个并发竞速,取最快返回

低延迟

健康检查逻辑

  • 调用前过滤掉已离线未过 recover_threshold 的 provider

  • 调用成功后标记 provider online

  • 调用失败后标记 provider offline

  • 未知 provider(kv 无记录)视为健康

3.4 实例方法(健康状态)

markProviderOnline($name) / markProviderOffline($name)

标记 provider 在线/离线(仅状态变化时写 kv)。

isProviderHealthy($name, $recoverThreshold = 600)

判断 provider 是否健康。未知 provider 视为健康,离线超过阈值视为可恢复。

getProviderHealth($name = null)

返回单个或全部 provider 健康状态。

$all = $ai->getProviderHealth();
// 返回:['openai' => ['online' => true, 'last_check' => 1234567890], ...]

$one = $ai->getProviderHealth('openai');
// 返回:['online' => true, 'last_check' => 1234567890]

3.5 实例方法(测试)

testProvider($name)

测试 provider 连接(发送 ping 请求)。成功/失败后自动标记健康状态。

$result = $ai->testProvider('openai');
// 返回:['code' => 0/1, 'message' => ..., 'data' => ['time_ms' => ...]]

四、调用流程

4.1 单 provider 调用流程(call()

call($key, $messages, $options)
  ├─ getEffectiveConfig($key, $uid)  // 按 mode 解析配置
  ├─ callByConfig($config, $messages, $options, $logBase)  // 底层 curl 调用
  │   ├─ 构造请求体(model/messages/temperature/max_tokens)
  │   ├─ curl POST 到 {url}/chat/completions
  │   ├─ 解析响应(choices[0].message.content + usage)
  │   └─ writeLog()  // 写入 xnx_ai_call_log
  └─ applyPostFilters($key, $content, $context)  // 应用已注册的后处理过滤器

4.2 多 provider 调用流程(callWithFailover()

callWithFailover($key, $messages, $options)
  ├─ 解析 providerNames(options.providers > feature.allowed_providers > feature.default_provider)
  ├─ 构建 configs 列表(过滤掉配置不完整和已离线未恢复的)
  ├─ 按模式调用:
  │   ├─ concurrent: callConcurrent()  // curl_multi 前 3 个并发竞速
  │   ├─ random:     callRandom()      // shuffle 后顺序 fallback
  │   ├─ round_robin: callRoundRobin() // 从上次下一个开始,kv 持久化
  │   └─ failover:   callFailover()    // 顺序故障转移 + retry
  │   每种模式内部都调用 callByConfig() 执行单次 curl
  └─ applyPostFilters($key, $content, $context)

五、插件接入指南

5.1 接入步骤

  1. 注册功能:在 hook/model_inc_start.php 调用 AIService::registerFeature()

  2. 配置功能:在 install.php 写入 conf.ai.features.{key}

  3. 调用 AI:在插件业务代码中调用 $ai->call()$ai->callWithFailover()

  4. (可选)注册后处理:通过 registerPostFilter() 注册内容过滤器

5.2 接入示例(xnx_ai_reply 插件)

步骤 1:注册功能hook/model_inc_start.php

if (class_exists('AIService') && method_exists('AIService', 'registerFeature')) {
    AIService::registerFeature('xnx_ai_reply', array(
        'name'             => 'AI 自动回复',
        'type'             => 'text',
        'mode'             => 'global',
        'call_method'      => 'proxy',
        'allowed_providers' => array(),
    ));
}

步骤 2:调用 AI(插件 Service 类)

$ai = new AIService($db, $conf);
$result = $ai->callWithFailover('xnx_ai_reply', $messages, array(
    'mode'              => 'failover',
    'retry'             => 2,
    'temperature'       => 0.7,
    'recover_threshold' => 600,
    'source'            => 'xnx_ai_reply',
));

if ($result['code'] === 0) {
    $content = $result['data']['content'];
    $provider_name = $result['data']['provider_name'];
    $usage = $result['data']['usage'];  // prompt_tokens/completion_tokens/total_tokens
}

5.3 接入注意事项

  1. 类加载守卫:生产环境(DEBUG=0)走 tmp/model.min.php 合并加载,类加载顺序不可预测。调用 AIService 前必须:

    if (!class_exists('AIService')) {
        include_once APP_PATH . 'lib/AIService.php';
    }
    
  2. provider 来源:插件不应自建 provider 表,统一用核心 conf.ai.providers。用户在后台「AI - 全局提供商」页面配置。

  3. 健康状态:核心用 kv 持久化(ai_provider_health),插件不要自建健康检查逻辑,直接调用 isProviderHealthy()getProviderHealth()

  4. 日志写入call()callWithFailover() 内部已自动写入核心日志表 xnx_ai_call_log,插件如需自有日志表可双写(参考 xnx_ai_reply 的 AiLogService)。

  5. 流式调用call()callWithFailover() 是非流式调用。流式调用(SSE)由 route/ai.php/ai-chat 端点处理,插件如需流式需自行实现。

六、相关文件

文件

职责

lib/AIService.php

核心 AI 调用中台(本文档)

lib/AILogService.php

统一 AI 调用日志接口(写入 xnx_ai_call_log

route/ai.php

前台 AI 代理路由(/ai-chat,流式 SSE)

admin/route/ai.php

后台 AI 配置路由(providers/features)

admin/view/htm/ai_providers.htm

后台全局提供商配置页

admin/view/htm/ai_features.htm

后台功能配置页

admin/view/htm/ai_logs.htm

后台 AI 调用日志页

view/htm/my_ai.htm

前台「我的 AI」配置页

conf/conf.default.php

默认配置(含预置 5 个 AI 厂商)

七、数据库表

7.1 xnx_ai_call_log(核心统一日志表)

字段

类型

说明

id

int unsigned

主键

uid

int unsigned

用户ID

feature

varchar(32)

功能标识(editor/xnx_ai_reply/…)

source

varchar(32)

来源标识(core/xnx_ai_reply/…)

provider_name

varchar(64)

provider 名

model

varchar(64)

模型名

mode

varchar(16)

模式(global/user_key/both)

prompt_tokens

int

输入 token 数

completion_tokens

int

输出 token 数

total_tokens

int

总 token 数

response_time

int

响应时间(ms)

status

tinyint

1成功 / 0失败

error_msg

varchar(500)

错误信息

request_summary

varchar(500)

请求摘要

response_summary

varchar(500)

响应摘要

create_time

int unsigned

创建时间

7.2 kv 表

说明

ai_provider_health

provider 健康状态(name => {online, last_check})

ai_roundrobin_last_{feature}

round_robin 模式上次使用的 provider 名

八、错误码

code

含义

说明

0

成功

data 含 content/usage/provider_name/model/time_ms

1

失败

message 含错误信息

常见错误信息:

  • AI 配置不完整:apiKey/url/model 为空

  • 无可用 provider:allowed_providers 为空且无 default_provider

  • 无可用 provider 配置(可能全部离线或配置不完整):所有 provider 都离线或配置缺失

  • curl error: ...:curl 调用失败

  • HTTP 4xx/5xx: ...:provider 返回错误状态码

  • empty content:provider 返回空内容

最新回复

请先登录后再回复 登录

uid:1 管理
关注
随遇而安,随缘而行
发帖 71
评论 319
粉丝 11
关注 1
发新帖
目录
XIUNOX AIService 核心文档