← Back to Prompts

LLM.2 instructor lite adapter

Documentation for LLM.2_instructor_lite_adapter from the Dspex repository.

Task: LLM.2 - InstructorLite Adapter Implementation

Context

You are implementing the InstructorLite adapter for DSPex, which provides structured output generation using the InstructorLite library. This adapter is crucial for operations requiring validated, typed responses from LLMs.

Required Reading

1. InstructorLite Documentation

  • Package: Check the InstructorLite hex package documentation
  • Focus on:
    • InstructorLite.instruct/2 function
    • Schema definition patterns
    • Error handling

2. Existing InstructorLite Adapter

  • File: /home/home/p/g/n/dspex/lib/dspex/llm/adapters/instructor_lite.ex
    • Review current implementation
    • Note integration patterns with response_model

3. libStaging InstructorLite Example

  • File: /home/home/p/g/n/dspex/docs/LIBSTAGING_PATTERNS_FOR_COGNITIVE_ORCHESTRATION.md
    • Lines 127-131: InstructorLite integration example
    • Note structured output support pattern

4. LLM Adapter Protocol

  • File: /home/home/p/g/n/dspex/docs/specs/immediate_implementation/prompts/LLM.1_adapter_protocol.md
    • Review the protocol that must be implemented
    • Focus on structured output requirements

5. Test Examples

  • File: /home/home/p/g/n/dspex/test/dspex/llm/adapters/instructor_lite_test.exs
    • Review existing test patterns
    • Note mock setup if present

6. Success Criteria

  • File: /home/home/p/g/n/dspex/docs/specs/dspex_cognitive_orchestration/06_SUCCESS_CRITERIA.md
    • Section: “Stage 6: Adaptive LLM Architecture”
    • Focus on InstructorLite selection criteria

Implementation Requirements

Adapter Module Structure

defmodule DSPex.LLM.Adapters.InstructorLite do
  @behaviour DSPex.LLM.Adapter
  
  defstruct [
    :config,
    :client,
    :default_model,
    :retry_config
  ]
  
  # Required protocol implementations
  def capabilities(_adapter)
  def generate(adapter, prompt, opts)
  def stream(_adapter, _prompt, _opts)  # Not supported
  def validate_config(adapter)
  def format_messages(adapter, messages)
  def extract_content(adapter, response)
end

Schema Conversion

Convert DSPex schemas to InstructorLite format:

# DSPex schema format
%{
  name: :string,
  age: :integer,
  tags: {:array, :string},
  metadata: %{
    created_at: :datetime,
    score: :float
  }
}

# Convert to InstructorLite response_model
%{
  name: "string",
  age: "integer", 
  tags: ["string"],
  metadata: %{
    created_at: "datetime",
    score: "float"
  }
}

Configuration Options

%{
  # InstructorLite specific
  adapter_module: InstructorLite.Adapters.OpenAI,  # or Anthropic, etc.
  adapter_config: %{
    api_key: System.get_env("OPENAI_API_KEY"),
    model: "gpt-3.5-turbo"
  },
  
  # Common options
  max_retries: 3,
  validation_retries: 2,
  timeout: 30_000,
  
  # Advanced options
  response_model_type: :simple | :detailed,
  include_raw_response: false
}

Error Handling

Handle InstructorLite-specific errors:

case InstructorLite.instruct(messages, config) do
  {:ok, result} ->
    {:ok, result}
    
  {:error, %{type: :validation_error, errors: errors}} ->
    {:error, format_validation_errors(errors)}
    
  {:error, %{type: :api_error, message: message}} ->
    {:error, {:api_error, message}}
    
  {:error, reason} ->
    {:error, {:instructor_error, reason}}
end

Acceptance Criteria

  • Implements all DSPex.LLM.Adapter protocol functions
  • Converts DSPex schemas to InstructorLite format correctly
  • Supports multiple underlying providers (OpenAI, Anthropic, etc.)
  • Handles validation errors with clear messages
  • Includes retry logic for transient failures
  • Properly formats chat messages for the provider
  • Extracts structured content from responses
  • Includes comprehensive error handling
  • Performance: <200ms overhead for structured parsing

Testing Requirements

Create/update tests in:

  • test/dspex/llm/adapters/instructor_lite_test.exs

Test scenarios:

  • Simple structured output generation
  • Complex nested schemas
  • Array and optional field handling
  • Validation error cases
  • API error handling
  • Retry behavior
  • Multiple provider backends

Example Usage

# Create adapter
adapter = %DSPex.LLM.Adapters.InstructorLite{
  config: %{
    adapter_module: InstructorLite.Adapters.OpenAI,
    adapter_config: %{
      api_key: "...",
      model: "gpt-3.5-turbo"
    }
  }
}

# Generate structured output
{:ok, user} = DSPex.LLM.Adapter.generate(
  adapter,
  "Generate a user profile for a software developer",
  schema: %{
    name: :string,
    experience_years: :integer,
    skills: {:array, :string},
    contact: %{
      email: :string,
      github: {:optional, :string}
    }
  }
)

# Result
%{
  "name" => "Jane Smith",
  "experience_years" => 8,
  "skills" => ["Elixir", "Python", "React"],
  "contact" => %{
    "email" => "[email protected]",
    "github" => "janesmith"
  }
}

Dependencies

  • Requires LLM.1 (Adapter Protocol) to be complete
  • Depends on InstructorLite hex package
  • May require environment variables for API keys

Time Estimate

6 hours total:

  • 2 hours: Core adapter implementation
  • 1 hour: Schema conversion logic
  • 1 hour: Error handling and retries
  • 1 hour: Multi-provider support
  • 1 hour: Comprehensive testing

Notes

  • InstructorLite already handles much complexity
  • Focus on clean integration with DSPex schemas
  • Ensure good error messages for schema mismatches
  • Consider caching compiled schemas
  • Add telemetry events for structured generation