View Source InstructorLite.Instruction behaviour (instructor_lite v0.3.0)
use InstructorLite.Instruction
is a way to make your Ecto schema into an Instruction, which provides additional callbacks used by InstructorLite.
Example
defmodule SpamPrediction do
use Ecto.Schema
use InstructorLite.Instruction
@notes """
Field Descriptions:
- class: Whether or not the email is spam.
- reason: A short, less than 10-word rationalization for the classification.
- score: A confidence score between 0.0 and 1.0 for the classification.
"""
@primary_key false
embedded_schema do
field(:class, Ecto.Enum, values: [:spam, :not_spam])
field(:reason, :string)
field(:score, :float)
end
@impl InstructorLite.Instruction
def validate_changeset(changeset, _opts) do
Ecto.Changeset.validate_number(changeset, :score,
greater_than_or_equal_to: 0.0,
less_than_or_equal_to: 1.0
)
end
end
use InstructorLite.Instruction
When you use InstructorLite.Instruction
, the Instruction module will set @behaviour InstructorLite.Instruction
, and define default implementations of notes/0
and json_schema/0
callbacks.
Summary
Callbacks
Defines JSON schema for the instruction.
Defines an optional free-form description of the schema.
Called by InstructorLite.consume_response/3
as part of changeset validation.
Callbacks
@callback json_schema() :: map()
Defines JSON schema for the instruction.
By default, InstructorLite.JSONSchema.from_ecto_schema/1
is called at runtime every time InstructorLite needs to convert an Ecto schema to JSON schema. However, you can bake your own JSON schema into the json_schema/0
callback to eliminate the need to do it on every call.
Tip
Take advantage of this callback! Most JSON schemas are known ahead of time, so there is no need to constantly build them at runtime. In addition, InstructorLite.JSONSchema
module aims to generate one-size-fits-all schema, so it's very unlikely to take full advantage of JSON capabilities of your LLM of choice.
@callback notes() :: String.t() | nil
Defines an optional free-form description of the schema.
You can define a @notes
attribute or notes/0
callback to provide an additional free-form description to the schema. This description will be passed to the LLM together with the schema definition.
@callback validate_changeset(Ecto.Changeset.t(), InstructorLite.opts()) :: Ecto.Changeset.t()
Called by InstructorLite.consume_response/3
as part of changeset validation.
It has full access to all opts
. If you need to pass an arbitrary term to this callback, use the extra
key.
Example
# Let's play a guessing game!
defmodule CoinGuess do
use Ecto.Schema
use InstructorLite.Instruction
@primary_key false
embedded_schema do
field(:guess, Ecto.Enum, values: [:heads, :tails])
end
@impl InstructorLite.Instruction
def validate_changeset(cs, opts) do
target = Keyword.fetch!(opts, :extra)
case Ecto.Changeset.fetch_field!(cs, :guess) do
^target -> cs
_ -> Ecto.Changeset.add_error(cs, :guess, "Wrong! Try again")
end
end
end