去年在做AI产品对接时,我发现大模型API的请求响应黑箱问题特别让人头疼。明明参数都按文档设置了,返回结果却总是不稳定,调试起来像在盲人摸象。后来在同事推荐下尝试用Mitmproxy做中间人抓包,终于能看清每次请求的完整链路细节。这种反向代理抓包技术后来成了我们团队分析大模型行为的标配工具。
不同于Charles/Fiddler这些图形化抓包工具,Mitmproxy的纯命令行特性和可编程性让它特别适合处理大模型这类复杂API场景。你不仅能实时看到请求响应内容,还能用Python脚本动态修改流量,这对理解大模型的行为逻辑帮助巨大。
对比常见抓包方案,Mitmproxy有三个不可替代的优势:
重要提示:生产环境使用务必关闭
--insecure选项,测试环境也建议单独创建证书
推荐使用Python虚拟环境安装:
bash复制python -m venv mitm-env
source mitm-env/bin/activate # Linux/Mac
mitm-env\Scripts\activate # Windows
pip install mitmproxy==9.0.1
生成专属CA证书(避免与团队其他成员冲突):
bash复制mitmproxy --cert-hostname "*.yourdomain.com"
生成的证书会保存在~/.mitmproxy目录,需要手动导入到系统信任证书库。
针对大模型API的特殊配置:
bash复制mitmweb --mode reverse:https://api.openai.com \
--ssl-insecure \
--listen-port 9000 \
-s modify_headers.py
关键参数说明:
reverse:目标地址:将本地端口流量转发到大模型真实APIssl-insecure:跳过证书验证(仅调试用)listen-port:指定代理监听端口-s:加载自定义脚本创建modify_headers.py脚本示例:
python复制def request(flow):
# 添加自定义请求头
flow.request.headers["X-Debug-Session"] = "12345"
# 修改请求体(适用于POST)
if "application/json" in flow.request.headers.get("content-type", ""):
try:
body = flow.request.json()
body["temperature"] = 0.7 # 强制固定温度参数
flow.request.text = json.dumps(body)
except:
pass
启动时添加存储选项:
bash复制mitmdump -w traffic.mitm \
--set stream_large_bodies=1m
后期分析技巧:
bash复制# 1. 按时间过滤请求
mitmdump -nr traffic.mitm -t '~t 2023-08-01'
# 2. 统计API耗时分布
mitmdump -nr traffic.mitm -s stats.py
其中stats.py示例:
python复制import statistics
timings = []
def response(flow):
if flow.request.host == "api.openai.com":
timings.append(flow.response.elapsed)
def done():
print(f"平均响应时间: {statistics.mean(timings):.2f}s")
print(f"P95延迟: {sorted(timings)[int(len(timings)*0.95)]:.2f}s")
在脚本中添加计算逻辑:
python复制def response(flow):
if "usage" in flow.response.json():
usage = flow.response.json()["usage"]
print(f"本次消耗: {usage['total_tokens']} tokens")
print(f"Prompt占比: {usage['prompt_tokens']/usage['total_tokens']:.1%}")
自动识别API密钥泄露:
python复制API_KEYS = ["sk-", "Bearer "]
def request(flow):
for key in API_KEYS:
if key in (flow.request.text or ""):
print(f"⚠️ 检测到敏感信息: {flow.request.url}")
break
保存特定请求用于回放:
bash复制mitmdump -w replay.mitm -t '~m POST & ~u /v1/completions'
然后用curl重放:
bash复制mitmdump -nc replay.mitm -s replay.py
replay.py脚本需实现请求提取和发送逻辑。
高并发场景建议调整:
bash复制mitmproxy --set connection_strategy=lazy \
--set proxy_debug=false \
--set stream_large_bodies=5m
必须添加的防护配置:
ini复制# config.yaml
block_global: true
ssl_insecure: false
allow_hosts:
- "*.yourdomain.com"
证书错误:
连接中断:
bash复制netstat -tulnp | grep 9000 # 检查端口占用
journalctl -u mitmproxy # 查看服务日志
使用--mode reverse:目标地址配合--server-replay参数,可以实现:
结合机器学习库实现自动分类:
python复制from sklearn.feature_extraction.text import TfidfVectorizer
classifier = load_model('classifier.pkl')
def response(flow):
if "completions" in flow.request.path:
text = flow.response.json()["choices"][0]["text"]
category = classifier.predict([text])[0]
flow.response.headers["X-Content-Category"] = category
在CI流水线中加入Mitmproxy检查:
yaml复制# .github/workflows/test.yml
steps:
- run: |
mitmdump -s check_quality.py &
pytest tests/
kill %1
check_quality.py可实现对API响应质量的自动化断言。
bash复制mitmproxy --set stream_large_bodies=1k \
-s stream_analyzer.py
python复制buffer = {}
def response(flow):
if "text/event-stream" in flow.response.headers.get("content-type", ""):
chunk = flow.response.content
req_id = flow.request.headers.get("x-request-id")
buffer[req_id] = buffer.get(req_id, b"") + chunk
if chunk.endswith(b"\n\n"):
print(f"完整响应: {buffer[req_id].decode()}")
del buffer[req_id]
通过分析发现:
python复制# benchmark.py
import time
from mitmproxy import http
class Benchmark:
def __init__(self):
self.stats = {}
def request(self, flow: http.HTTPFlow):
flow.metadata["start"] = time.time()
def response(self, flow: http.HTTPFlow):
latency = time.time() - flow.metadata["start"]
endpoint = flow.request.path.split("?")[0]
self.stats.setdefault(endpoint, []).append(latency)
安装matplotlib后添加:
python复制def done(self):
import matplotlib.pyplot as plt
for endpoint, latencies in self.stats.items():
plt.hist(latencies, label=endpoint, alpha=0.5)
plt.legend()
plt.savefig("latency.png")
dockerfile复制FROM python:3.9
RUN pip install mitmproxy
COPY config.yaml /root/.mitmproxy/config.yaml
ENTRYPOINT ["mitmproxy", "--mode", "reverse:https://api.openai.com"]
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: mitm-proxy
spec:
replicas: 3
template:
spec:
containers:
- name: proxy
image: your-registry/mitmproxy:v1
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /root/.mitmproxy
name: config
volumes:
- name: config
configMap:
name: mitm-config
python复制def response(flow):
if "email" in flow.response.text:
flow.response.text = flow.response.text.replace(
r"\b[\w.-]+@[\w.-]+\.\w+\b",
"[REDACTED]"
)
bash复制find /var/log/mitmproxy -type f -mtime +7 -delete
这套方案在我们团队已经稳定运行一年多,累计分析超过200万次大模型API调用。最实用的其实是那些简单的统计脚本,往往能发现文档里没写的API特性。比如通过统计我们发现,相同参数下GPT-4在UTC时间凌晨3点的响应速度比高峰期快40%,后来就把非紧急任务调度到这个时段执行。