免费模型API返回的JSON结构可能每次不同,仅解析成功不能证明字段符合预期,应在输出进入配置文件、linter或shell命令前加Schema契约校验。
免费模型输出需要一个 Schema 门控,而不仅仅是 JSON 解析。
免费模型 API 每次调用都可能返回结构不同的有效 JSON。
解析只能证明这些字节是 JSON 格式。它无法证明键、类型和必需字段是否与你的处理流程相匹配。
缺失的 line 字段,或 severity 字段从 high 变成 'high'(字符串与枚举值不符),都可能悄无声息地导致下游消费者出错。
在任何模型输出进入配置文件、linter 或 shell 命令之前,应该运行一个小的契约门控。
声明:本文是 MonkeyCode 产品推广的一部分。
MonkeyCode 的免费模型访问和免费服务器选项使得运行重复的非生产调用变得实用,无需按 token 付费。但这不会改变规则:不受信任的输出仍然需要 schema 契约。
安装一个依赖:
pip install jsonschema
为代码审查输出定义一个契约。该示例拒绝未知字段,要求四个键,并约束 severity 的取值范围。
import json
from jsonschema import Draft202012Validator
CONTRACT = {
'type': 'object',
'required': ['finding', 'severity', 'file', 'line'],
'additionalProperties': False,
'properties': {
'finding': {'type': 'string', 'minLength': 1},
'severity': {'enum': ['low', 'medium', 'high', 'critical']},
'file': {'type': 'string', 'minLength': 1},
'line': {'type': 'integer', 'minimum': 1}
}
}
def check(payload: dict) -> dict:
errors = sorted(
Draft202012Validator(CONTRACT).iter_errors(payload),
key=lambda e: list(e.path),
)
return {
'ok': not errors,
'errors': [
{'path': list(e.path), 'message': e.message}
for e in errors[:5]
],
}
sample = {'finding': 'unchecked egress', 'severity': 'medium', 'file': 'run.sh', 'line': 12}
print(check(sample))
在每次使用输出之前,对每个缓冲的响应运行此检查。
此版本读取换行符分隔的 JSON,应用 schema,并在遇到速率限制时重试一次(而不是围绕限制反复重试)。
import json
import time
from pathlib import Path
def run_gate(file_path: str, call_model_same_prompt) -> list:
results = []
for raw in Path(file_path).read_text().splitlines():
if not raw.strip():
continue
payload = json.loads(raw)
ok, errors = check(payload)
attempts = 0
while not ok and attempts < 1:
time.sleep(1)
payload = call_model_same_prompt() # pseudocode: replace with your client
ok, errors = check(payload)
attempts += 1
results.append({'ok': ok, 'errors': errors, 'attempts': attempts})
return results
将 call_model_same_prompt 替换为你自己的客户端。sleep 和单次重试是刻意为之的:遇到 429 时暂停,不要狂敲端点。
使用此方案来捕获漂移而不消耗配额。
冻结 20 个相同的提示词用于一个狭窄的任务。
通过免费模型端点运行它们。
在解析前缓冲每个完整响应,而不是流式处理。
根据 schema 检查每个解析后的 payload。
记录通过率、字段漂移和每次调用的延迟。
将结果记录到表格中:
不要复制上面的数字。它们是占位符。运行你自己的测试。
重试规则很窄:一次重试,相同提示词,不进行静默自动修复。
缺失必需字段。
字段的 JSON 类型错误。
可能隐藏新行为的未知字段。
超出允许枚举范围的 severity 值。
看起来有效但实际无用的空 finding 文本。
Schema 门控检查的是形状,而不是正确性。形状有效的 finding 仍然可能是错误的。
免费端点可能很慢或受到速率限制。测试计划应该在遇到 429 时暂停,而不是在限制周围重试。
模型可能在一天内发生漂移。昨天通过的契约不能作为今天的证明。
这不是沙箱。它不会阻止有效形状的命令造成损害。
在生成命令获得更多访问权限之前,在受限环境中进行试运行。
需要模型输出的认证 SLA 的团队不应依赖免费端点。
任何处理 secrets、生产凭证或不可逆操作的人都不应该将这些输入提供给免费模型。
如果无法让人工审查高严重性的发现,不要让模型输出进入自动合并路径。
如果预期的 schema 仍在变化,在构建门控之前先完成 schema 设计。
解析检查语法。Schema 检查契约。当免费模型输出很便宜但你的下游信任不应该便宜时,添加一个 schema 门控。
在下一次非生产模型响应上尝试检查器,并在将其连接到任何重要内容之前记录漂移。