作为一名长期从事AI应用开发的工程师,我经常需要深入分析大模型服务的请求响应过程。最近在调试Dify平台与Ollama本地模型的交互时,发现直接抓包存在诸多不便。经过多次实践,我总结出一套基于mitmproxy的反向代理抓包方案,能够完整捕获并分析大模型请求的全链路数据。
这个方案的核心价值在于:
mitmproxy作为中间人代理,其工作流程可分为四个关键阶段:
选择mitmproxy而非其他抓包工具(如Wireshark、Fiddler)主要基于以下考量:
| 对比维度 | mitmproxy优势 | 其他工具局限性 |
|---|---|---|
| 协议支持 | 完整HTTP/HTTPS解析能力 | Wireshark需额外配置解密 |
| 反向代理 | 原生支持reverse模式 | Fiddler需插件扩展 |
| 定制化程度 | 支持Python脚本扩展 | Charles闭源扩展性差 |
| 资源占用 | 轻量级内存消耗(实测<100MB) | 部分工具占用500MB+内存 |
| 命令行支持 | 完整CLI操作接口 | 部分工具仅GUI操作 |
对于本地Ollama服务的典型部署架构:
code复制[Dify Client]
↓ (请求代理端口)
[mitmproxy:8003]
↓ (反向代理)
[Ollama:11434]
↑ (响应返回)
关键设计要点:
首先确认Ollama服务正常运行:
bash复制# 启动Ollama服务(后台模式)
ollama serve &
# 验证服务可用性
curl -v http://127.0.0.1:11434/api/tags
预期应返回类似响应:
json复制{
"models": [
{
"name": "qwen:7b",
"modified_at": "2024-03-15T08:00:00Z"
}
]
}
建议使用Python虚拟环境安装:
bash复制python -m venv mitm-env
source mitm-env/bin/activate
pip install mitmproxy==9.0.1
# 验证安装
mitmweb --version
完整启动命令示例:
bash复制mitmweb -m reverse:http://127.0.0.1:11434 \
-p 8003 \
--web-port 8004 \
--ssl-insecure \
--set keep_host_header=true \
--set flow_detail=3 \
--verbose
参数详解:
-p 8003:业务流量入口端口--web-port 8004:Web控制台访问端口flow_detail=3:显示完整请求/响应详情--verbose:输出详细调试日志当Ollama部署在远程服务器时:
bash复制mitmweb -m reverse:http://<remote_ip>:11434 \
-p 8003 \
--web-host 0.0.0.0 \ # 允许远程访问控制台
--web-port 8004 \
--ssl-insecure
重要安全提示:生产环境暴露控制台端口时,务必配置
--web-host指定可信IP范围,避免未授权访问。
关键配置项说明:
| 配置项 | 本地部署值 | Docker部署值 |
|---|---|---|
| 基础URL | http://host.docker.internal:8003 | http://<宿主机IP>:8003 |
| 模型名称 | 需与ollama pull的模型名一致 | |
| 超时设置 | 建议30-60秒 | 根据网络状况适当延长 |
点击「保存并测试」时常见问题处理:
连接超时:
sudo ufw allow 8003/tcpnetstat -tulnp | grep 8003证书错误:
--ssl-insecure参数Host头问题:
keep_host_header=true访问http://localhost:8004进入控制台后,重点关注:
请求列表区:
详情面板:
以聊天接口为例,正常请求应包含:
http复制POST /api/chat HTTP/1.1
Content-Type: application/json
Host: 127.0.0.1:11434
{
"model": "llama3",
"messages": [
{"role": "user", "content": "你好"}
],
"temperature": 0.7
}
关键参数说明:
temperature:控制生成随机性(0-2)top_p:核采样概率(默认0.9)max_tokens:最大生成token数使用-f参数实现请求过滤:
bash复制# 只捕获/api/chat路径的请求
mitmweb -m reverse:http://127.0.0.1:11434 \
-p 8003 \
-f "~u /api/chat"
常用过滤表达式:
~u /api/chat:URL路径匹配~b "temperature":请求体内容匹配~m POST:请求方法过滤症状:Dify测试连接失败,mitmproxy无请求记录
排查步骤:
bash复制telnet 127.0.0.1 8003
bash复制ps aux | grep mitmweb
bash复制sudo iptables -L -n -v | grep 8003
症状:请求可见但响应内容乱码
解决方案:
bash复制--set http2_priority=true \
--set proxy_debug=true
application/json当处理大量请求时:
bash复制--set stream_large_bodies=1m
bash复制--set proxy_buffer_size=8k
bash复制--set intercept="~d example.com"
通过编写addon脚本实现内容修改:
python复制# modify_requests.py
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if "/api/chat" in flow.request.pretty_url:
flow.request.query["temperature"] = "0.5"
def response(flow: http.HTTPFlow) -> None:
if "application/json" in flow.response.headers.get("content-type", ""):
flow.response.content = flow.response.content.replace(
b'"model":', b'"modified_model":'
)
启动时加载脚本:
bash复制mitmweb -s modify_requests.py ...
结合pytest实现自动化验证:
python复制import requests
def test_model_response():
proxy = {"http": "http://127.0.0.1:8003"}
resp = requests.post(
"http://127.0.0.1:11434/api/chat",
json={"model": "llama3", "messages": [...]},
proxies=proxy
)
assert resp.status_code == 200
assert "content" in resp.json()
bash复制mitmdump -w traffic.mitm -p 8003
bash复制mitmproxy -n -c traffic.mitm
在实际项目中使用这套方案后,我们成功发现了几个关键问题:
通过持续监控模型请求,团队显著提升了调试效率和系统稳定性。这套方法同样适用于其他AI服务的协议分析场景,只需调整反向代理目标地址即可快速适配。