ES|QL COMPLETION command
The ES|QL COMPLETION command enables LLM inference directly within ES|QL queries. It sends a prompt to a configured inference endpoint and returns the completion result as a new column. This supports both RAG (retrieval-augmented generation) pipelines and standalone completions.
COMPLETION [column =] prompt WITH { "inference_id" : "endpoint-id" }
- prompt - a field reference or expression containing the prompt text
- inference_id - the inference endpoint ID configured in your Elasticsearch cluster
- column (optional) - output column name; defaults to
completionif omitted
The InferenceEndpoints class provides constants for preconfigured serverless inference endpoints:
using Elastic.Esql;
InferenceEndpoints.Anthropic.Claude46Opus // ".anthropic-claude-4.6-opus-completion"
InferenceEndpoints.Anthropic.Claude45Sonnet // ".anthropic-claude-4.5-sonnet-completion"
InferenceEndpoints.Anthropic.Claude45Opus // ".anthropic-claude-4.5-opus-completion"
InferenceEndpoints.Anthropic.Claude37Sonnet // ".anthropic-claude-3.7-sonnet-completion"
InferenceEndpoints.Google.Gemini25Pro // ".google-gemini-2.5-pro-completion"
InferenceEndpoints.Google.Gemini25Flash // ".google-gemini-2.5-flash-completion"
InferenceEndpoints.OpenAi.Gpt52 // ".openai-gpt-5.2-completion"
InferenceEndpoints.OpenAi.Gpt41 // ".openai-gpt-4.1-completion"
InferenceEndpoints.OpenAi.Gpt41Mini // ".openai-gpt-4.1-mini-completion"
InferenceEndpoints.OpenAi.GptOss120B // ".openai-gpt-oss-120b-completion"
InferenceEndpoints.Elastic.GpLlmV2 // ".gp-llm-v2-completion"
You can also pass any string as the inference ID for custom endpoints.
Append .Completion() to a FROM-based query to run LLM inference on query results. This is the typical RAG pattern: retrieve documents, then send a field to the LLM.
var esql = client.CreateQuery<LogEntry>()
.Where(l => l.StatusCode >= 500)
.Take(1)
.Completion("message", InferenceEndpoints.OpenAi.Gpt41, column: "analysis")
.Keep("message", "analysis")
.ToString();
FROM logs-*
| WHERE statusCode >= 500
| LIMIT 1
| COMPLETION analysis = message WITH { "inference_id" : ".openai-gpt-4.1-completion" }
| KEEP message, analysis
Use a lambda selector for type-safe field resolution. Field names are resolved from [JsonPropertyName] attributes or the configured naming policy:
var esql = client.CreateQuery<LogEntry>()
.Completion(l => l.Message, InferenceEndpoints.Anthropic.Claude46Opus, column: "summary")
.ToString();
FROM logs-*
| COMPLETION summary = message WITH { "inference_id" : ".anthropic-claude-4.6-opus-completion" }
When column is omitted, ES|QL defaults the output column to completion:
var esql = client.CreateQuery<LogEntry>()
.Completion(l => l.Message, InferenceEndpoints.Google.Gemini25Flash)
.ToString();
FROM logs-*
| COMPLETION message WITH { "inference_id" : ".google-gemini-2.5-flash-completion" }
Use .Row() to create a standalone ROW + COMPLETION pipeline for sending a prompt without querying an index. The Row() extension method accepts an anonymous object — property names become column names and values are automatically escaped:
var esql = client.CreateQuery<CompletionResult>()
.Row(() => new { prompt = "Tell me about Elasticsearch" })
.Completion("prompt", InferenceEndpoints.Anthropic.Claude46Opus, column: "answer")
.ToString();
ROW prompt = "Tell me about Elasticsearch"
| COMPLETION answer = prompt WITH { "inference_id" : ".anthropic-claude-4.6-opus-completion" }
A full retrieval-augmented generation pipeline that fetches error logs, builds a prompt, sends it to an LLM, and keeps only the relevant output:
var esql = client.CreateQuery<LogEntry>()
.Where(l => l.StatusCode >= 500)
.OrderByDescending(l => l.Timestamp)
.Take(10)
.Completion(l => l.Message, InferenceEndpoints.OpenAi.Gpt41, column: "analysis")
.Keep("message", "analysis")
.ToString();
FROM logs-*
| WHERE statusCode >= 500
| SORT @timestamp DESC
| LIMIT 10
| COMPLETION analysis = message WITH { "inference_id" : ".openai-gpt-4.1-completion" }
| KEEP message, analysis
The ROW source command produces a row with literal values. It is primarily used with COMPLETION for standalone prompts, but is available as a general-purpose command:
var esql = client.CreateQuery<MyType>()
.Row(() => new { a = 1, b = "hello" })
.ToString();
ROW a = 1, b = "hello"
| Method | Description |
|---|---|
.Row(Expression<Func<object>> columns) |
Produces a row with literal values (ROW command) |
.Completion(string prompt, string inferenceId, string? column) |
Adds a COMPLETION command with a string field name |
.Completion(Expression<Func<T, string>> prompt, string inferenceId, string? column) |
Adds a COMPLETION command with a type-safe lambda selector |