Function calling extraction means giving a model a function schema and using the arguments it returns as your structured data, without ever running the function. It gets you well-formed JSON. It does not get you correct values, and it does not make runs identical. Everything below is about closing that gap: schema design, validation, retries, evaluation, and where a deterministic layer has to sit around a probabilistic model.
TL;DR
- Function calling lets a model return a tool call with arguments that match a JSON Schema you define. Used for extraction, the schema is just a format contract.
- Schema-constrained generation guarantees syntactic validity, not value correctness. Validate every response.
- "Deterministic" extraction is a system property, not a model property: typed schemas, validation, bounded retries, logged raw output, human review for failures.
- If you only need extraction and no action choice, schema-constrained output is the leaner tool.
Table of Contents
- How function calling becomes an extraction tool
- Writing a schema that extracts reliably
- What "deterministic" can and can't mean
- Parsing, validating, and failing loudly
- Measuring whether extraction is accurate
- Our perspective
- Try it on real pages
- FAQ
- Sources
How function calling becomes an extraction tool
Function calling was designed so a model could ask your application to do something: look up a record, send a message. You describe a function with a JSON Schema, the model returns a tool call with arguments, and your application executes it.
For extraction you skip the execution. You define a function such as record_invoice(vendor, total, currency, due_date), pass in a page or document, and treat the returned arguments as the result. One developer describes this as using function calling to get structured data in a provided schema, which beats parsing free-form chat text. Databricks researchers note that batched feature extraction of this kind is increasingly common for turning large document collections into machine-readable JSON.
Two caveats before you build on it:
- The schema constrains shape. It says nothing about whether
totalis the number on the page. - If the model never has to choose between actions, you are paying for tool-selection machinery you don't use. Function calling suits tasks where the model must pick an action; schema-constrained output is leaner for extraction alone.
Writing a schema that extracts reliably
Most extraction bugs are schema bugs. The OpenAI guidance is a good baseline:
- Descriptive names.
invoice_total_usdbeatsamount. - Explicit types. Numbers as numbers, dates as strings with a stated format.
- Enums for closed sets.
status: "paid" | "unpaid" | "unknown". - A description on the function and every parameter, plus specific instructions or examples in the prompt.
- The intern test. Could a human use the function correctly from the description alone? If not, the model can't either.
One addition we hold to hard: give every field an honest way to be empty. A required price field on a page with no price invites a plausible invented one. Make fields nullable, add an unknown enum value, and tell the model that null is correct when the source is silent. MLflow puts the cost of sloppy design bluntly: schema decisions made in week one tend to decide how many 2 AM pages you get by month three.
What "deterministic" can and can't mean
Readers searching for deterministic LLM extraction usually want the same input to give the same output, every time. No prompt or setting promises that. What you can promise is narrower and still valuable:
| Property | Achievable? | How |
|---|---|---|
| Output parses as JSON | Yes, with constrained generation | Schema-enforced output |
| Output matches your types | Yes | Schema plus validation on your side |
| Values match the source | No guarantee | Validation, evaluation, review |
| Identical output across runs | Not guaranteed | Cache results, store raw output, version the schema |
Google's explanation of controlled generation makes the same point: schema enforcement makes the format predictable, but the response still depends on the model's extraction ability, and when the source lacks information the model can fill in an answer from training data. Merely asking for JSON is weaker still: prompted JSON carries no structural guarantee and belongs in prototypes.
So make determinism a property of your pipeline. Store the fetched source and the raw model output together, so any result can be replayed and audited. Our write-up on data collection repeatability covers that side in detail.

Parsing, validating, and failing loudly
Treat the model's arguments as untrusted input.
- Parse. Handle malformed output as a normal case.
- Validate. Run the result through Pydantic or Zod. The MLflow guidance is to validate, then retry with a tightened prompt or route to human review, logging the raw output.
- Retry with a bound. One or two retries with the validation error included. Not a loop.
- Escalate. Failures go to a review queue, not into your database.
- Return a typed failure.
{ "status": "failed", "reason": "missing_field", "field": "due_date" }is something downstream code and agents can reason about. A silent empty string is not.
At larger scale, orchestration helps. AWS describes Step Functions pipelines that invoke a model, validate against a JSON schema, and retry or escalate. For a deeper look at how tool-calling setups fail in layers, see this piece on function calling limits for engineers.
We go through a staged version of this flow, with typed errors at each stage, in our six-stage LLM data extraction pipeline and the post on structured extraction with schema validation.
Measuring whether extraction is accurate
The published evidence says LLM extraction is strong on explicit, discrete fields and weaker elsewhere.
- A peer-reviewed ecological-literature study found accuracy above 90% for discrete and categorical data but poor results on some quantitative data, and concluded that extra quality assurance is required.
- A PLOS ONE study reported 92.4% accuracy across 484 systematic-review data points, with reproducibility dropping when information was not reported in the source.
The pattern is consistent: numbers, units, and absent fields are where errors concentrate. Build your evaluation around them.
For method, Databricks describes checking arguments against ground truth with AST or executable evaluation and recommends combining frameworks, since each has limits. HammerBench splits scoring into function-name accuracy, parameter hallucination and missing rates, and argument accuracy, a useful template for your own metrics. Arize suggests inspecting traces for schema conformity and correctness, and admits scale evaluation is hard because ground truth is often absent.
A practical start: hand-label 50 to 100 documents, score each field separately, and track hallucinated-value and missing-value rates apart from format errors.
Our perspective
Web data is a storm: pages change, render differently, and omit what you expected. A model that returns tidy JSON for that mess can look more certain than it has any right to be.
We build Gyrence around that problem. Every call returns a typed, discriminated-union response, failures included, so an agent or pipeline sees ok, partial, or a named failure mode instead of guessing. Extraction is schema-guided, and there is no separate AI extraction charge, so retries and validation passes don't hide a second meter. Our view: if your extraction layer can't say "I couldn't find this field," it will eventually say something false instead. Pair constrained output with validation, keep the source, and let review catch the rest.
On web pages specifically, see our schema-guided extraction benchmarks and the guide to structured JSON extraction from the web.
— Glen
Try it on real pages
If you'd rather not wire up fetching, cleaning, prompting, and typed errors yourself, the Gyrence API combines Fetch and Extract behind one call, with spending caps. Paid plans start with Standard at $75 per month; Growth is $299 and Scale is $549 per month. There is also a Free tier and Pay-As-You-Go. See plans and pricing.
If the pages you extract from change often, WebDoppler monitors them and sends webhook alerts.
FAQ
Is function calling or structured output better for extraction?
If the model only has to fill a schema, schema-constrained output is the leaner choice. Function calling earns its place when the model must also decide which action to take. Either way, you still validate the values.
Can function calling guarantee correct values?
No. Constrained generation guarantees syntactic validity, not value correctness. A field can be perfectly typed and wrong, so check outputs against rules and, for high-stakes data, a reviewer.
How do I handle missing fields?
Make them nullable or give them an unknown enum value, and instruct the model to use it when the source is silent. Then validate and route failures to a retry or review queue. Missing information is where models are most likely to produce plausible inventions.
How do I get repeatable results?
Store the source and raw output, version your schema, and cache results by input hash. Identical outputs from a fresh model call are not guaranteed, so repeatability comes from your pipeline.
Sources
- Function calling, OpenAI
- Function Calling is Structured Output
- Beyond the Leaderboard: Unpacking Function Calling Evaluation, Databricks
- Enforce, Validate, Observe: LLM Structured Output, MLflow
- Mastering Controlled Generation with Gemini 1.5, Google Developers
- Ensuring Consistent JSON Output from LLMs on Amazon Bedrock
- Function Calling Limits for Engineers
- Testing the reliability of an AI-based large language model for data extraction
- ChatGPT-4o can serve as the second rater for data extraction, PLOS ONE
- HammerBench, ACL Findings 2025
- Structured Data Extraction, Arize Phoenix

