relay-audit 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- relay_audit-2.3.0/LICENSE +21 -0
- relay_audit-2.3.0/PKG-INFO +301 -0
- relay_audit-2.3.0/README.md +279 -0
- relay_audit-2.3.0/pyproject.toml +57 -0
- relay_audit-2.3.0/relay_audit/__init__.py +136 -0
- relay_audit-2.3.0/relay_audit/__main__.py +6 -0
- relay_audit-2.3.0/relay_audit/_version.py +3 -0
- relay_audit-2.3.0/relay_audit/analysis.py +660 -0
- relay_audit-2.3.0/relay_audit/calibrate.py +286 -0
- relay_audit-2.3.0/relay_audit/cli.py +628 -0
- relay_audit-2.3.0/relay_audit/client.py +317 -0
- relay_audit-2.3.0/relay_audit/models.py +173 -0
- relay_audit-2.3.0/relay_audit/patterns.py +208 -0
- relay_audit-2.3.0/relay_audit/reporter.py +808 -0
- relay_audit-2.3.0/relay_audit/scanner.py +757 -0
- relay_audit-2.3.0/relay_audit/serve.py +389 -0
- relay_audit-2.3.0/relay_audit.egg-info/PKG-INFO +301 -0
- relay_audit-2.3.0/relay_audit.egg-info/SOURCES.txt +33 -0
- relay_audit-2.3.0/relay_audit.egg-info/dependency_links.txt +1 -0
- relay_audit-2.3.0/relay_audit.egg-info/entry_points.txt +3 -0
- relay_audit-2.3.0/relay_audit.egg-info/requires.txt +9 -0
- relay_audit-2.3.0/relay_audit.egg-info/top_level.txt +1 -0
- relay_audit-2.3.0/setup.cfg +4 -0
- relay_audit-2.3.0/tests/test_analysis.py +526 -0
- relay_audit-2.3.0/tests/test_calibrate.py +284 -0
- relay_audit-2.3.0/tests/test_cli.py +1001 -0
- relay_audit-2.3.0/tests/test_client.py +442 -0
- relay_audit-2.3.0/tests/test_e2e.py +237 -0
- relay_audit-2.3.0/tests/test_models.py +171 -0
- relay_audit-2.3.0/tests/test_package.py +63 -0
- relay_audit-2.3.0/tests/test_patterns.py +125 -0
- relay_audit-2.3.0/tests/test_reporter.py +386 -0
- relay_audit-2.3.0/tests/test_scanner.py +466 -0
- relay_audit-2.3.0/tests/test_scanner_run.py +381 -0
- relay_audit-2.3.0/tests/test_serve.py +381 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 relay-audit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: relay-audit
|
|
3
|
+
Version: 2.3.0
|
|
4
|
+
Summary: OpenAI-compatible 中转 API 检测工具 — 安全、质量、身份验证审计
|
|
5
|
+
Author: relay-audit contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xiaomaozjj666/relay-audit
|
|
8
|
+
Project-URL: Repository, https://github.com/xiaomaozjj666/relay-audit
|
|
9
|
+
Project-URL: Issues, https://github.com/xiaomaozjj666/relay-audit/issues
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
14
|
+
Requires-Dist: rich<14.0,>=13.0
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest<9,>=8.0; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
18
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
|
|
19
|
+
Requires-Dist: ruff<0.16,>=0.15; extra == "dev"
|
|
20
|
+
Requires-Dist: mypy<2,>=1.10; extra == "dev"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# Relay Audit
|
|
24
|
+
|
|
25
|
+
<p align="center">
|
|
26
|
+
<img src="https://img.shields.io/badge/Python-3.10%2B-3776AB" alt="Python 3.10+" />
|
|
27
|
+
<img src="https://img.shields.io/badge/httpx-async-0F6B9E" alt="httpx" />
|
|
28
|
+
<img src="https://img.shields.io/badge/rich-terminal-FFC300" alt="rich" />
|
|
29
|
+
<img src="https://img.shields.io/badge/tests-pytest-brightgreen" alt="pytest" />
|
|
30
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" />
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
**OpenAI 兼容中转 API 安全与质量检测工具** — 提供 API Key 和地址即可完成中转服务的安全审计、身份验证、质量检测与性能评估,并生成可视化报告。
|
|
34
|
+
|
|
35
|
+
买第三方中转 API 之前先跑一遍,自建中转站也可以拿来日常巡检。
|
|
36
|
+
|
|
37
|
+
## 检测流程
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart LR
|
|
41
|
+
A["输入 base-url + API Key"] --> B["自动获取模型列表<br/>挑选最强模型"]
|
|
42
|
+
B --> C["身份与真实性"]
|
|
43
|
+
B --> D["安全审计"]
|
|
44
|
+
B --> E["质量检测"]
|
|
45
|
+
B --> F["性能评估"]
|
|
46
|
+
C --> G["20+ 项检测 · 6 大类别"]
|
|
47
|
+
D --> G
|
|
48
|
+
E --> G
|
|
49
|
+
F --> G
|
|
50
|
+
G --> H{"风险判定"}
|
|
51
|
+
H --> I["彩色终端报告"]
|
|
52
|
+
H --> J["HTML 可视化报告<br/>风险等级 · 评分 · 通过率"]
|
|
53
|
+
H --> K["JSON 结构化输出"]
|
|
54
|
+
I --> L["历史报告浏览<br/>--serve 本地 Web 服务"]
|
|
55
|
+
J --> L
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 示例报告
|
|
59
|
+
|
|
60
|
+
对本地 mock 服务(模拟真实中转站)跑完整扫描生成的报告界面——风险等级、评分、通过率、关键问题与失败测试一目了然:
|
|
61
|
+
|
|
62
|
+
| HTML 可视化报告(低风险样例) |
|
|
63
|
+
| :---: |
|
|
64
|
+
| <img src="docs/screenshots/report-sample.png" alt="Relay Audit 示例报告" width="820" /> |
|
|
65
|
+
|
|
66
|
+
## 功能特性
|
|
67
|
+
|
|
68
|
+
- **一条命令检测** — 仅需 `--base-url` 和 API Key;未指定模型时自动获取模型列表并挑选最强模型,交互模式(零参数启动)可自动并发检测 3 个最强模型
|
|
69
|
+
- **身份与真实性** — 模型偷换检测、身份识别探针、知识截止日期验证、模型综合指纹、模型列表一致性、可疑/非标准模型名识别
|
|
70
|
+
- **安全审计** — System Prompt 完整性(随请求注入 canary 标记,检测系统消息被篡改或内容泄露)、危险内容拒答检测(破坏性删除、Cookie 窃取、勒索软件、反向 Shell、SQL 注入),结合危险内容模式与拒答模式双重判定
|
|
71
|
+
- **质量检测** — 基础对话、指令遵循、多轮对话、长上下文、编码一致性、乱码检测、Token 计费校验;JSON 模式与 Function Calling 失败时自动降级为纯文本重试
|
|
72
|
+
- **性能评估** — 延迟统计(p50 / 抖动;样本充足时含 p95 / p99)、稳定性采样、并发突发测试、流式响应(SSE)测试与首字延迟(TTFT)测量
|
|
73
|
+
- **模型对比** — `--compare` 并排对比多个模型的真实身份与响应
|
|
74
|
+
- **报告输出** — 彩色终端报告(rich)、HTML 报告(风险等级、评分、通过率、改进建议)、JSON 输出,扫描结果自动持久化到报告目录(Windows `%LOCALAPPDATA%\relay-audit\reports`,Linux/macOS `~/.relay_audit/reports`,可用环境变量 `RELAY_AUDIT_REPORTS_DIR` 覆盖;默认自动清理 7 天前的旧报告,`RELAY_AUDIT_REPORT_TTL_DAYS=0` 可关闭)。报告携带探针套件版本号,不同时间的扫描结果可复现、可对比
|
|
75
|
+
- **历史报告浏览** — 内置本地 Web 服务器,在浏览器中浏览往期 HTML / JSON 扫描报告
|
|
76
|
+
- **隐私与安全** — 报告与日志中 API Key 自动脱敏;`--save-key` 以受限权限(Linux/macOS `0o600`,Windows 经 `icacls`)保存在本地
|
|
77
|
+
|
|
78
|
+
## 技术栈
|
|
79
|
+
|
|
80
|
+
- **Python 3.10+**
|
|
81
|
+
- **httpx** — 异步 HTTP 客户端(连接池、指数退避重试、SSE 流式解析)
|
|
82
|
+
- **rich** — 终端富文本渲染
|
|
83
|
+
- **Python 标准库** `http.server` — 报告浏览服务器
|
|
84
|
+
- **开发 / CI** — pytest、pytest-asyncio、ruff、mypy,GitHub Actions 自动执行 lint 与测试
|
|
85
|
+
|
|
86
|
+
## 安装与运行
|
|
87
|
+
|
|
88
|
+
推荐从源码安装:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/xiaomaozjj666/relay-audit.git
|
|
92
|
+
cd relay-audit
|
|
93
|
+
python -m pip install -e .
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
若已发布到 PyPI,也可直接 `pip install relay-audit`。
|
|
97
|
+
|
|
98
|
+
### 最简用法
|
|
99
|
+
|
|
100
|
+
设置环境变量后直接运行(自动选择最强模型):
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Windows
|
|
104
|
+
set RELAY_API_KEY=<your-key>
|
|
105
|
+
relay-audit --base-url https://api.example.com
|
|
106
|
+
|
|
107
|
+
# Linux / macOS
|
|
108
|
+
export RELAY_API_KEY=<your-key>
|
|
109
|
+
relay-audit --base-url https://api.example.com
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 交互模式(零参数启动)
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
relay-audit
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
按提示输入 Key(**掩码显示,不回显明文**)和地址,工具会自动获取模型列表并选择最强的 3 个模型并发检测。检测前可确认或挑选模型:直接回车全部检测,或输入序号(如 `1,2`)、模型名(如 `claude` 模糊匹配)筛选。
|
|
119
|
+
|
|
120
|
+
Windows 下也可直接运行仓库中的 `relay_audit.bat`。
|
|
121
|
+
|
|
122
|
+
### 退出码
|
|
123
|
+
|
|
124
|
+
| 退出码 | 含义 |
|
|
125
|
+
|--------|------|
|
|
126
|
+
| `0` | 扫描完成,未发现高危问题 |
|
|
127
|
+
| `1` | 扫描完成,发现高危问题 |
|
|
128
|
+
| `2` | 参数或 API Key 错误 |
|
|
129
|
+
| `130` | 用户取消(Ctrl+C) |
|
|
130
|
+
|
|
131
|
+
> 扫描过程实时输出每项测试的进度(`[OK]` / `[x ]` + 延迟),长扫描无需干等。
|
|
132
|
+
|
|
133
|
+
## 使用示例
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# 指定模型检测
|
|
137
|
+
relay-audit --base-url https://api.example.com --model claude-opus-4-6
|
|
138
|
+
|
|
139
|
+
# 只看模型列表
|
|
140
|
+
relay-audit --base-url https://api.example.com --models
|
|
141
|
+
|
|
142
|
+
# 快速模式(跳过部分高级测试)
|
|
143
|
+
relay-audit --quick --base-url https://api.example.com
|
|
144
|
+
|
|
145
|
+
# 流式响应测试
|
|
146
|
+
relay-audit --stream --base-url https://api.example.com
|
|
147
|
+
|
|
148
|
+
# 启用 JSON 输出
|
|
149
|
+
relay-audit --json --base-url https://api.example.com
|
|
150
|
+
|
|
151
|
+
# 保存 Key 到本地以便下次自动读取
|
|
152
|
+
relay-audit --key <your-key> --save-key
|
|
153
|
+
|
|
154
|
+
# 对比多个模型
|
|
155
|
+
relay-audit --base-url https://api.example.com --model gpt-4o --compare claude-opus-4-6
|
|
156
|
+
|
|
157
|
+
# 指定输出报告路径
|
|
158
|
+
relay-audit --base-url https://api.example.com --output report.html
|
|
159
|
+
|
|
160
|
+
# 启动报告浏览服务器(浏览历史扫描结果)
|
|
161
|
+
relay-audit --serve 8080
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 命令行参数
|
|
165
|
+
|
|
166
|
+
| 参数 | 说明 | 默认值 |
|
|
167
|
+
|------|------|--------|
|
|
168
|
+
| `--base-url` | API 端点地址 | 必填 |
|
|
169
|
+
| `--model` | 指定检测模型 | 自动选择 |
|
|
170
|
+
| `--key` | API Key(优先于环境变量) | - |
|
|
171
|
+
| `--api-key-env` | Key 环境变量名 | `RELAY_API_KEY` |
|
|
172
|
+
| `--timeout` | 请求超时秒数 | 60 |
|
|
173
|
+
| `--samples` | 稳定性采样次数 | 2 |
|
|
174
|
+
| `--compare` | 对比模型(可多次使用) | - |
|
|
175
|
+
| `--quick` | 快速模式(跳过部分高级测试) | `false` |
|
|
176
|
+
| `--stream` | 启用流式响应测试 | `false` |
|
|
177
|
+
| `--json` | 输出 JSON 格式结果 | `false` |
|
|
178
|
+
| `--output` | 报告输出路径 | 自动生成 |
|
|
179
|
+
| `--no-html` | 不生成 HTML 报告 | `false` |
|
|
180
|
+
| `--skip-safety` | 跳过安全测试 | `false` |
|
|
181
|
+
| `--config` | JSON 配置文件路径 | - |
|
|
182
|
+
| `--save-key` | 保存 Key 到本地 | `false` |
|
|
183
|
+
| `--models` / `--list-models` | 只展示模型列表,不跑测试 | `false` |
|
|
184
|
+
| `--serve [PORT]` | 启动报告浏览服务器 | 8080 |
|
|
185
|
+
|
|
186
|
+
> 注意:`--save-key` 将 API Key **明文**保存在 `~/.relay_key`。工具会收紧该文件权限
|
|
187
|
+
> (Linux/macOS 为 `0o600`,Windows 通过 `icacls` 仅授权当前用户),但不加密内容——
|
|
188
|
+
> 共享机器上请慎用,或改用环境变量。
|
|
189
|
+
|
|
190
|
+
## 配置
|
|
191
|
+
|
|
192
|
+
### 环境变量
|
|
193
|
+
|
|
194
|
+
| 变量 | 说明 |
|
|
195
|
+
|------|------|
|
|
196
|
+
| `RELAY_API_KEY` | API Key(也可用 `--key` 或 `--save-key` 提供) |
|
|
197
|
+
| `RELAY_AUDIT_REPORTS_DIR` | 报告目录(默认 Windows `%LOCALAPPDATA%\relay-audit\reports`,Linux/macOS `~/.relay_audit/reports`) |
|
|
198
|
+
| `RELAY_AUDIT_REPORT_TTL_DAYS` | 旧报告自动清理天数(默认 7,设 `0` 表示永不清理) |
|
|
199
|
+
|
|
200
|
+
如需使用其他环境变量名,通过 `--api-key-env <NAME>` 指定。
|
|
201
|
+
|
|
202
|
+
### 配置文件
|
|
203
|
+
|
|
204
|
+
支持 JSON 配置文件(通过 `--config` 指定):
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"base_url": "https://api.example.com",
|
|
209
|
+
"model": "claude-opus-4-6",
|
|
210
|
+
"timeout": 60,
|
|
211
|
+
"samples": 3,
|
|
212
|
+
"quick": false,
|
|
213
|
+
"stream": false
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 检测项目
|
|
218
|
+
|
|
219
|
+
完整扫描(默认非快速模式)共 20+ 项检测,覆盖 6 大类别:
|
|
220
|
+
|
|
221
|
+
| 类别 | 检测内容 |
|
|
222
|
+
|------|----------|
|
|
223
|
+
| 安全 | System Prompt 完整性(canary 注入)、危险内容拒答(破坏性删除 / Cookie 窃取 / 勒索软件 / 反向 Shell / SQL 注入) |
|
|
224
|
+
| 身份 | 模型身份识别、模型偷换检测、知识截止日期验证、模型指纹、模型列表一致性 |
|
|
225
|
+
| 质量 | 基础对话、指令遵循、编码一致性、JSON 模式、Function Calling、多轮对话、长上下文、Token 计费校验、乱码检测 |
|
|
226
|
+
| 性能 | 延迟统计(p50 / 抖动;样本 ≥20 时含 p95 / p99)、并发突发测试、稳定性采样、流式首字延迟(TTFT) |
|
|
227
|
+
| 模型 | 可疑模型名检测、多供应商聚合识别、大小写重复检测 |
|
|
228
|
+
| 通用 | 代理 / CDN 特征检测、响应头分析、错误模式识别 |
|
|
229
|
+
|
|
230
|
+
> 探针提示与判定规则统称为「探针套件」,以 `relay_audit.scanner.PROBE_SUITE_VERSION` 标识版本并写入每份报告;修改探针时需递增该版本号。
|
|
231
|
+
|
|
232
|
+
## 检测有效性校准
|
|
233
|
+
|
|
234
|
+
检测结论的可信度需要用已知底细的目标来验证。内置校准工具:对一组已知真实情况(是否应触发高危)的中转站批量扫描,输出混淆矩阵与精确率/召回率,把严重等级从经验值校准为实证值。
|
|
235
|
+
|
|
236
|
+
1. 准备目标清单 `targets.json`:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
[
|
|
240
|
+
{"name": "直连官方", "base_url": "https://api.example.com",
|
|
241
|
+
"api_key": "sk-...", "label": "no_high", "note": "官方 API,不应有高危"},
|
|
242
|
+
{"name": "偷换站A", "base_url": "https://relay.example.com",
|
|
243
|
+
"api_key": "sk-...", "label": "high", "model": "gpt-4o",
|
|
244
|
+
"note": "已知 gpt-4o 被换成小模型"}
|
|
245
|
+
]
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
2. 运行(报告默认写入 `<报告目录>/calibration/`):
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
relay-audit-calibrate targets.json # 或 python -m relay_audit.calibrate targets.json
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
3. 查看 `calibration_*.md`(混淆矩阵、精确率/召回率、每目标明细)与每目标原始 JSON。
|
|
255
|
+
|
|
256
|
+
退出码:`0` 判定全部与真实情况一致;`1` 存在误报/漏报;`2` 有目标扫描失败或清单无效。
|
|
257
|
+
|
|
258
|
+
## 项目结构
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
relay_audit/
|
|
262
|
+
├── __init__.py # 包入口与版本信息
|
|
263
|
+
├── __main__.py # python -m relay_audit 入口
|
|
264
|
+
├── cli.py # 命令行入口 & 交互模式
|
|
265
|
+
├── models.py # 数据类型定义
|
|
266
|
+
├── patterns.py # 检测模式与常量定义
|
|
267
|
+
├── analysis.py # 分析检测逻辑(错误诊断、稳定性、并发等)
|
|
268
|
+
├── client.py # OpenAI API 异步客户端
|
|
269
|
+
├── scanner.py # 测试编排与执行
|
|
270
|
+
├── calibrate.py # 检测有效性校准(混淆矩阵 / 精确率 / 召回率)
|
|
271
|
+
├── reporter.py # 报告生成(HTML / 终端 / JSON)
|
|
272
|
+
└── serve.py # 报告浏览 Web 服务器
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 开发
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# 安装开发依赖
|
|
279
|
+
python -m pip install -r requirements-dev.txt
|
|
280
|
+
|
|
281
|
+
# 本地安装
|
|
282
|
+
python -m pip install -e .
|
|
283
|
+
|
|
284
|
+
# 运行测试
|
|
285
|
+
pytest tests/ -v
|
|
286
|
+
|
|
287
|
+
# 代码检查
|
|
288
|
+
ruff check .
|
|
289
|
+
ruff format --check .
|
|
290
|
+
mypy relay_audit
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## 许可证
|
|
294
|
+
|
|
295
|
+
[MIT License](LICENSE)
|
|
296
|
+
|
|
297
|
+
## 文档
|
|
298
|
+
|
|
299
|
+
- [English Documentation](README.en.md)
|
|
300
|
+
- [更新日志](CHANGELOG.md)
|
|
301
|
+
- [参与贡献](CONTRIBUTING.md)
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Relay Audit
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://img.shields.io/badge/Python-3.10%2B-3776AB" alt="Python 3.10+" />
|
|
5
|
+
<img src="https://img.shields.io/badge/httpx-async-0F6B9E" alt="httpx" />
|
|
6
|
+
<img src="https://img.shields.io/badge/rich-terminal-FFC300" alt="rich" />
|
|
7
|
+
<img src="https://img.shields.io/badge/tests-pytest-brightgreen" alt="pytest" />
|
|
8
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" />
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
**OpenAI 兼容中转 API 安全与质量检测工具** — 提供 API Key 和地址即可完成中转服务的安全审计、身份验证、质量检测与性能评估,并生成可视化报告。
|
|
12
|
+
|
|
13
|
+
买第三方中转 API 之前先跑一遍,自建中转站也可以拿来日常巡检。
|
|
14
|
+
|
|
15
|
+
## 检测流程
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart LR
|
|
19
|
+
A["输入 base-url + API Key"] --> B["自动获取模型列表<br/>挑选最强模型"]
|
|
20
|
+
B --> C["身份与真实性"]
|
|
21
|
+
B --> D["安全审计"]
|
|
22
|
+
B --> E["质量检测"]
|
|
23
|
+
B --> F["性能评估"]
|
|
24
|
+
C --> G["20+ 项检测 · 6 大类别"]
|
|
25
|
+
D --> G
|
|
26
|
+
E --> G
|
|
27
|
+
F --> G
|
|
28
|
+
G --> H{"风险判定"}
|
|
29
|
+
H --> I["彩色终端报告"]
|
|
30
|
+
H --> J["HTML 可视化报告<br/>风险等级 · 评分 · 通过率"]
|
|
31
|
+
H --> K["JSON 结构化输出"]
|
|
32
|
+
I --> L["历史报告浏览<br/>--serve 本地 Web 服务"]
|
|
33
|
+
J --> L
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 示例报告
|
|
37
|
+
|
|
38
|
+
对本地 mock 服务(模拟真实中转站)跑完整扫描生成的报告界面——风险等级、评分、通过率、关键问题与失败测试一目了然:
|
|
39
|
+
|
|
40
|
+
| HTML 可视化报告(低风险样例) |
|
|
41
|
+
| :---: |
|
|
42
|
+
| <img src="docs/screenshots/report-sample.png" alt="Relay Audit 示例报告" width="820" /> |
|
|
43
|
+
|
|
44
|
+
## 功能特性
|
|
45
|
+
|
|
46
|
+
- **一条命令检测** — 仅需 `--base-url` 和 API Key;未指定模型时自动获取模型列表并挑选最强模型,交互模式(零参数启动)可自动并发检测 3 个最强模型
|
|
47
|
+
- **身份与真实性** — 模型偷换检测、身份识别探针、知识截止日期验证、模型综合指纹、模型列表一致性、可疑/非标准模型名识别
|
|
48
|
+
- **安全审计** — System Prompt 完整性(随请求注入 canary 标记,检测系统消息被篡改或内容泄露)、危险内容拒答检测(破坏性删除、Cookie 窃取、勒索软件、反向 Shell、SQL 注入),结合危险内容模式与拒答模式双重判定
|
|
49
|
+
- **质量检测** — 基础对话、指令遵循、多轮对话、长上下文、编码一致性、乱码检测、Token 计费校验;JSON 模式与 Function Calling 失败时自动降级为纯文本重试
|
|
50
|
+
- **性能评估** — 延迟统计(p50 / 抖动;样本充足时含 p95 / p99)、稳定性采样、并发突发测试、流式响应(SSE)测试与首字延迟(TTFT)测量
|
|
51
|
+
- **模型对比** — `--compare` 并排对比多个模型的真实身份与响应
|
|
52
|
+
- **报告输出** — 彩色终端报告(rich)、HTML 报告(风险等级、评分、通过率、改进建议)、JSON 输出,扫描结果自动持久化到报告目录(Windows `%LOCALAPPDATA%\relay-audit\reports`,Linux/macOS `~/.relay_audit/reports`,可用环境变量 `RELAY_AUDIT_REPORTS_DIR` 覆盖;默认自动清理 7 天前的旧报告,`RELAY_AUDIT_REPORT_TTL_DAYS=0` 可关闭)。报告携带探针套件版本号,不同时间的扫描结果可复现、可对比
|
|
53
|
+
- **历史报告浏览** — 内置本地 Web 服务器,在浏览器中浏览往期 HTML / JSON 扫描报告
|
|
54
|
+
- **隐私与安全** — 报告与日志中 API Key 自动脱敏;`--save-key` 以受限权限(Linux/macOS `0o600`,Windows 经 `icacls`)保存在本地
|
|
55
|
+
|
|
56
|
+
## 技术栈
|
|
57
|
+
|
|
58
|
+
- **Python 3.10+**
|
|
59
|
+
- **httpx** — 异步 HTTP 客户端(连接池、指数退避重试、SSE 流式解析)
|
|
60
|
+
- **rich** — 终端富文本渲染
|
|
61
|
+
- **Python 标准库** `http.server` — 报告浏览服务器
|
|
62
|
+
- **开发 / CI** — pytest、pytest-asyncio、ruff、mypy,GitHub Actions 自动执行 lint 与测试
|
|
63
|
+
|
|
64
|
+
## 安装与运行
|
|
65
|
+
|
|
66
|
+
推荐从源码安装:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/xiaomaozjj666/relay-audit.git
|
|
70
|
+
cd relay-audit
|
|
71
|
+
python -m pip install -e .
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
若已发布到 PyPI,也可直接 `pip install relay-audit`。
|
|
75
|
+
|
|
76
|
+
### 最简用法
|
|
77
|
+
|
|
78
|
+
设置环境变量后直接运行(自动选择最强模型):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Windows
|
|
82
|
+
set RELAY_API_KEY=<your-key>
|
|
83
|
+
relay-audit --base-url https://api.example.com
|
|
84
|
+
|
|
85
|
+
# Linux / macOS
|
|
86
|
+
export RELAY_API_KEY=<your-key>
|
|
87
|
+
relay-audit --base-url https://api.example.com
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 交互模式(零参数启动)
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
relay-audit
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
按提示输入 Key(**掩码显示,不回显明文**)和地址,工具会自动获取模型列表并选择最强的 3 个模型并发检测。检测前可确认或挑选模型:直接回车全部检测,或输入序号(如 `1,2`)、模型名(如 `claude` 模糊匹配)筛选。
|
|
97
|
+
|
|
98
|
+
Windows 下也可直接运行仓库中的 `relay_audit.bat`。
|
|
99
|
+
|
|
100
|
+
### 退出码
|
|
101
|
+
|
|
102
|
+
| 退出码 | 含义 |
|
|
103
|
+
|--------|------|
|
|
104
|
+
| `0` | 扫描完成,未发现高危问题 |
|
|
105
|
+
| `1` | 扫描完成,发现高危问题 |
|
|
106
|
+
| `2` | 参数或 API Key 错误 |
|
|
107
|
+
| `130` | 用户取消(Ctrl+C) |
|
|
108
|
+
|
|
109
|
+
> 扫描过程实时输出每项测试的进度(`[OK]` / `[x ]` + 延迟),长扫描无需干等。
|
|
110
|
+
|
|
111
|
+
## 使用示例
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# 指定模型检测
|
|
115
|
+
relay-audit --base-url https://api.example.com --model claude-opus-4-6
|
|
116
|
+
|
|
117
|
+
# 只看模型列表
|
|
118
|
+
relay-audit --base-url https://api.example.com --models
|
|
119
|
+
|
|
120
|
+
# 快速模式(跳过部分高级测试)
|
|
121
|
+
relay-audit --quick --base-url https://api.example.com
|
|
122
|
+
|
|
123
|
+
# 流式响应测试
|
|
124
|
+
relay-audit --stream --base-url https://api.example.com
|
|
125
|
+
|
|
126
|
+
# 启用 JSON 输出
|
|
127
|
+
relay-audit --json --base-url https://api.example.com
|
|
128
|
+
|
|
129
|
+
# 保存 Key 到本地以便下次自动读取
|
|
130
|
+
relay-audit --key <your-key> --save-key
|
|
131
|
+
|
|
132
|
+
# 对比多个模型
|
|
133
|
+
relay-audit --base-url https://api.example.com --model gpt-4o --compare claude-opus-4-6
|
|
134
|
+
|
|
135
|
+
# 指定输出报告路径
|
|
136
|
+
relay-audit --base-url https://api.example.com --output report.html
|
|
137
|
+
|
|
138
|
+
# 启动报告浏览服务器(浏览历史扫描结果)
|
|
139
|
+
relay-audit --serve 8080
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 命令行参数
|
|
143
|
+
|
|
144
|
+
| 参数 | 说明 | 默认值 |
|
|
145
|
+
|------|------|--------|
|
|
146
|
+
| `--base-url` | API 端点地址 | 必填 |
|
|
147
|
+
| `--model` | 指定检测模型 | 自动选择 |
|
|
148
|
+
| `--key` | API Key(优先于环境变量) | - |
|
|
149
|
+
| `--api-key-env` | Key 环境变量名 | `RELAY_API_KEY` |
|
|
150
|
+
| `--timeout` | 请求超时秒数 | 60 |
|
|
151
|
+
| `--samples` | 稳定性采样次数 | 2 |
|
|
152
|
+
| `--compare` | 对比模型(可多次使用) | - |
|
|
153
|
+
| `--quick` | 快速模式(跳过部分高级测试) | `false` |
|
|
154
|
+
| `--stream` | 启用流式响应测试 | `false` |
|
|
155
|
+
| `--json` | 输出 JSON 格式结果 | `false` |
|
|
156
|
+
| `--output` | 报告输出路径 | 自动生成 |
|
|
157
|
+
| `--no-html` | 不生成 HTML 报告 | `false` |
|
|
158
|
+
| `--skip-safety` | 跳过安全测试 | `false` |
|
|
159
|
+
| `--config` | JSON 配置文件路径 | - |
|
|
160
|
+
| `--save-key` | 保存 Key 到本地 | `false` |
|
|
161
|
+
| `--models` / `--list-models` | 只展示模型列表,不跑测试 | `false` |
|
|
162
|
+
| `--serve [PORT]` | 启动报告浏览服务器 | 8080 |
|
|
163
|
+
|
|
164
|
+
> 注意:`--save-key` 将 API Key **明文**保存在 `~/.relay_key`。工具会收紧该文件权限
|
|
165
|
+
> (Linux/macOS 为 `0o600`,Windows 通过 `icacls` 仅授权当前用户),但不加密内容——
|
|
166
|
+
> 共享机器上请慎用,或改用环境变量。
|
|
167
|
+
|
|
168
|
+
## 配置
|
|
169
|
+
|
|
170
|
+
### 环境变量
|
|
171
|
+
|
|
172
|
+
| 变量 | 说明 |
|
|
173
|
+
|------|------|
|
|
174
|
+
| `RELAY_API_KEY` | API Key(也可用 `--key` 或 `--save-key` 提供) |
|
|
175
|
+
| `RELAY_AUDIT_REPORTS_DIR` | 报告目录(默认 Windows `%LOCALAPPDATA%\relay-audit\reports`,Linux/macOS `~/.relay_audit/reports`) |
|
|
176
|
+
| `RELAY_AUDIT_REPORT_TTL_DAYS` | 旧报告自动清理天数(默认 7,设 `0` 表示永不清理) |
|
|
177
|
+
|
|
178
|
+
如需使用其他环境变量名,通过 `--api-key-env <NAME>` 指定。
|
|
179
|
+
|
|
180
|
+
### 配置文件
|
|
181
|
+
|
|
182
|
+
支持 JSON 配置文件(通过 `--config` 指定):
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"base_url": "https://api.example.com",
|
|
187
|
+
"model": "claude-opus-4-6",
|
|
188
|
+
"timeout": 60,
|
|
189
|
+
"samples": 3,
|
|
190
|
+
"quick": false,
|
|
191
|
+
"stream": false
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 检测项目
|
|
196
|
+
|
|
197
|
+
完整扫描(默认非快速模式)共 20+ 项检测,覆盖 6 大类别:
|
|
198
|
+
|
|
199
|
+
| 类别 | 检测内容 |
|
|
200
|
+
|------|----------|
|
|
201
|
+
| 安全 | System Prompt 完整性(canary 注入)、危险内容拒答(破坏性删除 / Cookie 窃取 / 勒索软件 / 反向 Shell / SQL 注入) |
|
|
202
|
+
| 身份 | 模型身份识别、模型偷换检测、知识截止日期验证、模型指纹、模型列表一致性 |
|
|
203
|
+
| 质量 | 基础对话、指令遵循、编码一致性、JSON 模式、Function Calling、多轮对话、长上下文、Token 计费校验、乱码检测 |
|
|
204
|
+
| 性能 | 延迟统计(p50 / 抖动;样本 ≥20 时含 p95 / p99)、并发突发测试、稳定性采样、流式首字延迟(TTFT) |
|
|
205
|
+
| 模型 | 可疑模型名检测、多供应商聚合识别、大小写重复检测 |
|
|
206
|
+
| 通用 | 代理 / CDN 特征检测、响应头分析、错误模式识别 |
|
|
207
|
+
|
|
208
|
+
> 探针提示与判定规则统称为「探针套件」,以 `relay_audit.scanner.PROBE_SUITE_VERSION` 标识版本并写入每份报告;修改探针时需递增该版本号。
|
|
209
|
+
|
|
210
|
+
## 检测有效性校准
|
|
211
|
+
|
|
212
|
+
检测结论的可信度需要用已知底细的目标来验证。内置校准工具:对一组已知真实情况(是否应触发高危)的中转站批量扫描,输出混淆矩阵与精确率/召回率,把严重等级从经验值校准为实证值。
|
|
213
|
+
|
|
214
|
+
1. 准备目标清单 `targets.json`:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
[
|
|
218
|
+
{"name": "直连官方", "base_url": "https://api.example.com",
|
|
219
|
+
"api_key": "sk-...", "label": "no_high", "note": "官方 API,不应有高危"},
|
|
220
|
+
{"name": "偷换站A", "base_url": "https://relay.example.com",
|
|
221
|
+
"api_key": "sk-...", "label": "high", "model": "gpt-4o",
|
|
222
|
+
"note": "已知 gpt-4o 被换成小模型"}
|
|
223
|
+
]
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
2. 运行(报告默认写入 `<报告目录>/calibration/`):
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
relay-audit-calibrate targets.json # 或 python -m relay_audit.calibrate targets.json
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
3. 查看 `calibration_*.md`(混淆矩阵、精确率/召回率、每目标明细)与每目标原始 JSON。
|
|
233
|
+
|
|
234
|
+
退出码:`0` 判定全部与真实情况一致;`1` 存在误报/漏报;`2` 有目标扫描失败或清单无效。
|
|
235
|
+
|
|
236
|
+
## 项目结构
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
relay_audit/
|
|
240
|
+
├── __init__.py # 包入口与版本信息
|
|
241
|
+
├── __main__.py # python -m relay_audit 入口
|
|
242
|
+
├── cli.py # 命令行入口 & 交互模式
|
|
243
|
+
├── models.py # 数据类型定义
|
|
244
|
+
├── patterns.py # 检测模式与常量定义
|
|
245
|
+
├── analysis.py # 分析检测逻辑(错误诊断、稳定性、并发等)
|
|
246
|
+
├── client.py # OpenAI API 异步客户端
|
|
247
|
+
├── scanner.py # 测试编排与执行
|
|
248
|
+
├── calibrate.py # 检测有效性校准(混淆矩阵 / 精确率 / 召回率)
|
|
249
|
+
├── reporter.py # 报告生成(HTML / 终端 / JSON)
|
|
250
|
+
└── serve.py # 报告浏览 Web 服务器
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## 开发
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# 安装开发依赖
|
|
257
|
+
python -m pip install -r requirements-dev.txt
|
|
258
|
+
|
|
259
|
+
# 本地安装
|
|
260
|
+
python -m pip install -e .
|
|
261
|
+
|
|
262
|
+
# 运行测试
|
|
263
|
+
pytest tests/ -v
|
|
264
|
+
|
|
265
|
+
# 代码检查
|
|
266
|
+
ruff check .
|
|
267
|
+
ruff format --check .
|
|
268
|
+
mypy relay_audit
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 许可证
|
|
272
|
+
|
|
273
|
+
[MIT License](LICENSE)
|
|
274
|
+
|
|
275
|
+
## 文档
|
|
276
|
+
|
|
277
|
+
- [English Documentation](README.en.md)
|
|
278
|
+
- [更新日志](CHANGELOG.md)
|
|
279
|
+
- [参与贡献](CONTRIBUTING.md)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "relay-audit"
|
|
7
|
+
version = "2.3.0"
|
|
8
|
+
description = "OpenAI-compatible 中转 API 检测工具 — 安全、质量、身份验证审计"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [{ name = "relay-audit contributors" }]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.27,<1.0",
|
|
15
|
+
"rich>=13.0,<14.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
dev = [
|
|
20
|
+
"pytest>=8.0,<9",
|
|
21
|
+
"pytest-cov>=5.0",
|
|
22
|
+
"pytest-asyncio>=0.24",
|
|
23
|
+
"ruff>=0.15,<0.16",
|
|
24
|
+
"mypy>=1.10,<2",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/xiaomaozjj666/relay-audit"
|
|
29
|
+
Repository = "https://github.com/xiaomaozjj666/relay-audit"
|
|
30
|
+
Issues = "https://github.com/xiaomaozjj666/relay-audit/issues"
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
relay-audit = "relay_audit.cli:main"
|
|
34
|
+
relay-audit-calibrate = "relay_audit.calibrate:main"
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
line-length = 100
|
|
38
|
+
target-version = "py310"
|
|
39
|
+
|
|
40
|
+
[tool.ruff.lint]
|
|
41
|
+
extend-select = ["I", "UP", "B"]
|
|
42
|
+
|
|
43
|
+
# E402: __init__.py 需要先定义 REPORTS_DIR 再导入子模块(规避循环导入);
|
|
44
|
+
# test_scanner.py 在文件中部引入 httpx/ApiClient 供用例复用。
|
|
45
|
+
[tool.ruff.lint.per-file-ignores]
|
|
46
|
+
"relay_audit/__init__.py" = ["E402"]
|
|
47
|
+
"tests/test_scanner.py" = ["E402"]
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
testpaths = ["tests"]
|
|
51
|
+
|
|
52
|
+
[tool.mypy]
|
|
53
|
+
python_version = "3.10"
|
|
54
|
+
ignore_missing_imports = true
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.packages.find]
|
|
57
|
+
include = ["relay_audit*"]
|