Skip to content

LLM CLI

Installation

# Install via pip (Python 3.8+)
pip install llm

# Or via Homebrew (macOS)
brew install llm

# Or via pipx (isolated environment, recommended)
pipx install llm

# Verify installation
llm --version

# Quick test (requires API key)
llm "Say hello in one sentence"

Configuration

# Set OpenAI API key (default provider)
llm keys set openai
# Prompts for key: sk-your-key-here

# Set Anthropic API key
llm keys set anthropic

# Set Google API key
llm keys set gemini

# List stored keys
llm keys

# View key storage location
llm keys path

# Keys stored at:
# macOS:  ~/Library/Application Support/io.datasette.llm/keys.json
# Linux:  ~/.config/io.datasette.llm/keys.json
# Windows: %APPDATA%\io.datasette.llm\keys.json
# Set a default model
llm models default gpt-4o

# View current default model
llm models default

# View log database location
llm logs path

# Open log database in sqlite-utils or Datasette
datasette "$(llm logs path)"

Core Commands / API

CommandDescription
llm "prompt"Run a one-shot prompt
llm -m MODEL "prompt"Use a specific model
llm -s "system"Add a system prompt
llm -c "prompt"Continue previous conversation
llm chatStart interactive chat session
llm chat -m MODELInteractive chat with specific model
llm modelsList all available models
llm models default MODELSet default model
llm keys set PROVIDERStore an API key
llm keysList configured keys
llm logsShow recent conversation logs
llm logs listList recent log entries
llm logs -n 5Show last 5 logs
llm logs -cShow logs for current conversation
llm logs pathShow log database path
llm templatesList saved templates
llm templates show NAMEShow a template
llm -t TEMPLATEUse a saved template
llm aliasesList model aliases
llm aliases set NAME MODELCreate model alias
llm embedCreate embeddings
llm install PLUGINInstall a plugin
llm pluginsList installed plugins

Advanced Usage

Model Selection and Aliases

# List all models (built-in + plugins)
llm models

# Use specific models
llm -m gpt-4o "Explain recursion"
llm -m claude-3-5-sonnet-20241022 "Write a poem about code"
llm -m gemini-1.5-pro "Analyze this data"

# Create convenient aliases
llm aliases set opus claude-3-opus-20240229
llm aliases set sonnet claude-3-5-sonnet-20241022
llm aliases set mini gpt-4o-mini
llm aliases set big gpt-4o

# Now use short aliases
llm -m sonnet "Review this PR"
llm -m mini "Quick question: what is 42 * 7?"

# List all aliases
llm aliases

# Remove an alias
llm aliases remove mini

System Prompts

# Add a system prompt inline
llm -s "You are a senior Python developer. Be concise and use type hints." \
  "How do I implement a binary search?"

# Combine system prompt with template (see Templates section)
llm -s "You are a DBA." -m gpt-4o "Optimize this query: SELECT * FROM users"

# Multi-line system prompts
llm -s "$(cat system_prompt.txt)" "Do your task"

Templates

# Create a template
llm templates edit code_review
# Opens $EDITOR with YAML template format

# Template YAML format:
# ---
# system: "You are an expert code reviewer. Focus on security, performance, and readability."
# model: gpt-4o
# ---

# List all templates
llm templates

# Show a template
llm templates show code_review

# Use a template
cat my_code.py | llm -t code_review

# Template with default prompt (pre-filled)
# template.yaml:
# ---
# system: "You are a helpful assistant."
# prompt: "Summarize the following text:"
# model: gpt-4o-mini
# ---
# Template file location
llm templates path

# Create templates programmatically
mkdir -p "$(llm templates path)"
cat > "$(llm templates path)/summarize.yaml" << 'EOF'
system: |
  You are an expert summarizer. Create clear, concise summaries that capture
  the key points. Use bullet points for readability. Keep it under 200 words.
model: gpt-4o-mini
prompt: "Summarize the following:\n"
EOF

# Use it
cat article.txt | llm -t summarize

Conversation Continuation

# Start a conversation
llm "What is the capital of France?"
# Response: Paris is the capital of France.

# Continue the conversation with -c
llm -c "What is its population?"
# Remembers context: "Paris has a population of approximately 2.1 million..."

llm -c "What language do they speak?"
# Continues the thread

# Start interactive chat (persistent session)
llm chat
# Type messages, use Ctrl+C or type "exit" to quit

llm chat -m claude-3-5-sonnet-20241022
# Chat with a specific model

# View conversation history
llm logs -c

# Continue the last conversation from a new shell
llm -c "Keep going from where we left off"

Plugin System

# Install plugins for additional model providers
pip install llm-anthropic           # Claude models (claude-3-opus, etc.)
pip install llm-gemini              # Google Gemini models
pip install llm-ollama              # Local models via Ollama
pip install llm-gpt4all             # Local GPT4All models
pip install llm-mistral             # Mistral API models
pip install llm-cohere              # Cohere models
pip install llm-replicate           # Run any Replicate model
pip install llm-groq                # Groq fast inference
pip install llm-perplexity          # Perplexity AI models

# List installed plugins
llm plugins

# After installing, set the API key
llm keys set anthropic
llm keys set gemini

# Use newly available models
llm models list | grep claude
llm -m claude-3-5-sonnet-20241022 "Hello!"

# Local models via Ollama plugin
llm install llm-ollama
ollama pull llama3
llm -m ollama/llama3 "Explain transformers"

Embeddings

# Embed a string
llm embed -m text-embedding-3-small "The quick brown fox"

# Embed from file
llm embed -m text-embedding-3-small - < document.txt

# Create an embedding collection (SQLite-backed)
llm embed-multi documents \
  -m text-embedding-3-small \
  --files . "*.txt"

# Semantic search across embedded collection
llm similar documents -c "machine learning concepts"

# Compare two strings
llm embed-multi comparison \
  -m text-embedding-3-small \
  --store \
  - << 'EOF'
apple: "A fruit that grows on trees"
orange: "A citrus fruit"
car: "A motorized vehicle"
EOF

llm similar comparison -c "fruit"

Log Database Queries

# Show recent conversations
llm logs list

# Show last 5 conversations  
llm logs list -n 5

# Show a specific log entry (by ID)
llm logs show 1

# Open the SQLite database directly
sqlite3 "$(llm logs path)"

# Query logs with SQL via sqlite-utils
sqlite-utils "$(llm logs path)" "SELECT * FROM responses ORDER BY datetime_utc DESC LIMIT 10"

# Use Datasette for a web UI
pip install datasette
datasette "$(llm logs path)"

# Search logs for a keyword
sqlite-utils "$(llm logs path)" \
  "SELECT id, model, datetime_utc, prompt FROM responses WHERE prompt LIKE '%python%'"

# Export all logs to JSON
sqlite-utils "$(llm logs path)" "SELECT * FROM responses" > all_logs.json

Piping and Scripting

# Pipe content to llm
echo "Explain this error: NameError: name 'x' is not defined" | llm

# Process a file
cat code.py | llm "Explain what this code does"

# Summarize output of another command
git log --oneline -20 | llm "Summarize these recent commits"

# Process multiple files in a loop
for file in *.py; do
  echo "=== $file ===" >> review.md
  cat "$file" | llm -t code_review >> review.md
done

# Use with other Unix tools
curl -s https://api.example.com/data | jq . | llm "Analyze this API response"

# Extract structured data
cat emails.txt | llm "Extract all email addresses and return as JSON array"

# Transform data format
cat data.csv | llm "Convert this CSV to a markdown table"

Python API

import llm

# Get default model
model = llm.get_model()

# Get specific model
model = llm.get_model("gpt-4o")

# Simple prompt
response = model.prompt("What is 2+2?")
print(response.text())

# With system prompt
response = model.prompt(
    "Explain recursion",
    system="You are a computer science professor. Use simple analogies."
)
print(response.text())

# Stream response
for chunk in model.prompt("Tell me a long story", stream=True):
    print(chunk, end="", flush=True)

# Conversation
conversation = model.conversation()
response1 = conversation.prompt("My name is Alice")
print(response1.text())

response2 = conversation.prompt("What is my name?")
print(response2.text())  # Remembers "Alice"

# Embeddings
embedding_model = llm.get_embedding_model("text-embedding-3-small")
vector = embedding_model.embed("Hello world")
print(len(vector))  # 1536 dimensions

Common Workflows

Code Review Helper

# Create a code review template
cat > "$(llm templates path)/review.yaml" << 'EOF'
system: |
  You are a senior software engineer doing a code review.
  Identify: security issues, bugs, performance problems, and style issues.
  Format your response with clear sections for each category.
  Be specific and constructive.
model: gpt-4o
EOF

# Review a file
cat mycode.py | llm -t review

# Review a git diff
git diff | llm -t review

# Review a PR
git diff main | llm -t review > review_output.md

Writing Assistant

# Create writing templates
cat > "$(llm templates path)/improve.yaml" << 'EOF'
system: "Improve this writing for clarity, conciseness, and impact. Keep the author's voice."
model: gpt-4o
EOF

cat > "$(llm templates path)/proofread.yaml" << 'EOF'
system: "Proofread for grammar, spelling, and punctuation. Show corrections with explanations."
model: gpt-4o-mini
EOF

# Use them
cat draft.txt | llm -t improve > improved.txt
cat essay.txt | llm -t proofread

Quick Reference Lookup

# Create aliases for common questions
alias lw="llm -m gpt-4o-mini"       # lightweight/cheap model

# Quick syntax lookups
lw "Python: how do I format a date as YYYY-MM-DD?"
lw "Bash: one-liner to find files larger than 100MB"
lw "SQL: how do I calculate a running total?"
lw "git: undo last commit but keep changes"

Document Summarization

# Summarize any document
cat research_paper.pdf | pdftotext - - | llm "Summarize this paper in 3 bullet points"

# Summarize a webpage
curl -s "https://example.com/article" | \
  python3 -c "import sys; from html.parser import HTMLParser; ..." | \
  llm "Summarize the key points"

# Process a folder of notes
find ~/notes -name "*.md" -exec cat {} \; | \
  llm "What are the recurring themes in these notes?"

Tips and Best Practices

Cost Management

ModelCostBest For
gpt-4o-miniLowQuick questions, summaries, templates
gpt-4oMediumComplex reasoning, code review
claude-3-haikuLowFast, cheap tasks
claude-3-5-sonnetMediumBalanced quality/cost
ollama/llama3FreePrivacy, offline, experimentation
# Check which model you're using (avoid accidentally using expensive one)
llm models default

# Use mini for bulk/scripted tasks
for f in *.txt; do cat "$f" | llm -m gpt-4o-mini "Summarize"; done

# Use full model only when quality matters
cat important_contract.txt | llm -m gpt-4o "Identify any concerning clauses"

Shell Integration Tips

# Add to ~/.bashrc or ~/.zshrc:

# Quick AI question
ai() { llm -m gpt-4o-mini "$*"; }

# Explain a command
explain() { echo "$*" | llm "Explain this shell command in plain English"; }

# Fix an error
fix() { llm -c "I got this error: $*. How do I fix it?"; }

# Summarize stdin
alias summarize="llm -m gpt-4o-mini 'Summarize this in 3 bullet points'"

# Usage:
ai "What does chmod 755 do?"
explain "find . -name '*.py' -exec grep -l 'import os' {} ;"
fix "ModuleNotFoundError: No module named 'requests'"
cat logfile.txt | summarize

Privacy Considerations

# Use local models for sensitive content
llm install llm-ollama
ollama pull llama3

# Set as default for private work
llm models default ollama/llama3

# Or use per-command
cat sensitive_document.txt | llm -m ollama/llama3 "Summarize"

# Review what's been logged
llm logs list -n 20

# The log database contains your full prompt/response history
# Location: $(llm logs path)
# Contains all queries unless disabled

Debugging

# See full request details
llm --verbose "Hello"

# Check plugin status
llm plugins

# Test a model is working
llm -m gpt-4o-mini "Reply with just: OK"

# Reinstall if issues
pip install --upgrade llm