1. 正则表达式的困境与LLM的崛起
在数据处理领域,我们经常面临一个经典难题:如何从非结构化文本中提取结构化信息。传统工程师的第一反应往往是"上正则表达式",但这条路越走越窄。让我用一个真实案例说明:
去年我接手一个发票识别项目,客户提供的样本中包含这样的日期格式:"2023年12月31日"、"2023/12/31"、"2023-12-31"、"12月31日"、"明年1月底"。为了覆盖所有情况,我写了近20个正则匹配规则,结果测试时发现还有"腊月初八"这样的农历日期。更糟的是,当OCR识别把"2023"错识别为"2O23"(字母O代替数字0)时,整个匹配链直接崩溃。
这就是正则表达式的三大致命伤:
- 维护噩梦:每次新增格式都需要修改代码,
r'^(\d{4})[-/年](\d{1,2})[-/月](\d{1,2})[日]?$'这样的表达式可读性极差 - 语义盲区:无法理解"下周三"、"三个月后"等相对时间概念
- 零容错:一个错别字就能导致匹配失败
而大语言模型(LLM)的天然优势恰好能解决这些问题:
- 能理解"尽快处理"和"不急"的优先级差异
- 自动纠正"2O23"→"2023"这类常见OCR错误
- 处理未见过的时间表达格式
但新问题随之而来:LLM的自由文本输出难以直接接入数据库。我们需要一座桥梁,将模糊语义转化为精确的数据结构——这就是Pydantic的用武之地。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Pydantic与LLM的化学反应
2.1 类型系统作为约束框架
Pydantic的核心价值在于将Python类型提示(type hints)转化为运行时校验器。当它与LLM结合时,会产生奇妙的协同效应:
python复制from datetime import date
from pydantic import BaseModel, validator
class Invoice(BaseModel):
invoice_date: date # 自动校验日期格式
amount: float # 字符串"1,000.50"会自动转为浮点数
tax_id: str # 可添加自定义校验规则
@validator('tax_id')
def check_tax_id(cls, v):
if not v.startswith('US'):
raise ValueError("Tax ID must start with 'US'")
return v
这种强类型约束通过以下机制提升LLM输出质量:
- 格式标准化:确保日期、数字等字段符合规范
- 值域限制:通过Enum限定可选值范围
- 逻辑校验:跨字段验证(如"金额=单价×数量")
2.2 自愈循环(Self-Healing Loop)
真正的工程级解决方案需要容错机制。我们实现的校验闭环流程如下:
- 首次请求:发送文本和JSON Schema给LLM
- 校验失败:捕获Pydantic的ValidationError
- 错误回传:将错误信息作为新prompt发送给LLM
- 自动修正:LLM根据错误调整输出
- 最多重试3次(可配置)
这个过程的实际代码实现:
python复制from typing import TypeVar, Type
import instructor
from
