ExLLM Quick Start Guide
View SourceGet up and running with ExLLM in 5 minutes! This guide covers installation, basic configuration, and common usage patterns.
Installation
Add ExLLM to your mix.exs
dependencies:
def deps do
[
{:ex_llm, "~> 0.7.0"}
]
end
Then run:
mix deps.get
Configuration
Environment Variables
Set API keys for the providers you want to use:
# Core providers
export ANTHROPIC_API_KEY="sk-ant-your-key"
export OPENAI_API_KEY="sk-your-key"
export GROQ_API_KEY="gsk_your-key"
# Additional providers (optional)
export GEMINI_API_KEY="your-gemini-key"
export MISTRAL_API_KEY="your-mistral-key"
export OPENROUTER_API_KEY="sk-or-your-key"
export PERPLEXITY_API_KEY="pplx-your-key"
Application Configuration (Optional)
# config/config.exs
config :ex_llm,
# Default provider
default_provider: :anthropic,
# Cost tracking
cost_tracking_enabled: true,
# Test caching (speeds up tests 25x)
test_cache: [
enabled: true,
cache_dir: "test/cache",
ttl: 604_800_000 # 7 days in milliseconds
]
Basic Usage
Simple Chat Completion
# Start with a basic chat
{:ok, response} = ExLLM.chat(:anthropic, [
%{role: "user", content: "What is the capital of France?"}
])
IO.puts(response.content)
# => "The capital of France is Paris."
# Access additional metadata
IO.puts("Model: #{response.model}")
IO.puts("Cost: $#{response.cost}")
IO.puts("Tokens used: #{response.usage.total_tokens}")
Different Providers
# Try different providers
{:ok, response1} = ExLLM.chat(:openai, [
%{role: "user", content: "Explain quantum computing briefly"}
])
{:ok, response2} = ExLLM.chat(:groq, [
%{role: "user", content: "Write a haiku about coding"}
])
{:ok, response3} = ExLLM.chat(:gemini, [
%{role: "user", content: "What's 2+2?"}
])
Streaming Responses
# Stream responses in real-time
ExLLM.chat_stream(:openai, [
%{role: "user", content: "Write a short story about a robot"}
], fn chunk ->
IO.write(chunk.delta)
end)
Session Management
# Maintain conversation context
{:ok, session} = ExLLM.Session.new(:anthropic)
# First message
{:ok, session, response1} = ExLLM.Session.chat(session, "Hi, I'm learning Elixir")
IO.puts(response1.content)
# Continue the conversation
{:ok, session, response2} = ExLLM.Session.chat(session, "What are GenServers?")
IO.puts(response2.content)
# Session automatically tracks conversation history
IO.puts("Messages in session: #{length(session.messages)}")
IO.puts("Total cost: $#{session.total_cost}")
Advanced Features
Multimodal (Vision)
# Analyze images (with Gemini or OpenAI)
image_data = File.read!("image.jpg") |> Base.encode64()
{:ok, response} = ExLLM.chat(:gemini, [
%{role: "user", content: [
%{type: "text", text: "What's in this image?"},
%{type: "image", image: %{
data: image_data,
media_type: "image/jpeg"
}}
]}
])
IO.puts(response.content)
Function Calling
# Define tools
tools = [
%{
type: "function",
function: %{
name: "get_weather",
description: "Get current weather for a location",
parameters: %{
type: "object",
properties: %{
location: %{type: "string", description: "City name"},
unit: %{type: "string", enum: ["celsius", "fahrenheit"]}
},
required: ["location"]
}
}
}
]
{:ok, response} = ExLLM.chat(:openai, [
%{role: "user", content: "What's the weather in Paris?"}
], tools: tools)
# Handle function calls
case response.function_calls do
[%{name: "get_weather", arguments: args}] ->
# Call your weather API here
weather_data = get_weather(args["location"])
# Continue conversation with function result
{:ok, final_response} = ExLLM.chat(:openai, [
%{role: "user", content: "What's the weather in Paris?"},
response.message,
%{role: "function", name: "get_weather", content: Jason.encode!(weather_data)}
])
_ ->
IO.puts(response.content)
end
Model Discovery
# List available models
{:ok, models} = ExLLM.list_models(:anthropic)
Enum.each(models, fn model ->
IO.puts("#{model.id} - Context: #{model.context_window} tokens")
end)
# Get specific model info
{:ok, model} = ExLLM.get_model(:openai, "gpt-4o")
IO.puts("Supports streaming: #{model.capabilities.supports_streaming}")
IO.puts("Supports vision: #{model.capabilities.supports_vision}")
Testing
Fast Testing with Caching
ExLLM includes intelligent test caching for 25x faster integration tests:
# Run tests with automatic caching
mix test
# Test specific providers
mix test.anthropic
mix test.openai --include live_api
# Manage cache
mix ex_llm.cache stats
mix ex_llm.cache clean --older-than 7d
Writing Tests
defmodule MyAppTest do
use ExUnit.Case
# Tag for automatic caching
@moduletag :live_api
@moduletag :requires_api_key
@moduletag provider: :anthropic
test "chat completion works" do
{:ok, response} = ExLLM.chat(:anthropic, [
%{role: "user", content: "Say hello"}
])
assert response.content =~ "hello"
assert response.cost > 0
end
end
Local Models
Ollama
# Start Ollama
ollama serve
# Pull a model
ollama pull llama3.2
# Use local Ollama models
{:ok, response} = ExLLM.chat(:ollama, [
%{role: "user", content: "Hello!"}
], model: "llama3.2")
LM Studio
# Start LM Studio server on localhost:1234
# Use LM Studio models
{:ok, response} = ExLLM.chat(:lmstudio, [
%{role: "user", content: "Hello!"}
])
Bumblebee (Elixir Native)
# Add to deps for local inference
{:exla, "~> 0.7"} # For CPU/GPU acceleration
# Use Bumblebee models
{:ok, response} = ExLLM.chat(:bumblebee, [
%{role: "user", content: "Hello!"}
], model: "microsoft/DialoGPT-medium")
Error Handling
case ExLLM.chat(:anthropic, messages) do
{:ok, response} ->
IO.puts(response.content)
{:error, {:api_error, %{status: 401}}} ->
IO.puts("Invalid API key")
{:error, {:api_error, %{status: 429}}} ->
IO.puts("Rate limited - try again later")
{:error, {:api_error, %{status: 400, body: body}}} ->
IO.puts("Bad request: #{inspect(body)}")
{:error, {:network_error, reason}} ->
IO.puts("Network error: #{reason}")
{:error, reason} ->
IO.puts("Other error: #{inspect(reason)}")
end
Environment-Specific Configuration
Development
# config/dev.exs
config :ex_llm,
log_level: :debug,
log_components: [:http_client, :streaming],
test_cache: [enabled: true]
Test
# config/test.exs
config :ex_llm,
log_level: :warn,
test_cache: [
enabled: true,
cache_dir: "test/cache",
ttl: 604_800_000 # 7 days
]
Production
# config/prod.exs
config :ex_llm,
log_level: :info,
log_redaction: true,
cost_tracking_enabled: true
Next Steps
- Read the User Guide for comprehensive documentation
- Check Provider Capabilities to compare features
- Review Testing Guide for advanced testing patterns and caching
Common Issues
"API key not found"
# Make sure you've set the environment variable
export ANTHROPIC_API_KEY="your-key"
"Model not found"
# Check available models
{:ok, models} = ExLLM.list_models(:anthropic)
"Rate limited"
# Use different providers or implement backoff
Process.sleep(1000)
{:ok, response} = ExLLM.chat(:groq, messages) # Try Groq for speed
Tests running slowly
# Enable test caching
export EX_LLM_TEST_CACHE_ENABLED=true
mix test --include live_api
That's it! You're now ready to build amazing applications with ExLLM. 🚀