工程日記・第十九天:我們做了個CLI,因爲AI Agent討厭瀏覽器
2026年,最火的UI範式不是設計系統——是終端。AI Agent通過CLI完成任務的可靠性比MCP高28%,token消耗比瀏覽器自動化低4-32倍。所以我們構建了volo-cli:16個命令、JSON-first輸出、4個生產依賴、離線機隊數據,以及一個把每個上游API都當國家機密的安全架構。這是把VOLO整個API面變成任何Agent只需一行npx命令就能使用的故事。
核心論點:CLI是新的API
2026年,有些東西變了。AI Agent生態不再試圖讓Agent使用瀏覽器,而是開始在Agent真正工作的地方與它們會面——終端。Devin、Cursor、Claude Code、Windsurf、Cline——每個正經的Agent運行時都有一流的shell訪問能力。數據也證實了這一點:
- 任務完成率:在基準測試中,CLI命令的成功率比等效的MCP工具調用高28%
- Token效率:一條
volo search "NYC to London"命令消耗的token比瀏覽網頁UI或解析HTML少4-32倍 - 可組合性:
volo fleet list | jq '.[] | select(.range_km > 10000)'—— Unix管道是最初的函數組合 - 確定性:沒有會崩的DOM,沒有會失效的CSS選擇器,沒有需要關閉的Cookie橫幅
E2B、Stripe、Vercel、Supabase、Neon——每個面向開發者的公司現在都把CLI當作一流的Agent接口。VOLO已經有REST、GraphQL、MCP和OpenAI Plugin。缺失的那塊拼圖很明顯。
架構:四個依賴和一個原則
設計約束很簡單:stdout給機器,stderr給人類。
默認情況下,每個命令都向stdout輸出乾淨的JSON。沒有加載動畫,沒有顏色,沒有進度條。AI Agent可以直接把輸出管道到 jq 或用 JSON.parse() 解析。加上 --pretty 就有彩色表格、加載動畫和格式化輸出——但只在stderr上,永遠不會污染數據流。
# Agent模式(默認)—— 乾淨的JSON
volo search "NYC to London 4 pax" | jq '.data.flights[0].price'
# 人類模式 —— 彩色表格
volo fleet list --pretty --category heavy
生產依賴:恰好四個。
| 包 | 用途 | 大小 |
|---|---|---|
| commander | CLI框架 | ~50KB |
| chalk | 終端顏色(僅--pretty模式) | ~16KB |
| cli-table3 | 表格格式化(僅--pretty模式) | ~30KB |
| ora | 加載動畫(僅--pretty模式) | ~20KB |
HTTP?Node 18+原生 fetch。零依賴。配置存儲?fs.writeFileSync 配合 0600 權限。沒有鑰匙串庫,沒有憑據管理器——就是一個只有所有者能讀的JSON文件。
16個命令,一個API面
CLI直接映射到VOLO的REST API。每個命令都是HTTP調用的薄封裝:
volo search "上海到東京下週五,4位乘客"
volo quote --from ZSPD --to RJTT --pax 4 --date 2026-04-15
volo track CX520
volo weather Singapore --forecast 3
volo fleet list --category heavy
volo fleet compare "Gulfstream G650ER" "Bombardier Global 7500"
volo airports search "changi"
volo empty-legs --region asia-pacific --limit 10
volo routes --tag popular
volo destinations --region europe
volo content --type fleet --locale zh
volo agent register --name MyBot --email bot@example.com
volo agent dashboard --pretty
volo chat "幫我找一架重型公務機,8位乘客"
volo api GET /v1/openapi.json
volo config list
不需要認證的命令(search、weather、fleet、airports、track)用 npx volo-cli 立即可用。無需註冊,無需API key,無需配置。Agent命令(dashboard、referrals)需要通過 volo agent register 獲取的密鑰。
安全架構
這是最重要的設計決策,也是需要最多紀律性的決策。VOLO集成了多個上游航空數據供應商。CLI必須永遠不暴露它們中的任何一個。
原則:CLI是一個純API客戶端,只知道 flyvolo.ai。它不知道上游供應商的存在。
用戶/Agent ──> volo-cli ──> flyvolo.ai/api/v1/* ──> [VOLO後端] ──> 上游供應商
│ ↑
│ 所有供應商調用
│ 僅在服務端發生
└── CLI只知道flyvolo.ai,不知道其他任何東西
實踐中的意義:
- 無上游URL:CLI源碼中只包含一個域名——
flyvolo.ai。沒有供應商API地址,沒有代理URL,沒有CDN端點。 - 無內部ID:內嵌的機隊數據只包含公開信息——飛機名稱、座位數、航程、價格區間。沒有供應商內部標識符。
- 無泄露的錯誤詳情:當上遊API失敗時,CLI顯示"服務暫時不可用"——永遠不顯示上游錯誤消息或URL。
- 無供應商導入:CLI包對內部包的導入爲零。不依賴
@volo/ai、@volo/database或任何供應商客戶端庫。
認證鏈遵循縱深防禦:
優先級:VOLO_API_KEY 環境變量 > --api-key 參數 > ~/.volo/config.json > 匿名
~/.volo/config.json 中的憑據以 0600 權限存儲(僅所有者可讀寫)。volo config list 在顯示時遮蔽API key(volo_abc...xyz)。volo auth logout 安全刪除文件。
離線能力
兩個命令無需任何網絡連接即可工作:
volo fleet list:內嵌4個類別15款飛機的數據(輕型、中型、超中型、重型/超遠程)。完整規格:名稱、製造商、座位數、航程、速度、客艙尺寸、價格區間。volo fleet compare:基於內嵌數據的並排對比。試試volo fleet compare "Citation CJ4" "Phenom 300E" --pretty。
內嵌數據與網站上公開展示的信息完全一致——沒有內部定價模型,沒有供應商利潤率,沒有機密數據。
交互式聊天:終端裏的AI管家
volo chat 把VOLO的14工具AI管家帶到了命令行。兩種模式:
# 單次調用(適合Agent)
volo chat "找找這周從倫敦出發3萬美元以下的空腿航班"
# 交互式REPL(適合人類)
volo chat
volo> 我需要一架下個月從上海到東京的飛機,6個人
volo> Global 7500怎麼樣?
volo> /quit
REPL跨對話輪次保持上下文記憶,管家會記住之前聊的內容。單次模式返回JSON——完美適配Agent流水線。
前端集成:CLI成爲第五協議
構建CLI只是一半的工作。另一半是讓它被看見。我們把CLI集成到了Agent主頁的每個部分:
| 組件 | 變更 |
|---|---|
| CodeTabs | 添加第8個"CLI"標籤頁,包含安裝和命令示例 |
| AgentHero | 在統計數據下方添加 npx volo-cli --help 可複製安裝卡片 |
| EndpointCards | 每個API端點在展開視圖中顯示對應的CLI命令 |
| ProtocolStatus | 添加第5個"CLI"協議卡片(狀態:LIVE) |
| AgentHome | 在Quick Start部分添加CLI入口點 |
CLI現在與REST、GraphQL、MCP和OpenAI Plugin並列——從Agent或開發者訪問 /for-agents 的那一刻起就能看到。
核心數據
| 指標 | 數值 |
|---|---|
| 命令數 | 16(+ config/auth) |
| 源文件 | 28 |
| 代碼行數 | ~2,500 |
| 生產依賴 | 4 |
| 測試 | 17(全部通過) |
| 暴露的上游API | 0 |
| 離線命令 | 2(fleet list、fleet compare) |
| 修改的前端組件 | 5 |
| 從規劃到部署 | 1個會話 |
我學到的
1. JSON-first對Agent接口來說沒有商量餘地
你在stdout中混入人類可讀格式的那一刻,就破壞了每一個下游消費者。Agent無法解析表格,無法可靠地去除ANSI顏色碼。stdout/stderr的分離不是"有更好"——它是根本契約。
2. 通過架構而非策略來保證安全
我們沒有添加"不要暴露上游API"的lint規則。我們讓它在結構上不可能——CLI包不依賴任何內部包,沒有通往任何供應商客戶端的導入路徑,只硬編碼了一個域名。最安全的代碼是那些根本無法觸及不應觸及之物的代碼。
3. 離線能力贏得信任
volo fleet compare G650 "Global 7500" 在沒有WiFi的飛機上也能用。這不是噱頭——它證明了你的工具尊重用戶的環境。當Agent在受限沙箱中運行時,離線命令依然有效。
4. Monorepo模式很重要
向Turborepo monorepo添加新包幾乎沒有摩擦。packages/cli/ 自然地放在 packages/mcp-server/ 旁邊。相同的構建模式,相同的tsconfig基礎,相同的CI管道。MCP server就是模板——我們完全匹配了它的結構。
5. CLI是從零到價值的最快路徑
npx volo-cli search "NYC to Aspen" ——就這樣。不需要瀏覽器,不需要註冊,不需要API key,不需要安裝SDK。一個命令,立即獲得結果。對於一個正在評估是否與VOLO集成的AI Agent來說,摩擦基本爲零。
下一步
- npm publish:將
volo-cli推送到公共npm registry,讓npx volo-cli全球可用 - Shell補全:bash/zsh/fish的Tab補全
- 插件系統:讓Agent開發者用自定義命令擴展volo-cli
- 流式輸出:用
--watch標誌實時追蹤航班 - CI/CD集成:用GitHub Actions構建自動化航空數據流水線
準備好飛行了嗎?幾秒鐘獲取個性化包機報價。
訂閱資訊
空腿航班優惠、新航線與航空洞察,直達您的郵箱。