凌晨4点,我看着Agent返回了一个格式错误的JSON,突然想起了《喜剧之王》里那句经典台词。
「其实,我是一个演员。」
但问题是,如果Agent的输出格式都不对,那跟「演员」也没啥分别——都是「演」给别人看的。
于是,我悟了——Output Validation,就是给AI装上「质检员」的魔法。
凌晨4点,我看着Agent返回了一个格式错误的JSON,突然想起了《喜剧之王》里那句经典台词。
「其实,我是一个演员。」
但问题是,如果Agent的输出格式都不对,那跟「演员」也没啥分别——都是「演」给别人看的。
于是,我悟了——Output Validation,就是给AI装上「质检员」的魔法。
Output Validation(输出验证)是对Agent输出进行结构化验证的机制。它让Agent能够:
想象Agent是个快递员,Output Validation就是:
- JSON Schema验证:检查包裹是否完整
- 类型检查:确认包裹里是衣服还是易碎品
- 范围约束:检查包裹重量是否在合理范围
- 格式校验:确认收件人地址是否正确
没有验证?那就是「快递员送了个空包裹」了。
| 验证方式 | 作用 | 示例 |
|---|---|---|
| JSON Schema验证 | 验证JSON结构是否符合定义 | 检查是否有必需字段、字段类型是否正确 |
| 类型检查 | 验证数据类型是否匹配 | 确认是string、number还是boolean |
| 范围约束 | 验证数值是否在合理范围 | 确认年龄在0-150之间、分数在0-100之间 |
| 格式校验 | 验证字符串格式是否规范 | 确认邮箱、手机号、日期格式是否正确 |
// JSON Schema验证示例
// 定义Schema
const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
email: { type: "string", format: "email" }
},
required: ["name", "age", "email"]
};
// 验证输出
const output = {
name: "张三",
age: 25,
email: "zhangsan@example.com"
};
// 验证结果
validate(output, schema);
// → true: 符合Schema
// 错误示例
const badOutput = {
name: "张三",
age: "二十五", // 错误:应该是number
email: "invalid-email"
};
validate(badOutput, schema);
// → false: 不符合Schema
// 错误: age应该是number类型
// 类型检查示例
// 检查基本类型
function checkType(value, expectedType) {
if (typeof value !== expectedType) {
throw new Error(`类型错误: 期望${expectedType}, 实际${typeof value}`);
}
return true;
}
// 使用示例
checkType("hello", "string"); // ✅ 通过
checkType(123, "number"); // ✅ 通过
checkType(true, "boolean"); // ✅ 通过
checkType("123", "number"); // ❌ 错误: 期望number, 实际string
// 检查复杂类型
function checkArrayType(arr, itemType) {
if (!Array.isArray(arr)) {
throw new Error("不是数组");
}
for (const item of arr) {
checkType(item, itemType);
}
return true;
}
checkArrayType([1, 2, 3], "number"); // ✅ 通过
checkArrayType([1, "2", 3], "number"); // ❌ 错误: 第2项不是number
// 范围约束示例
// 检查数值范围
function checkRange(value, min, max) {
if (value < min || value > max) {
throw new Error(`范围错误: ${value} 不在 [${min}, ${max}] 内`);
}
return true;
}
// 使用示例
checkRange(25, 0, 150); // ✅ 通过: 年龄在合理范围
checkRange(200, 0, 150); // ❌ 错误: 年龄超出范围
checkRange(85, 0, 100); // ✅ 通过: 分数在合理范围
checkRange(150, 0, 100); // ❌ 错误: 分数超出范围
// 检查字符串长度
function checkLength(str, min, max) {
if (str.length < min || str.length > max) {
throw new Error(`长度错误: ${str.length} 不在 [${min}, ${max}] 内`);
}
return true;
}
checkLength("hello", 1, 10); // ✅ 通过
checkLength("", 1, 10); // ❌ 错误: 长度为0
checkLength("very long string", 1, 10); // ❌ 错误: 长度超出范围
// 格式校验示例
// 邮箱格式校验
function checkEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!regex.test(email)) {
throw new Error(`邮箱格式错误: ${email}`);
}
return true;
}
checkEmail("zhangsan@example.com"); // ✅ 通过
checkEmail("invalid-email"); // ❌ 错误: 格式不正确
checkEmail("test@.com"); // ❌ 错误: 格式不正确
// 手机号格式校验
function checkPhone(phone) {
const regex = /^1[3-9]\d{9}$/;
if (!regex.test(phone)) {
throw new Error(`手机号格式错误: ${phone}`);
}
return true;
}
checkPhone("13800138000"); // ✅ 通过
checkPhone("12345678901"); // ❌ 错误: 格式不正确
// 日期格式校验
function checkDate(date) {
const regex = /^\d{4}-\d{2}-\d{2}$/;
if (!regex.test(date)) {
throw new Error(`日期格式错误: ${date}`);
}
return true;
}
checkDate("2026-06-12"); // ✅ 通过
checkDate("2026/06/12"); // ❌ 错误: 格式不正确
在OpenClaw中,Output Validation通过Structured Output和function calling返回值验证实现:
# OpenClaw Structured Output示例
# 1. 定义输出Schema
output_schema = {
"type": "object",
"properties": {
"summary": {"type": "string"},
"keywords": {"type": "array", "items": {"type": "string"}},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
},
"required": ["summary", "keywords", "confidence"]
}
# 2. Agent生成输出
agent_output = {
"summary": "OpenClaw是一个AI Agent框架",
"keywords": ["AI", "Agent", "OpenClaw"],
"confidence": 0.95
}
# 3. 验证输出
validate(agent_output, schema)
# → true: 符合Schema
# 4. 错误处理
bad_output = {
"summary": "OpenClaw是一个AI Agent框架",
"keywords": "AI, Agent, OpenClaw", # 错误: 应该是数组
"confidence": 1.5 # 错误: 超出范围
}
validate(bad_output, schema)
# → false: 不符合Schema
# 错误1: keywords应该是数组
# 错误2: confidence应该在0-1之间
# OpenClaw Function Calling返回值验证
# 1. 定义工具返回值Schema
tool_schema = {
"name": "get_weather",
"description": "获取天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
},
"returns": {
"type": "object",
"properties": {
"temperature": {"type": "number"},
"condition": {"type": "string"},
"humidity": {"type": "number", "minimum": 0, "maximum": 100}
},
"required": ["temperature", "condition", "humidity"]
}
}
# 2. 工具返回结果
tool_result = {
"temperature": 25,
"condition": "晴",
"humidity": 60
}
# 3. 验证返回值
validate(tool_result, tool_schema.returns)
# → true: 符合Schema
# 4. 错误处理
bad_result = {
"temperature": "25度", # 错误: 应该是number
"condition": "晴",
"humidity": 150 # 错误: 超出范围
}
validate(bad_result, tool_schema.returns)
# → false: 不符合Schema
# 错误1: temperature应该是number
# 错误2: humidity应该在0-100之间
真正的威力在于智能验证策略,让Agent自动适应验证规则:
# 智能验证策略示例
任务:"分析用户评论并生成报告"
Agent执行流程:
1. Schema定义
{
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"keywords": {"type": "array", "items": {"type": "string"}},
"score": {"type": "number", "minimum": 0, "maximum": 100},
"summary": {"type": "string", "maxLength": 500}
},
"required": ["sentiment", "keywords", "score", "summary"]
}
2. Agent生成输出
{
"sentiment": "positive",
"keywords": ["好用", "推荐", "性价比高"],
"score": 85,
"summary": "用户对产品评价很高,认为性价比高,值得推荐。"
}
3. 验证结果
- sentiment: ✅ 在枚举范围内
- keywords: ✅ 是字符串数组
- score: ✅ 在0-100范围内
- summary: ✅ 长度在500字符内
4. 错误处理
如果验证失败:
- 记录错误信息
- 尝试修复(如果可能)
- 返回友好错误提示
凌晨4点30分,我看着Agent的输出通过了所有验证,突然有种错觉。
世界上有一种质量叫Output Validation,它让AI从「大概是对的」变成「一定是正确的」。
就像给一个刚入职的质检员配了检测设备、标准流程、合格标准,从此不再担心「次品流出」。
Output Validation,大概就是那把打开「AI可信化」大门的钥匙吧。