This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/java/extraction/decide-document.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Making decisions from JSON data | Nutrient Java SDK

Not every judgment call fits a classification label or a structured extraction field. “Is this total plausible?”, “Which expense category applies?”, “How confident are we this clause is a liability waiver?” — these are calibrated yes/no, multiple-choice, or ordinal decisions over state you already have, not a document Nutrient needs to open and parse itself.

This sample shows how to get calibrated decisions from Nutrient’s decision model using Nutrient Java SDK. You supply the shared state and the questions to ask against it directly as JSON; the SDK returns a calibrated answer — with a confidence and the full probability distribution — for each question. It runs locally.

Decision API is available in Nutrient Java SDK 2.1.13 and later.

Download sample

How Nutrient helps

The decision API is a generic pass-through onto Nutrient’s decision model — no document, schema, or template list is involved. The SDK handles:

  • Rendering the shared state and each question into the model’s expected prompt format
  • Embedding any inline images in the state at the position they appear
  • Reading one label token’s logits per question — the model never generates text, so answers are deterministic reads, not samples
  • Calibrating the raw result into a confidence and a full probability distribution per question
  • Serializing every answer plus token usage to JSON

Questions and state

stateJson is the shared context every question is evaluated against — any JSON object, array, or plain string. Embed images anywhere in the structure as {"type": "image", "source": "data:<mime>;base64,<bytes>"}; the SDK walks the whole state, substitutes each with the model’s media marker, and sends the image bytes alongside, in encounter order.

questionsJson is an array of {id, type, instructions, options?}:

  • type: "noul" — a yes/no judgment. options can be omitted (default true/false wording) or given as exactly two entries for custom wording.
  • type: "choice" — pick one of 2+ options, each {key, description}.
  • type: "score" — an ordinal judgment over 2+ unlabeled options, numbered low to high by position.

Every question is answered independently in the same call, against the same shared state.

The decision API requires the decision model feature in your license.

Complete implementation

Declare the sample’s package:

package io.nutrient.Sample;

Import the classes used in the sample:

import io.nutrient.sdk.Vision;
import io.nutrient.sdk.exceptions.NutrientException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

Building the state and questions

Decide works on plain JSON you already have — here, a parsed invoice record instead of a loaded document. This sample builds the JSON by hand to keep the dependency list minimal; use your preferred JSON library in production code:

public class DecideDocument {
public static void main(String[] args) {
String stateJson =
"{" +
" \"invoice\": {" +
" \"vendor\": \"Acme Consulting LLC\"," +
" \"total\": 1204.50," +
" \"currency\": \"USD\"," +
" \"description\": \"Software and subscriptions renewal\"" +
" }" +
"}";
String questionsJson =
"[" +
" {" +
" \"id\": \"amount_reasonable\"," +
" \"type\": \"noul\"," +
" \"instructions\": \"Is the total a plausible amount for this invoice?\"" +
" }," +
" {" +
" \"id\": \"category\"," +
" \"type\": \"choice\"," +
" \"instructions\": \"Which expense category applies?\"," +
" \"options\": [" +
" { \"key\": \"travel\", \"description\": \"Travel and lodging\" }," +
" { \"key\": \"software\", \"description\": \"Software and subscriptions\" }," +
" { \"key\": \"office_supplies\", \"description\": \"Office supplies and equipment\" }" +
" ]" +
" }" +
"]";

Getting the decisions

Call the static Vision.decide(stateJson, questionsJson):

try {
String resultJson = Vision.decide(stateJson, questionsJson);
Files.writeString(Path.of("output.json"), resultJson);
} catch (NutrientException | IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}

Understanding the output

decide() returns JSON with top-level answers and usage objects:

  • answers — one entry per question id. Each carries:
    • type — the question’s type (noul, choice, or score), echoed back.
    • chosenIndex — the index of the selected option.
    • chosenKey — the option’s key ("true"/"false" for noul; a lettered label like "A" for score, since score options have no key).
    • confidence — the calibrated probability of the chosen answer.
    • probabilities — the full calibrated probability distribution over every option, in option order.
  • usage — promptTokens (exact, from the model’s own decode) and outputTokens (one per question answered — decide() never generates text, so this counts work done, not text length).

Choosing question types

Use noul for a single yes/no judgment, choice when the answer is one of several discrete categories, and score for an ordinal judgment (low to high) where the options don’t need individual names. Batching related judgments into fewer, larger choice/score questions is more efficient than asking many separate noul questions, since each question re-evaluates the full shared state.

Error handling

Vision API throws VisionException (a NutrientException) when a decision call fails.

Common failure scenarios include:

  • stateJson or questionsJson is empty or missing
  • The decision model is missing or inaccessible, or the feature isn’t licensed
  • A question’s options are malformed for its type (for example, choice with fewer than two options)

In production code:

  • Catch NutrientException.
  • Return a clear error message.
  • Log failure details for debugging.

Conclusion

The workflow for getting decisions is:

  1. Build the shared state as a JSON value — any object, array, or string you already have.
  2. Build the questions array, choosing noul, choice, or score per judgment.
  3. Call Vision.decide() with both payloads as JSON strings.
  4. Write the JSON result to a file, then read each question’s chosenKey and confidence for downstream routing.
  5. Handle NutrientException for robust error recovery.

For related document workflows, refer to the Java SDK guides.

Download this ready-to-use sample package to explore the decision API.