🔥 为什么需要结构化识别?
传统 AI 文本识别面临一个普遍痛点:输出的信息往往是自由文本格式,需要额外的解析工作才能转为可用数据。
传统方式示例:
“公司名称是XX科技,信用代码是91110108MA01XX,成立于2020年...”
开发人员需要编写复杂的正则表达式或文本解析逻辑,这一过程容易出错且效率低下。
Prism Schema 带来的革新: 通过定义数据结构模板,AI 能够直接返回标准化的 JSON 数据:
{
"company_name": "XX科技有限公司",
"credit_code": "91110108MA01XX",
"established_date": "2020-01-01"
}
核心价值:
- 零解析成本:无需编写和维护复杂的文本解析逻辑
- 高准确性:结构化输出大幅降低字段提取错误率
- 开发效率:直接获得可用数据,减少80%的数据处理代码
🎯 核心技术:Prism Schema 深度解析
什么是 Schema?
Schema 即 数据结构定义模板,用于明确告知 AI 模型应返回的数据格式、字段类型、验证规则等。
基础 Schema 类型
Prism 提供了完整的数据类型支持:
use Prism\Prism\Schema\{
ObjectSchema, StringSchema,
ArraySchema, NumberSchema,
BooleanSchema, EnumSchema
};
示例:用户信息 Schema 定义
// 定义用户个人信息 Schema
$userSchema = new ObjectSchema(
name: 'user',
description: '用户个人信息',
properties: [
new StringSchema('name', '姓名', required: true),
new StringSchema('id_card', '身份证号', pattern: '/^\d{17}[\dX]$/'),
new NumberSchema('age', '年龄', minimum: 0, maximum: 150),
new ArraySchema(
name: 'hobbies',
description: '爱好列表',
items: new StringSchema('hobby', '爱好名称')
)
],
requiredFields: ['name', 'id_card']
);
💼 实战应用:营业执照结构化识别系统
第一步:设计营业执照 Schema
我们创建一个完整的营业执照数据结构定义:
<?php
// app/Schemas/BusinessLicenseSchema.php
namespace App\Schemas;
use Prism\Prism\Schema\{
ObjectSchema, StringSchema,
NumberSchema, ArraySchema,
EnumSchema
};
class BusinessLicenseSchema
{
/**
* 获取完整营业执照 Schema
*/
public static function getSchema()
{
return new ObjectSchema(
name: 'business_license',
description: '中国营业执照结构化信息',
properties: [
// 基础信息
new StringSchema(
name: 'company_name',
description: '公司全称',
minLength: 2,
maxLength: 200,
required: true
),
new StringSchema(
name: 'credit_code',
description: '统一社会信用代码',
pattern: '/^[A-Z0-9]{18}$/',
required: true
),
// 更多字段定义...
],
requiredFields: ['company_name', 'credit_code', 'established_date']
);
}
/**
* 获取简化版 Schema(用于快速验证)
*/
public static function getSimpleSchema()
{
return new ObjectSchema(
name: 'simple_business_license',
description: '营业执照基础信息',
properties: [
new StringSchema('company_name', '公司名称', required: true),
new StringSchema('credit_code', '统一社会信用代码', required: true),
// 简化字段集...
]
);
}
}
第二步:集成到识别服务
创建识别服务,整合 Schema 与 AI 模型调用:
<?php
// app/Services/StructuredLicenseOCRService.php
namespace App\Services;
use Prism\Prism;
use Prism\Media\Image;
use App\Schemas\BusinessLicenseSchema;
class StructuredLicenseOCRService
{
private $retryCount = 0;
private $maxRetries = 2;
/**
* 主识别方法:使用 Schema 进行结构化识别
*/
public function recognizeWithSchema($imagePath, $useComplexSchema = true)
{
try {
// 根据需求选择 Schema 复杂度
$schema = $useComplexSchema
? BusinessLicenseSchema::getSchema()
: BusinessLicenseSchema::getSimpleSchema();
// 构建 AI 请求(核心:withSchema 方法)
$response = Prism::text()
->using('openai', 'gpt-4-vision-preview')
->withSchema($schema) // 指定数据结构模板
->withPrompt(
'请从这张营业执照图片中提取信息,严格按照要求的Schema格式返回数据。' .
'特别注意:统一社会信用代码必须是18位,日期格式为YYYY-MM-DD。' .
'如果图片中某些信息缺失,请对应字段返回null。'
)
->withImages([Image::fromLocalPath($imagePath)])
->asStructured(); // 请求结构化输出
// 验证和清理返回数据
return $this->validateAndClean($response->data);
} catch (\Exception $e) {
// 智能重试逻辑
return $this->handleRecognitionError($e, $imagePath);
}
}
/**
* 数据验证与增强处理
*/
private function validateAndClean($data)
{
// 1. 必填字段校验
$required = ['company_name', 'credit_code'];
foreach ($required as $field) {
if (empty($data[$field])) {
$data['validation_warnings'][] = "缺失必填字段: {$field}";
}
}
// 2. 格式验证
if (isset($data['credit_code']) && !preg_match('/^[A-Z0-9]{18}$/', $data['credit_code'])) {
$data['validation_warnings'][] = '统一社会信用代码格式不正确';
}
// 3. 添加处理元数据
$data['_meta'] = [
'extracted_at' => now()->toIso8601String(),
'schema_version' => '1.0',
'confidence_score' => $this->calculateConfidence($data)
];
return $data;
}
}
第三步:创建 API 接口
提供 RESTful API 供前端或第三方系统调用:
<?php
// app/Http/Controllers/LicenseController.php
namespace App\Http\Controllers;
use App\Services\StructuredLicenseOCRService;
use Illuminate\Http\Request;
class LicenseController extends Controller
{
protected $ocrService;
public function __construct()
{
$this->ocrService = new StructuredLicenseOCRService();
}
/**
* 营业执照识别 API
* POST /api/license/recognize
*/
public function recognize(Request $request)
{
$validated = $request->validate([
'image' => 'required|file|image|max:10240',
'schema_type' => 'sometimes|in:simple,complex'
]);
try {
$path = $request->file('image')->store('temp', 'public');
$fullPath = storage_path('app/public/' . $path);
$useComplexSchema = $request->get('schema_type', 'complex') === 'complex';
$result = $this->ocrService->recognizeWithSchema($fullPath, $useComplexSchema);
// 清理临时文件
unlink($fullPath);
return response()->json([
'success' => true,
'data' => $result,
'processing_time_ms' => $result['_meta']['processing_time_ms'] ?? 0
]);
} catch (\Exception $e) {
return response()->json([
'error' => '识别失败',
'message' => $e->getMessage()
], 500);
}
}
}
🚀 高级功能:智能校验与数据增强
为确保数据质量,我们可以在 Schema 识别基础上增加智能校验层:
<?php
// app/Services/LicenseValidator.php
namespace App\Services;
class LicenseValidator
{
/**
* 营业执照数据智能校验
*/
public function validateLicense($licenseData)
{
$errors = [];
$warnings = [];
// 1. 统一社会信用代码校验(国家标准算法)
if (isset($licenseData['credit_code'])) {
if (!$this->validateCreditCode($licenseData['credit_code'])) {
$errors[] = '统一社会信用代码校验失败';
}
}
// 2. 成立日期逻辑校验
if (isset($licenseData['established_date'])) {
$established = \Carbon\Carbon::parse($licenseData['established_date']);
if ($established->isFuture()) {
$errors[] = '成立日期不能是未来日期';
}
}
// 3. 与工商数据库对比(可选增强)
if (isset($licenseData['credit_code']) && $this->hasOfficialAccess()) {
$officialData = $this->queryOfficialDatabase($licenseData['credit_code']);
$comparison = $this->compareWithOfficial($licenseData, $officialData);
if ($comparison['has_discrepancy']) {
$warnings[] = '部分信息与官方登记存在差异';
}
}
return [
'is_valid' => empty($errors),
'errors' => $errors,
'warnings' => $warnings,
'validation_score' => $this->calculateValidationScore($errors, $warnings)
];
}
}
📊 实施效果与优势总结
通过集成 Prism Schema,我们实现了以下显著改进:
性能提升
1 ** 开发效率** 2 识别准确率 3 ** 处理速度** 4 ** 维护成本**
核心优势
- 标准化输出:消除数据格式不一致问题
- 零解析代码:无需编写和维护复杂的文本解析逻辑
- 易于集成:结构化 JSON 可直接对接业务系统
- 灵活扩展:通过修改 Schema 即可适应新需求
- 质量可控:内置验证规则确保数据质量
适用场景
- 证件、执照、票据等标准化文档识别
- 合同关键信息提取
- 报告结构化数据抽取
- 多源数据归一化处理
- 实时数据流结构化处理
🎯 最佳实践建议
- 渐进式 Schema 设计:从简单 Schema 开始,逐步增加复杂度
- 版本管理:对 Schema 进行版本控制,便于回溯和更新
- 测试用例:为每个 Schema 编写对应的测试用例
- 监控告警:监控识别成功率,设置自动告警机制
- 降级策略:准备传统 OCR 降级方案,确保系统可用性
Prism Schema 通过将数据结构定义前置,从根本上改变了 AI 识别输出的处理范式。它不仅大幅提升了开发效率和识别准确率,更重要的是提供了一种可维护、可扩展的数据提取解决方案。随着业务需求的变化,仅需调整 Schema 定义即可适应新的数据结构,真正实现了"一次定义,到处使用"的开发体验。
结构化输出正在成为 AI 应用的标配功能,提前掌握 Schema 驱动开发模式,将在未来的 AI 集成项目中占据显著优势。