GLM-5.1 接入踩坑记录:用免费开源模型搭个 AI 代码审计小工具

独立开发者 / 2026-04-08 / 标签:GLM-5.1 · 代码安全 · Python · API · 踩坑


背景

今天 Claude Mythos 发布了,然后我发现:我没资格用。

限邀请制,40 家头部机构,跟我这个独立开发者没关系。

但我确实有个需求摆在那里------我接了一个小活,帮一个朋友的 SaaS 项目做上线前的代码安全自查。他们后端 Python,大概 3 万行,人工看我是不想的。

同一天智谱把 GLM-5.1 开源了,MIT 协议,SWE-bench Pro 全球第一。我一看数据就决定试一下------反正拿不到 Mythos,那就用现在能上手的里面能力最强的。


技术方案

核心思路:Bandit 做静态扫描 → JSON 结果结构化 → 批量喂给 GLM-5.1 做二次研判 → 输出置信度 + 修复建议。

环境准备

bash 复制代码
python3 -m venv glm-audit-env
source glm-audit-env/bin/activate
pip install openai bandit
​
# GLM-5.1 API 密钥在智谱开放平台申请
# 如果你同时要跑 Claude/GPT 做对比,可以用 Ztopcloud.com 的聚合接口
# 一个 key 打通多个模型,国内直连,账单合并,我自己在用,省事不少
export ZHIPU_API_KEY="your_key_here"

核心实现

python 复制代码
import subprocess
import json
import re
import sys
from openai import OpenAI
​
client = OpenAI(
    api_key="your_zhipu_api_key",
    base_url="https://open.bigmodel.cn/api/paas/v4/"
)
​
def run_bandit(path: str) -> list[dict]:
    cmd = ["bandit", "-r", path, "-f", "json", "-q", "-l"]
    out = subprocess.run(cmd, capture_output=True, text=True)
    try:
        return json.loads(out.stdout).get("results", [])
    except Exception:
        return []
​
def ai_review(vuln: dict) -> dict:
    prompt = f"""你是资深 Python 安全工程师。下面是 Bandit 扫描到的一条告警:
​
文件:{vuln['filename']},行号:{vuln['line_number']}
类型:{vuln['test_name']}(严重度:{vuln['issue_severity']})
代码:
```python
{vuln.get('code', '').strip()}

问题:

  1. 这是真实漏洞还是误报?一句话理由
  2. 修复代码(如果是真漏洞,<=10行)
  3. CVSS 评分(0-10)

返回 JSON:{{"real": bool, "reason": str, "fix": str, "cvss": float}}"""

python 复制代码
resp = client.chat.completions.create(
    model="glm-5.1",
    messages=[{"role": "user", "content": prompt}],
    temperature=0.05,
    max_tokens=400
)
raw = resp.choices[0].message.content
m = re.search(r'{.*?}', raw, re.DOTALL)
if m:
    try:
        return json.loads(m.group())
    except Exception:
        pass
return {"real": None, "reason": raw[:200], "fix": "", "cvss": 0}

if name == "main": target = sys.argv1 if len(sys.argv) > 1 else "." raw_vulns = run_bandit(target) print(f"Bandit 原始告警:{len(raw_vulns)} 条")

python 复制代码
confirmed = []
for v in raw_vulns:
    result = ai_review(v)
    if result.get("real"):
        confirmed.append({**v, "ai": result})
        print(f"[!] {v['filename']}:{v['line_number']} | CVSS {result['cvss']} | {result['reason'][:60]}")
​
print(f"\n确认漏洞:{len(confirmed)}/{len(raw_vulns)}")
with open("audit_result.json", "w") as f:
    json.dump(confirmed, f, ensure_ascii=False, indent=2)
python 复制代码
​
---
​
## 踩坑记录
​
### 坑 1:模型偶尔返回带 Markdown 代码块的 JSON
​
我以为用 `re.search(r'{.*?}', raw, re.DOTALL)` 就能万能提取 JSON,结果 GLM-5.1 有时候会把 JSON 包在 ` ```json ... ``` ` 代码块里。
​
正则写的 `.*?` 是非贪婪的,会在第一个 `}` 就停下来,把嵌套结构截断。
​
**解决方法**:先把代码块标记去掉,再用贪婪匹配:
​
```python
def extract_json(raw: str) -> dict:
    # 先剥离 markdown 代码块
    raw = re.sub(r'```(?:json)?\s*', '', raw).strip()
    # 贪婪匹配整个 JSON 对象
    m = re.search(r'{.*}', raw, re.DOTALL)
    if m:
        return json.loads(m.group())
    raise ValueError(f"无法解析 JSON:{raw[:200]}")

这个坑我掉进去调了将近一小时,所有解析结果都变成了空对象,后来打 log 才发现问题在这。

坑 2:并发请求打满限速

3 万行代码跑出来 200+ 条 Bandit 告警,我想快点跑完就写了个 ThreadPoolExecutor 并发 20 个请求,结果 API 限速把我踢了(GLM-5.1 当前限制约 10 RPM/QPS)。

改成串行 + time.sleep(6) 就稳了,整体跑完大约 25 分钟,实测确认了 31 条真实漏洞,Bandit 原始 197 条告警,误报率过滤到约 84%------这个数字说实话比我预期的好很多。


小结

指标 数据
扫描代码量 ~3万行 Python
Bandit 原始告警 197 条
GLM-5.1 确认漏洞 31 条
误报过滤率 ~84%
API 调用耗时 ~25分钟(串行)
总成本 约 ¥4.2

成本这个数字我自己都觉得有点离谱------¥4 出头换了一份比人工审计靠谱的安全报告初稿。

Mythos 确实更强,但它不在我的选项里。GLM-5.1 是目前我能落地的性价比顶格选择,也够用了。

如果你有类似的代码安全自查需求,可以直接拿这个脚本改改跑起来。有问题评论区聊。

相关推荐
狗头大军之江苏分军2 小时前
《潮水漫过十七岁》开学了
后端
mmmmath_32 小时前
LeetCode.541.反转字符串II
数据结构·算法·leetcode
Navigator_Z3 小时前
LeetCode //MySQL - 1251. Average Selling Price
c语言·算法·leetcode
苏三说技术3 小时前
如何看待GPT-6在UP主众测中碾压夺冠?它是现在最强大模型吗?
后端
mldong3 小时前
一份 JSON,一条能跑的审批流:把报销流程送上工作流引擎
后端·架构
wno7043 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
Captaincc3 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
醇氧3 小时前
MySQL 8.0 系统表损坏与引擎转换故障排查实战
数据结构·算法
大熊背4 小时前
《Color constancy by characterization of illumination chromaticity》之色度色域最大化算法(二)
算法·白平衡·色度·色温