Search documentation of instructor_lite

# InstructorLite.Instruction behaviour (instructor_lite v1.0.0)

View Source

`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

json_schema()

Defines JSON schema for the instruction.

notes()

Defines an optional free-form description of the schema.

validate_changeset(t, opts)

Called by `InstructorLite.consume_response/3` as part of changeset validation.

# Callbacks

# json_schema()

    @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.

# notes()

    @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.

# validate_changeset(t, opts)

(optional)

    @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