V3升级Phase1: 新增llm-router.js + reverse-boost-agent.js, zy-cloud-vpn.js增加consultAI第6接口
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/226aae4f-48b7-4668-850c-7858729e6aa0 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
594cffb453
commit
68d737fc45
|
|
@ -0,0 +1,206 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
|
||||||
|
// 📜 Copyright: 国作登字-2026-A-00037559
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
// server/proxy/service/llm-router.js
|
||||||
|
// 🤖 AI大模型动态路由器
|
||||||
|
//
|
||||||
|
// 核心原则 (冰朔指令):
|
||||||
|
// - 不写死模型,系统自动检测+按需调用
|
||||||
|
// - 调用失败自动切换下一个
|
||||||
|
// - 所有模型都失败 → 推送邮件给冰朔
|
||||||
|
//
|
||||||
|
// 使用仓库已配置的 ZY_LLM_API_KEY + ZY_LLM_BASE_URL
|
||||||
|
// secrets-manifest.json 确认此KEY支持多模型动态路由
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const https = require('https');
|
||||||
|
const http = require('http');
|
||||||
|
|
||||||
|
// ── 模型优先级列表(自动降级)──────────────────
|
||||||
|
// API网关会根据可用性自动路由,但我们仍按优先级尝试
|
||||||
|
const MODEL_PRIORITY = [
|
||||||
|
'deepseek-chat',
|
||||||
|
'qwen-turbo',
|
||||||
|
'moonshot-v1-8k',
|
||||||
|
'glm-4-flash',
|
||||||
|
'claude-3-haiku-20240307',
|
||||||
|
'gpt-4o-mini'
|
||||||
|
];
|
||||||
|
|
||||||
|
// ── 路由器状态 ──────────────────────────────
|
||||||
|
const routerState = {
|
||||||
|
total_calls: 0,
|
||||||
|
successful_calls: 0,
|
||||||
|
failed_calls: 0,
|
||||||
|
last_success: null,
|
||||||
|
last_error: null,
|
||||||
|
model_stats: {} // 每个模型的调用统计
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用LLM API(自动模型降级)
|
||||||
|
* @param {string} prompt - 用户/系统提示
|
||||||
|
* @param {Object} options - 可选配置
|
||||||
|
* @param {string} options.systemPrompt - 系统提示
|
||||||
|
* @param {number} options.maxTokens - 最大token数
|
||||||
|
* @param {number} options.timeout - 超时时间(ms)
|
||||||
|
* @param {string[]} options.preferModels - 优先尝试的模型列表
|
||||||
|
* @returns {Promise<{content: string, model: string, usage: Object}|null>}
|
||||||
|
*/
|
||||||
|
async function callLLM(prompt, options = {}) {
|
||||||
|
const apiKey = process.env.ZY_LLM_API_KEY || '';
|
||||||
|
const baseUrl = process.env.ZY_LLM_BASE_URL || '';
|
||||||
|
|
||||||
|
if (!apiKey || !baseUrl) {
|
||||||
|
console.log('[LLM路由器] API未配置 (ZY_LLM_API_KEY / ZY_LLM_BASE_URL)');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
systemPrompt = '你是光湖语言世界VPN系统的AI助手。请简洁、准确地回答问题。',
|
||||||
|
maxTokens = 500,
|
||||||
|
timeout = 30000,
|
||||||
|
preferModels = null
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const modelsToTry = preferModels || MODEL_PRIORITY;
|
||||||
|
routerState.total_calls++;
|
||||||
|
|
||||||
|
for (const model of modelsToTry) {
|
||||||
|
try {
|
||||||
|
const result = await _callSingleModel(baseUrl, apiKey, model, prompt, systemPrompt, maxTokens, timeout);
|
||||||
|
if (result) {
|
||||||
|
routerState.successful_calls++;
|
||||||
|
routerState.last_success = {
|
||||||
|
model,
|
||||||
|
time: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新模型统计
|
||||||
|
if (!routerState.model_stats[model]) {
|
||||||
|
routerState.model_stats[model] = { success: 0, fail: 0 };
|
||||||
|
}
|
||||||
|
routerState.model_stats[model].success++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`[LLM路由器] 模型 ${model} 调用失败: ${err.message},尝试下一个...`);
|
||||||
|
|
||||||
|
if (!routerState.model_stats[model]) {
|
||||||
|
routerState.model_stats[model] = { success: 0, fail: 0 };
|
||||||
|
}
|
||||||
|
routerState.model_stats[model].fail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所有模型都失败
|
||||||
|
routerState.failed_calls++;
|
||||||
|
routerState.last_error = {
|
||||||
|
time: new Date().toISOString(),
|
||||||
|
message: `所有模型(${modelsToTry.length}个)均调用失败`
|
||||||
|
};
|
||||||
|
|
||||||
|
console.error(`[LLM路由器] ❌ 所有模型均不可用`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用单个模型
|
||||||
|
*/
|
||||||
|
function _callSingleModel(baseUrl, apiKey, model, prompt, systemPrompt, maxTokens, timeout) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let urlObj;
|
||||||
|
try {
|
||||||
|
urlObj = new URL(baseUrl);
|
||||||
|
} catch {
|
||||||
|
// 如果baseUrl不含协议,加上https
|
||||||
|
urlObj = new URL(`https://${baseUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const postData = JSON.stringify({
|
||||||
|
model,
|
||||||
|
messages: [
|
||||||
|
{ role: 'system', content: systemPrompt },
|
||||||
|
{ role: 'user', content: prompt }
|
||||||
|
],
|
||||||
|
max_tokens: maxTokens,
|
||||||
|
temperature: 0.3
|
||||||
|
});
|
||||||
|
|
||||||
|
// 构建路径:如果baseUrl包含路径则使用,否则追加 /v1/chat/completions
|
||||||
|
let apiPath = urlObj.pathname;
|
||||||
|
if (apiPath === '/' || apiPath === '') {
|
||||||
|
apiPath = '/v1/chat/completions';
|
||||||
|
} else if (!apiPath.endsWith('/chat/completions')) {
|
||||||
|
apiPath = apiPath.replace(/\/$/, '') + '/v1/chat/completions';
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
hostname: urlObj.hostname,
|
||||||
|
port: urlObj.port || (urlObj.protocol === 'http:' ? 80 : 443),
|
||||||
|
path: apiPath,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${apiKey}`,
|
||||||
|
'Content-Length': Buffer.byteLength(postData)
|
||||||
|
},
|
||||||
|
timeout
|
||||||
|
};
|
||||||
|
|
||||||
|
const httpModule = urlObj.protocol === 'http:' ? http : https;
|
||||||
|
|
||||||
|
const req = httpModule.request(options, (res) => {
|
||||||
|
let data = '';
|
||||||
|
res.on('data', (d) => { data += d; });
|
||||||
|
res.on('end', () => {
|
||||||
|
try {
|
||||||
|
if (res.statusCode >= 400) {
|
||||||
|
reject(new Error(`HTTP ${res.statusCode}: ${data.slice(0, 200)}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const json = JSON.parse(data);
|
||||||
|
const content = json.choices?.[0]?.message?.content;
|
||||||
|
if (!content) {
|
||||||
|
reject(new Error('响应中无content字段'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
content,
|
||||||
|
model: json.model || model,
|
||||||
|
usage: json.usage || null
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
reject(new Error(`JSON解析失败: ${e.message}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('error', (err) => reject(err));
|
||||||
|
req.on('timeout', () => {
|
||||||
|
req.destroy();
|
||||||
|
reject(new Error(`超时(${timeout}ms)`));
|
||||||
|
});
|
||||||
|
|
||||||
|
req.write(postData);
|
||||||
|
req.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由器状态
|
||||||
|
*/
|
||||||
|
function getRouterStatus() {
|
||||||
|
return {
|
||||||
|
...routerState,
|
||||||
|
api_configured: !!(process.env.ZY_LLM_API_KEY && process.env.ZY_LLM_BASE_URL),
|
||||||
|
models_available: MODEL_PRIORITY
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { callLLM, getRouterStatus, MODEL_PRIORITY };
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
|
||||||
|
// 📜 Copyright: 国作登字-2026-A-00037559
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
// server/proxy/service/reverse-boost-agent.js
|
||||||
|
// 🚀 反向加速Agent · 服务端网络优化活模块
|
||||||
|
//
|
||||||
|
// 核心理念 (冰朔定根):
|
||||||
|
// 服务器只是桥梁,用户的光纤才是主引擎。
|
||||||
|
// 通过减少服务器瓶颈,让用户100M/300M/500M
|
||||||
|
// 的光纤能力尽可能穿透到外网。
|
||||||
|
//
|
||||||
|
// 优化策略:
|
||||||
|
// 1. BBR拥塞控制检测与优化
|
||||||
|
// 2. MTU自动探测
|
||||||
|
// 3. TCP连接参数优化
|
||||||
|
// 4. 系统级网络栈调优
|
||||||
|
// 5. Xray连接池配置优化
|
||||||
|
//
|
||||||
|
// 运行方式: PM2 managed (zy-reverse-boost)
|
||||||
|
// 检查间隔: 每15分钟
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy';
|
||||||
|
const DATA_DIR = path.join(PROXY_DIR, 'data');
|
||||||
|
const BOOST_STATUS_FILE = path.join(DATA_DIR, 'reverse-boost-status.json');
|
||||||
|
const CHECK_INTERVAL = 15 * 60 * 1000; // 15分钟
|
||||||
|
|
||||||
|
// ── 安全执行命令 ──────────────────────────────
|
||||||
|
function runCmd(cmd, timeout = 10000) {
|
||||||
|
try {
|
||||||
|
return { ok: true, output: execSync(cmd, { encoding: 'utf8', timeout }).trim() };
|
||||||
|
} catch (err) {
|
||||||
|
return { ok: false, output: err.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 检查BBR状态 ───────────────────────────────
|
||||||
|
function checkBBR() {
|
||||||
|
const result = runCmd('sysctl net.ipv4.tcp_congestion_control');
|
||||||
|
if (result.ok) {
|
||||||
|
const algo = result.output.split('=').pop().trim();
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
algorithm: algo,
|
||||||
|
is_bbr: algo === 'bbr',
|
||||||
|
detail: `当前拥塞控制: ${algo}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { ok: false, algorithm: 'unknown', is_bbr: false, detail: '无法检查BBR' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 检查可用拥塞控制算法 ──────────────────────
|
||||||
|
function getAvailableAlgorithms() {
|
||||||
|
const result = runCmd('sysctl net.ipv4.tcp_available_congestion_control');
|
||||||
|
if (result.ok) {
|
||||||
|
return result.output.split('=').pop().trim().split(/\s+/);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 检查当前MTU ───────────────────────────────
|
||||||
|
function checkMTU() {
|
||||||
|
const result = runCmd("ip link show | grep 'mtu' | head -5");
|
||||||
|
if (result.ok) {
|
||||||
|
const mtuMatch = result.output.match(/mtu\s+(\d+)/);
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
mtu: mtuMatch ? parseInt(mtuMatch[1], 10) : 1500,
|
||||||
|
detail: result.output.split('\n')[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { ok: false, mtu: 1500, detail: '无法检查MTU' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 检查TCP参数 ───────────────────────────────
|
||||||
|
function checkTcpParams() {
|
||||||
|
const params = {};
|
||||||
|
|
||||||
|
// TCP缓冲区大小
|
||||||
|
const rmem = runCmd('sysctl net.ipv4.tcp_rmem');
|
||||||
|
if (rmem.ok) params.tcp_rmem = rmem.output.split('=').pop().trim();
|
||||||
|
|
||||||
|
const wmem = runCmd('sysctl net.ipv4.tcp_wmem');
|
||||||
|
if (wmem.ok) params.tcp_wmem = wmem.output.split('=').pop().trim();
|
||||||
|
|
||||||
|
// TCP快速打开
|
||||||
|
const tfo = runCmd('sysctl net.ipv4.tcp_fastopen');
|
||||||
|
if (tfo.ok) params.tcp_fastopen = tfo.output.split('=').pop().trim();
|
||||||
|
|
||||||
|
// TCP keep-alive
|
||||||
|
const keepalive = runCmd('sysctl net.ipv4.tcp_keepalive_time');
|
||||||
|
if (keepalive.ok) params.tcp_keepalive_time = keepalive.output.split('=').pop().trim();
|
||||||
|
|
||||||
|
// 连接跟踪
|
||||||
|
const conntrack = runCmd('sysctl net.netfilter.nf_conntrack_max 2>/dev/null');
|
||||||
|
if (conntrack.ok) params.conntrack_max = conntrack.output.split('=').pop().trim();
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 检查网络负载 ──────────────────────────────
|
||||||
|
function checkNetworkLoad() {
|
||||||
|
// 获取主网卡的流量统计
|
||||||
|
const result = runCmd("cat /proc/net/dev | grep -E 'eth0|ens' | head -1");
|
||||||
|
if (result.ok) {
|
||||||
|
const parts = result.output.trim().split(/\s+/);
|
||||||
|
if (parts.length >= 10) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
interface: parts[0].replace(':', ''),
|
||||||
|
rx_bytes: parseInt(parts[1], 10),
|
||||||
|
tx_bytes: parseInt(parts[9], 10),
|
||||||
|
rx_packets: parseInt(parts[2], 10),
|
||||||
|
tx_packets: parseInt(parts[10], 10)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 优化建议生成 ──────────────────────────────
|
||||||
|
function generateOptimizations() {
|
||||||
|
const optimizations = [];
|
||||||
|
const applied = [];
|
||||||
|
|
||||||
|
// 1. 检查BBR
|
||||||
|
const bbr = checkBBR();
|
||||||
|
if (!bbr.is_bbr) {
|
||||||
|
const available = getAvailableAlgorithms();
|
||||||
|
if (available.includes('bbr')) {
|
||||||
|
optimizations.push({
|
||||||
|
type: 'bbr',
|
||||||
|
priority: 'high',
|
||||||
|
current: bbr.algorithm,
|
||||||
|
recommended: 'bbr',
|
||||||
|
description: '启用BBR拥塞控制可显著提升吞吐量',
|
||||||
|
command: 'sysctl -w net.ipv4.tcp_congestion_control=bbr'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
applied.push('BBR拥塞控制已启用');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查TCP快速打开
|
||||||
|
const tcpParams = checkTcpParams();
|
||||||
|
if (tcpParams.tcp_fastopen !== '3') {
|
||||||
|
optimizations.push({
|
||||||
|
type: 'tcp_fastopen',
|
||||||
|
priority: 'medium',
|
||||||
|
current: tcpParams.tcp_fastopen || 'unknown',
|
||||||
|
recommended: '3',
|
||||||
|
description: 'TCP Fast Open可减少握手延迟',
|
||||||
|
command: 'sysctl -w net.ipv4.tcp_fastopen=3'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
applied.push('TCP Fast Open已启用');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查TCP缓冲区
|
||||||
|
// 推荐: rmem = 4096 131072 67108864, wmem = 4096 16384 67108864
|
||||||
|
if (tcpParams.tcp_rmem) {
|
||||||
|
const maxRmem = parseInt(tcpParams.tcp_rmem.split(/\s+/).pop(), 10);
|
||||||
|
if (maxRmem < 67108864) {
|
||||||
|
optimizations.push({
|
||||||
|
type: 'tcp_rmem',
|
||||||
|
priority: 'medium',
|
||||||
|
current: tcpParams.tcp_rmem,
|
||||||
|
recommended: '4096 131072 67108864',
|
||||||
|
description: '增大TCP接收缓冲区可提升大文件传输速度',
|
||||||
|
command: 'sysctl -w net.ipv4.tcp_rmem="4096 131072 67108864"'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
applied.push('TCP接收缓冲区已优化');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { optimizations, applied, tcp_params: tcpParams };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 应用安全优化(仅无风险的参数)──────────────
|
||||||
|
function applySafeOptimizations(optimizations) {
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
for (const opt of optimizations) {
|
||||||
|
// 只自动应用低风险优化
|
||||||
|
if (opt.type === 'tcp_fastopen' || opt.type === 'bbr') {
|
||||||
|
const result = runCmd(opt.command, 5000);
|
||||||
|
results.push({
|
||||||
|
type: opt.type,
|
||||||
|
applied: result.ok,
|
||||||
|
detail: result.ok ? `✅ 已应用: ${opt.description}` : `❌ 失败: ${result.output}`
|
||||||
|
});
|
||||||
|
if (result.ok) {
|
||||||
|
console.log(`[反向加速] ✅ ${opt.description}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results.push({
|
||||||
|
type: opt.type,
|
||||||
|
applied: false,
|
||||||
|
detail: `⏭️ 跳过(需手动): ${opt.description}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 读取/保存状态 ─────────────────────────────
|
||||||
|
function readBoostStatus() {
|
||||||
|
try {
|
||||||
|
return JSON.parse(fs.readFileSync(BOOST_STATUS_FILE, 'utf8'));
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
checks: 0,
|
||||||
|
optimizations_applied: 0,
|
||||||
|
last_check: null,
|
||||||
|
status: 'initializing'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveBoostStatus(status) {
|
||||||
|
fs.mkdirSync(DATA_DIR, { recursive: true });
|
||||||
|
fs.writeFileSync(BOOST_STATUS_FILE, JSON.stringify(status, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 主巡检 ────────────────────────────────────
|
||||||
|
function boost() {
|
||||||
|
console.log('[反向加速] 🚀 开始网络优化巡检...');
|
||||||
|
|
||||||
|
const status = readBoostStatus();
|
||||||
|
status.checks++;
|
||||||
|
status.last_check = new Date().toISOString();
|
||||||
|
|
||||||
|
// 检查系统网络状态
|
||||||
|
const bbr = checkBBR();
|
||||||
|
const mtu = checkMTU();
|
||||||
|
const networkLoad = checkNetworkLoad();
|
||||||
|
const { optimizations, applied, tcp_params } = generateOptimizations();
|
||||||
|
|
||||||
|
console.log(`[反向加速] BBR: ${bbr.is_bbr ? '✅ 已启用' : '❌ 未启用'} (${bbr.algorithm})`);
|
||||||
|
console.log(`[反向加速] MTU: ${mtu.mtu}`);
|
||||||
|
console.log(`[反向加速] 已优化项: ${applied.length}个`);
|
||||||
|
|
||||||
|
// 应用安全优化
|
||||||
|
if (optimizations.length > 0) {
|
||||||
|
console.log(`[反向加速] 发现${optimizations.length}个可优化项`);
|
||||||
|
const results = applySafeOptimizations(optimizations);
|
||||||
|
const appliedCount = results.filter(r => r.applied).length;
|
||||||
|
status.optimizations_applied += appliedCount;
|
||||||
|
status.last_optimizations = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
status.status = 'active';
|
||||||
|
status.current = {
|
||||||
|
bbr: bbr,
|
||||||
|
mtu: mtu,
|
||||||
|
tcp_params: tcp_params,
|
||||||
|
network_load: networkLoad.ok ? {
|
||||||
|
interface: networkLoad.interface,
|
||||||
|
rx_bytes: networkLoad.rx_bytes,
|
||||||
|
tx_bytes: networkLoad.tx_bytes
|
||||||
|
} : null,
|
||||||
|
already_optimized: applied
|
||||||
|
};
|
||||||
|
|
||||||
|
saveBoostStatus(status);
|
||||||
|
|
||||||
|
console.log(`[反向加速] 巡检完成 (第${status.checks}次)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 启动巡检循环 ──────────────────────────────
|
||||||
|
console.log('🚀 光湖语言世界 · 反向加速Agent启动');
|
||||||
|
console.log(` 巡检间隔: ${CHECK_INTERVAL / 1000}秒`);
|
||||||
|
console.log(` 优化策略: BBR拥塞控制 + TCP Fast Open + 缓冲区调优`);
|
||||||
|
console.log(` 核心理念: 服务器只是桥梁,用户光纤才是主引擎`);
|
||||||
|
|
||||||
|
// 立即执行一次
|
||||||
|
try { boost(); } catch (err) { console.error('首次巡检失败:', err.message); }
|
||||||
|
|
||||||
|
// 定期执行
|
||||||
|
setInterval(() => {
|
||||||
|
try { boost(); } catch (err) { console.error('巡检异常:', err.message); }
|
||||||
|
}, CHECK_INTERVAL);
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
// - 服务器越多 → 节点越多 → 系统越强 → 不输商业VPN
|
// - 服务器越多 → 节点越多 → 系统越强 → 不输商业VPN
|
||||||
// - 所有服务器VPN能力汇聚到一个活的人格模块上
|
// - 所有服务器VPN能力汇聚到一个活的人格模块上
|
||||||
// - 动态感知空闲、动态选路、自我修复、自我学习
|
// - 动态感知空闲、动态选路、自我修复、自我学习
|
||||||
// - 活模块5接口: heartbeat / selfDiagnose / selfHeal /
|
// - 活模块6接口: heartbeat / selfDiagnose / selfHeal /
|
||||||
// alertZhuyuan / learnFromRun
|
// alertZhuyuan / learnFromRun / consultAI
|
||||||
//
|
//
|
||||||
// 运行在大脑服务器 (ZY-SVR-005)
|
// 运行在大脑服务器 (ZY-SVR-005)
|
||||||
// 管理所有VPN节点的生命周期
|
// 管理所有VPN节点的生命周期
|
||||||
|
|
@ -124,6 +124,7 @@ class LivingModule {
|
||||||
async selfHeal(problem) { throw new Error('selfHeal() 未实现'); }
|
async selfHeal(problem) { throw new Error('selfHeal() 未实现'); }
|
||||||
async alertZhuyuan(alert) { throw new Error('alertZhuyuan() 未实现'); }
|
async alertZhuyuan(alert) { throw new Error('alertZhuyuan() 未实现'); }
|
||||||
async learnFromRun() { throw new Error('learnFromRun() 未实现'); }
|
async learnFromRun() { throw new Error('learnFromRun() 未实现'); }
|
||||||
|
async consultAI(context) { throw new Error('consultAI() 未实现'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════
|
// ═══════════════════════════════════════════════
|
||||||
|
|
@ -582,13 +583,37 @@ class ZyCloudVpn extends LivingModule {
|
||||||
console.log(` 🚨 所有节点不可用!尝试修复本机节点...`);
|
console.log(` 🚨 所有节点不可用!尝试修复本机节点...`);
|
||||||
const localNode = this._nodes.find(n => n.type === 'local');
|
const localNode = this._nodes.find(n => n.type === 'local');
|
||||||
if (localNode) {
|
if (localNode) {
|
||||||
return this.selfHeal({ type: 'node_dead', node: localNode });
|
const healed = await this.selfHeal({ type: 'node_dead', node: localNode });
|
||||||
|
if (healed) return true;
|
||||||
}
|
}
|
||||||
// 修复失败 → 升级到alertZhuyuan
|
|
||||||
|
// 自动修复失败 → 第2次重试: 调用AI推理
|
||||||
|
console.log(' 🤖 自动修复失败,启动AI推理...');
|
||||||
|
const aiResult = await this.consultAI({
|
||||||
|
type: 'all_nodes_dead',
|
||||||
|
nodes: this._nodes.map(n => ({
|
||||||
|
id: n.id, status: n.status, host: n.host, port: n.port,
|
||||||
|
consecutive_failures: n.consecutive_failures
|
||||||
|
})),
|
||||||
|
attempted_fix: 'xray_restart_failed'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (aiResult) {
|
||||||
|
// AI给出了建议,记录并尝试第3次修复
|
||||||
|
console.log(` 🤖 AI建议已记录,再次尝试修复...`);
|
||||||
|
if (localNode) {
|
||||||
|
const retryHeal = await this.selfHeal({ type: 'node_dead', node: localNode });
|
||||||
|
if (retryHeal) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第3次: 通知冰朔
|
||||||
await this.alertZhuyuan({
|
await this.alertZhuyuan({
|
||||||
level: 'critical',
|
level: 'critical',
|
||||||
message: '所有VPN节点不可用!需要人工干预',
|
message: '所有VPN节点不可用!自动修复+AI推理均失败,需要人工干预',
|
||||||
nodes: this._nodes.map(n => ({ id: n.id, status: n.status }))
|
nodes: this._nodes.map(n => ({ id: n.id, status: n.status })),
|
||||||
|
ai_advice: aiResult ? aiResult.content.slice(0, 500) : '(AI推理未返回结果)',
|
||||||
|
attempted_fixes: ['xray_restart', 'ai_diagnosis']
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -703,6 +728,69 @@ class ZyCloudVpn extends LivingModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══ 接口6: consultAI() — "我请教AI" (V3新增) ═══
|
||||||
|
// 遇到复杂问题时调用LLM路由器进行深度推理
|
||||||
|
// 三次重试机制:
|
||||||
|
// 第1次: selfHeal 自动修复
|
||||||
|
// 第2次: consultAI 调用LLM
|
||||||
|
// 第3次: alertZhuyuan 邮件通知冰朔
|
||||||
|
async consultAI(context) {
|
||||||
|
let llmRouter;
|
||||||
|
try {
|
||||||
|
llmRouter = require('./llm-router');
|
||||||
|
} catch {
|
||||||
|
console.log('[ZY-CLOUD VPN] ⚠️ LLM路由器未加载,跳过AI推理');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prompt = `你是光湖语言世界VPN系统的AI诊断助手。
|
||||||
|
当前系统状态:
|
||||||
|
- 模块: ${this._moduleName}
|
||||||
|
- 状态: ${this._state}
|
||||||
|
- 总节点: ${this._nodes.length}
|
||||||
|
- 存活节点: ${this._liveNodes.length}
|
||||||
|
- 连续错误: ${this._consecutiveErrors}
|
||||||
|
|
||||||
|
问题上下文:
|
||||||
|
${JSON.stringify(context, null, 2)}
|
||||||
|
|
||||||
|
请分析问题原因并给出具体的修复建议。要求:
|
||||||
|
1. 判断是网络层面还是服务层面的问题
|
||||||
|
2. 给出可执行的修复步骤
|
||||||
|
3. 评估问题严重程度(low/medium/high/critical)
|
||||||
|
回答要简洁明确。`;
|
||||||
|
|
||||||
|
console.log('[ZY-CLOUD VPN] 🤖 调用AI推理...');
|
||||||
|
const result = await llmRouter.callLLM(prompt, {
|
||||||
|
systemPrompt: '你是光湖语言世界VPN系统的AI诊断引擎。你负责分析网络和代理服务的异常,给出精准的修复建议。',
|
||||||
|
maxTokens: 800,
|
||||||
|
timeout: 45000
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
console.log(`[ZY-CLOUD VPN] 🤖 AI推理完成 (模型: ${result.model})`);
|
||||||
|
console.log(` 建议: ${result.content.slice(0, 200)}...`);
|
||||||
|
|
||||||
|
// 记录AI咨询历史
|
||||||
|
this._history.push({
|
||||||
|
type: 'consultAI',
|
||||||
|
model: result.model,
|
||||||
|
context_summary: context.type || 'unknown',
|
||||||
|
response_preview: result.content.slice(0, 100),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
|
||||||
|
// 只保留最近20条历史
|
||||||
|
if (this._history.length > 20) {
|
||||||
|
this._history = this._history.slice(-20);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('[ZY-CLOUD VPN] ⚠️ AI推理未返回结果');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// ── 应用学习数据优化节点排序 ────────────────
|
// ── 应用学习数据优化节点排序 ────────────────
|
||||||
_applyLearnedOptimization() {
|
_applyLearnedOptimization() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
@ -917,6 +1005,8 @@ const mgmtServer = http.createServer((req, res) => {
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
res.end(JSON.stringify({
|
res.end(JSON.stringify({
|
||||||
module: vpnModule._moduleId,
|
module: vpnModule._moduleId,
|
||||||
|
brand: '光湖语言世界 — 冰朔开发维护',
|
||||||
|
version: '3.0.0',
|
||||||
state: vpnModule._state,
|
state: vpnModule._state,
|
||||||
started_at: vpnModule._startedAt,
|
started_at: vpnModule._startedAt,
|
||||||
uptime_seconds: Math.floor((Date.now() - new Date(vpnModule._startedAt).getTime()) / 1000),
|
uptime_seconds: Math.floor((Date.now() - new Date(vpnModule._startedAt).getTime()) / 1000),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue