Skip to main content
The OpenAI Decisions API reads natural language and images, and returns typed answers and calibrated probabilities instead of generated text. OpenAIDecisions exposes these decisions as a LangChain Runnable, so you can invoke, batch, or compose them with other runnables. It accepts strings, structured JSON, and LangChain message objects, and records traces and token usage in LangSmith. Use it for focused decisions such as routing a request, choosing a model, or checking whether a tool call is safe to run. Use OpenAI decisions in LangChain middleware to control create_agent behavior at specific lifecycle points, including with custom middleware that classifies agent state. See Agent middleware for examples.
OpenAIDecisions and its middleware are in beta and require langchain-openai>=1.7.0. Their APIs may change without notice.

Setup

Create an API key in the OpenAI dashboard and export it:
Optional: Set OPENAI_BASE_URL to use a compatible gateway or test server. The default is the OpenAI API endpoint.
To route requests through the LangSmith LLM gateway, set LANGSMITH_GATEWAY=true. Gateway requests authenticate with LANGSMITH_GATEWAY_API_KEY or LANGSMITH_API_KEY:

Quickstart

Create an OpenAIDecisions instance with a decisions model, then pass the input and named questions together in each invocation. Questions that share input are answered in one request:
Answers are keyed by the question names you supplied, and grouped by type on predicates, choices, scores, and refusals. The response also carries the model that answered, token usage, and the OpenAI request_id. The request input can be a string, a JSON object or array, or LangChain messages. Strings and HumanMessage objects, including text and base64 image content, are sent natively. Other input, such as conversations with system, AI, or tool messages, or JSON objects, is sent as JSON text in a single user message, with base64 images kept in place as image parts.

Decision types

Each question is one of three types: Predicate is the only one without a confidence, since the probability is the answer. Use Score rather than a Predicate for a spectrum: a probability of 0.5 means an even split between yes and no, not “medium”. Score levels are ordered from lowest to highest and indexed from 0. Pass a plain string for a label-only level, or a Level with a label and description. The returned score is the probability-weighted average of the level indices, so it may fall between levels, and legend maps each index to its label. When the model declines to answer a question, the answer is a RefusalAnswer on refusals instead of a typed answer. Check for a missing key before reading a typed answer when refusals are possible.

Agent middleware

The package includes two beta middleware that put OpenAI decisions on an agent’s decision points. Import them from langchain_openai.middleware. Install langchain alongside the OpenAI integration before using them:
Both middleware require a model: a decisions model name, or a configured OpenAIDecisions instance.

Model routing

Classifies the latest human message across your named models and uses the selected one for every model call in the run. Each ModelChoice pairs a model with the criterion for picking it:
The answer is stored in agent state under model_route as a mapping with choice, probabilities, and confidence. When the model refuses, or the state has no human message, model_route is None and model calls use the agent’s own model.

Tool-risk gating

Asks for the probability that a tool call is risky or insufficiently authorized. Calls with a probability of 0.5 or higher return an error ToolMessage instead of running the tool. Only the tools you list are classified. Pass their names or tool objects:
Override instructions to describe risk for your own tools. The middleware fails closed: refusals block the call, and API errors propagate without running the tool.
Do not put secrets in tool arguments or conversation state unless sending them to OpenAI is acceptable. This middleware refuses risky calls. It does not request approval. Pair it with human-in-the-loop middleware when you want a person to approve them.

Custom middleware

OpenAIDecisions accepts LangChain message objects directly, so a custom middleware hook can classify an agent’s conversation state without converting it first. This example classifies the conversation once at the start of each run and stores the complete ChoiceAnswer in agent state:
Use any lifecycle hook that matches your decision point. For example, use before_model to reclassify after each tool result, or wrap_tool_call to classify a proposed action. See Custom middleware for all hooks and state patterns.

Tracing

OpenAI decisions are traced in LangSmith, so you can inspect decisions and token usage alongside the rest of your agent.

See also