账号池
0 项已选
用户管理
五因子加权:近 30 天调用成功率、风控无违纪、LLM 预审通过率、账龄、累计充值。
分数决定速率窗口配额倍率与预审豁免,所以它是真的会花钱的东西,不是一个装饰分。
自动扣分有每小时冷却(同一用户同一类型同一理由);人工调整必须写理由,
理由会写进 trust_events 与 audit_log —— 无痕改分等于没有这套体系。
实时监控
全局准入调度
整台网关同时最多跑几笔;满了排队,队列也满就直接拒
调度事件
本进程的实时尾巴,重启就没了;要查历史看上面的 24 小时统计
在途分布
这些在途请求压在哪些池位上。RPM / TPM / 配额水位在资源池健康那一页
实时信息
0QPS
0TPS
峰值 0 QPS / 0 TPS
平均 0 QPS / 0 TPS
请求
请求数:0
Token数:0
平均 QPS:0
平均 TPS:0
请求时长
—
ms (P99)
P95: —
P90: —
P50: —
Avg: —
Max: —
实时用户 Top
本进程启动以来累计,前 20 名
| 时间 | 用户 | 账号 | 模型 | Input | Output | 费用 | 延迟 | 状态 | 端点 |
计费管理
费用趋势
近 30 日,来自 usage_log 逐日聚合
按供应商 (30 日)
用量按「实际用掉的那个账号」的供应商归属
| 供应商 | 账号 可用/总数 |
请求 |
费用 |
Prompt Tok |
Completion Tok |
平均延迟 |
错误 |
错误率 |
模型定價
token 计费 = 每 1M tokens USD(各家官方牌价的单位);按次计费 = 每次请求 USD;按秒计费(影片)= 每秒 USD
| 模型 | 计费方式 | Prompt $/1M | Completion $/1M | 按次单价 $ | 操作 |
| 用户 | 余额 | 余额不足时停用 | 30 日费用 | 30 日请求 | 操作 |
未收金额 (30 日)
余额扣款夹在 0 以上之后,扣不到的那一段记在 usage_log.uncollected —— 余额本身已经不带「他欠多少」了
30 日账单(按模型)
| 模型 | 请求数 | Prompt Tokens | Completion Tokens | 费用 |
通道管理
上游通道
一条通道 = 一个上游端点(base URL + 模型 + 认证);账号是挂在它底下的凭证
接入新通道
client_credentials(机器对机器):令牌属于这条通道,到期前 60 秒自动换新。与「OAuth 授权」那张卡不同 —— 那一张是把某个人的上游账号加进池子。
新通道的路径表固定用 OpenAI 相容的 /chat/completions、/images/generations、/models。接好之后还要在下面「新增 API Key」把凭证挂上去,它才会被选路选到。
OAuth 授权(把某个人的上游账号加进池子)
这是 authorization_code + PKCE(浏览器跳转、一个人授权),结果是一个 accounts 列。通道级的 client_credentials 在上面「接入新通道」里设。
近 30 日用量
账号健康 + 请求 / 费用 / 错误率 / 延迟(来自 usage_log,与上面的通道健康度是两种观测)
智能导入(拖拽或选择文件)
拖拽 JSON / 文本文件到此处,或
系统设置
外观风格
只存在这台浏览器,不影响其他管理员。与右上角的明暗切换是两个独立的轴,可自由搭配。
系统参数
保存后立即生效,无需重启:并发上限每次请求都会重新读取。超出范围的值会被夹回边界并回填到下方输入框。
分组与路由
费率倍率直接乘在成本上:1 = 原价,0.8 = 八折,1.5 = 加价,0 = 免费(0 是合法值)。
尖峰视窗是服务器本地时间的整点半开区间 [起, 迄),可以跨午夜 —— 例如 22 → 2 表示 22:00–01:59。起 = 迄 视为零长度视窗(等于没开)。
把「对外模型名」映射到某个供应商与上游模型名。exact = 完全相同才命中;prefix = 以此开头就命中(前缀比对时较长的规则优先,priority 只在长度相同时分胜负)。
上游模型名留空 = 原样透传调用者传的模型名。账号类型留空 = 不限。只有 exact 规则会出现在 /v1/models。
系统
这一页没有可以改的东西 —— 下面每一项都由启动时的环境变数决定
(SECRET_KEY / BIND_HOST / CORS_ORIGINS / ADMIN_KEY),
改完要重启才生效。
⚠ 弄丢 SECRET_KEY = 所有上游凭证无法恢复:密文没有后门,账号必须全部重新导入。
请把它跟数据库备份分开保存。
开始 / 结束时间留空 = 该侧不限。只有状态为 active 且落在时间窗内的公告才会显示给用户。
分潤
比例一律是整数百分比:20 = 20%。合法范围 0–100,超范围后端会拒绝(不会静默夹回)。
用户的「专属比例」留空 = 跟随全局,跟设成 0% 是两件不同的事。
| 用户 | 邀请码 | 邀请人 | 邀请数 | 待转出 | 累计 | 专属比例 (%) | 生效比例 | 操作 |
这里配置的是「用户用 LinuxDO / GitHub / OIDC 登入本网关」,产出的是本站用户与 session。
跟「供应商」页里的 OAuth 授权(把上游 xAI / Gemini 账号加进中继池)完全无关,两者不要混用。
client_secret 读取时不会回传,只回一个「已设置」标记:留空提交 = 保持不变,要真的清掉请按「清除密钥」。
使用记录
快捷时段
这一页只看调用与费用。同一笔请求的风控拦截与提示词预审在
日志检索(三源合一,支持
req: 精确下钻)。
| 时间 | 用户 | 账号 | 模型 |
Input | Output | 费用 |
延迟 | 状态 | 端点 |
| 点击查询加载数据 |
订阅管理
后端没有提供删除兑换码的接口(只有列出与新增),所以这里不放删除按钮 —— 放一颗按下去必定失败的按钮比没有更糟。用完的码会自动灰掉。
风控
命中条件是「窗口内次数 > max_requests」。warn / log 在后端同样会挡下该次请求(回 429),差别只在事件里记录的动作名。
后端做的是完全字串比对(ips.includes(ip)),不支持 CIDR 或通配符。
留空 = 这条规则不生效(后端只在 ips 非空时才拦截)。填了就代表清单外的所有 IP 一律拒绝。
同样是完全字串比对:端点要写请求的 path(例如 /v1/chat/completions),模型要写请求里带的 model 名。
进阶 (JSON)
上面的表单会即时生成这段 JSON;直接改这里也会同步回表单。
这里只列
risk_events 最近的事件(配规则时顺手看一眼)。
要跨三源查、按 IP / 规则 / 请求 ID 精确检索,请到
日志检索 · 风控。
审计日志
这一页记的是
audit_log:
谁改了什么(管理动作留痕)。
使用者的调用 / 风控 / 预审记录是另外三张表,在
日志检索。
账号池健康度
可用率 = account_health 里 source ∈ (relay, probe) 的成功次数 ÷ 观测次数,
只统计选定的时间窗。没有任何观测的账号显示「—」,不是 100% —— 「没量过」跟「量到全通」是两件事。
「探测」发的是一个真实但最小的上游请求(列模型),不建对话、不吃消息额度;
free 类型走浏览器池,探一次等于开一个匿名对话,后端会直接回「不支持探测」。
额度 / 速率水位来自 /api/admin/accounts/limits(lib/account-limits.js)。
三个上限都是真的闸门:取号的四层(用户指派 / 对话亲和 / 团队池 / 全域池)全部过闸,
超额的账号会被硬过滤掉,不是只画成一条进度条。
三态语义:留空 = 不限(预设,也是目前绝大多数账号的状态)、
0 = 明确停用、> 0 = 上限。
没有上限的那一条不画水位,只印实际观测到的用量 ——
画一条 0% 会被读成「用了 0%」,可是「没设上限」根本没有水位这回事。
唯一的例外是并发上限(accounts.max_concurrency):
它留空 = 沿用全域 account_concurrency,不是无限。
那道全域闸门一直在挡,所以留空的账号照样画得出水位(分母取后端一起回的
effective)。把它画成「无上限」会让人以为给某一个账号填值是在收紧,
其实那才是唯一真的改变了行为的动作。
额度的单位是 USD(usage_log.cost)而不是 token:一个池子里同时有
gpt-4o、grok 与 chatgpt-web,把它们的 token 加起来得到的数字既不是钱也不是量。
要按 token 管的是 tpm_limit,那本来就是速率。
防降智那一栏是「上游实际服务的模型」对上「请求的模型」,三态分开算:
model_verified(比对过、一致)/ model_mismatches(比对过、不一致)/
model_unverifiable(这条路拿不到模型身份,或请求的是 auto)。
三栏全是 NULL 时显示「尚未观测」而不是「0 次不一致」 ——
拿一个从来没查过的东西冒充查过了,比不显示更糟。
free 类型走浏览器池只回文字块,结构上就验不了。
封号风险(lib/ban-risk.js)收的是四类目前一笔都没有落库的原始观测,
不是把 consecutive_failures 乘一个系数换个颜色 ——
那个数字这一页早就画着,而且它刻意不含 429 与 CF 403,
可是「被边缘层挡下来」恰恰是封号风险最强的讯号之一。四类是:
拒绝形状(把 last_error 的原文真的分类:
403+HTML 挑战页 / 403 Unusual activity ... from your device /
401 token_invalidated 三者在库里长得一样,处理方式完全相反;
429 与 5xx 权重 0)、
刷新健康(换 token 的成败,以及这次换到的寿命是不是腰斩)、
延迟基线(拿账号自己的历史中位数当对照组,跨账号比只会量到谁挂在哪条代理)、
上游状态(RT 刷新被 401/403 拒 → status = banned)。
四条讯号不是每种账号都观测得到:apikey 永远不刷新 token、
free 连状态码都拿不到。观测不到的记「不适用」,
一条都没观测到的账号分数是「—」而不是 0 分 ——
一个评不了的账号显示成最安全,跟把「无法验证」画成「已验证 ✓」是同一个错误。
每一列都附「观测 n/m」,因为「四条都量过、都干净」跟「只量到一条」不是同一件事。
每一条都是从这一页已经拿到的字段推出来的(可用率、连续失败、自动停用、AT 到期、最后探测时间),没有额外请求、也没有猜测的分数。
| 账号 |
ID |
类型 |
供应商 |
状态 |
可用率 |
观测次数 |
平均延迟 |
连续失败 |
近期观测 |
额度 / 速率水位 |
最后探测 |
最后错误 |
AT 到期 |
防降智 |
封号风险 |
风险信号 |
权重 |
额度上限 (USD) |
RPM / TPM 上限 |
日调用上限 |
并发上限 |
模型范围 |
操作 |
密钥总览
跨用户的密钥治理:额度消耗、日调用限额、IP 与模型白名单、启停、轮替与删除。
清单由 /api/admin/users + 逐个用户的 /api/admin/users/:id/keys 拼出来
—— 后端没有全站密钥列表端点,所以这里看到的用户集合与「用户」页完全相同。
白名单留空 = 不限;allow_ips 一旦有值就代表清单外的来源一律拒绝,
要解除强制就把它清空(后端没有「配置保留但停用」这个状态)。
公告推送
只有 status = active 而且此刻落在时间窗内的公告,才会出现在用户端。
开始 / 结束留空 = 该侧不限;结束早于开始会被后端拒绝(不会静默夹回)。
「已读」数来自 announcement_reads(每人一笔,幂等);已读率的分母是
/api/admin/users 回的用户总数 —— 后端没有「订阅者 / 推送触达」这类计数,这里不编。
维护模式
开启后,/v1/*(/v1/models 除外,它不打上游)、
/api/chat/send 与 WebSocket 转发一律回 503;
登入、后台、/health 与用户端的只读页面不受影响。
文案留空时用后端的预设句子(下面的 placeholder 就是它)。
Retry-After 填 0 = 不带这个标头 ——
有些客户端看到它会自己排程重试,那时候「不给」比「给一个 0」正确。
成长与分润
比例一律是整数百分比:20 = 20%,合法范围 0–100(超范围后端会拒绝,不会静默夹回)。
用户的「专属比例」留空 = 跟随全局,跟设成 0% 是两件不同的事。
累计分润 是历史累计入账,待转出 是还没转进余额的部分;
两者相减就是「已转出」—— 这一页的占比条画的就是这个,没有第三个来源。
推广规模分布
按 user_affiliates.aff_count(已绑定的下线人数)分档统计,档位是固定区间,人数是实际计数。
告警推送
风控规则命中 → 按每个通道的订阅条件异步分发。条件三选:级别门槛(事件级别 ≥ 通道门槛)、
动作白名单、规则类型白名单 —— 三个都留空 = 全收。
Webhook 带 (HMAC-SHA256);密钥永远不会从任何 GET 回传,
编辑时留空 = 保留原密钥,要清空得明确送一个空字串。
防轰炸聚合:同一个(通道 × 规则)在窗口内只送第一条,后续命中并进那一条并累加 ×N。
0 = 关闭聚合。
近 14 天投递趋势
按天分成功 / 失败两段。pending(还在投递中)不计入任何一段,也不进成功率的分母。
模型审计
按模型聚合 usage_log:调用量、错误率、Token 流向、均延迟、涉及用户数与账号数。
异常判定口径:调用 ≥ — 且错误率 ≥ —% → 「错误率偏高」;
均延迟 ≥ — ms → 「延迟偏高」;model_pricing 里没有这个模型 → 「未定价」
(那代表这些调用一律吃 getModelPrice() 的保底单价,是真的漏收)。
缓存命中率只拿「上游真的回报过 cached_tokens」的那几笔算:
分母是那几笔的输入 Token,一笔都没回报过就显示「未回报」而不是 0%
—— ChatGPT 网页那条路根本拿不到 usage,记成 0 会把命中率稀释成一个看起来很低的假数字。
风控命中只数 risk_events.model 非空的事件。这一栏是后来才补的,
所以时间窗若早于开始记录的时刻,栏里会标出「自 … 起」;
记录到了但本来就与模型无关的事件(例如登录端点的 IP 封锁)单独列在下面的未归属里,
不并进任何一个模型的数字。
请求进入转发链路之前先由一个模型评审内容安全。评审跑在**专属引擎**上(本地模型或另一把云端密钥),
不走账号池 —— 池子挂了审计不该跟着挂,审计也不该跟用户抢配额与并发槽。
裁决分三档:< 标记线 安全 → 放行;
[标记线, 拦截线) 争议 → 只记录,不拦;
≥ 拦截线 违规 → 拦。fail_policy 只在
「引擎配好了但挂了」时生效;「还没配引擎」不套 —— 那会把一次升级变成全站拦截。
判定缓存存的是分数不是结论(改阈值立刻生效),TTL 不对称:安全 24 小时、违规 30 天;
fail-open 与启发式的结论一律不进缓存。这张卡的数字全部来自
llm_audit_log,没有任何观测时显示「—」,不显示 0。
审计表不存提示词原文,只存 hash + 一行理由 + 命中类别 —— 一段被判违规的提示词
把正文抄进另一张表本身就是一次外泄。
专属评审引擎 · 主 → 备
任何 OpenAI 相容的 /chat/completions 端点都行:本地 Ollama / vLLM /
llama.cpp,或另一把云端密钥。主引擎失败(含逾时、吐不出 JSON)后按各自的重试次数重试,仍失败就换备用引擎。
预算算术:最坏耗时 = Σ 超时 × (重试 + 1),必须 ≤ 整体预算,否则存不进去;
执行时也带一条硬截止线。参考部署就是在这里爆的 —— 5 秒 × 3 次重试实测 15.6 秒,
撞穿 30 秒的整体预算,每天约 500 笔被拒;他们量了 6 小时,第三次重试救回 22 笔却拖慢 155 笔,于是砍掉。
base_url 绝不能指回本网关自己:那样每一次评审都会再触发一次预审,
一路递归。保存时会挡,执行时还有一道 header 闸。密钥存进去之后任何读取出口都只回遮罩后的尾码。
评审政策 · 改完即生效,不必重启
这是送给评审模型的系统提示词,也就是「什么算越界」的全部定义。保存之后下一笔请求就用新的,
不需要重启进程 —— 每次评审都现读这一列。
出厂那一份管六个维度(违法犯罪 / 危险物品 / 未成年人 / 仇恨骚扰 / 隐私刺探 / 注入越狱)。
要收窄(例如只管网络滥用与深伪色情、纯越狱一律放行)或放宽,都由你自己改;
恢复默认随时把出厂那一份放回来,不必动数据库。
三个键是硬性的:政策必须让模型回
{"score": …, "categories": […], "reason": "…"}。
少讲一个键,模型就不会回这个形状,每一笔判定都解不开 ——
而那种坏法不报错,只会让每一笔请求悄悄退回启发式。所以缺键直接拒绝保存。
保存会作废整批缓存分数(政策变了 = 同一段提示词会得到不同分数)。
下面会印出新旧指纹与这次丢掉了几条 —— 那就是「这次编辑真的生效了」的凭证。
静态校验查不了「模型会不会真的照做」。先用草稿试跑一次再保存,那一路会真的打一次引擎,且完全不碰线上缓存。
裁决与预算
逐日调用分布
调用量前 4 名的模型独立着色,其余合并成「其他」。每一天各段加起来等于当天总调用数。
| 模型 |
定价 |
异常 |
调用构成 |
调用 |
错误率 |
均延迟 |
消耗 |
缓存命中率 |
风控命中 |
输入 → 输出 Token |
用户 / 账号 |
最近调用 |
当前单价 |
操作 |
日志检索
三源合一:usage_log(调用)·risk_events(风控)·llm_audit_log(预审)。
支持 key:value 精准检索与自由词模糊匹配,两者可以混用。
某一源没有的字段会把那一源整个排除,不是「这个条件对它不生效、其余照捞」——
否则 ip:1.2.3.4 这种收窄的手势反而会让结果变多。哪个源被排掉、被哪个字段排掉,都印在下面。
分页跨三张表是精确的:排序键 (时间 ↓, 来源, id ↓) 是全序,所以第 N 页与第 N+1 页不会重叠、也不会跳过任何一列;
总数是三张表各自 COUNT(*) 的和,没有「每源先取 N 笔再合并」的天花板。
req: 单独出现时走精确关联(billing.getTrace),不扫三张表 ——
三张表都有 request_id,所以那是按 id 对上的,不是「同用户 + 同模型 + ±5 秒」凑出来的。
只贴后几码时会落回子串检索。
旧列的 request_id 是 NULL:那些请求发生在开始记录 ID 之前(或本来就没有请求情境)。
所以「查无此 ID」与「那一笔查不回来」会分开讲,还会告诉你有几笔是这种。
这一页不取代「使用记录」(那是 usage_log 的计费视图,有费用明细、栏位开关与 CSV 汇出)、
「风控」(规则 CRUD)、「审计日志」(查的是 audit_log,谁改了什么,根本不是这三源之一)
与「模型审计」(按模型聚合,不是列级检索)。这一页是横着问三张表的入口,那几页是单源深挖的去处。
检索语法 · 来源 × 字段支持矩阵 · 自由词比对哪些栏位
|
时间 | 来源 | 状态 | 摘要 |
用户 | 模型 / 规则 | 请求 ID | 数值 |
| 加载中… |
通知设置
三个渠道:inapp 站内信、email 邮件、webhook。
外部渠道带去重窗口(存 DB 不是内存,重启不会补发)。
订阅明细来自 /api/admin/notify(全站横切的只读聚合)。
Webhook 的签名密钥只回 has_secret,明文不出现在任何回应里。
这一页只读订阅、不代用户改订阅:通知订阅是用户自己的设定,
管理端能治理的是报表排程(下面那张表)。
订阅结构
按事件类型 / 投递渠道统计「有多少条订阅覆盖到它」。一条订阅可以同时订多个事件,所以各类相加会大于订阅总数。
定时报表订阅治理
全站的报表排程。可以暂停 / 恢复 / 立即执行 / 删除 —— 每一个动作都会写进审计日志。
| 拥有者 |
范围 |
频率 |
状态 |
已产出 |
失败 |
下次执行 |
上次结果 |
操作 |
站内通知流水
全站用户最近收到的站内信。这里只读,删除通知是用户自己的权利。
报表
上半部的经营分析来自 /api/admin/billing?days=N(与「计费管理」同源同口径);
下半部的排程与产出来自 /api/admin/reports。
排程的拥有者决定报表寄去哪:报表最终经他的通知订阅送出,所以建立时选的是「谁的报表」,
不是「寄给谁的邮箱」。scope=platform 的平台经营报表只有管理员订得了。
同一条排程、同一个统计周期只会产出一份(UNIQUE(schedule_id, period_start))——
停机三天后重启补的是一笔,不是三笔。
历史产出
每一次真的产出的报表全文都留档 —— 「排程失败」与「排程根本没跑」在事后分得出来。下载支持 txt / csv / json 三种格式。
| 产出时间 |
标题 |
范围 |
周期 |
调用 |
Token |
费用 |
状态 |
下载 |