第134题:结构化输出验证通过,是否意味着语义结论可靠?

1. 核心回答
不能。
结构化输出验证通过,通常只说明模型输出满足预定义的:
- JSON 语法;
- 字段类型;
- required 字段;
- enum;
- pattern;
- 数值范围;
- Schema 允许的其他约束。
它解决的是:
Schema Validity Schema\ Validity Schema Validity
语义结论可靠还需要进一步验证:
Semantic Correctness Semantic\ Correctness Semantic Correctness
对于漏洞分析系统,我会把最终验收拆成:
$$
V_{\text{final}}
V_{\text{schema}}
\land
V_{\text{domain}}
\land
V_{\text{evidence}}
\land
V_{\text{program}}
$$
分别检查:
- Schema 是否合法;
- 字段之间是否满足安全领域语义;
- 每个结论是否真正有检索证据支持;
- source、sink、sanitizer、data-flow 等程序事实是否真实存在。
所以:
Schema Pass 是生产接口可靠性的必要控制之一,但远不足以证明漏洞结论可信。
2. 一个最简单的反例
假设系统要求:
{
"vulnerable": true,
"cwe": "CWE-78",
"source": "request.args",
"sink": "sql.execute",
"confidence": 0.99
}
这个 JSON:
- 可以正常 Parse;
- 所有字段齐全;
vulnerable是 Boolean;cwe是 String;confidence位于 [0,1][0,1][0,1]。
Schema 可以完全通过。
但语义可能存在严重错误。
例如:
CWE-78
描述的是 OS Command Injection 类弱点。
而:
sql.execute
更可能与 SQL Injection 场景有关。
因此:
SchemaValid(x)=True SchemaValid(x)=True SchemaValid(x)=True
并不能推出:
SemanticCorrect(x)=True SemanticCorrect(x)=True SemanticCorrect(x)=True
3. Structured Output 真正解决了什么
Structured Output 的主要价值在于把自由文本:
“我认为这里可能存在漏洞……”
转换为稳定的机器接口:
{
"status": "vulnerable",
"cwe": "CWE-78",
"evidence_ids": ["E12", "E19"],
"source": "...",
"sink": "...",
"confidence": 0.82
}
这对生产系统非常重要,因为下游程序可以稳定读取:
status
cwe
evidence_ids
source
sink
confidence
从而减少:
- JSON Parse Failure;
- 缺字段;
- 类型错误;
- 非法枚举;
- 输出格式漂移。
但模型依然可能在字段内部填写错误内容。
OpenAI 的 Structured Outputs 官方说明也明确指出,即使输出符合 Schema,模型仍然可能在 JSON 的具体值中犯错。
4. 第一层:Syntax / Schema Validation
最底层检查:
Can I parse it?
例如:
{
"vulnerable": true
}
是否属于合法 JSON。
随后进行 Schema Validation:
Does it satisfy the contract?
例如要求:
{
"type": "object",
"required": [
"vulnerable",
"cwe",
"evidence_ids"
]
}
以及:
vulnerable ∈ Boolean
cwe ∈ String
evidence_ids ∈ Array[String]
这一层可以阻止:
cwe = 123
confidence = "very high"
这类接口错误。
5. Schema 本身也可以表达部分值约束
需要注意,JSON Schema 并非只能检查大括号和字段类型。
它还能约束:
- enum;
- minimum / maximum;
- pattern;
- array length;
- required;
- additionalProperties;
- 条件结构等。
例如:
confidence ∈ [0,1]
可以直接通过 Schema 控制。
但 Schema 能验证的是:
开发者已经明确编码到 Schema 中的约束。
假设:
{
"cwe": "CWE-78"
}
满足:
pattern = "^CWE-[0-9]+$"
只能说明:
格式像一个 CWE ID
无法证明:
CWE-78 就是当前代码真正对应的漏洞类型。
6. 第二层:Domain Semantic Validation
Schema 之后,我会增加领域规则。
例如漏洞系统输出:
{
"vulnerable": false,
"exploitability": "confirmed",
"source": "...",
"sink": "..."
}
这里可能存在跨字段矛盾。
因此可以定义 Domain Invariants。
例如:
vulnerable = false
AND
exploitability = confirmed
需要拒绝或进入复核。
又例如:
status = insufficient_evidence
时不应该同时输出:
confidence = 0.99
除非 confidence 的语义被明确规定为其他含义。
因此这一层检查:
CrossFieldConsistency CrossFieldConsistency CrossFieldConsistency
7. CWE 与漏洞证据也需要一致
例如模型输出:
CWE-89
同时给出的唯一证据却是:
user input → os.system()
那么需要检查:
CWE↔Mechanism CWE \leftrightarrow Mechanism CWE↔Mechanism
是否一致。
可以维护:
CWE
→ expected weakness mechanism
→ typical source/sink relation
作为弱约束。
但这也不能直接作为最终 Oracle,因为真实漏洞可能具有复杂实现方式。
这层主要用于发现明显的:
Cross-field Semantic Contradiction
8. 第三层:Claim–Evidence Validation
如果系统是 RAG,我会要求输出:
{
"claim": "存在命令注入",
"evidence_ids": ["chunk_17", "chunk_31"]
}
随后检查:
Evidence⊨Claim? Evidence \models Claim? Evidence⊨Claim?
也就是:
被引用的证据是否真正蕴含这个结论。
Retriever 返回某个文档,只意味着:
RelevanceScore(q,d) RelevanceScore(q,d) RelevanceScore(q,d)
比较高。
它不能直接推出:
d⊨claim d\models claim d⊨claim
9. “引用了证据”也不能证明证据真的支持结论
例如:
Claim:
当前函数存在 SQL Injection。
Citation:
CWE-89 describes SQL injection vulnerabilities.
这条知识只解释:
什么叫 SQL Injection
没有证明:
当前函数
真的满足漏洞条件。
因此需要把输出拆成 Atomic Claims。
例如:
Claim 1:
user_input 是外部可控输入。
Claim 2:
user_input 未经过 sanitizer。
Claim 3:
user_input 进入 SQL query。
Claim 4:
query 使用字符串拼接。
Claim 5:
最终到达 SQL execution sink。
逐条进行:
Claimi↔Evidencei Claim_i \leftrightarrow Evidence_i Claimi↔Evidencei
验证。
10. 第四层:程序语义验证
对于代码安全系统,单纯自然语言 entailment 仍然不够。
如果模型声称:
Source:
request.args["cmd"]
Sink:
os.system(cmd)
还应该验证:
Source⇝Sink Source \rightsquigarrow Sink Source⇝Sink
是否真的存在数据流。
例如实际代码:
cmd = request.args["cmd"]
if not allowlist(cmd):
return
os.system(cmd)
模型如果忽略:
allowlist
仍然可能输出完全符合 Schema 的:
{
"vulnerable": true,
"source": "request.args[cmd]",
"sink": "os.system(cmd)"
}
此时真正要验证的是:
Source
→ Propagation
→ Sanitizer / Barrier
→ Sink
整个程序路径。
11. 可以使用静态分析作为独立 Validator
例如调用:
- CodeQL;
- 自定义 Data Flow;
- Taint Analysis;
- AST / CFG / DFG;
- Symbol Resolution。
检查模型输出的:
source
sink
path
sanitizer
是否能映射到真实代码实体。
例如模型生成:
{
"source_line": 25,
"sink_line": 78
}
Validator 可以检查:
Line 25 是否真的存在?
Line 78 是否真的存在?
两个节点是否可建立数据流?
中间是否经过 barrier?
于是结构化输出开始具有:
可执行验证接口
的价值。
12. 结构化输出真正有价值的地方也在这里
如果模型只输出自由文本:
“看起来存在命令注入风险。”
自动验证很困难。
如果输出:
{
"claim": "CWE-78",
"source": {
"file": "api.py",
"line": 20
},
"sink": {
"file": "shell.py",
"line": 81
}
}
系统就可以继续执行:
Check Source Exists
↓
Check Sink Exists
↓
Check Call Relationship
↓
Run Data Flow
↓
Check Sanitizer
所以 Structured Output 最大的工程价值之一是:
让后续语义验证变得可自动化。
13. 第五层:Execution / Test Oracle
如果静态分析还无法确认,可以进一步执行验证。
例如生成:
PoC Input
然后在:
Sandbox
Test Environment
Container
中运行。
对修复任务,可以运行:
Original Failing Test
↓
Apply Patch
↓
Regression Test
↓
Security Test
如果模型声称:
“补丁已经修复漏洞”
真正强的证据来自:
漏洞 PoC 已无法触发
+
正常功能没有回归
而不是 JSON 中:
{
"fixed": true
}
这一字段。
14. 正确结论和正确解释还要分开
假设真实标签是:
Vulnerable
模型输出:
{
"vulnerable": true,
"source": "wrong_source",
"sink": "wrong_sink"
}
分类结果偶然猜对了。
但推理证据是错的。
因此我会分别评估:
14.1 Decision Correctness
y^=y \hat y=y y^=y
14.2 Evidence Correctness
E^=E \hat E=E E^=E
14.3 Path Correctness
模型给出的 source–sink 路径是否成立。
14.4 Attribution Correctness
引用是否真正支持对应 claim。
不能只因为:
vulnerable = true
预测正确,就把整个回答判成完全正确。
15. 可以设计分级评分
例如:
Level 0:
Schema invalid
Level 1:
Schema valid
Level 2:
Schema + domain consistency valid
Level 3:
Conclusion correct
Level 4:
Evidence grounded
Level 5:
Program path verified
这样就能够区分:
Format Reliability
和:
Semantic Reliability
16. 一个推荐的生产验证 Pipeline
可以设计:
LLM
↓
Structured Output
↓
JSON Parse
↓
Schema Validation
↓
Domain Invariant Validation
↓
Evidence ID Validation
↓
Claim-Evidence Entailment
↓
Program Semantic Validation
↓
Policy / Risk Validation
↓
Accept / Reject / Human Review
对于高风险动作:
Patch
Firewall Rule
Account Disable
Production Change
还应继续:
Execution Validation
↓
Human / Policy Gate
↓
Commit
17. Validator 自己也可能出错
如果:
Semantic Validator
本身也是一个 LLM,那么问题只是增加了另一层模型判断。
例如:
Generator:
“存在漏洞”
LLM Judge:
“正确”
无法自动推出真实标签就是:
Vulnerable
所以高风险结论需要尽量结合独立信号:
Human Gold
Static Analysis
Execution Result
Unit Test
Security Test
Rule-based Invariant
18. LLM-as-a-Judge 应该怎样使用
LLM Judge 可以用于:
- Claim decomposition;
- Entailment 初筛;
- Explanation quality;
- 错误分类;
- 大规模 Eval 的辅助评分。
但应该用人工样本校准:
Judge↔HumanGold Judge \leftrightarrow HumanGold Judge↔HumanGold
至少检查:
- Accuracy;
- Precision / Recall;
- Agreement;
- Position Stability;
- Prompt Stability;
- Model-family bias。
因为已有研究发现 LLM Judge 会存在位置偏差等系统性问题。
19. 最强的验证实验:构造 Schema 合法但语义错误的样本
我会专门建立 adversarial semantic test。
例如所有输出都满足相同 JSON Schema。
Case A:错误 CWE
{
"vulnerable": true,
"cwe": "CWE-78"
}
但 Gold 是 CWE-89。
Case B:错误 Source
结论正确,source 错误。
Case C:错误 Sink
结论正确,sink 错误。
Case D:错误路径
source 和 sink 都存在,但二者没有 data flow。
Case E:忽略 Sanitizer
路径存在,但安全检查阻断了漏洞。
Case F:引用无关证据
Citation 存在,却不蕴含 claim。
然后测 Validator 能识别多少。
20. 还应该做 Evidence Replacement
固定输出 Schema。
将正确检索证据:
E_correct
替换成:
E_wrong
其中:
语义主题非常相似
+
最终结论相反
如果系统仍然生成完全相同的:
{
"vulnerable": true
}
说明模型可能主要依赖:
Parametric Knowledge
Shortcut
Prior
没有真正利用证据。
21. 再做 No-Retrieval 对照
比较:
A:
Code + Retrieval
B:
Code Only
如果:
OutputA≈OutputB Output_A\approx Output_B OutputA≈OutputB
即使 A 中每次都输出漂亮、合法的 JSON,也无法说明 RAG Evidence 真正产生了作用。
还应该加入:
Random Retrieval
Negative Retrieval
Oracle Retrieval
形成完整诊断矩阵。
22. Schema Pass Rate 和 Semantic Accuracy 必须分别报告
例如:
$$
SchemaPassRate
\frac{
N_{\text{schema valid}}
}{
N
}
$$
表示接口稳定性。
然后定义:
$$
SemanticAccuracy
\frac{
N_{\text{semantically correct}}
}{
N
}
$$
二者必须分开。
可能出现:
Schema Pass Rate = 100%
Semantic Accuracy = 较低
这种系统:
接口很稳定,但稳定地输出错误内容。
23. 还应该报告 Cross-Field Consistency
定义:
$$
ConsistencyRate
\frac{
N_{\text{internally consistent}}
}{
N
}
$$
例如检查:
vulnerable
cwe
source
sink
severity
evidence
是否相互一致。
典型错误:
vulnerable = false
severity = critical
exploit_status = confirmed
或者:
cwe = SQL Injection
sink = os.system
这类错误单看字段类型全部合法。
24. Evidence Grounding 指标怎么设计
可以把输出拆成:
C={c1,c2,…,cn} C=\{c_1,c_2,\ldots,c_n\} C={c1,c2,…,cn}
每个 Claim 对应证据集合:
Ei E_i Ei
然后计算:
Claim Support Precision
模型声称有证据支持的 claim 中,有多少真的得到支持。
Claim Support Recall
Gold 中需要证据的 claim,有多少获得了充分证据。
Citation Precision
引用的文档是否真的支持当前 claim。
Citation Completeness
重要 claim 是否都具有引用。
这比:
“回答里带引用”
严格得多。
25. Citation Correctness 仍不等于模型真正依赖了证据
这里还有一个更细的研究问题。
模型可能先依靠参数知识生成:
答案 A
随后找到一个恰好支持 A 的文档进行引用。
这种情况 Citation 从文本上看是正确的。
但:
模型产生 A 的原因
未必来自该证据。
相关研究将它描述为 attribution faithfulness 问题。
因此如果论文声称:
RAG 证据驱动了模型推理,
就需要进一步做:
- evidence replacement;
- evidence removal;
- contradictory evidence;
- order perturbation。
检查模型输出是否真正随证据变化。
26. 什么时候可以比较有把握地说“语义可靠”
我至少希望看到:
- Schema Pass Rate 高;
- Domain Invariant Violation 很低;
- 最终标签在独立测试集上正确;
- Atomic Claim 有明确证据支持;
- Citation 与 claim 之间存在真实 entailment;
- source/sink/path 能由独立程序分析验证;
- evidence replacement 会产生符合预期的输出变化;
- 无证据或证据冲突时能够拒答;
- 高风险样本经过人工或执行 Oracle 验证;
- 所有指标在项目/时间外推测试中仍稳定。
这时才能从:
Format Correctness
逐步建立到:
Semantic Assurance
27. 什么结果会直接推翻“结构化输出更可信”的主张
如果实验只发现:
SchemaPass↑ SchemaPass\uparrow SchemaPass↑
但:
TaskF1 TaskF1 TaskF1
EvidenceAccuracy EvidenceAccuracy EvidenceAccuracy
PathAccuracy PathAccuracy PathAccuracy
都没有提升,
那么能够支持的结论只有:
结构化输出提高了接口和格式可靠性。
不能进一步写成:
结构化输出提高了语义可信性。
如果 Semantic Accuracy 反而下降,那么还需要检查 constrained output 是否限制了模型表达必要的不确定性或复杂状态。
28. 一个更合理的输出 Schema
例如:
{
"status": "vulnerable | safe | insufficient_evidence",
"cwe": "CWE-XX | null",
"claims": [
{
"claim": "...",
"evidence_ids": ["..."]
}
],
"source": {
"file": "...",
"line": 0
},
"sink": {
"file": "...",
"line": 0
},
"sanitizers": [],
"confidence": 0.0
}
这里加入:
insufficient_evidence
很重要。
否则二分类 Schema:
vulnerable: true / false
本身就在强迫模型对所有输入猜一个答案。
29. 生产系统最终怎么处理
我会把系统状态设计成:
SCHEMA_INVALID
DOMAIN_INVALID
EVIDENCE_UNSUPPORTED
PROGRAM_CHECK_FAILED
INSUFFICIENT_EVIDENCE
VALIDATED
而不是只有:
PASS
FAIL
例如:
Schema:
PASS
Evidence:
PASS
Data Flow:
FAIL
最终系统就不会把这个输出自动升级为:
Confirmed Vulnerability
而是进入:
Needs Review
30. 当前题目最准确的结论
结构化输出通过只证明模型满足了指定的数据契约。
它可以显著提高:
- 可解析性;
- 接口稳定性;
- 字段完整性;
- 自动化处理能力。
语义可靠性需要另外建立验证链。
对于漏洞分析,我会继续检查:
CWE 与漏洞机制是否一致
source / sink 是否真实存在
source-sink 是否具有实际 data flow
sanitizer 是否被正确处理
claim 是否被具体 evidence 支持
evidence 是否属于正确版本和时间
最终漏洞结论是否与独立 Oracle 一致
所以我会分别报告:
SchemaPassRate SchemaPassRate SchemaPassRate
SemanticAccuracy SemanticAccuracy SemanticAccuracy
EvidenceSupport EvidenceSupport EvidenceSupport
PathAccuracy PathAccuracy PathAccuracy
EndToEndF1 EndToEndF1 EndToEndF1
这样才能知道系统究竟提高了:
格式可靠性
还是:
任务语义可靠性。
31. 面试时可以压缩成下面这段
结构化输出验证通过,只能说明输出满足 JSON Schema 或数据接口约束,不能直接证明漏洞结论正确。
例如模型完全可以生成一个合法 JSON,字段写着 vulnerable=true、CWE-78,但给出的 sink 却是 SQL 执行函数,或者 source 和 sink 在真实程序里根本没有数据流。这些字段在类型上全部合法,语义依然可能错误。
所以我的验证会分层。第一层检查 JSON 和 Schema;第二层检查 CWE、状态、严重度等字段之间的 domain consistency;第三层把输出拆成 atomic claims,逐条检查 citation 是否真的支持 claim;第四层用 CodeQL、DFG 或 taint analysis 验证 source、sink、sanitizer 和实际路径。必要时再通过 sandbox test 或安全 PoC 做 execution validation。
实验上我会分别报告 Schema Pass Rate、Semantic Accuracy、Evidence Support 和 Path Accuracy,并构造“Schema 完全合法但 CWE、source/sink 或证据故意错误”的反例集。
另外,我会做 evidence removal 和 replacement。如果把正确证据换成结论相反的证据以后模型仍输出同样结果,就不能声称模型真正使用了检索证据。
所以 Structured Output 的价值主要是稳定接口,并为后续自动语义验证提供机器可读字段。真正的可信性需要证据验证、程序分析、独立测试和必要时的人工复核共同建立。
32. 来源
- 原始 相关 题库,第134题:要求通过证据替换、顺序扰动、冲突上下文、no-retrieval 与拒答样本检查模型是否真正使用证据,并将输出拆成原子 claim 与具体证据分别评估。
- OpenAI, Structured Outputs:Structured Outputs 可以约束输出符合指定 JSON Schema,但官方明确说明模型仍可能在 JSON 字段的具体值上犯错。
- JSON Schema, Validation Specification:JSON Schema 定义 JSON 实例的结构、类型和声明式约束验证。
- OWASP, Input Validation Cheat Sheet:区分 syntactic validation 与 semantic validation,后者检查值在具体业务上下文中的正确性。
- CodeQL Documentation, Data Flow / Path Queries:安全数据流分析围绕 source、sink、barrier/sanitizer 和实际 flow path 建模。
- Song et al., VeriScore, Findings of EMNLP 2024:采用 atomic claim 分解再验证事实性的评测框架。
- Wallat et al., Correctness is not Faithfulness in RAG Attributions, 2024:区分 citation correctness 与 attribution faithfulness,并指出正确引用仍可能来自事后合理化。
- Shi et al., Judging the Judges: A Systematic Study of Position Bias in LLM-as-a-Judge, 2025:表明自动 LLM Judge 存在可测的系统性位置偏差,因此重要结论需要与人工或独立 Oracle 校准。

1836

被折叠的 条评论
为什么被折叠?



