Home Knowledge Base Building AI Command-Line Tools

Building AI Command-Line Tools

CLI Frameworks for Python

Popular Libraries

LibraryHighlightsComplexity
ClickDecorators, composableMedium
TyperModern, type hintsEasy
argparseBuilt-in, no depsMedium
FireAuto-generate from functionsVery easy
RichBeautiful terminal outputAddon

Building an LLM CLI with Typer

Basic Structure

import typer
from rich.console import Console
from openai import OpenAI

app = typer.Typer(help="AI Command Line Assistant")
console = Console()
client = OpenAI()

@app.command()
def ask(
    prompt: str = typer.Argument(..., help="Your question"),
    model: str = typer.Option("gpt-4o", "--model", "-m"),
    stream: bool = typer.Option(True, "--stream/--no-stream"),
):
    """Ask the AI a question."""
    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        stream=stream,
    )

    if stream:
        for chunk in response:
            if chunk.choices[0].delta.content:
                console.print(chunk.choices[0].delta.content, end="")
        console.print()
    else:
        console.print(response.choices[0].message.content)

@app.command()
def translate(
    text: str = typer.Argument(...),
    target: str = typer.Option("English", "--to", "-t"),
):
    """Translate text to target language."""
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": f"Translate to {target}. Only output the translation."},
            {"role": "user", "content": text}
        ],
    )
    console.print(response.choices[0].message.content)

if __name__ == "__main__":
    app()

Usage Examples

**Ask a question**
llm ask "What is the capital of France?"

**Use specific model**
llm ask "Explain attention" --model gpt-4o-mini

**Translate text**
llm translate "Hello, world!" --to Spanish

CLI Best Practices

User Experience

PatternImplementation
ProgressRich progress bars for long operations
StreamingShow output as it generates
ColorsUse for status (red=error, green=success)
HelpClear documentation for all options
DefaultsSensible defaults for common cases

Error Handling

@app.command()
def summarize(file: Path = typer.Argument(...)):
    if not file.exists():
        console.print(f"[red]Error:[/red] File not found: {file}")
        raise typer.Exit(1)

    try:
        content = file.read_text()
**Process with LLM...**
    except Exception as e:
        console.print(f"[red]Error:[/red] {e}")
        raise typer.Exit(1)

Distribution

**Install with pip**
pip install -e .

**Or use pipx for isolated install**
pipx install .

**Create standalone binary with PyInstaller**
pyinstaller --onefile cli.py
clitoolingcommand line app

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.