Τι είναι το OpenAI CLI — και τι ΔΕΝ είναι
Το openai/openai-cli είναι, με τα λόγια του repository, το «official CLI for the OpenAI REST API». Γραμμένο σε Go (θέλει Go 1.26+ για build από πηγές), με Apache 2.0 license και release pipeline με goreleaser + release-please. Έρχεται ως single binary, οπότε σβήνεις το «πρέπει πρώτα να στήσω Python/Node για να τρέξω το SDK» από τη λίστα.
Το κρίσιμο είναι το πού τοποθετείται. Το CLI δεν είναι agent. Δεν διαβάζει τη codebase σου, δεν κρατάει σημειωματάριο βημάτων, δεν σχεδιάζει μόνο του δράσεις. Είναι wrapper γύρω από το REST API: του δίνεις resource + command + flags, σου δίνει δομημένη απάντηση. Η μεγαλύτερη σύγχυση της πρώτης ημέρας ήταν ακριβώς αυτή η διάκριση:
Πρακτικά: τι θες να κάνεις; Αν θες να καλείς μοντέλα, να κάνεις generate εικόνες, να ανεβάζεις files ή να βλέπεις usage της organization σου — μέσα από scripts, cron jobs και CI pipelines — το CLI κάνει τη δουλειά σε μιάμιση γραμμή. Αν θες «συνεργάτη» που δουλεύει πάνω στο project σου και γράφει/τρέχει κώδικα αυτόνομα, εκεί συνεχίζει να δουλεύει το Codex.
Εγκατάσταση: δύο βήματα
Homebrew ή Go
# Επίσημος τρόπος (macOS/Linux)
brew install openai/tools/openai
# Από πηγές — θέλει Go 1.26+
go install 'github.com/openai/openai-cli/cmd/openai@latest'
# binary στο $HOME/go/bin (ή $GOPATH/bin)
export PATH="$PATH:$(go env GOPATH)/bin"
Το CLI δεν εγκαθιστά ποτέ αναβαθμίσεις μόνο του — δες την update policy παρακάτω.
Το πρώτο βήμα μετά την εγκατάσταση είναι το OPENAI_API_KEY και το πρώτο σου command:
export OPENAI_API_KEY="sk-..."
openai responses create \
--input "Say this is a test" \
--model gpt-5.5
Για τα admin endpoints (usage, metrics) υπάρχει ξεχωριστό OPENAI_ADMIN_KEY — μην το κρατάς loaded σε shells που δεν το χρειάζονται.
Η αρχιτεκτονική των εντολών
Η δομημένη φιλοσοφία του CLI είναι resource-based, ακριβώς όπως θα περιμένε κανείς από ένα REST tool:
openai <resource> [subresource...] <command> [flags...]
Η βοήθεια δουλεύει παντού — και offline:
openai --help # command groups + global flags
openai images generate --help # παράδειγμα + κάθε flag
openai help setup # το σωστό setup του API key
Η help δουλεύει χωρίς API key και χωρίς δίκτυο, και το Tab completion (bash, zsh, fish) ακολουθεί την ίδια δομή. Τρία design σημεία που ωφελούν engineers:
- Readable by default: τα JSON responses τυπώνονται ως ευανάγνωστο κείμενο — αλλά και μέσα σε pipes. Για scripts που κάνουν parse, περνάς
--format jsonή--format jsonl· συνολικά διαθέσιμα formats: auto, text, explore, json, jsonl, pretty, raw, yaml. - GJSON transforms: το
--transformβγάζει απευθείας το path που σε νοιάζει, χωρίς jq για απλές εξαγωγές — και το ίδιο ισχύει για errors με--transform-error/--format-error. - Offline help: κάθε σελίδα βοήθειας δουλεύει χωρίς key και χωρίς δίκτυο — σπάνια φροντίδα σε CLIs που μιλούν σε cloud APIs.
Panorama των command groups
| Resource | Τι καλύπτει | Παράδειγμα |
|---|---|---|
| responses | Responses API — το βασικό «συνομιλιακό» path | openai responses create --input "..." --model gpt-5.5 |
| models | Λίστα και λεπτομέρειες μοντέλων | openai models list |
| files | Upload, metadata, download (user_data κ.ά.) | openai files upload "f.txt" --purpose user_data |
| images | Generate, edit, preview, inline setting | openai images generate --prompt "..." |
| admin | Organization usage, metrics, admin-only endpoints | openai admin organization usage completions |
Files: upload → inspect → download
openai files upload "upload space.txt" --purpose user_data
openai files get file-example
openai files download file-example --output "downloaded copy.txt"
Αν θέλεις explicit encoding: το @file:// στέλνει περιεχόμενο ως plain string, το @data:// ως base64. Αν θες να περάσεις τιμή που αρχίζει κυριολεκτικά από @, το κάνεις escape ως '\@abe'.
Images: saved, not returned
Η συμπεριφορά που εκπλήσσει: το openai images generate --prompt "A tiny orange robot" σώζει τις εικόνες σε ~/Downloads/gpt-images/ και τυπώνει τα paths — αυτό ισχύει και μέσα σε pipes. Χωρίς explicit model, χρησιμοποιεί το preset gpt-image-2.5-sunburst· με --model επιλέγεις συγκεκριμένο ID, με --name filename και με --output-dir υπάρχοντα directory. Τα υπάρχοντα αρχεία διατηρούνται.
Το openai images preview <path> ξαναεμφανίζει saved εικόνα χωρίς API request — και το openai images inline on/off θυμάται αν οι αποθηκευμένες εικόνες ανοίγουν αυτόματα. Και ιστορικό footnote: το images create-variation retired — variations πια γίνονται με images edit + GPT Image model + prompt. Αν έχεις scripts που καλούν το παλιό command, είναι ήδη σπασμένα.
Headers, organizations, custom backends
Global flags: --api-key, --admin-api-key, --organization/OPENAI_ORG_ID, --project/OPENAI_PROJECT_ID, --webhook-secret, --mtls-*, --base-url, --header/-H, --debug, --version. Το --base-url (και το OPENAI_BASE_URL) απαιτεί HTTPS εκτός από localhost / literal loopback (127.0.0.1, ::1) — ένα από τα details που δείχνουν ότι το CLI σχεδιάστηκε με threat model: δεν θα στείλεις credentials over HTTP σε remote backend.
Admin key και organization usage
Αυτό το κομμάτι θα το αγαπήσουν οι tech leads: usage του API, callable από cron, χωρίς dashboard scraping:
export OPENAI_ADMIN_KEY="sk-admin-..."
openai admin organization usage completions \
--start-time 1735689600 \
--end-time 1735776000 \
--bucket-width 1d
Το openai admin --help (και openai admin organization --help) σου δείχνει κάθε subgroup, και οι παλαιές colon-style εντολές όπως openai admin:organization:usage completions συνεχίζουν να δουλεύουν. Τα admin keys είναι ισχυρά: κράτα τα σε secret manager, χρησιμοποίησέ τα μόνο σε metrics jobs, και μην τα μοιράζεις ως literal args στο history.
Security deep dive: τα λεπτά σημεία που αξίζουν
Γιατί σε ένα security blog η είσοδος του CLI είναι news για άλλον λόγο: μέσα στο README, η OpenAI έχει κρύψει στοιχεία threat-model σκέψης που σπάνια βλέπεις σε επίσημο developer tooling. Τα τρία μεγάλα:
1. Untrusted-stdin mode: ο εφιάλτης του @-expansion
Το @myfile.ext ως τιμή διαβάζει τοπικό αρχείο — by design. Και references δουλεύουν μέσα και σε JSON/YAML blobs (π.χ. {image: "@abe.jpg"}). Το δόλωμα: αν κάνεις pipe JSON/YAML από μη έμπιστη πηγή στο CLI, ένα body όπως {image: "@abe.jpg"} που έρχεται από stdin διαβάζει τοπικό σου αρχείο και το στέλνει ως μέρος του request. Για αυτό υπάρχει:
untrusted-producer | OPENAI_UNTRUSTED_STDIN=1 openai <command> --file ./upload.txt
Σε αυτό το mode, οι τιμές που έρχονται από stdin είναι κυριολεκτικές: τα @, @file://, @data:// δεν διαβάζουν αρχεία. Παράλληλα, τα explicit flags όπως --file διατηρούν τη φυσιολογική συμπεριφορά τους και υπερισχύουν των stdin τιμών. Αν κάνεις pipe από trusted heredoc που θέλει references, αφήνεις το flag off — security-by-default, με ρητό opt-out.
2. Mutual TLS (beta)
export OPENAI_MTLS_CLIENT_CERT_FILE=/run/secrets/openai/client-chain.pem
export OPENAI_MTLS_CLIENT_KEY_FILE=/run/secrets/openai/client.key
export OPENAI_BASE_URL=https://mtls.api.openai.com/v1
Ενδιαφέρον detail: HTTPS proxies απορρίπτονται (HTTP/SOCKS δουλεύουν) — ακριβώς επειδή το client πιστοποιητικό ΔΕΝ πρέπει να παραδίνεται στον proxy κατά το δικό του TLS handshake. Το private key, φυσικά, σε permission-restricted file — όχι σε command arguments. Και τα δύο αρχεία πρέπει να ρυθμίζονται μαζί, αλλιώς το mTLS δεν ενεργοποιείται.
3. Headers redacted + history hygiene
Οι τιμές σε --header 'X-Trace-ID: ...' κρύβονται από το help και redact-ονται από τα debug logs. Για credential-bearing headers, το README προτείνει secret manager ή trusted launcher που στέλνει OPENAI_CUSTOM_HEADERS στο environment — ώστε literal secrets να μη φτάνουν στο shell history ή στα process args.
Checklist πριν το βάλεις σε production scripts
- Secrets εκτός history:
OPENAI_API_KEY/OPENAI_CUSTOM_HEADERSαπό secret manager ή launcher — όχι ως literal CLI args. - Project-scoped keys: χρησιμοποίησε
OPENAI_PROJECT_IDκαι restricted keys, ώστε ένα leak να περιορίζεται σε per-project blast radius. - Untrusted input: σε pipelines που δέχονται JSON/YAML από τρίτους —
OPENAI_UNTRUSTED_STDIN=1, πάντα. - Rotate: αν βρεις keys σε logs/history/screenshots, rotate αμέσως — δες το litellm incident για το γιατί: όταν κλέβονται, χρησιμοποιούνται.
- Admin key isolation: ξεχωριστό
OPENAI_ADMIN_KEYμόνο σε metrics jobs, όχι στο κύριο workflow. - Updates από επίσημες πηγές:
brew upgradeήgo install @latest— ποτέ third-party binaries.
Update policy: ελέγχεται, δεν σιγοντάρει
Το CLI δεν εγκαθιστά ποτέ αναβαθμίσεις μόνο του. Όταν τρέχεις «γυμνό» openai σε interactive shell, ελέγχει (συγκρατημένα) για newer stable releases: το πολύ μία φορά την ημέρα, χρησιμοποιώντας δημόσια GitHub release metadata χωρίς API credentials, με timeout 200ms και σιωπή αν η check αποτύχει. Το plaintext notice εμφανίζεται το πολύ μία φορά την εβδομάδα, κάτω από το help — και skip-αρίζεται παντελώς σε CI, σε redirected output ή όταν τρέχεις ρητές εντολές. Αν δεν θες καν το check:
export OPENAI_CLI_NO_UPDATE_CHECK=1
Η διαδρομή upgrade ανά install method: πιστοποιημένο Homebrew install προτείνει brew upgrade --cask openai/tools/openai· τα Go installs θέλουν verified binary, διαθέσιμο Go command και ρητό matching GOBIN. Custom GOOS/GOARCH ή αναβαθμίσεις σε επόμενο major version σε στέλνουν πίσω στον installation guide. Πρακτικά: version bump και changelog (release-please) είναι ρητά και αναζητήσιμα — όχι κάτι που θα σου έρχεται σιωπηλά.
Σύγκριση: OpenAI CLI vs Codex vs Claude Code vs Gemini CLI
Τα AI εργαλεία του τερματικού σήμερα χωρίζονται σε δύο κατηγορίες: API wrappers (script-first) και agents (codebase-first). Το ενδιαφέρον: το OpenAI CLI έρχεται να καλύψει την πρώτη κατηγορία — και εντός 24 ωρών είχε ήδη συγκριθεί (λάθος) με τον Codex στα fora. Γι' αυτό, ο πίνακας:
| Εργαλείο | Τύπος | Δυνατά σημεία | Προσοχή σε |
|---|---|---|---|
| OpenAI CLI (Go) | API wrapper | Πλήρες REST surface (responses/models/files/images/admin), GJSON transforms, single binary χωρίς dependencies, untrusted-stdin guard, mTLS beta, offline help | Δεν κάνει agentic δουλειά· πολύ νέο — ήδη υπάρχει retired command (images create-variation) |
| Codex | Agent harness | Αυτόνομη δουλειά σε codebase, multi-step tasks, tools | Δεν προσφέρει curl-style scripting |
| Claude Code (Anthropic) | Agent | File editing, git integrations, πιό ώριμο agentic DX | Subscription στο Anthropic οικοσύστημα |
| Gemini CLI (Google) | Agent | Open source, multimodal, generous quotas | Δεμένο στο Google ecosystem, νεότερο και λιγότερο ώριμο |
| GitHub Copilot CLI | Agent/extension | Βαθιά gh/GitHub integration | Περιορισμένο στο GitHub context |
Η πρόβλεψη: το OpenAI CLI θα είναι ο «curl της εποχής GPT» — το default εργαλείο σε CI pipelines, cron jobs και quick calls από τερματικό. Οι agents (Codex, Claude Code, Gemini CLI) καλύπτουν τα agentic scenarios — και λογικά θα καλούν κι εκείνοι το CLI ως scripting layer κάτω από τις στοιβάδες τους. Σήμερα το CLI έχει ήδη χρήσιμα command groups, αλλά και το πρώτο retired command — σημάδι ότι το project τρέχει γρήγορα.
Τι λέει η κοινότητα
Δύο πρακτικές του repo καθορίζουν το πλαίσιο του contribution: κανένα pull request από εξωτερικούς (μόνο collaborators) και issues μόνο για bug reports / feature requests. Σε συνδυασμό με release-please, το project τρέχει πλήρως εντός του δικού του κλειστού release pipeline — όχι community-driven patches.
Συμπέρασμα
Το OpenAI CLI είναι από τα πιο τεχνολογικά ρεαλιστικά εργαλεία του τρίτου κύματος AI tooling: όχι agent, όχι hype, μόνο δομημένη πληρότητα πάνω από το REST API. Πού θα λάμψει: scripting, CI pipelines, cron jobs, quick calls, metrics, admin dashboards. Πού θα μείνει πίσω: agentic coding — εκεί υπάρχουν ήδη Codex, Claude Code και Gemini CLI.
Σε επίπεδο στάσης: κράτα surface οικολογικό. Είναι πολύ νωρίς, η ιστορία του OpenAI ecosystem με τα fast deprecations διδάσκει conservative adoption: env vars — όχι literal args, project-scoped keys, untrusted-stdin on σε pipelines με τρίτες sources, και changelog-watching μέσω release-please για τα breaking changes που θα έρθουν κάποτε.
Δύο πρακτικές συστάσεις: αν ήδη τρέχεις το Codex, προσθέσε το CLI ως scripting layer δίπλα του, όχι ως αντικατάσταση. Αν δούλευες με curl + jq στο OpenAI API: επιτέλους ήρθε το εργαλείο στο σπίτι σου.
Συχνές Ερωτήσεις (FAQ)
Τι είναι το OpenAI CLI;
openai <resource> <command>) και καλύπτει responses, models, files, images και admin endpoints. Είναι wrapper του API — όχι agent.Ποια η διαφορά του OpenAI CLI από το Codex;
Πώς εγκαθιστάται;
brew install openai/tools/openai. Εναλλακτικά, με Go 1.26+: go install 'github.com/openai/openai-cli/cmd/openai@latest', με το binary στο $GOPATH/bin. Το CLI δεν κάνει ποτέ αυτόματες αναβαθμίσεις.Πώς προστατεύονται τα API keys και τα headers;
OPENAI_API_KEY/OPENAI_ADMIN_KEY είναι environment variables — στείλ' τα από secret manager ή trusted launcher, όχι ως literal args στο shell history. Οι τιμές του --header κρύβονται από το help και redact-ονται στα debug logs. Το --debug καταγράφει request bodies — μην μοιράζεσαι τέτοια logs.Μπορεί να διαβάσει τοπικά αρχεία μου χωρίς να το ζητήσω;
@, @file:// ή @data:// σε request bodies διαβάζουν τοπικό αρχείο. Αν κάνεις pipe JSON/YAML από μη έμπιστη πηγή, βάλε OPENAI_UNTRUSTED_STDIN=1 — τότε οι τιμές από stdin λογίζονται κυριολεκτικά και δεν ανοίγουν αρχεία. Τα ρητά flags όπως --file κρατούν τη φυσιολογική συμπεριφορά και υπερισχύουν.