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.