由模式驱动的数据提取
在提示中提供 JSON 模式,以确保结构化输出格式
由模式驱动的数据提取 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。
为什么要采用模式驱动的抽取
当您告诉模型提取重要数据时,得到的输出会不一致且不可预测。当您提供 JSON 模式并说提取与此确切模式匹配的数据时,每次都能得到机器可读、一致且类型安全的输出。
模式驱动的抽取是生产系统中采用的模式,适用于处理发票、合同、医疗记录、会议记录,以及任何需要从非结构化文本中可靠抽取结构化数据的文档。
在提示词中提供模式
模式直接写在提示词中。模型将其作为输出契约使用:
import anthropic, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
INVOICE_SCHEMA = '''
{
"invoice_number": "string",
"vendor_name": "string",
"vendor_address": "string or null",
"invoice_date": "YYYY-MM-DD",
"due_date": "YYYY-MM-DD or null",
"line_items": [
{
"description": "string",
"quantity": "number",
"unit_price": "number",
"total": "number"
}
],
"subtotal": "number",
"tax": "number or null",
"total_amount": "number",
"currency": "3-letter ISO code e.g. USD"
}
'''
def extract_invoice(invoice_text):
prompt = f'Extract structured data from this invoice.\nReturn JSON matching this schema exactly:\n{INVOICE_SCHEMA}\n\nInvoice:\n{invoice_text}'
r = client.messages.create(model='claude-opus-4-5', max_tokens=500, messages=[{'role': 'user', 'content': prompt}])
return json.loads(r.content[0].text)
print('Invoice schema defined.')发票抽取示例
将模式应用于从真实发票文本中抽取结构化数据:
invoice_text = '''
INVOICE #INV-2025-0342
From: Acme Software Ltd.
123 Tech Street, San Francisco, CA 94105
Date: March 15, 2025
Due: April 14, 2025
Items:
- Annual Pro License (5 seats) x1 @ $2,400.00 = $2,400.00
- Setup & Onboarding x2 @ $300.00 = $600.00
Subtotal: $3,000.00
Tax (8.5%): $255.00
TOTAL DUE: $3,255.00 USD
'''
result = extract_invoice(invoice_text)
print(f'Invoice: {result["invoice_number"]}')
print(f'Vendor: {result["vendor_name"]}')
print(f'Total: {result["currency"]} {result["total_amount"]}')
print(f'Line items: {len(result["line_items"])}')会议记录抽取
将模式驱动的抽取应用于会议记录——这是一种结构化程度较低的文档类型:
MEETING_SCHEMA = '''
{
"meeting_title": "string",
"date": "YYYY-MM-DD",
"attendees": ["string"],
"decisions": ["string"],
"action_items": [
{
"task": "string",
"owner": "string or null",
"due_date": "YYYY-MM-DD or null"
}
],
"next_meeting": "string or null"
}
'''
meeting_notes = '''
Product Sync - March 20, 2025
Attendees: Sarah (PM), Jake (Engineering), Priya (Design)
Decided to push the v2.0 launch to April 15.
Will not include the analytics dashboard in v2.0.
Actions:
- Jake to fix the login bug by March 25
- Priya to finalize mockups by March 22
- Sarah to send updated roadmap to stakeholders (no date set)
Next sync: March 27, same time.
'''
print(f'Meeting schema: {len(MEETING_SCHEMA)} chars')
print(f'Notes length: {len(meeting_notes)} chars')产品规格抽取
从目录描述中抽取结构化的产品规格:
PRODUCT_SCHEMA = '''
{
"product_name": "string",
"sku": "string or null",
"category": "string",
"price": {"amount": "number", "currency": "string"},
"dimensions": {
"length_cm": "number or null",
"width_cm": "number or null",
"height_cm": "number or null",
"weight_kg": "number or null"
},
"colors": ["string"],
"materials": ["string"],
"features": ["string"],
"in_stock": true | false
}
'''
product_text = 'AlphaDesk Pro standing desk. SKU: AD-PRO-001. $899. Available in white and black. 120x60x75cm, 35kg. Steel frame, bamboo top. Features: memory height, anti-collision, app control. In stock.'
prompt = f'Extract product specs. Return JSON:\n{PRODUCT_SCHEMA}\n\nProduct: {product_text}'
r = client.messages.create(model='claude-opus-4-5', max_tokens=400, messages=[{'role': 'user', 'content': prompt}])
print(json.loads(r.content[0].text))处理可选字段
模式必须妥善处理可选字段。对于缺失数据,请使用 null 作为默认值,而不是省略字段——这样可以保持输出结构一致:
prompt_optional = '''
Extract the data. For fields not present in the source text,
use null — do NOT omit the field.
Every field in the schema must appear in the output.
Schema:
{
"company": "string",
"ceo": "string or null",
"founded": "YYYY or null",
"revenue": "string or null",
"employees": "number or null"
}
Text: Vertex AI Solutions is a B2B SaaS company.
'''
# Expected output: ceo, founded, revenue, employees all set to null
# NOT omitted — null fields are still present in the JSON
print(prompt_optional)使用同一模式进行多文档抽取
同一模式可以一致地应用于许多文档。这就是如何大规模地从非结构化文档构建结构化数据库:
def extract_many(documents, schema):
results = []
for i, doc in enumerate(documents):
try:
r = client.messages.create(
model='claude-opus-4-5', max_tokens=400,
messages=[{'role': 'user', 'content': f'Extract data. Return JSON matching schema:\n{schema}\n\nDocument:\n{doc}'}]
)
parsed = json.loads(r.content[0].text)
parsed['_source_doc'] = i
parsed['_extraction_ok'] = True
results.append(parsed)
except (json.JSONDecodeError, Exception) as e:
results.append({'_source_doc': i, '_extraction_ok': False, '_error': str(e)})
return results
invoices = ['Invoice from Acme, March 2025, $500', 'Invoice from Beta Corp, April 2025, $1200']
results = extract_many(invoices, INVOICE_SCHEMA)
print(f'Processed: {len([r for r in results if r["_extraction_ok"]])} success, {len([r for r in results if not r["_extraction_ok"]])} failed')抽取后的模式验证
使用 Python 的 jsonschema 库或自定义验证器,根据预期模式验证抽取的数据:
def validate_extracted(data, required_fields, type_checks):
errors = []
# Check required fields
for field in required_fields:
if field not in data or data[field] is None:
errors.append(f'Required field missing or null: {field}')
# Check types
for field, expected_type in type_checks.items():
if field in data and data[field] is not None:
if not isinstance(data[field], expected_type):
errors.append(f'{field}: expected {expected_type.__name__}, got {type(data[field]).__name__}')
return errors
extracted = {'invoice_number': 'INV-001', 'total_amount': 3255.0, 'vendor_name': 'Acme', 'invoice_date': '2025-03-15'}
required = ['invoice_number', 'total_amount', 'vendor_name']
types = {'total_amount': float, 'invoice_number': str, 'line_items': list}
errors = validate_extracted(extracted, required, types)
print('Validation errors:', errors)迭代完善模式
模式通过反复测试不断演进。流程如下:
- 根据领域知识定义初始模式
- 在 20 份样本文档上运行抽取
- 检查输出——哪些字段经常出错或缺失?
- 完善模式描述并添加字段定义
- 在同样的 20 份文档上重新运行
- 重复此过程,直到质量达到阈值
向模式添加字段描述
当字段含义不明确时,请添加描述性注释来引导模型:
ANNOTATED_SCHEMA = '''
{
"invoice_number": "string // The unique identifier for this invoice, e.g., INV-2025-001",
"invoice_date": "YYYY-MM-DD // Date the invoice was issued",
"due_date": "YYYY-MM-DD or null // Payment due date; null if not specified",
"subtotal": "number // Amount before tax, as a decimal number",
"tax": "number or null // Tax amount as a decimal; null if tax is not listed",
"total_amount": "number // Final amount to pay, including tax",
"payment_terms": "string or null // e.g., Net 30, Due on receipt; null if not mentioned"
}
'''
print('Annotated schema adds context per field.')
print(f'Schema length: {len(ANNOTATED_SCHEMA)} chars')抽取字段的置信度分数
对于生产系统,请为每个字段包含置信度分数。低置信度的抽取结果可以转交人工审核:
SCHEMA_WITH_CONFIDENCE = '''
{
"fields": {
"invoice_number": {"value": "string", "confidence": "high|medium|low"},
"total_amount": {"value": "number", "confidence": "high|medium|low"},
"due_date": {"value": "YYYY-MM-DD or null", "confidence": "high|medium|low"}
},
"overall_confidence": "high|medium|low",
"extraction_notes": "string or null // Any ambiguities encountered"
}
'''
prompt = f'Extract invoice data with confidence scores.\nReturn JSON:\n{SCHEMA_WITH_CONFIDENCE}\n\nInvoice: Payment due within 30 days. Total is approximately $500.'
r = client.messages.create(model='claude-opus-4-5', max_tokens=300, messages=[{'role': 'user', 'content': prompt}])
result = json.loads(r.content[0].text)
print('Overall confidence:', result.get('overall_confidence'))
print('Notes:', result.get('extraction_notes'))快速检查
当源文档中不存在必填字段时,模式驱动的抽取提示词应该指示模型为该字段返回什么?
模式驱动的抽取——要点
模式驱动的抽取是生产环境中可靠处理文档的标准:
- 在提示词中提供完整准确的 JSON 模式——模型将其作为输出契约使用
- 为含义不明确的字段添加字段描述,引导模型进行解释
- 始终指示:缺失字段返回空值,绝不省略字段
- 在许多文档中应用同一模式,以获得一致且可直接用于数据库的输出
- 为每个字段加入置信度分数,以便将结果转交人工审核
- 每次抽取后都以编程方式验证抽取的数据
- 迭代完善模式:抽取 20 份样本、检查、改进、重复
常见问题解答
「由模式驱动的数据提取」课时是免费的吗?
是的 — 「由模式驱动的数据提取」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。
「由模式驱动的数据提取」这节课中我会学到什么?
在提示中提供 JSON 模式,以确保结构化输出格式 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Prompt Engineering 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「由模式驱动的数据提取」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Prompt Engineering 课中编写并运行代码吗?
能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 命名实体提取提示
- 由模式驱动的数据提取
- 将 LLM 用作文本分类器
- 分类中的置信度与不确定性