Skip to content

CLI设计

定位:CLI 是给 Agent(模型)设计的指令系统,是业务与技术之间的「胶水」。形态没变,但服务对象从「人」换成了「模型」——让 AI 调固定子命令、读结构化输出,而不是临场拼路径、写脚本。

📎 来源:实践分享第三章 + 好 Skill 与 AI 原生 CLI/CI 设计指南 + 控制价 CLI 化实战。

📐 深度规范(五层模型 / 颗粒度 / 输出协议 / 安全分级 / 命名 / 迁移)→ 设计指南/CLI设计/CLI设计规范 🧪 实战案例(4 方评测,79m→15m)→ 实践分享/控制价审核CLI化实战


同样是 AI 原生 CLI,按「干什么」分四类——后端(API / DSL / 编排)是设计策略,各有一套取舍:

原型后端策略风险干什么文档
查询类APIR0 读取一条确定数据,端点固化设计指南/CLI设计/查询类CLI
分析类DSL(语义层/宽表)R0 读多维聚合/排名/下钻归因,本体兜口径设计指南/CLI设计/分析类CLI
操作类APIR1–R3 写改世界:建文档/发消息/下单,要 dry-run+审计设计指南/CLI设计/操作类CLI
报告类编排(直出/分段)R0–R1成稿:简单直出,复杂用 CLI 分段拼接设计指南/CLI设计/报告类CLI

选型口诀:取一条 → 查询类;多维分析 → 分析类;改状态 → 操作类;出成稿 → 报告类。四者常在一个 Skill 里串联(查询/分析出数 → 报告类成稿 → 操作类发布)。


口诀是抽象的,下面把它落到 5 句真实问话上——听到这句话,AI 该判成哪一类、最终落成什么命令。这就是 CLI 设计的目标:让模型不拼路径、不写 SQL,只把业务意图填进固定子命令。

🗣️ 用户:「深圳湾一号 1801 这套房,现在什么状态?」 🎯 判型:取一条确定数据、维度固定(房号→状态)→ 查询类(口诀「取一条」)。 ⌨️ 转换:

Terminal window
sql-query ledger --project 深圳湾一号 --keyword 1801 --limit 1

💡 要点:房号是 --keyword,状态是端点固化的返回字段。一个子命令打一个 API 端点,AI 只填业务参数;新维度要查得改代码——这是查询类的天花板。

🗣️ 用户:「上个月谁卖得最好?」 🎯 判型:要按置业顾问分组、按成交额排序取第一 → 分析类rank(口诀「多维分析」)。 ⌨️ 转换:

Terminal window
sales-query rank --dsl '{
"cube":"OrderDetail",
"rankBy":{"member":"cjTotal","agg":"sum"},
"dimensions":["zygw"],
"filters":[{"member":"month","op":"=","val":"2026-05"}],
"limit":1
}'

💡 要点:「卖得最好」被翻成「按成交额求和降序取 Top-1」。模型只填 DSL,引擎编 SQL 并自动注入 Status=激活 AND OrderType=认购 口径护栏——不靠模型记得加。

案例 3 · 分析类「聚合 + 口径护栏」

Section titled “案例 3 · 分析类「聚合 + 口径护栏」”

🗣️ 用户:「各业态的货值分别是多少?」 🎯 判型:按业态 GROUP BY、对货值求和 → 分析类aggregate。 ⌨️ 转换:

Terminal window
sales-query aggregate --dsl '{
"cube":"Inventory",
"dimensions":["yetai"],
"measures":[{"member":"huozhi","agg":"sum"}]
}'
# 引擎自动补 WHERE Level=3 —— 不补就把多层级货值重复累加(货值三倍 bug)

💡 要点:同一句问话,模型裸写 SQL 会错 3 倍;护栏 defaultFilters 写在本体(TBox),模型不传也补——这正是 设计指南/本体设计/TBox 货值 bug 的解法。

案例 4 · 操作类「发布(写操作)」

Section titled “案例 4 · 操作类「发布(写操作)」”

🗣️ 用户:「把这份销售报告发到飞书,给团队看。」 🎯 判型:建文档/写内容,有外部副作用 → 操作类,走业务 SOP(口诀「改状态」)。 ⌨️ 转换(命令树第一层是业务对象,不是 POST /open-apis/...):

Terminal window
feishu whoami # 确认用户身份,否则别人看不到
feishu create_doc "5月销售达成" <folder> # 拿 doc_id
feishu add_blocks <doc_id> <报告正文 json> # 局部追加,不整篇覆盖
feishu insert_image <doc_id> chart.png # 配图

💡 要点:建草稿是 R1,明确意图即可直接做;但若用户说的是「删/撤/外发邮件」(R3),必须先 --dry-run 预演、等 --yes 才执行。详见 设计指南/CLI设计/操作类CLI

案例 5 · 一句话串多类「审控制价出报告」

Section titled “案例 5 · 一句话串多类「审控制价出报告」”

🗣️ 用户:「审一下信宏城一期的控制价,出份报告。」 🎯 判型:多阶段重计算 + 异步 + 要可复现 → 复杂报告(报告类分段 pipeline),中途两处停下来问口径。 ⌨️ 转换(一句话其实串了 分析 → 报告,可再接操作类发布):

Terminal window
report-gen resolve-bq --project 深圳湾一号 --bq 信宏城一期
report-gen confirm-audit-mode ... # ⏸ 按什么口径审,要你定
report-gen confirm-similar ... # ⏸ 拿哪些历史项目对标,要你定
report-gen scan scan.json # ② 指标异常(分析)
report-gen insight insight.json # ③ 归因(分析)
report-gen price create/poll/fetch # ④ 单价偏离,异步拆三段
report-gen report report.md # 把各块拼成成稿

💡 要点:每块结果落草稿文件,上下文不爆、可复盘、可「只重做归因那段再拼」;口径判断不替用户默认,停下来问(⏸)。详见 设计指南/CLI设计/报告类CLI

一眼对照:听到这种话 → 走哪条

Section titled “一眼对照:听到这种话 → 走哪条”
用户话里的信号判型一级指令
「这一套/这一条…是什么状态/多少」查询类ledger / resource-action
「谁最高 / Top N / 排个名」分析类rank
「各 X 的 Y 是多少 / 按…分组」分析类aggregate
「明细 / 列出符合…的行」分析类find
「发到 / 建个 / 删掉 / 同步 / 下单」操作类业务对象 + 业务动词
「出份报告 / 总结一下 / 复盘」报告类直出 or 分段 pipeline

⚠️ 同一句话可能先触发分析取数、再触发报告成稿、最后操作发布(案例 5)——Skill 的职责就是把这条链按顺序编排好(见 设计指南/Skill设计/SKILL里如何调用CLI)。


传统 CLI · 给人用AI 原生 CLI · 给模型用
服务对象:人类开发者服务对象:Agent
目标:覆盖所有功能选项目标:完成一个业务动作
输出:给人读的日志 / 堆栈输出:JSON + error_code + hint,机器可解析
命令来自:API 能力清单命令来自:业务任务,不是 API 路径

同一个任务「审一下这个清单的控制价」:

Terminal window
# 脚本模式 · 面向「文件」——AI 得先知道脚本在哪、参数怎么排(~200 字符)
python3 /Users/x/.claude/skills/cost-audit/scripts/run_price_deviation_pipeline.py \
--project-name 深圳湾一号 --bq-name 信宏城一期 --mode indicator --coverage 1.0 ...
# CLI 模式 · 面向「指令」——AI 只说「做什么」,命令在 PATH 里(~100 字符)
report-gen price create --project 深圳湾一号 --bq 信宏城一期 --coverage 1.0

差距在累加:一次请求常调 4 次工具,脚本模式 200×4≈800 字符 vs CLI 100×4≈400。长路径一行行塞满上下文,直接拖累 AI 的注意力与指令遵循。

CLI 化的实测收益(同任务 · GPT-5.5)

Section titled “CLI 化的实测收益(同任务 · GPT-5.5)”
指标脚本模式CLI 模式
实际用时79m15m
错误率(工具调用失败)11%0%
Token 消耗13M2.9M
临时补丁脚本60
读源码次数(猜内部实现)960

0 报错、0 补丁、0 读源码 = production-ready;弱模型 Qwen 同样降本 3 倍以上。

核心机制:物理隔离强于文档约定

Section titled “核心机制:物理隔离强于文档约定”

不靠提示词求模型「别乱来」,而是让它无路可走,只能走对的那条:

脚本模式的问题CLI 化后
猜脚本路径失败CLI 在 PATH,不需知道物理位置
Windows 路径/引号出错CLI 内部处理路径
模型想改 Skill 源码兜底目录里根本没有 .py 可改
JSON/GBK 编码混乱CLI 统一封装读写编码
字段名靠猜 KeyErrorCLI 输出稳定 schema

好 CLI 是「业务动作接口」,不是 API wrapper

Section titled “好 CLI 是「业务动作接口」,不是 API wrapper”

命令树第一层是业务对象,不是 API URL。飞书 CLI 范式:

feishu create_doc <title> # 不是 POST /open-apis/docx/v1/...
feishu add_blocks <doc_id> <json>
feishu insert_image <doc_id> <path>

左边一组业务命令,右边把它们编成业务 SOP(「把报告发布到飞书」= whoami → create_doc → add_blocks → insert_image)。Skill 只管「按这个顺序,每步调哪个命令」。

复杂查询用 3 个一级指令收窄动作空间(配合 设计指南/本体设计 的护栏):

指令用途SQL 语义
find行级查询SELECT … WHERE … LIMIT
aggregate聚合分组SELECT … GROUP BY … HAVING
rankTop-NSELECT … ORDER BY … LIMIT N

模型只填 JSON,引擎编 SQL,护栏自动注入——接口窄、错不了

🔒 一旦提供 CLI,所有写操作必须经过它,否则状态/索引/编码会不一致。子命令正交可组合;price 这类异步任务拆 create/poll/fetch