Natural na wika tungo sa shell command gamit ang LLM API: JSON at gastos
Isang Python script na humihingi sa murang modelo ng isang shell command bilang JSON, tumatanggi o nagfa-flag ng unsure na request, walang pinapatakbo, at nagpe-presyo ng 1,000 request.

Sa pahinang ito
Hilingin sa modelo ang isang JSON object na may tatlong field (type, command, explanation), limitahan ang sagot sa ilang daang token, at i-print ang command sa halip na patakbuhin ito. Sa bilang ng token, ang ganoong request ay halos prompt na may maikli at mahuhulaang sagot: sa ilalim ng mga pagpapalagay sa ibaba, ang 1,000 sa mga ito ay nagkakahalaga ng $0.012 sa DeepSeek-V4-Flash.
Sabihin nating nagdadagdag ka ng "describe what you want" box sa isang internal CLI. May nagta-type ng find files bigger than 100 MB in my home folder, at gusto mong makabalik ang isang linya na mababasa, masusuri at maipapaste nila. Dalawang tanong ang sumusunod: paano mo pipigilan ang modelo na manghula o gumawa ng mapanganib, at magkano ito kapag isang daang tao ang gumagamit nito buong araw?
Isang makitid na gawain: bakit maikli ang sagot#
Noong 9 Nobyembre 2026, muling isinalaysay ng isang Telegram channel ang model card ng dale-0.8b, isang open model na eksaktong ito lang ang ginagawa. Ayon sa model card sa Hugging Face (sinuri noong 10 Nobyembre 2026), ang dale-0.8b ay isang full fine-tune ng Qwen3.5-0.8B sa ilalim ng Apache-2.0 na nagpapalit ng request sa Spanish o English tungo sa isang Linux bash command. Iniulat ng may-akda, si Manuel García, ang 79.4% (374 sa 471 kaso) sa sarili niyang test set, laban sa 62.8% para sa Qwen3.5-9B base at para sa Gemma 4 E4B-it na walang fine-tuning. Mga self-reported na numero iyon sa test set ng isang tao, kaya ituring itong isang data point, hindi ranking.
Ang kapaki-pakinabang sa atin ay ang hugis ng gawain, hindi ang modelo. Inilalarawan ng card ang isang fixed system prompt, isang context line (OS, distro, package manager, tools) kasama ang request, patay ang thinking, at sagot na nililimitahan sa 200 token. Ang cap na iyon ay isa sa dalawang lever sa gastos: kapag ang sagot ay isang maikling JSON object, maikli at mahuhulaan ang output side, dahil nililimitahan ito ng cap. Ang isa pang lever ay ang prompt. Anong bahagi ng bill ang binubuo ng bawat panig, ipinapakita ng talahanayan sa ibaba; nag-iiba ito sa bawat modelo.
Hindi mo kailangan ng 0.8B na modelo para diyan. Gumagana ang parehong format sa anumang API model, at iyon ang itinatayo ng natitirang bahagi ng artikulong ito.

Ang format ng sagot: command, refuse o unsure#
Ang trick ay laging may legal na paraan ang modelo para sabihing "hindi". Ang sagot ay isang object:
{"type": "command | refuse | unsure", "command": "...", "explanation": "..."}command: isang bash command, kasama ang isang pangungusap na paliwanag kung ano ang ginagawa nito.refuse: ang request ay mapaminsala o walang kinalaman sa shell. Walang command.unsure: masyadong malabo ang request ("clean up my disk"). Ang paliwanag ay may kasamang clarifying question.
Kung walang unsure, pinipilit ng malabong request ang isang hula, at ang hinulaang rm ang natatandaan mo. Ang format ng card ay may parehong tatlong uri; ginagamit namin muli ang ideya, hindi ang modelo.
Itugma ang mga pares
Itugma ang bawat uri ng sagot sa dapat gawin ng script
I-tap ang isang item sa kaliwa, pagkatapos ang pares nito
- commandIpakita ang command at ang paliwanag; ang tao mismo ang kumokopya at nagpapatakbo nito
- refuseI-print ang paliwanag at walang iaalok na patakbuhin
- unsureI-print ang tanong at hayaang mag-rephrase ang user
Ang script#
Isang file, ang openai package, key sa isang environment variable. Ang base URL at ang buong model id ay galing sa CheapTokens docs; hindi tinatanggap ang maiikling id, kaya gamitin ang deepseek-.
import json
import os
import sys
from openai import OpenAI
client = OpenAI(
base_url='https://api.cheaptokens.dev/v1',
api_key=os.environ['CHEAPTOKENS_API_KEY'],
)
MODEL = 'deepseek-ai/DeepSeek-V4-Flash-0731'
SYSTEM = '''You turn a request into ONE Linux bash command.
Reply with a single JSON object and nothing else:
{"type": "command" | "refuse" | "unsure", "command": "<one command, or empty>", "explanation": "<one short sentence>"}
Use "refuse" when the request is destructive or not about the shell.
Use "unsure" when it is too vague, and put a clarifying question in "explanation".'''
CONTEXT = 'os: Ubuntu 24.04; package manager: apt; tools: git, curl, jq'
def parse(text):
start = text.find('{')
if start == -1:
return None
try:
obj, _ = json.JSONDecoder().raw_decode(text[start:])
except json.JSONDecodeError:
return None
if not isinstance(obj, dict) or obj.get('type') not in ('command', 'refuse', 'unsure'):
return None
return obj
def ask(request):
resp = client.chat.completions.create(
model=MODEL,
max_tokens=200,
temperature=0,
messages=[
{'role': 'system', 'content': SYSTEM},
{'role': 'user', 'content': f'Context: {CONTEXT}\nRequest: {request}'},
],
)
return parse(resp.choices[0].message.content), resp.usage
if __name__ == '__main__':
result, usage = ask(' '.join(sys.argv[1:]))
if result is None:
print('Could not read the reply as JSON. Try again.')
elif result['type'] == 'command':
print(result['explanation'])
print('\n ' + result['command'] + '\n')
print('Read it, then copy it yourself. This script never runs it.')
else:
print(f"[{result['type']}] {result['explanation']}")
print(f'tokens: {usage.prompt_tokens} in, {usage.completion_tokens} out')Patakbuhin ito bilang python shellhelp.. Tatlong pagpipilian ang mahalaga dito:
- Walang
subprocesskahit saan. Ang command ay text sa screen. Ang pagpapatakbo nito ay desisyon mo, pagkatapos mong basahin ito. max_tokens=200, kapareho ng cap ng card. Madaling kasya ang isang JSON object; ang mahabang sagot ay pinuputol sa 200 token sa halip na magpatuloy sa gastos mo. Nalalapat ang cap sa buong sagot, kaya kung isusulat ng modelo ang reasoning nito, maaaring maubos nito ang limit. Kung may sagot na nagtatapos safinish_reasonna katumbas nglength, taasan nang kaunti ang cap. Higit pa riyan sa cutting output tokens with max_tokens.- Hinihiling ang format sa prompt, tapos defensive na pag-parse. Nilalaktawan ng
raw_decodeang ligaw na code fence o isang pangungusap bago ang{. Kung gusto mong lumayo pa, tingnan ang valid JSON from an OpenAI-compatible API at ang fix para sa json.JSONDecodeError on a reply.
Bago ka magpatakbo ng kahit ano, tiyakin na malinaw ang pagkakasunod-sunod ng mga hakbang:
Ilagay sa tamang pagkakasunod-sunod
Ilagay sa tamang ayos ang mga hakbang ng script
I-drag ang mga item o gamitin ang mga arrow
- Buuin ang prompt: fixed system text, isang context line, ang request
- Tawagin ang API na may maliit na max_tokens
- I-parse ang JSON at tiyaking ang type ay isa sa tatlo
- Ipakita ang command at hintayin ang tao na patakbuhin ito
Magkano ang 1,000 request#
Ipiniprint ng huling linya ng script ang usage. Iyon ang totoong numero, at dapat mong basahin ang sarili mo. Hanggang mayroon ka nito, gumamit ng palagay: ang prompt ay umaabot sa mga 400 input token (ang bare prompt sa script ay humigit-kumulang 150 token sa isang magaspang na bilang; ang natitira ay espasyo para sa tatlo o apat na halimbawang request-and-reply pair na malamang idadagdag mo), at ang JSON reply sa mga 60 output token.
Para sa 1,000 request, iyon ay 400 × 1,000 = 400,000 input token at 60 × 1,000 = 60,000 output token. Presyo ng talahanayan ang eksaktong iyon para sa bawat modelo sa catalog, kasama ang OpenRouter column sa tabi nito; galing sa live na presyo ang mga numero, kaya nananatili silang updated.
| Modelo | Input $/1M | Output $/1M | Bawat kahilingan | 1,000 mga kahilingan | OpenRouter, 1,000 mga kahilingan |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.00001 | $0.0104 | $0.0184 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.000012 | $0.012 | $0.0364 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.000029 | $0.029 | $0.348 |
400 input at 60 output na token bawat kahilingan. Ang mga presyo kada 1M token ay kasalukuyan at nagbabago kasabay ng aming mga taripa; ang column ng OpenRouter ay nagpapakita ng reference na presyo para sa parehong workload.
Sa kabuuan, kasama ang input at output, mas mura ang DeepSeek-V4-Flash kaysa OpenRouter para sa workload na ito. Sa bilang ng token, halos lahat ng request ay input at maikli ang sagot, pero sinisingil ang magkabilang panig, kaya bawasan ang prompt at ang sagot pareho. Ang presyo kada modelo ay nasa pricing page, at ang modelo mismo ay inilalarawan sa the DeepSeek page: 380K context, hanggang 32,768 output token, isang presyo sa anumang oras.
Mabilis na paraan para maramdaman ang proporsyon:
Mabilisang pagsusuri
Aling bahagi ng request ang nililimitahan ng max_tokens=200?
Ipakita ang sagot
Sagot: Ang sagot
ang max_tokens ay nililimitahan lang ang sagot; sinisingil ang prompt kung ano ito, kaya bawasan ito nang hiwalay.
Gusto ng 100,000 request kada buwan? I-multiply sa 100: 40,000,000 input at 6,000,000 output token. Ilagay ang dalawang numerong iyon sa ::cost sa parehong paraan at basahin ang row.
Subukan ito sa sarili mong request#
Walang sinasabi ang 79.4% ng card tungkol sa prompt mo, sa OS mo o sa pananalita ng mga user mo. Sumulat ng 20 totoong request kasama ang mga command na tatanggapin mo at ihambing, eksaktong gaya ng sa testing a prompt on a small eval set. Isama ang ilang dapat i-refuse o i-flag ng script bilang unsure, gaya ng "delete everything" o "make my computer faster".
Kapag may nagkamali, karaniwang itinuturo ng sintomas ang fix:
Could not read the reply as JSON: i-print ang raw text isang beses. Ang prefix gaya ng "Sure!" ay hinahawakan; ang sagot na pinutol ng cap ay hindi, kaya tingnan angfinish_reason.401o404: maling key, base URL o model id. Nasa API 401 or 404: key, base URL, model id ang listahan.- Mga command na bagay sa ibang system: ang context line ang dahilan. Panatilihin itong tumpak (OS, package manager, tools); nagkakahalaga ito ng ilang dosenang token at nakakaiwas sa maling
aptsa isang Fedora box.
Parehong gawain, ibang modelo? Palitan ang MODEL ng GLM o MiniMax id mula sa docs, panatilihin ang prompt, at ihambing ang bilang ng token na ipiniprint ng script sa talahanayan sa itaas.



