输出验证

#2025/12/31 #ai

当你的AI应用要投入实际使用时,验证和控制模型输出就变得非常重要了。

想象一下,如果模型随便乱输出,你的应用可能会崩溃或出现各种问题。


目录

一、为什么需要验证输出?

文档提到了几个关键原因:

1. 结构化输出

问题:模型默认输出的是“自由形式“的文本,想怎么写就怎么写。

你要求:给我JSON格式  
模型可能输出:这是一段普通文本...  

需求:很多应用需要固定格式(比如JSON、表格等)才能自动处理数据。


2. 输出的有效性

问题:模型可能“自由发挥“,创造不存在的选项。

你问:这句话是正面还是负面?  
模型可能答:中立偏积极带点讽刺... (你根本没这个选项!)  

需求:在两个选项中选,就不能出现第三个。


3. 伦理和安全

问题:开源模型可能没有内置的安全防护。

模型可能输出:  
❌ 不文明用语  
❌ 个人隐私信息  
❌ 文化刻板印象  

需求:企业应用必须符合安全和伦理标准。


4. 准确性

问题:模型可能“幻觉“(编造事实)。

你问:2023年的诺贝尔物理学奖得主是谁?  
模型可能编:是爱因斯坦... (明显错误!)  

需求:确保输出符合事实、连贯、没有幻觉。


二、控制输出的三种方法

通常有三种方法:

方法难度本节讲解
示例法⭐ 简单✅ 6.5.1
语法约束⭐⭐ 中等✅ 6.5.2
微调模型⭐⭐⭐ 困难❌ 第12章

三、方法1:提供示例(少样本学习)

核心思想

“展示给模型看”,而不是“用语言描述“

实战案例:角色扮演游戏的角色生成

❌ 零样本(不给示例)

prompt = "Create a character profile for an RPG game in JSON format."  

模型输出:可能格式乱七八糟,不统一。


✅ 少样本(给示例)

prompt = """  
Create a character profile in JSON format.  

Example 1:  
{  
  "name": "Eldrin the Brave",  
  "class": "Warrior",  
  "level": 10,  
  "health": 100  
}  

Example 2:  
{  
  "name": "Luna Shadowstep",  
  "class": "Rogue",  
  "level": 8,  
  "health": 75  
}  

Now create a new character:  
"""  

结果:模型完美遵循示例格式!


优势与局限

优点

  • 简单直接
  • 不需要额外工具
  • 适合大多数场景

缺点

  • 无法100%保证格式正确
  • 模型“可能“不遵循(取决于模型质量)
  • 没有强制约束

四、方法2:语法约束(约束采样)

问题背景

少样本学习有个大缺点:我们无法明确阻止模型生成某些输出。虽然给了指令,但模型可能“阳奉阴违“。

解决方案:专业工具包

文档提到了几个验证工具

  • Guidance
  • Guardrails
  • LMQL

工作原理1:让模型自我验证

如图6-19所示,流程是这样的:

第1步:模型生成输出  
         ↓  
第2步:把输出再给模型看  
         ↓  
第3步:模型检查:"这符合JSON格式吗?"  
         ↓  
第4步:如果不符合 → 重新生成  

核心思路用LLM来检查LLM的输出


工作原理2:预先生成格式框架

如图6-20所示,更聪明的做法:

{  
  "id": "___模型填这里___",  
  "height": "___模型填这里___",  
  "name": "___模型填这里___",  
  "age": "___模型填这里___"  
}  

我们已知的部分:自己写
模型生成的部分:只让模型填空

这样就能强制控制格式


工作原理3:限制词元选择(最强约束)

如图6-21所示,在采样阶段就进行控制:

问题:这句话是正面、中性还是负面?  

采样时:  
所有可能的词元:amazing, positive, neutral, horrible, negative, awful...  
                    ↓  
限制采样范围:只允许 [positive, neutral, negative]  
                    ↓  
模型只能从这3个词中选!  

实战:使用 llama-cpp-python

第1步:安装和加载模型

from llama_cpp import Llama  

# 加载GGUF格式的模型(量化版本)  
llm = Llama(  
    model_path="phi-3-mini-4k-instruct.gguf",  
    n_gpu_layers=-1,  # 使用GPU  
    n_ctx=2048  
)  

注意:需要使用GGUF格式(量化模型)。


第2步:定义JSON格式约束 → 使用 JSON schema

import json  

# 定义期望的JSON结构  
json_schema = {  
    "type": "object",  
    "properties": {  
        "name": {"type": "string"},  
        "class": {"type": "string"},  
        "level": {"type": "integer"},  
        "equipment": {  
            "type": "array",  
            "items": {  
                "type": "object",  
                "properties": {  
                    "name": {"type": "string"},  
                    "type": {"type": "string"}  
                }  
            }  
        }  
    },  
    "required": ["name", "class", "level"]  
}  

第3步:强制JSON输出

output = llm(  
    "Create a character profile for an RPG game",  
    max_tokens=500,  
    grammar=json.dumps(json_schema)  # 应用JSON语法约束  
)  

print(output["choices"][0]["text"])  

输出示例

{  
    "name": "Eldrin the Brave",  
    "class": "Warrior",  
    "level": 10,  
    "skills": {  
        "combat": {  
            "sword_skill": 15,  
            "shield_skill": 17  
        }  
    },  
    "equipment": [  
        {  
            "name": "Ironclad Armor",  
            "type": "Armor",  
            "defense_bonus": 15  
        }  
    ]  
}  

保证:输出格式 100%正确

五、两种方法对比

维度方法1:示例法方法2:语法约束
实现难度⭐ 简单⭐⭐⭐ 复杂
可靠性约80-95%100%
速度较慢(需要额外计算)
灵活性中等
需要工具不需要需要专业库
适用场景快速原型、要求不严格生产环境、格式严格

六、实战建议流程

第一阶段:快速验证(用示例法)

# 先用少样本测试可行性  
prompt = """  
示例1:{...}  
示例2:{...}  
现在生成:...  
"""  

第二阶段:生产部署(加语法约束)

# 关键业务用约束采样  
from llama_cpp import Llama  

llm = Llama(model_path="...", grammar=json_schema)  
output = llm(prompt)  

第三阶段:极致优化(微调模型)

  • 如果前两种方法还不够好
  • 考虑第12章的微调技术
  • 让模型“天生“就会输出正确格式

七、常见应用场景

1. 分类任务

# 约束:只能输出3个类别之一  
allowed_tokens = ["positive", "negative", "neutral"]  
# 应用约束采样  

2. 数据提取

# 约束:必须是JSON格式  
json_schema = {...}  
# 强制JSON输出  

3. 代码生成

# 约束:必须是合法的Python语法  
# 使用语法检查工具  

核心要点总结

  1. 为什么验证:生产环境需要可靠、安全、结构化的输出
  2. **示例法:
    • 简单易用
    • 适合原型开发
    • 可靠性约80-95%
  3. 语法约束: → JSON schema
    • 100%可靠
    • 需要专业工具
    • 适合生产环境
  4. 渐进策略
    • 开发阶段 → 示例法
    • 测试阶段 → 加约束
    • 生产阶段 → 严格约束
  5. 工具选择
    • Guidance / Guardrails / LMQL
    • llama-cpp-python
    • 根据需求选择

最后

记住:在关键业务中,永远不要完全信任模型的“自觉性“——验证是必须的!