Recipe

Entity extraction patterns

Pulling structured entities out of unstructured text is one of the most common Meridian workloads. This recipe walks through three patterns that work reliably in production: schema-locked JSON, span-grounded extraction, and multi-pass refinement. Each pattern trades latency for precision.

1. Schema-locked JSON

The fastest pattern. Define a strict JSON schema, pass it as a response format, and let the model fill it in one shot. Best for well-bounded entities like contacts, line items, or invoice fields where the shape is known up front and false negatives are cheaper than false positives.

const response = await meridian.chat.completions.create({
  model: 'azure/model-router',
  messages: [{ role: 'user', content: doc }],
  response_format: {
    type: 'json_schema',
    json_schema: {
      name: 'invoice',
      schema: {
        type: 'object',
        properties: {
          vendor: { type: 'string' },
          total:  { type: 'number' },
          line_items: { type: 'array' }
        },
        required: ['vendor', 'total']
      }
    }
  }
})

2. Span-grounded extraction

When you need to cite the source, ask the model to return character offsets alongside each entity. This makes downstream review tractable and gives you a built-in audit trail. Pair it with a cheap verifier pass that checks the cited span actually contains the claimed entity.

Span grounding adds roughly 30% to output tokens but eliminates the most common hallucination failure: confidently invented values that never appeared in the source document.

3. Multi-pass refinement

For high-stakes extraction (legal, medical, financial) run two passes with different models and reconcile. First pass: a fast model produces a draft. Second pass: a stronger reasoning model reviews the draft against the source and flags any field where it disagrees. Surface disagreements for human review; auto-accept consensus fields. Cost roughly doubles, error rate drops 4-8x.