0Pricing
AI Prompt Engineering · 课时

由模式驱动的数据提取

在提示中提供 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)

迭代完善模式

模式通过反复测试不断演进。流程如下:

  1. 根据领域知识定义初始模式
  2. 在 20 份样本文档上运行抽取
  3. 检查输出——哪些字段经常出错或缺失?
  4. 完善模式描述并添加字段定义
  5. 在同样的 20 份文档上重新运行
  6. 重复此过程,直到质量达到阈值

向模式添加字段描述

当字段含义不明确时,请添加描述性注释来引导模型:

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 命名实体提取提示
  2. 由模式驱动的数据提取
  3. 将 LLM 用作文本分类器
  4. 分类中的置信度与不确定性
← 返回 AI Prompt Engineering