### Install Dependencies and Run Tests Source: https://github.com/martosaur/instructor_lite/blob/main/pages/local_development_guide.md Run these commands to get project dependencies and execute all tests. ```bash mix deps.get mix test ``` -------------------------------- ### Copy Example Configuration File Source: https://github.com/martosaur/instructor_lite/blob/main/pages/local_development_guide.md Copy the example configuration file to create your own configuration. This file is ignored by Git. ```bash cp config/config.example.exs config/config.exs ``` -------------------------------- ### Instructor Configuration Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of configuring Instructor with an adapter and API key in config.exs. ```elixir # config.exs config :instructor, adapter: Instructor.Adapters.OpenAI, openai: [api_key: "my_secret_key"] ``` -------------------------------- ### Instructor Release Configuration Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of configuring a release to keep documentation files with Instructor. ```elixir # mix.exs def project do # ... releases: [ myapp: [ strip_beams: [keep: ["Docs"]] ] ] end ``` -------------------------------- ### InstructorLite Instruct Call Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of calling InstructorLite.instruct with input, model, adapter, and adapter context for API key. ```elixir InstructorLite.instruct(%{ input: [ %{role: "user", content: "Classify the following text: Hello, I am a Nigerian prince and I would like to give you $1,000,000." } ], model: "gpt-4o-mini" }, response_model: SpamPrediction, adapter: InstructorLite.Adapters.OpenAI, adapter_context: [api_key: "my_secret_key"] ) {:ok, %SpamPrediction{class: :spam, score: 0.999}} ``` -------------------------------- ### Instruct with Gemini Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Use `InstructorLite.instruct/2` with the `InstructorLite.Adapters.Gemini` adapter for Gemini API. This example also explicitly defines the `json_schema` for response validation. The `gemini_key` must be configured. ```elixir iex> InstructorLite.instruct(%{ contents: [ %{role: "user", parts: [%{text: "John Doe is forty-two years old"}]} ] }, response_model: UserInfo, json_schema: %{ type: "object", required: [:age, :name], properties: %{name: %{type: "string"}, age: %{type: "integer"}}, }, adapter: InstructorLite.Adapters.Gemini, adapter_context: [ api_key: Application.fetch_env!(:instructor_lite, :gemini_key) ] ) {:ok, %UserInfo{name: "John Doe", age: 42}} ``` -------------------------------- ### LLM Validation with Instructor Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of using Instructor.Validator.validate_with_llm/2 to validate a changeset based on LLM instructions. ```elixir defmodule QuestionAnswer do use Ecto.Schema use Instructor.Validator @primary_key false embedded_schema do field(:question, :string) field(:answer, :string) end @impl true def validate_changeset(changeset) do changeset |> validate_with_llm(:answer, "Do not say anything objectionable") end end ``` -------------------------------- ### Instructor Chat Completion Call Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of calling Instructor.chat_completion with parameters and expected response model. ```elixir Instructor.chat_completion(%{ model: "gpt-3.5-turbo", response_model: SpamPrediction, messages: [ %{role: "user", content: "Classify the following text: Hello, I am a Nigerian prince and I would like to give you $1,000,000." } ] }) {:ok, %SpamPrediction{class: :spam, score: 0.999}} ``` -------------------------------- ### Add Instructor Lite Dependency Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Add the Instructor Lite library to your project's dependencies in `mix.exs`. This is the primary step for installation. ```elixir def deps do [ {:instructor_lite, "~> 1.2.0"} ] end ``` -------------------------------- ### Instructor Schema Definition Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of defining an Ecto schema with `Instructor.Validator` and `@doc` for field descriptions. ```elixir defmodule SpamPrediction do use Ecto.Schema use Instructor.Validator @doc """ ## 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 true def validate_changeset(changeset) do changeset |> Ecto.Changeset.validate_number(:score, greater_than_or_equal_to: 0.0, less_than_or_equal_to: 1.0 ) end end ``` -------------------------------- ### InstructorLite Schema Definition Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Example of defining an Ecto schema with `InstructorLite.Instruction` and `@notes` for field descriptions. ```elixir 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 changeset |> Ecto.Changeset.validate_number(:score, greater_than_or_equal_to: 0.0, less_than_or_equal_to: 1.0 ) end end ``` -------------------------------- ### Instruct with Grok (Chat Completions Compatible) Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Use `InstructorLite.instruct/2` with the `InstructorLite.Adapters.ChatCompletionsCompatible` adapter for Grok API, which is compatible with OpenAI's Chat Completions endpoint. The `grok_key` must be configured. ```elixir iex> InstructorLite.instruct(%{ model: "grok-3-latest", messages: [ %{role: "user", content: "John Doe is forty-two years old"} ] }, response_model: UserInfo, adapter: InstructorLite.Adapters.ChatCompletionsCompatible, adapter_context: [ url: "https://api.x.ai/v1/chat/completions", api_key: Application.fetch_env!(:instructor_lite, :grok_key) ] ) {:ok, %UserInfo{name: "John Doe", age: 42}} ``` -------------------------------- ### Instruct with Llamacpp Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Use `InstructorLite.instruct/2` with the `InstructorLite.Adapters.Llamacpp` adapter for local LLM inference. The `llamacpp_url` must be configured in your application environment. ```elixir iex> InstructorLite.instruct(%{ prompt: "John Doe is forty-two years old" }, response_model: UserInfo, adapter: InstructorLite.Adapters.Llamacpp, adapter_context: [url: Application.fetch_env!(:instructor_lite, :llamacpp_url)] ) {:ok, %UserInfo{name: "John Doe", age: 42}} ``` -------------------------------- ### Instruct with Anthropic Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Use `InstructorLite.instruct/2` with the `InstructorLite.Adapters.Anthropic` adapter to interact with Anthropic's API. The `anthropic_key` must be configured in your application environment. ```elixir iex> InstructorLite.instruct(%{ messages: [ %{role: "user", content: "John Doe is forty-two years old"} ] }, response_model: UserInfo, adapter: InstructorLite.Adapters.Anthropic, adapter_context: [api_key: Application.fetch_env!(:instructor_lite, :anthropic_key)] ) {:ok, %UserInfo{name: "John Doe", age: 42}} ``` -------------------------------- ### Instruct with OpenAI Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Use `InstructorLite.instruct/2` to generate structured data from unstructured text using the OpenAI API. Ensure the `openai_key` is configured in your application environment. ```elixir iex> InstructorLite.instruct(%{ input: [ %{role: "user", content: "John Doe is forty-two years old"} ] }, response_model: UserInfo, adapter_context: [api_key: Application.fetch_env!(:instructor_lite, :openai_key)] ) {:ok, %UserInfo{name: "John Doe", age: 42}} ``` -------------------------------- ### Run OpenAI Integration Tests Source: https://github.com/martosaur/instructor_lite/blob/main/pages/local_development_guide.md Execute the integration tests specifically for the OpenAI adapter. Ensure your OpenAI API key is configured. ```bash mix test test/integrations/openai_test.exs ``` -------------------------------- ### Migrate OpenAI Adapter to ChatCompletionsCompatible Source: https://github.com/martosaur/instructor_lite/blob/main/CHANGELOG.md When migrating to v1.0.0, if you were using the OpenAI adapter and wish to continue using the chat completions endpoint, switch to the `ChatCompletionsCompatible` adapter. ```elixir InstructorLite.instruct(%{ messages: [ %{role: "user", content: "John Doe is fourty two years old"} ] }, response_model: %{name: :string, age: :integer}, - adapter: InstructorLite.Adapters.OpenAI, + adapter: InstructorLite.Adapters.ChatCompletionsCompatible, adapter_context: [api_key: Application.fetch_env!(:instructor_lite, :openai_key)] ) ``` -------------------------------- ### Running LLM Validation with Instructor Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Demonstrates how to cast data and then validate a changeset using the custom validate_changeset function. ```elixir %QuestionAnswer{} ``` ```elixir |> Instructor.cast_all(%{ question: "What is the meaning of life?", answer: "Sex, drugs, and rock'n roll" }) ``` ```elixir |> QuestionAnswer.validate_changeset() ``` ```elixir #Ecto.Changeset< action: nil, changes: %{question: "What is the meaning of life?", answer: "Sex, drugs, and rock'n roll"}, errors: [answer: {"is invalid, Do not say anything objectionable", []}], data: #QuestionAnswer<>, valid?: false > ``` -------------------------------- ### Define an Ecto Schema for Instructions Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Define a new Ecto schema that includes the `InstructorLite.Instruction` module to create structured instructions for LLMs. This schema will define the expected shape of the LLM's response. ```elixir defmodule UserInfo do use Ecto.Schema use InstructorLite.Instruction @primary_key false embedded_schema do field(:name, :string) field(:age, :integer) end end ``` -------------------------------- ### Add Optional Dependencies (Req and Jason) Source: https://github.com/martosaur/instructor_lite/blob/main/README.md Optionally, include the Req HTTP client and Jason for JSON parsing if using an Elixir version older than 1.18. Ensure compatibility with your project. ```elixir def deps do [ {:req, "~> 0.5 or ~> 1.0"}, {:jason, "~> 1.4"} ] end ``` -------------------------------- ### Migrate OpenAI Adapter to Responses Endpoint Source: https://github.com/martosaur/instructor_lite/blob/main/CHANGELOG.md To switch the OpenAI adapter to the responses endpoint in v1.0.0, update the `params` to comply with the `POST /v1/responses` interface. Notably, change the `messages` key to `input`. ```elixir InstructorLite.instruct(%{ - messages: [ + input: [ %{role: "user", content: "John Doe is fourty two years old"} ] }, response_model: %{name: :string, age: :integer}, adapter: InstructorLite.Adapters.OpenAI, adapter_context: [api_key: Application.fetch_env!(:instructor_lite, :openai_key)] ) ``` -------------------------------- ### Embedded Schema with JSON Schema Definition (InstructorLite) Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md An embedded Ecto schema using InstructorLite.Instruction, including a manual JSON schema definition. ```elixir defmodule Database do use Ecto.Schema use InstructorLite.Instruction @notes """ The extracted database will contain one or more tables with data as csv formatted with ',' delimiters """ @primary_key false embedded_schema do embeds_many :tables, DataFrame, primary_key: false do field(:name, :string) field(:data, Ecto.CSVDataFrame) end end @impl InstructorLite.Instruction def json_schema do %{ type: "object", description: "", title: "Database", required: [:tables], "$defs": %{ "DataFrame" => %{ type: "object", description: "", title: "DataFrame", required: [:data, :name], properties: %{data: %{type: "string"}, name: %{type: "string"}}, additionalProperties: false } }, properties: %{tables: %{type: "array", items: %{"$ref": "#/$defs/DataFrame"}}}, additionalProperties: false } end end ``` -------------------------------- ### Custom Ecto Type for CSV DataFrames (InstructorLite) Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Defines a custom Ecto type for CSV DataFrames without Instructor.EctoType, for use with InstructorLite. ```elixir defmodule Ecto.CSVDataFrame do use Ecto.Type def type, do: :string def cast(csv_str) when is_binary(csv_str) do df = Explorer.DataFrame.load_csv!(csv_str) {:ok, df} end def cast(%Explorer.DataFrame{} = df), do: {:ok, df} def cast(_), do: :error def dump(x), do: {:ok, x} def load(x), do: {:ok, x} end ``` -------------------------------- ### Ecto Schema with InstructorLite Validation Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Defines an Ecto embedded schema with a custom validation function that uses InstructorLite to validate a field against a given rule. This demonstrates how to integrate LLM-based validation into Ecto changeset. ```elixir defmodule QuestionAnswer do use Ecto.Schema @primary_key false embedded_schema do field :question, :string field :answer, :string end def changeset(data, params) do data |> Ecto.Changeset.cast(params, [:answer]) |> validate_with_llm(:answer, "do not say anything objectionable") end def validate_with_llm(changeset, field, rule) do Ecto.Changeset.validate_change(changeset, field, fn ^field, value -> %{ input: [ %{role: "system", content: """You are a world-class validation model. Capable of determining if the following value is valid for the statement, if it is not, explain why. """} , %{role: "user", content: "Does `#{value}` follow the rule: #{rule}"} ] } |> InstructorLite.instruct( response_model: %{valid?: :boolean, reason: :string}, adapter_context: [api_key: "my_api_token"] ) |> case do {:ok, %{valid?: false, reason: reason}} -> [{field, reason}] _ -> [] end end) end end ``` -------------------------------- ### Custom Ecto Type for CSV DataFrames (Instructor) Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Defines a custom Ecto type for CSV DataFrames using Instructor.EctoType, including JSON schema conversion. ```elixir defmodule Ecto.CSVDataFrame do use Ecto.Type use Instructor.EctoType def type, do: :string def cast(csv_str) when is_binary(csv_str) do df = Explorer.DataFrame.load_csv!(csv_str) {:ok, df} end def cast(%Explorer.DataFrame{} = df), do: {:ok, df} def cast(_), do: :error def to_json_schema(), do: %{ type: "string", description: "A CSV representation of a data table" } def dump(x), do: {:ok, x} def load(x), do: {:ok, x} end ``` -------------------------------- ### Ecto Changeset with LLM Validation Failure Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md Shows the result of an Ecto changeset operation where the custom LLM validation fails. The output demonstrates the structure of an Ecto.Changeset with errors, including the specific reason provided by the LLM. ```elixir %QuestionAnswer{question: "What is the meaning of life?"} |> QuestionAnswer.changeset(%{answer: "Sex, drugs, and rock'n roll"}) #Ecto.Changeset< action: nil, changes: %{answer: "Sex, drugs, and rock'n roll"}, errors: [ answer: {"The phrase 'Sex, drugs, and rock'n roll' contains references to explicit content, substance use, and a lifestyle that may be considered objectionable or inappropriate by many standards.", []} ], data: #QuestionAnswer<>, valid?: false, ... ``` -------------------------------- ### Embedded Schema with Custom Ecto Type (Instructor) Source: https://github.com/martosaur/instructor_lite/blob/main/pages/migrating_from_instructor.md An embedded Ecto schema that utilizes the custom Ecto.CSVDataFrame type for tables. ```elixir defmodule Database do use Ecto.Schema use Instructor.Validator @doc """ The extracted database will contain one or more tables with data as csv formatted with ',' delimiters """ @primary_key false embedded_schema do embeds_many :tables, DataFrame, primary_key: false do field(:name, :string) field(:data, Ecto.CSVDataFrame) end end end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.