graph TD A[Command1] -->|stdout| B((pipe)) B -->|stdin| C[Command2] C -->|stdout| D((pipe)) D -->|stdin| E[Command3]
Perché la shell è il “posto” ideale per usare gli LLM
La vignetta “tar” di xkcd
man
E non scoppiano più le bombe?
man
di tarttok
è una utility del geniale Simon Willison
llm
(non i large language model)(👏 a Simon Willison)
llm
LLM è un’utility a riga di comando e una libreria Python per interagire con modelli di linguaggio di grandi dimensioni (LLM) come quelli di OpenAI, Anthropic, Google, Meta e tanti altri, compresi quelli installati in locale.
È scritta in Python
da quel genio di Simon Willison, il creatore di Datasette.
Esistono diversi plugin per llm
. Con questi è possibile aggiungere modelli di LLM
con cui interagire e/o attivare funzionalità aggiuntive.
OpenAI Chat: gpt-4o (aliases: 4o)
OpenAI Chat: chatgpt-4o-latest (aliases: chatgpt-4o)
OpenAI Chat: gpt-4o-mini (aliases: 4o-mini)
OpenAI Chat: gpt-4o-audio-preview
OpenAI Chat: gpt-4o-audio-preview-2024-12-17
OpenAI Chat: gpt-4o-audio-preview-2024-10-01
OpenAI Chat: gpt-4o-mini-audio-preview
OpenAI Chat: gpt-4o-mini-audio-preview-2024-12-17
OpenAI Chat: gpt-4.1 (aliases: 4.1)
OpenAI Chat: gpt-4.1-mini (aliases: 4.1-mini)
OpenAI Chat: gpt-4.1-nano (aliases: 4.1-nano)
OpenAI Chat: gpt-3.5-turbo (aliases: 3.5, chatgpt)
OpenAI Chat: gpt-3.5-turbo-16k (aliases: chatgpt-16k, 3.5-16k)
OpenAI Chat: gpt-4 (aliases: 4, gpt4)
OpenAI Chat: gpt-4-32k (aliases: 4-32k)
OpenAI Chat: gpt-4-1106-preview
OpenAI Chat: gpt-4-0125-preview
OpenAI Chat: gpt-4-turbo-2024-04-09
OpenAI Chat: gpt-4-turbo (aliases: gpt-4-turbo-preview, 4-turbo, 4t)
OpenAI Chat: gpt-4.5-preview-2025-02-27
OpenAI Chat: gpt-4.5-preview (aliases: gpt-4.5)
OpenAI Chat: o1
OpenAI Chat: o1-2024-12-17
OpenAI Chat: o1-preview
OpenAI Chat: o1-mini
OpenAI Chat: o3-mini
OpenAI Chat: o3
OpenAI Chat: o4-mini
OpenAI Completion: gpt-3.5-turbo-instruct (aliases: 3.5-instruct, chatgpt-instruct)
OpenAI Chat: groq-openai-llama3
OpenAI Chat: groq-openai-llama3-8b
Perplexity: sonar-pro
Perplexity: sonar
Perplexity: sonar-pro-online
Perplexity: sonar-deep-research
Perplexity: sonar-reasoning-pro
Perplexity: sonar-reasoning
Perplexity: r1-1776
gpt4all: all-MiniLM-L6-v2-f16 - SBert, 43.76MB download, needs 1GB RAM
gpt4all: all-MiniLM-L6-v2 - SBert, 43.82MB download, needs 1GB RAM
gpt4all: nomic-embed-text-v1 - Nomic Embed Text v1, 261.58MB download, needs 1GB RAM
gpt4all: nomic-embed-text-v1 - Nomic Embed Text v1.5, 261.58MB download, needs 1GB RAM
gpt4all: Llama-3 - Llama 3.2 1B Instruct, 737.21MB download, needs 2GB RAM
gpt4all: qwen2-1_5b-instruct-q4_0 - Qwen2-1.5B-Instruct, 894.10MB download, needs 3GB RAM
gpt4all: DeepSeek-R1-Distill-Qwen-1 - DeepSeek-R1-Distill-Qwen-1.5B, 1019.29MB download, needs 3GB RAM
gpt4all: Llama-3 - Llama 3.2 3B Instruct, 1.79GB download, needs 4GB RAM
gpt4all: replit-code-v1_5-3b-newbpe-q4_0 - Replit, 1.82GB download, needs 4GB RAM
gpt4all: orca-mini-3b-gguf2-q4_0 - Mini Orca (Small), 1.84GB download, needs 4GB RAM
gpt4all: Phi-3-mini-4k-instruct - Phi-3 Mini Instruct, 2.03GB download, needs 4GB RAM
gpt4all: mpt-7b-chat - MPT Chat, 3.54GB download, needs 8GB RAM
gpt4all: orca-2-7b - Orca 2 (Medium), 3.56GB download, needs 8GB RAM
gpt4all: rift-coder-v0-7b-q4_0 - Rift coder, 3.56GB download, needs 8GB RAM
gpt4all: mpt-7b-chat-newbpe-q4_0 - MPT Chat, 3.64GB download, needs 8GB RAM
gpt4all: em_german_mistral_v01 - EM German Mistral, 3.83GB download, needs 8GB RAM
gpt4all: mistral-7b-instruct-v0 - Mistral Instruct, 3.83GB download, needs 8GB RAM
gpt4all: ghost-7b-v0 - Ghost 7B v0.9.1, 3.83GB download, needs 8GB RAM
gpt4all: Nous-Hermes-2-Mistral-7B-DPO - Nous Hermes 2 Mistral DPO, 3.83GB download, needs 8GB RAM
gpt4all: mistral-7b-openorca - Mistral OpenOrca, 3.83GB download, needs 8GB RAM
gpt4all: gpt4all-falcon-newbpe-q4_0 - GPT4All Falcon, 3.92GB download, needs 8GB RAM
gpt4all: qwen2 - Reasoner v1, 4.13GB download, needs 8GB RAM
gpt4all: DeepSeek-R1-Distill-Qwen-7B-Q4_0 - DeepSeek-R1-Distill-Qwen-7B, 4.14GB download, needs 8GB RAM
gpt4all: Meta-Llama-3 - Llama 3.1 8B Instruct 128k, 4.34GB download, needs 8GB RAM
gpt4all: Meta-Llama-3-8B-Instruct - Llama 3 8B Instruct, 4.34GB download, needs 8GB RAM
gpt4all: DeepSeek-R1-Distill-Llama-8B-Q4_0 - DeepSeek-R1-Distill-Llama-8B, 4.35GB download, needs 8GB RAM
gpt4all: gpt4all-13b-snoozy-q4_0 - Snoozy, 6.86GB download, needs 16GB RAM
gpt4all: wizardlm-13b-v1 - Wizard v1.2, 6.86GB download, needs 16GB RAM
gpt4all: orca-2-13b - Orca 2 (Full), 6.86GB download, needs 16GB RAM
gpt4all: nous-hermes-llama2-13b - Hermes, 6.86GB download, needs 16GB RAM
gpt4all: DeepSeek-R1-Distill-Qwen-14B-Q4_0 - DeepSeek-R1-Distill-Qwen-14B, 7.96GB download, needs 16GB RAM
gpt4all: starcoder-newbpe-q4_0 - Starcoder, 8.37GB download, needs 4GB RAM
GeminiPro: gemini-pro
GeminiPro: gemini-1.5-pro-latest
GeminiPro: gemini-1.5-flash-latest
GeminiPro: gemini-1.5-pro-001
GeminiPro: gemini-1.5-flash-001
GeminiPro: gemini-1.5-pro-002
GeminiPro: gemini-1.5-flash-002
GeminiPro: gemini-1.5-flash-8b-latest
GeminiPro: gemini-1.5-flash-8b-001
GeminiPro: gemini-exp-1114
GeminiPro: gemini-exp-1121
GeminiPro: gemini-exp-1206
GeminiPro: gemini-2.0-flash-exp
GeminiPro: learnlm-1.5-pro-experimental
GeminiPro: gemini-2.0-flash-thinking-exp-1219
GeminiPro: gemini-2.0-flash-thinking-exp-01-21
GeminiPro: gemini-2.0-flash
GeminiPro: gemini-2.0-pro-exp-02-05
GeminiPro: gemini-2.0-flash-lite
GeminiPro: gemma-3-27b-it
GeminiPro: gemini-2.5-pro-exp-03-25
GeminiPro: gemini-2.5-pro-preview-03-25
GeminiPro: gemini-2.5-flash-preview-04-17
GeminiPro: gemini-2.5-pro-preview-05-06
Anthropic Messages: anthropic/claude-3-opus-20240229
Anthropic Messages: anthropic/claude-3-opus-latest (aliases: claude-3-opus)
Anthropic Messages: anthropic/claude-3-sonnet-20240229 (aliases: claude-3-sonnet)
Anthropic Messages: anthropic/claude-3-haiku-20240307 (aliases: claude-3-haiku)
Anthropic Messages: anthropic/claude-3-5-sonnet-20240620
Anthropic Messages: anthropic/claude-3-5-sonnet-20241022
Anthropic Messages: anthropic/claude-3-5-sonnet-latest (aliases: claude-3.5-sonnet, claude-3.5-sonnet-latest)
Anthropic Messages: anthropic/claude-3-5-haiku-latest (aliases: claude-3.5-haiku)
Anthropic Messages: anthropic/claude-3-7-sonnet-20250219
Anthropic Messages: anthropic/claude-3-7-sonnet-latest (aliases: claude-3.7-sonnet, claude-3.7-sonnet-latest)
Ollama: nuextract:latest (aliases: nuextract)
OpenAI: openai/gpt-4o
OpenAI: openai/gpt-4o-mini
OpenAI: openai/gpt-4.5-preview
OpenAI: openai/gpt-4.5-preview-2025-02-27
OpenAI: openai/o3-mini
OpenAI: openai/o1-mini
OpenAI: openai/o1
OpenAI: openai/o1-pro
OpenAI: openai/gpt-4.1
OpenAI: openai/gpt-4.1-2025-04-14
OpenAI: openai/gpt-4.1-mini
OpenAI: openai/gpt-4.1-mini-2025-04-14
OpenAI: openai/gpt-4.1-nano
OpenAI: openai/gpt-4.1-nano-2025-04-14
OpenAI: openai/o3
OpenAI: openai/o3-2025-04-16
OpenAI: openai/o3-streaming
OpenAI: openai/o3-2025-04-16-streaming
OpenAI: openai/o4-mini
OpenAI: openai/o4-mini-2025-04-16
LLMGroq: groq/playai-tts-arabic
LLMGroq: groq/qwen-2.5-coder-32b
LLMGroq: groq/llama-3.3-70b-specdec
LLMGroq: groq/allam-2-7b
LLMGroq: groq/whisper-large-v3
LLMGroq: groq/llama-3.3-70b-versatile (aliases: groq-llama-3.3-70b)
LLMGroq: groq/qwen-2.5-32b
LLMGroq: groq/mistral-saba-24b
LLMGroq: groq/gemma2-9b-it (aliases: groq-gemma2)
LLMGroq: groq/whisper-large-v3-turbo
LLMGroq: groq/deepseek-r1-distill-llama-70b
LLMGroq: groq/meta-llama/llama-4-scout-17b-16e-instruct
LLMGroq: groq/llama-3.2-90b-vision-preview
LLMGroq: groq/llama-3.2-3b-preview
LLMGroq: groq/meta-llama/llama-4-maverick-17b-128e-instruct
LLMGroq: groq/llama3-8b-8192 (aliases: groq-llama3)
LLMGroq: groq/llama-guard-3-8b
LLMGroq: groq/llama3-70b-8192 (aliases: groq-llama3-70b)
LLMGroq: groq/qwen-qwq-32b
LLMGroq: groq/llama-3.2-1b-preview
LLMGroq: groq/llama-3.2-11b-vision-preview
LLMGroq: groq/distil-whisper-large-v3-en
LLMGroq: groq/deepseek-r1-distill-qwen-32b
LLMGroq: groq/llama-3.1-8b-instant (aliases: groq-llama3.1-8b)
LLMGroq: groq/playai-tts
Default: gemini-2.0-flash-exp
for i in claude-3.5-sonnet gemini-2.0-flash-exp 4o; do
llm "Dammi un nome per un convegno su Esplorare il rapporto tra Open Data e Intelligenza Artificiale. Un solo nome senza commenti"
done
GeminiPro: gemini/gemini-2.0-flash-exp (aliases: gemini-2.0-flash-exp)
Options:
code_execution: boolean
temperature: float
max_output_tokens: int
top_p: float
top_k: int
json_object: boolean
timeout: float
google_search: boolean
Attachment types:
application/ogg, application/pdf, audio/aac, audio/aiff,
audio/flac, audio/mp3, audio/mpeg, audio/ogg, audio/wav,
image/heic, image/heif, image/jpeg, image/png, image/webp,
text/csv, text/plain, video/3gpp, video/avi, video/mov, video/mp4,
video/mpeg, video/mpg, video/quicktime, video/webm, video/wmv,
video/x-flv
Features:
- streaming
- schemas
- tools
- async
Keys:
key: gemini
env_var: LLM_GEMINI_KEY
OpenAI Chat: gpt-4o (aliases: 4o)
Options:
temperature: float
What sampling temperature to use, between 0 and 2. Higher values like
0.8 will make the output more random, while lower values like 0.2 will
make it more focused and deterministic.
max_tokens: int
Maximum number of tokens to generate.
top_p: float
An alternative to sampling with temperature, called nucleus sampling,
where the model considers the results of the tokens with top_p
probability mass. So 0.1 means only the tokens comprising the top 10%
probability mass are considered. Recommended to use top_p or
temperature but not both.
frequency_penalty: float
Number between -2.0 and 2.0. Positive values penalize new tokens based
on their existing frequency in the text so far, decreasing the model's
likelihood to repeat the same line verbatim.
presence_penalty: float
Number between -2.0 and 2.0. Positive values penalize new tokens based
on whether they appear in the text so far, increasing the model's
likelihood to talk about new topics.
stop: str
A string where the API will stop generating further tokens.
logit_bias: dict, str
Modify the likelihood of specified tokens appearing in the completion.
Pass a JSON string like '{"1712":-100, "892":-100, "1489":-100}'
seed: int
Integer seed to attempt to sample deterministically
json_object: boolean
Output a valid JSON object {...}. Prompt must mention JSON.
Attachment types:
application/pdf, image/gif, image/jpeg, image/png, image/webp
Features:
- streaming
- schemas
- tools
- async
Keys:
key: openai
env_var: OPENAI_API_KEY
I punti chiave del tuo sistema operativo, basati sulle informazioni fornite, sono:
* **Distribuzione:** Debian
* **Derivata:** Pengwin (una distribuzione specificamente progettata per l'uso con il sottosistema Windows per Linux, WSL)
* **Versione:** 12
* **Nome in codice:** Bookworm (il nome in codice per la versione 12 di Debian)
In sintesi, stai utilizzando **Pengwin**, una distribuzione Linux basata su **Debian 12 "Bookworm"**, ottimizzata per l'esecuzione all'interno di **WSL** (Windows Subsystem for Linux).
È markdown
👇👇👇
In sintesi, stai utilizzando Pengwin, una distribuzione Linux basata su Debian 12 “Bookworm”, ottimizzata per l’esecuzione all’interno di WSL (Windows Subsystem for Linux).
curl -kL "https://www.comune.palermo.it/amministrazione/unita_organizzativa/consiglio-comunale-3/" | \
llm --schema-multi "
nome: il nome del consigliere
ruolo: il ruolo
url: url della pagina del consigliere
sesso: m per maschio f per femmina NA per dubbio o inapplicabile
" --system 'estrai i dati dei consiglieri comunali presenti nella pagina web'
llm -t consiglio_comunale -a https://aborruso.github.io/blackboard/html/consiglio_comunale_trento.png
llm --schema-multi "nome
cognome
eta: inserisci l'età
data_nascita: inserisci la data di nascita in formato YYYY-MM-DD
" "crea una tabella con 5 persone" | jq -c '.items[]' | \
mlr --ijsonl --ocsv cat >persone.csv
{
"profile": "tabular-data-package",
"name": "people",
"title": "People Data",
"description": "A dataset containing information about people, including name, surname, date of birth, and age.",
"resources": [
{
"profile": "tabular-data-resource",
"name": "people-data",
"path": "people.csv",
"format": "csv",
"mediatype": "text/csv",
"encoding": "utf-8",
"schema": {
"fields": [
{
"name": "cognome",
"title": "Surname",
"type": "string"
},
{
"name": "data_nascita",
"title": "Date of Birth",
"type": "date",
"format": "YYYY-MM-DD"
},
{
"name": "eta",
"title": "Age",
"type": "integer"
},
{
"name": "nome",
"title": "Name",
"type": "string"
}
]
}
}
]
}
llm -c "e fammi anche la descrizion in markdown, la human readable utile per un readme.md, con una tabellina con nome campo, tipo campo, descrizione e valore di esempio. In italiano."
| Nome Campo | Tipo Campo | Descrizione | Valore di Esempio |
| :------------- | :--------- | :-------------------------------------------------------------------------- | :---------------- |
| `cognome` | string | Il cognome della persona. | Rossi |
| `data_nascita` | date | La data di nascita della persona (formato AAAA-MM-GG). | 1990-05-15 |
| `eta` | integer | L'età della persona. | 33 |
| `nome` | string | Il nome della persona. | Mario |
system: |
Estrai gli indirizzi stradali da un testo dato e identifica i seguenti componenti: 1. Tipo di strada, 2. Nome della strada (Odonimo), 3. Numero Civico, 4. Codice di Avviamento Postale (CAP), e 5. Città. Ogni indirizzo estratto deve essere rappresentato come un oggetto JSON separato, in formato JSON Lines (una riga per ogni indirizzo). Includi tutti i componenti disponibili anche se alcuni mancano nel testo originale. Se nel testo sono presenti più strade, estrai una riga per ogni strada trovata.
# Passaggi
1. **Identifica i Pattern degli Indirizzi**: Cerca i pattern comuni degli indirizzi nel testo, che possono includere tutti o parte dei componenti.
2. **Estrai i Componenti**:
- **Tipo di Strada**: Ad esempio, "Via", "Viale", "Piazza".
- **Nome della Strada (Odonimo)**: Il nome della strada, ad esempio "Roma".
- **Numero Civico**: Il numero associato all'edificio, ad esempio "15".
- **Codice di Avviamento Postale (CAP)**: Il codice postale dell'indirizzo, ad esempio "90100".
- **Città**: La città associata all'indirizzo, ad esempio "Palermo".
3. **Genera JSON**: Per ogni indirizzo identificato, crea un oggetto JSON con i componenti estratti.
4. **Output JSON Lines**: Stampa ogni oggetto JSON su una nuova riga in formato JSON Lines per ciascun indirizzo trovato.
# Formato di Output
- Ogni indirizzo identificato deve essere un oggetto JSON con chiavi per ogni componente:
```json
{"street_type": "Tipo di strada", "street_name": "Odonimo", "building_number": "Numero civico", "postal_code": "CAP", "city": "Città"}
```
- Assicurati che ogni oggetto JSON sia stampato su una linea separata.
- Includi i componenti quando disponibili; ometti o lascia vuote le stringhe per i componenti mancanti.
- Non scrivere nessun commento, soltanto output jsonline e niente altro
# Esempi
**Input:**
"Trova l'indirizzo Via Roma 15, 90100 Palermo in questo testo e il riferimento a Viale Mazzini."
**Output:**
```
{"street_type": "Via", "street_name": "Roma", "building_number": "15", "postal_code": "90100", "city": "Palermo"}
{"street_type": "Viale", "street_name": "Mazzini"}
```
# Note
- Gestire variazioni nei formati degli indirizzi e informazioni incomplete.
- L'estrazione deve essere robusta a variazioni comuni e errori nel testo di input.
Usage: qv <YouTube URL> <Question> [-p language <language>] [-sub <filename>] [-t|--template <template>] [--text-only] [--debug]
Example:
qv.sh 'https://www.youtube.com/watch?v=OM6XIICm_qo' 'What is this video about?' # Ask a question about the video
qv.sh 'https://www.youtube.com/watch?v=OM6XIICm_qo' 'What is this about?' -t andy # Use a specific template
qv.sh 'https://www.youtube.com/watch?v=OM6XIICm_qo' 'What is this video about?' -p language Italian # Get the answer in Italian
qv.sh 'https://www.youtube.com/watch?v=OM6XIICm_qo' --text-only # Output subtitles to stdout
qv.sh 'https://www.youtube.com/watch?v=OM6XIICm_qo' 'What is this video about?' -sub subtitles.txt # Save subtitles to a file
# Build system prompt with improved formatting
if [ "$debug" = true ]; then
cat <<EOF > "$temp_file"
You are a helpful assistant that can answer questions about YouTube videos.
${language:+Reply to me in $language\n}
Video title: $title
Content:
${content}
EOF
else
cat <<EOF > "$temp_file"
You are a helpful assistant that can answer questions about YouTube videos.
${language:+Reply to me in $language\n}
${content}
EOF
fi
# Process the question with LLM using stdin
echo "Processing your question..."
if [ "$debug" = true ]; then
echo -e "\nDEBUG: First 3 lines sent to LLM:"
head -n 3 "$temp_file"
echo -e "\n"
fi
if [ -n "$template" ]; then
cat "$temp_file" | llm prompt "$question" -t "$template"
else
cat "$temp_file" | llm prompt "$question"
fi
andrea.borruso@ondata.it
SMERALD