xAI (Grok) Provider Guide

View Source

xAI's Grok models provide powerful reasoning capabilities with real-time web search through Live Search integration.

Configuration

Set your xAI API key:

# Add to .env file (automatically loaded)
XAI_API_KEY=xai-...

Or use in-memory storage:

ReqLLM.put_key(:xai_api_key, "xai-...")

Supported Models

xAI Grok models:

  • grok-4 - Latest and most capable
  • grok-3-mini, grok-3-mini-fast - Efficient with reasoning support
  • grok-2-1212, grok-2-vision-1212 - Previous generation with vision
  • grok-beta - Beta features

See the full list with mix req_llm.model_sync xai.

Basic Usage

# Simple text generation
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Explain quantum computing"
)

# Streaming
{:ok, stream_response} = ReqLLM.stream_text(
  "xai:grok-4",
  "Write a story"
)

ReqLLM.StreamResponse.tokens(stream_response)
|> Stream.each(&IO.write/1)
|> Stream.run()

Provider-Specific Options

Max Completion Tokens

Preferred over max_tokens for Grok-4 models:

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Long explanation",
  provider_options: [max_completion_tokens: 2000]
)

Note: ReqLLM automatically translates max_tokens to max_completion_tokens for models that require it.

Enable real-time web search capabilities:

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "What are today's top tech headlines?",
  provider_options: [
    search_parameters: %{
      mode: "auto",              # auto, always, or never
      max_sources: 5,            # Maximum sources to cite
      date_range: "recent",      # recent, week, month, year
      citations: true            # Include citations in response
    }
  ]
)

Search modes:

  • "auto" - Search when beneficial (default)
  • "always" - Always search
  • "never" - Disable search

Note: Live Search incurs additional costs per source retrieved.

Reasoning Effort

Control reasoning level (grok-3-mini models only):

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-3-mini",
  "Complex problem",
  provider_options: [reasoning_effort: "high"]
)

Levels: "low", "medium", "high"

Note: Only supported for grok-3-mini and grok-3-mini-fast models.

Parallel Tool Calls

Control whether multiple tools can be called simultaneously:

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Check weather in multiple cities",
  tools: [weather_tool],
  provider_options: [parallel_tool_calls: true]  # Default
)

Structured Output Mode

xAI supports two modes for structured outputs:

schema = [
  name: [type: :string, required: true],
  age: [type: :integer, required: true]
]

# Auto mode (recommended) - automatic selection
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :auto]
)

# JSON schema mode - uses native response_format (models >= grok-2-1212)
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :json_schema]
)

# Tool strict mode - uses strict tool calling (fallback for older models)
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-2",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :tool_strict]
)

Modes:

  • :auto - Automatic selection based on model (default)
  • :json_schema - Native structured outputs (requires grok-2-1212+)
  • :tool_strict - Strict tool calling fallback

Stream Options

Configure streaming behavior:

{:ok, stream_response} = ReqLLM.stream_text(
  "xai:grok-4",
  "Story",
  provider_options: [
    stream_options: %{include_usage: true}
  ]
)
import ReqLLM.Context

context = Context.new([
  system("You are a helpful assistant with access to real-time web search"),
  user("Summarize today's news about AI developments")
])

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  context,
  temperature: 0.7,
  max_tokens: 1500,
  provider_options: [
    search_parameters: %{
      mode: "always",
      max_sources: 10,
      date_range: "recent",
      citations: true
    },
    parallel_tool_calls: true
  ]
)

text = ReqLLM.Response.text(response)
usage = response.usage

IO.puts(text)
IO.puts("Cost: $#{usage.total_cost}")

Tool Calling

Grok supports function calling:

tools = [
  ReqLLM.tool(
    name: "get_weather",
    description: "Get weather for a location",
    parameter_schema: [
      location: [type: :string, required: true]
    ],
    callback: {WeatherAPI, :fetch}
  ),
  ReqLLM.tool(
    name: "get_stock_price",
    description: "Get stock price",
    parameter_schema: [
      symbol: [type: :string, required: true]
    ],
    callback: {StockAPI, :fetch}
  )
]

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "What's the weather in NYC and the price of AAPL?",
  tools: tools,
  provider_options: [parallel_tool_calls: true]  # Can call both tools at once
)

Structured Output

Grok models support native structured outputs (grok-2-1212 and newer):

schema = [
  title: [type: :string, required: true],
  summary: [type: :string, required: true],
  tags: [type: {:list, :string}],
  confidence: [type: :float]
]

{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Analyze this article and extract structured data",
  schema
)

data = ReqLLM.Response.object(response)

Schema Constraints

xAI's native structured outputs have limitations:

Not Supported:

  • minLength/maxLength for strings
  • minItems/maxItems/minContains/maxContains for arrays
  • pattern constraints
  • allOf (must be expanded/flattened)

Supported:

  • anyOf
  • additionalProperties: false (enforced on root)

ReqLLM automatically sanitizes schemas to comply with these constraints.

Model-Specific Notes

Grok-4 Models

  • Do NOT support stop, presence_penalty, or frequency_penalty
  • Use max_completion_tokens instead of max_tokens
  • Support native structured outputs

Grok-3-mini Models

  • Support reasoning_effort parameter
  • Efficient for cost-sensitive applications
  • Good balance of speed and quality

Grok-2 Models (1212+)

  • Support native structured outputs
  • Support vision (grok-2-vision-1212)
  • Previous generation capabilities

Vision Support

Grok vision models support image analysis:

import ReqLLM.Context
alias ReqLLM.Message.ContentPart

context = Context.new([
  user([
    ContentPart.text("Describe this image"),
    ContentPart.image_url("https://example.com/photo.jpg")
  ])
])

{:ok, response} = ReqLLM.generate_text(
  "xai:grok-2-vision-1212",
  context
)

Error Handling

case ReqLLM.generate_text("xai:grok-4", "Hello") do
  {:ok, response} -> 
    handle_success(response)
    
  {:error, error} -> 
    IO.puts("Error: #{error.message}")
end

Cost Considerations

  1. Live Search: Each source retrieved adds cost
  2. Model Selection: grok-3-mini more cost-effective than grok-4
  3. Token Limits: Set appropriate max_completion_tokens to control costs

Resources