ExLLM.Instructor (ex_llm v0.1.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.
Requirements
This module requires the optional 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.
Returns
true
if the instructor library is available, false
otherwise.
Examples
if ExLLM.Instructor.available?() do
# Use structured outputs
else
# Fall back to regular chat
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
)