ML inference processor
The ml_inference search processor calls a registered machine learning model during a search, and exists in two forms:
- A search request processor, which maps fields out of the incoming query, calls the model, and writes the result back into the query — or into a query template — before the search runs.
- A search response processor, which calls the model on the returned hits and writes the result onto them before the response reaches the client.
Both share the name ml_inference and the same configuration vocabulary as the ml_inference ingest processor: model_id, input_map, output_map. Where they sit in the pipeline decides what they can see.
As a search request processor
The request form is how a model rewrites a query before it executes. It maps values out of the query string, calls the model, and substitutes the output into the query — either directly, or into a query_template you supply.
PUT /_search/pipeline/rewrite-query
{
"request_processors": [
{
"ml_inference": {
"model_id": "NWR9YIsBUysqmzBdifVJ",
"input_map": [
{ "input_text": "query.term.description.value" }
],
"output_map": [
{ "expanded": "response" }
],
"query_template": "{\"query\":{\"match\":{\"description\":\"${expanded}\"}}}"
}
}
]
}
If your goal is specifically to turn query text into a vector, prefer the semantic query or the query embedding processor. They enforce the correctness rule that matters — the query must be embedded with the same provider and model used at ingest, or the vectors are not comparable.
As a search response processor
The response form runs the model over the hits that came back — rerank them, classify them, enrich them, score them — and writes the result onto each hit.
PUT /_search/pipeline/enrich-hits
{
"response_processors": [
{
"ml_inference": {
"model_id": "NWR9YIsBUysqmzBdifVJ",
"input_map": [
{ "input_text": "description" }
],
"output_map": [
{ "category": "response" }
],
"one_to_one": true
}
}
]
}
one_to_one decides how hits are presented to the model: true sends one prediction per hit, false batches the hits into a single call. Batching is cheaper; one-to-one keeps each hit's result independent.
Request fields
| Field | Type | Description | Required |
|---|---|---|---|
model_id | String | The registered model to call. | Yes |
input_map | List | Maps query or hit fields to model input fields. | No |
output_map | List | Maps model output back onto the query or the hits. | No |
model_config | Object | Extra model configuration merged into the request. | No |
model_input | String | Template for the model input payload. | No |
function_name | String | The model's function name, for locally hosted models. | No |
full_response_path | Boolean | Read outputs from the full model response path. | No |
query_template | String | Request processor only. Query to substitute model output into. | No |
one_to_one | Boolean | Response processor only. One prediction per hit rather than one batched call. | No |
ignore_missing | Boolean | Skip quietly when a mapped source field is absent. Defaults to false. | No |
ignore_failure | Boolean | Standard processor setting — continue the pipeline if this processor fails. | No |
Choosing between ml_inference and a purpose-built processor
| Use | When |
|---|---|
semantic query | Search by meaning — the cluster embeds the text for you. |
query_embedding | Embed query text into an existing vector query. |
multimodal_rerank | Rerank hits with a multimodal model. |
retrieval_grounding | Ground generated answers in retrieved passages. |
ml_inference | Anything else a registered model can do at query time. |