CLI、MCP、API三层架构:AI时代系统开发接口的新范式
为什么突然聊这个话题?
上个月跟一位团队技术负责人聊天的时候,他说他们遇到一个典型问题:
“我们的系统提供了RESTful API,Swagger文档写得很全,但业务团队说'太难用了'。最后还是写在内部Wiki上,让大家复制curl命令去调。”
这实则不是个别现象。API很好,但对”人”来说不够好。
与此同时,Claude Code、Codex CLI这类AI编程工具的崛起,带来了一个新的接口范式——MCP(Model Context Protocol)。而CLI这个”古老”的交互方式,在AI时代反而重新焕发了生命力。
这三个接口范式到底怎么选?怎么配合? 今天从系统设计者的角度,聊聊CLI、API、MCP三者的定位差异、集成模式,以及未来开放平台该怎么设计。
一、三个接口的基因差异
先把三者的核心定位说清楚:

┌──────────────────────────────────────────────────────────┐
│ 系统能力暴露层 │
│ │
│ ┌─────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ CLI │ │ API │ │ MCP │ │
│ │ 命令行 │ │ HTTP接口 │ │ AI协议 │ │
│ └────┬────┘ └────┬─────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌────▼──────────────▼─────────────────▼─────────────┐ │
│ │ 核心业务逻辑 │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 用户: 开发者/运维 用户: 程序/系统 用户: AI Agent │
└──────────────────────────────────────────────────────────┘
CLI:以人为本的操作界面
CLI(命令行界面)是最古老也最直接的交互方式。它的核心特征:
-
交互性 :管道组合、参数调试、实时反馈
-
可脚本化 :可以嵌入shell脚本、CI/CD流水线
-
低门槛 :一个命令搞定,不需要理解HTTP、OAuth
# CLI的优雅之处:管道组合
hermes cron list | grep "公众号" | wc -l
# → 输出:7
# 一次性完成复杂操作
wechat publish article.md --title "CLI的魅力" --cover cover.jpg
一个好的CLI设计,能让用户 三分钟上手、一天内熟练 。而一个好的API设计,往往需要用户花半天读文档才能调通第一个请求。
一句话总结CLI的价值:把多步操作变成一步,把”怎么调”变成”直接干”。
API:以系统为本的集成接口
API(RESTful/gRPC/GraphQL)面向的是程序,不是人。它的核心特征:
-
标准化 :统一的请求/响应格式,易于被不同语言调用
-
幂等性 :GET/POST/PUT/DELETE语义清晰
-
可组合 :多个API可以编排成复杂工作流
但它的痛也很明显—— 对人类不友善 。调一个API需要:读文档→构造请求→处理认证→解析响应→错误处理。这还是最简单的,遇到分页、限流、批量操作,复杂度指数级上升。
MCP:以AI为根的协议层
MCP(Model Context Protocol)是2024年才兴起的新范式,由Anthropic提出。简单说,它是 专门为AI Agent设计的接口协议 。
传统的API需要人类开发者去阅读文档、理解参数、编写代码来调用。而MCP的目标是: 让AI大模型自己学会怎么用你的系统 。
MCP的核心机制:
# MCP Server注册工具的伪代码
classMyMCPServer:
@mcp.tool("search_products")
defsearch_products(self, keyword: str, page: int = 1) -> list:
"""搜索产品目录"""
returnself.db.search(keyword, page)
@mcp.tool("get_order_status")
defget_order_status(self, order_id: str) -> dict:
"""查询订单状态"""
returnself.order_system.get(order_id)
每个工具都有明确的 描述(description) 和 参数模式(parameter schema) 。AI Agent读到这些信息后,能自主决定何时调用、传递什么参数、如何组合多个工具。
这跟API的区别在哪? API是”你调用我”;MCP是”AI替你调用我”。 用户不需要知道你的API端点和认证方式,只需要说一句人话,AI Agent自己就去调MCP工具了。
二、系统架构设计:三者如何协作?
在真实的企业系统中,CLI、API、MCP不是”选一个”的关系,而应该是 三层递进 的关系:
用户交互层
┌─────────────┐
│ CLI工具 │ ← 面向开发者、运维人员
│ (hermes) │
└──────┬──────┘
│
协调调度层
┌─────────────┐
│ MCP协议 │ ← 面向AI Agent
│ (工具注册) │
└──────┬──────┘
│
能力暴露层
┌─────────────┐
│ RESTful API │ ← 面向系统集成
│ (CRUD) │
├─────────────┤
│ 内部RPC │ ← 服务间通信
│ (gRPC) │
└──────┬──────┘
│
┌─────────────┐
│ 核心业务逻辑 │
└─────────────┘
设计原则
原则一:API是根基,CLI和MCP都是API的”人性化封装”
不要把CLI做成独立的逻辑层。CLI应该是API的客户端:
# ❌ 坏设计:CLI直接操作数据库
defcli_create_user(name, email):
db.execute("INSERT INTO users ...") # 绕过API
# ✅ 好设计:CLI调API
defcli_create_user(name, email):
response = requests.post("/api/v1/users", json={"name": name, "email": email})
return response.json
同理,MCP Server也应该是API的包装,而不是另起炉灶:
# ✅ MCP Tool调API
@mcp.tool("create_user")
defcreate_user(name: str, email: str) -> dict:
"""创建新用户"""
resp = requests.post(
f"{BASE_URL}/api/v1/users",
json={"name": name, "email": email},
headers={"Authorization": f"Bearer {TOKEN}"}
)
return resp.json
原则二:MCP适合暴露”意图级”操作,而非”原子级”操作
API可以做得很细: GET /users/:id 、 POST /users/:id/roles 、 DELETE /users/:id 。但MCP工具应该暴露更上层的操作:
# ❌ 太细:AI Agent不知道怎么组合
@mcp.tool("get_user") # 获取用户
@mcp.tool("add_user_role") # 添加角色
@mcp.tool("remove_user_role") # 删除角色
# ✅ 合适:对应业务意图
@mcp.tool("invite_team_member") # 邀请团队成员(含创建用户+分配角色+发邮件)
@mcp.tool("update_user_permissions") # 修改权限(含增删角色+审计日志)
原则三:CLI面向”高频+组合操作”,API面向”标准化+程序集成”
CLI适合的场景:
-
日常运维 :查看状态、快速查询
-
脚本化 :CI/CD、自动化任务
-
交互式调试 :测试功能、查看日志
API适合的场景:
-
系统集成 :和其他系统对接
-
应用开发 :构建前端、移动端
-
数据交换 :批量导入/导出
三、设计一个好的CLI系统
如果决定给你的系统加一个CLI,这几点值得注意:
1. 子命令结构
mytool # 工具名
├── init # 初始化配置
├── config # 配置管理
│ ├── config get # 获取配置
│ └── config set # 设置配置
├── auth # 认证
│ └── auth login # 登录
├── project # 项目管理
│ ├── project list # 列表
│ ├── project create # 创建
│ └── project delete # 删除
└── --help # 协助
遵循 动词+名词 结构,这样用户即使不读文档,通过 mytool --help 也能摸索出大部分功能。
2. 输出格式
# 默认:人类友善
mytool project list
# → my-project (active)
# → test-project
# --json 或 --format=json:程序友善
mytool project list --json
# → [{"name": "my-project", "status": "active"}, {...}]
这一点很重大—— 同一个命令,既能给人看,也能给脚本用 。
3. 认证处理
CLI的认证一直是痛点。推荐的做法:
# 方式一:环境变量(适合CI/CD)
export MYTOOL_API_KEY="sk-xxx"
mytool project list
# 方式二:配置文件(适合开发机)
mytool auth login
# 浏览器弹窗完成OAuth
# 或:输入 API Key
# 方式三:参数传入(适合临时操作)
mytool project list --api-key "sk-xxx"
四、MCP Server设计要点

MCP Server是当前最值得关注的新方向。几点设计提议:
1. 工具描述写得越清楚越好
AI Agent根据描述决定调不调用你的工具。描述是”搜索引擎”,而你的工具是”搜索结果”:
# ❌ 太笼统
@mcp.tool("query")
defquery(sql: str) -> list:
"""查询数据"""
# ✅ 语义丰富
@mcp.tool("query_inventory")
defquery_inventory(product_name: str = None, category: str = None) -> list:
"""查询药品库存信息。支持按产品名称和分类筛选。
适用于:查看库存余量、检查药品有效期、统计库存周转。
注意:此工具只能查询,不能修改数据。"""
2. 工具粒度要适中
# ✅ 工具清单示例(6-10个为宜)
tools = [
"search_customers", # 搜索客户
"get_customer_detail", # 客户详情
"create_order", # 创建订单
"get_order_status", # 查询订单
"update_inventory", # 更新库存
"generate_report", # 生成报表
"send_notification", # 发送通知
]
每个工具对应一个 完整的业务动作 ,而不是一个数据库操作。
3. 错误处理
AI Agent遇到错误时会自己重试或调整策略,但需要足够的信息:
@mcp.tool("create_order")
defcreate_order(items: list, customer_id: str) -> dict:
try:
result = api.create_order(items, customer_id)
return {"success": True, "order_id": result["id"]}
except InsufficientStockError as e:
return {
"success": False,
"error": f"库存不足:{e.product_name} 当前库存 {e.current_stock},需要 {e.required}",
"suggestion": "请减少数量或更换产品"
}
返回提议信息,AI Agent能据此自动调整操作。
五、未来开放平台的架构方向
基于CLI + API + MCP的三层架构,我对未来开放平台的展望是这样的:
当前:API First
开发者 → 读文档 → 理解API → 写代码调用 → 处理错误
↑ 学习成本高,集成周期长
趋势:Agent First
用户 → 说出需求 → AI Agent → 自动调用MCP工具 → 完成任务
↑ ↑
零学习成本 AI自动处理错误
展望:三层统一平台
开放平台能力暴露层
├── RESTful API (REST API Gateway)
│ ├── 标准CRUD
│ ├── Webhook事件推送
│ └── 批量数据操作
│
├── MCP Server (AI Protocol Gateway)
│ ├── 工具注册/发现
│ ├── 语义化操作接口
│ └── AI友善错误处理
│
├── CLI (Command Line Interface)
│ ├── 交互式Shell
│ ├── 自动化脚本
│ └── 调试和测试
│
└── 统一认证层 (SSO + API Key + OAuth2)
└── 所有接口共享同一身份体系
设计理念

|
维度 |
传统API平台 |
未来Agent平台 |
|---|---|---|
|
用户 |
开发者 |
所有人(开发者+业务人员) |
|
接口 |
RESTful |
CLI + MCP + API 三层 |
|
交互 |
代码调用 |
自然语言驱动 |
|
编排 |
开发者写代码 |
AI自动编排 |
|
错误处理 |
开发者处理 |
AI自动重试+兜底 |
|
文档 |
Swagger/Readme |
语义化工具描述 |
这不是取代API,而是在API之上加了两层”人性化封装”——CLI给人用,MCP给AI用。
写在最后
回看过去十年的系统开发,接口范式经历了几轮变迁:
-
2015-2018 :RESTful API + Swagger文档(标准化时代)
-
2019-2022 :GraphQL + gRPC 多元并存(灵活化时代)
-
2023-2024 :AI SDK + Function Calling(AI原生时代)
-
2025+ :CLI + MCP + API 三层架构(人性化时代)
每一个新范式的出现,不是要消灭旧范式,而是让系统能力能被 更多类型的用户 以 更低成本 的方式使用。
如果你在规划新系统的开放接口,不妨从这个角度思考:
API给你的程序用,CLI给你的同事用,MCP给你的AI用。三者合一,才是面向未来AI时代的开放平台。
本文基于Hermes Agent项目的接口设计实践和行业观察综合整理。Hermes是一个基于Model Context Protocol的AI Agent框架,目前支持CLI交互、MCP集成和RESTful API三种接口模式。





