ExLLM.Instructor (ex_llm v0.5.0)
View SourceStructured output support for ExLLM using instructor_ex.
This module provides integration with the instructor
library to enable
structured outputs with validation when using ExLLM. It allows you to
define expected response structures using Ecto schemas and automatically
validates and retries LLM responses.
Supported Providers
The following providers support structured outputs through Instructor:
:anthropic
- Claude models:openai
- GPT models:gemini
- Google Gemini models:ollama
- Local Ollama models:groq
- Groq cloud models:xai
- X.AI Grok models
Other providers (:bedrock
, :openrouter
, :bumblebee
) do not currently
support structured outputs through Instructor.
Requirements
This module requires the instructor
dependency:
{:instructor, "~> 0.1.0"}
Usage
Basic Example
defmodule EmailClassification do
use Ecto.Schema
use Instructor.Validator
@llm_doc "Classification of an email as spam or not spam"
@primary_key false
embedded_schema do
field :classification, Ecto.Enum, values: [:spam, :not_spam]
field :confidence, :float
field :reason, :string
end
@impl true
def validate_changeset(changeset) do
changeset
|> Ecto.Changeset.validate_required([:classification, :confidence, :reason])
|> Ecto.Changeset.validate_number(:confidence,
greater_than_or_equal_to: 0.0,
less_than_or_equal_to: 1.0
)
end
end
# Use with ExLLM
{:ok, result} = ExLLM.Instructor.chat(:anthropic, [
%{role: "user", content: "Is this spam? 'You won a million dollars!'"}
], response_model: EmailClassification)
# result is now an EmailClassification struct
# %EmailClassification{classification: :spam, confidence: 0.95, reason: "..."}
With Retries
{:ok, result} = ExLLM.Instructor.chat(:anthropic, messages,
response_model: UserProfile,
max_retries: 3,
temperature: 0.7
)
With Simple Maps
# Define expected structure
response_model = %{
name: :string,
age: :integer,
tags: {:array, :string}
}
{:ok, result} = ExLLM.Instructor.chat(:anthropic, messages,
response_model: response_model
)
Integration with ExLLM
The structured output functionality is also available through the main ExLLM module when instructor is installed:
{:ok, response} = ExLLM.chat(:anthropic, messages,
response_model: EmailClassification,
max_retries: 2
)
Summary
Functions
Check if instructor is available.
Send a chat request with structured output validation.
Transform a regular ExLLM response into a structured output.
Create a simple schema module at runtime.
Functions
@spec available?() :: boolean()
Check if instructor is available.
Since instructor is now a required dependency, this always returns true
.
Returns
true
(always)
Examples
# This is now always true, but kept for backwards compatibility
if ExLLM.Instructor.available?() do
# Use structured outputs
end
@spec chat(ExLLM.provider(), ExLLM.messages(), keyword()) :: {:ok, struct() | map()} | {:error, term()}
Send a chat request with structured output validation.
Parameters
provider
- The LLM provider to usemessages
- List of conversation messagesoptions
- Options including:response_model
and standard chat options
Options
:response_model
- Required. Ecto schema module or simple type specification:max_retries
- Number of retries for validation errors (default: 0)- All standard ExLLM.chat/3 options
Returns
{:ok, struct}
where struct matches the response_model{:error, reason}
on failure
Examples
# With Ecto schema
{:ok, classification} = ExLLM.Instructor.chat(:anthropic, messages,
response_model: EmailClassification,
max_retries: 3
)
# With simple type spec
{:ok, data} = ExLLM.Instructor.chat(:openai, messages,
response_model: %{name: :string, age: :integer}
)
@spec parse_response(ExLLM.Types.LLMResponse.t(), module() | map()) :: {:ok, struct() | map()} | {:error, term()}
Transform a regular ExLLM response into a structured output.
This function is useful when you already have a response from ExLLM and want to parse it into a structured format.
Parameters
response
- An ExLLM.Types.LLMResponse structresponse_model
- The expected structure (Ecto schema or type spec)
Returns
{:ok, struct}
on successful parsing and validation{:error, reason}
on failure
Examples
{:ok, response} = ExLLM.chat(:anthropic, messages)
{:ok, structured} = ExLLM.Instructor.parse_response(response, UserProfile)
Create a simple schema module at runtime.
This is a convenience function for creating simple schemas without defining a full module.
Parameters
fields
- Map of field names to typesvalidations
- Optional list of validation functions
Examples
schema = ExLLM.Instructor.simple_schema(%{
name: :string,
age: :integer,
email: :string
}, [
{:validate_format, :email, ~r/@/}
])
{:ok, result} = ExLLM.Instructor.chat(:anthropic, messages,
response_model: schema
)