CLI设计
⌨️ CLI 设计 · 接口层
Section titled “⌨️ CLI 设计 · 接口层”定位:CLI 是给 Agent(模型)设计的指令系统,是业务与技术之间的「胶水」。形态没变,但服务对象从「人」换成了「模型」——让 AI 调固定子命令、读结构化输出,而不是临场拼路径、写脚本。
📎 来源:实践分享第三章 + 好 Skill 与 AI 原生 CLI/CI 设计指南 + 控制价 CLI 化实战。
📐 深度规范(五层模型 / 颗粒度 / 输出协议 / 安全分级 / 命名 / 迁移)→ 设计指南/CLI设计/CLI设计规范 🧪 实战案例(4 方评测,79m→15m)→ 实践分享/控制价审核CLI化实战
四种 CLI 原型(按用途选)
Section titled “四种 CLI 原型(按用途选)”同样是 AI 原生 CLI,按「干什么」分四类——后端(API / DSL / 编排)是设计策略,各有一套取舍:
| 原型 | 后端策略 | 风险 | 干什么 | 文档 |
|---|---|---|---|---|
| 查询类 | API | R0 读 | 取一条确定数据,端点固化 | 设计指南/CLI设计/查询类CLI |
| 分析类 | DSL(语义层/宽表) | R0 读 | 多维聚合/排名/下钻归因,本体兜口径 | 设计指南/CLI设计/分析类CLI |
| 操作类 | API | R1–R3 写 | 改世界:建文档/发消息/下单,要 dry-run+审计 | 设计指南/CLI设计/操作类CLI |
| 报告类 | 编排(直出/分段) | R0–R1 | 成稿:简单直出,复杂用 CLI 分段拼接 | 设计指南/CLI设计/报告类CLI |
选型口诀:取一条 → 查询类;多维分析 → 分析类;改状态 → 操作类;出成稿 → 报告类。四者常在一个 Skill 里串联(查询/分析出数 → 报告类成稿 → 操作类发布)。
案例:用户问题 → 对应 CLI
Section titled “案例:用户问题 → 对应 CLI”口诀是抽象的,下面把它落到 5 句真实问话上——听到这句话,AI 该判成哪一类、最终落成什么命令。这就是 CLI 设计的目标:让模型不拼路径、不写 SQL,只把业务意图填进固定子命令。
案例 1 · 查询类「取一条」
Section titled “案例 1 · 查询类「取一条」”🗣️ 用户:「深圳湾一号 1801 这套房,现在什么状态?」 🎯 判型:取一条确定数据、维度固定(房号→状态)→ 查询类(口诀「取一条」)。 ⌨️ 转换:
Terminal window sql-query ledger --project 深圳湾一号 --keyword 1801 --limit 1💡 要点:房号是
--keyword,状态是端点固化的返回字段。一个子命令打一个 API 端点,AI 只填业务参数;新维度要查得改代码——这是查询类的天花板。
案例 2 · 分析类「排名(Top-N)」
Section titled “案例 2 · 分析类「排名(Top-N)」”🗣️ 用户:「上个月谁卖得最好?」 🎯 判型:要按置业顾问分组、按成交额排序取第一 → 分析类 的
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_idfeishu 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 vs AI 原生 CLI
Section titled “传统 CLI vs AI 原生 CLI”| 传统 CLI · 给人用 | AI 原生 CLI · 给模型用 |
|---|---|
| 服务对象:人类开发者 | 服务对象:Agent |
| 目标:覆盖所有功能选项 | 目标:完成一个业务动作 |
| 输出:给人读的日志 / 堆栈 | 输出:JSON + error_code + hint,机器可解析 |
| 命令来自:API 能力清单 | 命令来自:业务任务,不是 API 路径 |
杀手论据:脚本模式 vs CLI 模式
Section titled “杀手论据:脚本模式 vs CLI 模式”同一个任务「审一下这个清单的控制价」:
# 脚本模式 · 面向「文件」——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 模式 |
|---|---|---|
| 实际用时 | 79m | 15m |
| 错误率(工具调用失败) | 11% | 0% |
| Token 消耗 | 13M | 2.9M |
| 临时补丁脚本 | 6 | 0 |
| 读源码次数(猜内部实现) | 96 | 0 |
0 报错、0 补丁、0 读源码 = production-ready;弱模型 Qwen 同样降本 3 倍以上。
核心机制:物理隔离强于文档约定
Section titled “核心机制:物理隔离强于文档约定”不靠提示词求模型「别乱来」,而是让它无路可走,只能走对的那条:
| 脚本模式的问题 | CLI 化后 |
|---|---|
| 猜脚本路径失败 | CLI 在 PATH,不需知道物理位置 |
| Windows 路径/引号出错 | CLI 内部处理路径 |
| 模型想改 Skill 源码兜底 | 目录里根本没有 .py 可改 |
| JSON/GBK 编码混乱 | CLI 统一封装读写编码 |
| 字段名靠猜 KeyError | CLI 输出稳定 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 只管「按这个顺序,每步调哪个命令」。
DSL:把查询也做成窄接口
Section titled “DSL:把查询也做成窄接口”复杂查询用 3 个一级指令收窄动作空间(配合 设计指南/本体设计 的护栏):
| 指令 | 用途 | SQL 语义 |
|---|---|---|
find | 行级查询 | SELECT … WHERE … LIMIT |
aggregate | 聚合分组 | SELECT … GROUP BY … HAVING |
rank | Top-N | SELECT … ORDER BY … LIMIT N |
模型只填 JSON,引擎编 SQL,护栏自动注入——接口窄、错不了。
关键约束:脚本是唯一入口
Section titled “关键约束:脚本是唯一入口”🔒 一旦提供 CLI,所有写操作必须经过它,否则状态/索引/编码会不一致。子命令正交可组合;
price这类异步任务拆create/poll/fetch。