CLI、MCP、Skill:构建 AI Agent 的三层基础设施,你真的分清楚了吗?
很多人在学 LangGraph、Claude Code 的时候,会同时接触到 CLI、MCP、Skill 这三个概念,但很少有文章把它们放在一起对比讲清楚。本文试图做这件事:它们分别解决什么问题、在 Agent 体系里扮演什么角色、应该怎么组合使用。
先说结论
三者不是同一层次的东西,不存在谁替代谁的关系:
objectivec
CLI → 解决"怎么运行 Agent"的问题(执行层)
MCP → 解决"Agent 怎么连接外部世界"的问题(协议层)
Skill → 解决"Agent 怎么复用能力"的问题(能力层)
就像盖房子:CLI 是施工队(执行),MCP 是水电管道(连接),Skill 是预制模块(能力)。三者各司其职,缺一不可。
一、CLI:最被低估的执行层
是什么
CLI(Command Line Interface,命令行界面)是通过文字命令操作程序的方式。对于 Agent 开发来说,CLI 是最直接的触发和调试手段。
bash
# 最简单的形式
python risk_agent.py --biz_hour "2026-06-11 08:00:00"
# Claude Code:把 Claude 变成命令行工具
claude "分析这段 SQL 有什么性能问题"
claude --model claude-sonnet-4-6 "帮我写单元测试"
# 结合 shell 脚本实现自动化调度
#!/bin/bash
for hour in 01 02 03 04 05 06; do
python agent.py --hour "2026-06-11 ${hour}:00:00"
echo "完成 ${hour} 时的处理"
done
为什么重要
很多人觉得 CLI 是"老技术",在 AI 时代显得过时。但恰恰相反,Agent 系统落地生产后,CLI 是最稳定的调度方式。
原因有三:
可脚本化:任何 CLI 命令都能写进 shell 脚本,配合 crontab 实现定时调度,不依赖额外的调度平台。
可管道化 :CLI 命令可以用管道组合,python extract.py | python transform.py | python load.py,每一步都可以独立测试。
可观测 :命令行的标准输出天然就是日志,配合 tee 命令可以同时输出到终端和文件,运维成本极低。
和 Agent 的关系
CLI 是 Agent 的"入口"。一个生产级的 Agent 系统,最终都需要一个清晰的 CLI 接口:
ini
# agent_cli.py
import argparse
import asyncio
def main():
parser = argparse.ArgumentParser(description="风控 Agent")
parser.add_argument("--biz_hour", required=True, help="处理时间")
parser.add_argument("--dry_run", action="store_true", help="试跑不写库")
parser.add_argument("--debug", action="store_true", help="调试模式")
args = parser.parse_args()
asyncio.run(run_agent(
biz_hour=args.biz_hour,
dry_run=args.dry_run,
debug=args.debug
))
if __name__ == "__main__":
main()
这个接口让 Agent 可以被任何调度系统调用------无论是 crontab、Airflow、华为云的任务调度服务,还是 CI/CD 流水线。
二、MCP:连接外部世界的协议标准
是什么
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 提出的开放标准,定义了 AI 模型和外部工具之间的通信规范。
在 MCP 出现之前,每个 Agent 系统都要自己实现工具调用的适配层:调用数据库要写一套、调用文件系统要写一套、调用 API 要写一套,每换一个 LLM 还要重写一遍。MCP 解决的就是这个重复造轮子的问题。
arduino
没有 MCP:
Agent ──自定义适配──→ 数据库
Agent ──自定义适配──→ 文件系统
Agent ──自定义适配──→ 外部 API
(换一个 LLM,三套适配全要重写)
有了 MCP:
Agent ──MCP 协议──→ MCP Server(数据库)
Agent ──MCP 协议──→ MCP Server(文件系统)
Agent ──MCP 协议──→ MCP Server(外部 API)
(换 LLM 只需支持 MCP 协议,工具层完全不用改)
架构设计
MCP 是典型的客户端-服务端架构:
arduino
MCP Host(宿主)
└── MCP Client(协议客户端)
└── MCP Server(工具提供方)
├── Tools(可调用的工具函数)
├── Resources(可读取的数据资源)
└── Prompts(可复用的提示词模板)
一个 MCP Server 本质上是一个进程,通过标准输入输出(stdio)或 HTTP SSE 和客户端通信。Claude Desktop、Claude Code、LangGraph 都是 MCP 的宿主。
实战:给风控 Agent 写一个 DWS MCP Server
python
# dws_mcp_server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import psycopg2
import json
app = Server("dws-risk-control")
DWS_CONFIG = {
"host": "your-dws-host.huaweicloudapps.com",
"port": 8000,
"database": "rc_dws",
"user": "dws_risk_control_prod",
"password": "your_password",
}
@app.list_tools()
async def list_tools():
return [
types.Tool(
name="query_risk_features",
description="查询指定时间段的风控特征数据",
inputSchema={
"type": "object",
"properties": {
"biz_hour": {
"type": "string",
"description": "业务时间,格式:2026-06-11 08:00:00"
},
"limit": {
"type": "integer",
"description": "返回行数限制,默认100"
}
},
"required": ["biz_hour"]
}
),
types.Tool(
name="get_risk_score",
description="查询指定uid的实时风险分",
inputSchema={
"type": "object",
"properties": {
"uid": {"type": "string", "description": "用户ID"}
},
"required": ["uid"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
conn = psycopg2.connect(**DWS_CONFIG)
cursor = conn.cursor()
if name == "query_risk_features":
biz_hour = arguments["biz_hour"]
limit = arguments.get("limit", 100)
cursor.execute("""
SELECT uid, risk_value, risk_level, gang_id
FROM rc_dws.validate_ads_risk_gang_daily_hourly
WHERE biz_hour = %s
LIMIT %s
""", (biz_hour, limit))
rows = cursor.fetchall()
result = [{"uid": r[0], "risk_value": r[1],
"risk_level": r[2], "gang_id": r[3]} for r in rows]
return [types.TextContent(type="text", text=json.dumps(result, ensure_ascii=False))]
elif name == "get_risk_score":
uid = arguments["uid"]
cursor.execute("""
SELECT risk_value, risk_level, gang_id, biz_hour
FROM rc_dws.validate_ads_risk_gang_daily_hourly
WHERE uid = %s
ORDER BY biz_hour DESC
LIMIT 1
""", (uid,))
row = cursor.fetchone()
if row:
result = {"uid": uid, "risk_value": row[0],
"risk_level": row[1], "gang_id": row[2], "biz_hour": str(row[3])}
else:
result = {"uid": uid, "message": "未找到风险记录"}
return [types.TextContent(type="text", text=json.dumps(result, ensure_ascii=False))]
conn.close()
async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream, app.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
配置到 Claude Desktop 或 Claude Code 后,你就可以直接用自然语言查风控数据库了:
yaml
你:查一下 2026-06-11 08:00 这个小时有多少高风险用户
Claude:(调用 query_risk_features MCP 工具)共识别 1247 个高风险用户,
其中团伙用户 386 个,分布在 42 个团伙中...
MCP 的核心价值
MCP 的价值不只是"让 Agent 能调工具",更重要的是标准化:
工具开发者只需要实现一次 MCP Server,就能被所有支持 MCP 的 AI 工具调用(Claude、Cursor、Windsurf......)。AI 工具开发者只需要实现一次 MCP Client,就能调用所有 MCP Server。这是一个双向解耦的设计,和 USB 接口的思路如出一辙。
三、Skill:Agent 的能力复用单元
是什么
Skill(技能)是对 Agent 某项能力的封装,让这段能力可以被复用、被组合、被测试。Skill 没有统一的技术规范,更多是一种架构设计理念。
在 LangGraph 体系里,Skill 有三种主要形态:
提示词 Skill:把复杂的提示词逻辑封装成函数。
python
def risk_analysis_skill(data: dict, context: str = "") -> str:
"""风险分析技能:标准化的风险评估提示词"""
return f"""
你是专业的风控分析师。请分析以下数据,按格式输出:
分析维度:
1. 行为异常:是否存在异常的时间、频率、金额模式
2. 设备风险:设备指纹是否异常,是否多账号共用
3. 关联风险:是否与已知风险账号有关联
4. 综合评级:高危 / 中危 / 低危
输出格式:JSON,包含 risk_level、risk_reasons、confidence 三个字段。
{'参考背景:' + context if context else ''}
待分析数据:{data}
"""
工具 Skill:把可调用的工具封装成标准接口。
python
from langchain_core.tools import tool
@tool
def gang_detection_skill(uids: list, biz_hour: str) -> dict:
"""
团伙识别技能:对给定uid列表进行团伙关联分析。
适用场景:已有高风险uid列表,需要识别团伙关系时调用。
算法:Union-Find 联通分量。
返回:团伙列表,每个团伙包含成员uid和平均风险分。
"""
edges = query_edges_from_dws(uids, biz_hour)
gangs = union_find(uids, edges)
return {
"gang_count": len(gangs),
"gang_list": gangs,
"total_uids": sum(len(g["members"]) for g in gangs)
}
子图 Skill:把完整的处理流程封装成可复用的 LangGraph 子图。
scss
def build_report_generation_skill():
"""报告生成技能:独立子图,接收风险数据,输出结构化报告"""
builder = StateGraph(ReportState)
builder.add_node("summarize", summarize_risk_data)
builder.add_node("visualize", generate_charts)
builder.add_node("format", format_report)
builder.add_node("distribute", send_to_notion)
builder.set_entry_point("summarize")
builder.add_edge("summarize", "visualize")
builder.add_edge("visualize", "format")
builder.add_edge("format", "distribute")
builder.add_edge("distribute", END)
return builder.compile()
# 作为节点嵌入主图
report_skill = build_report_generation_skill()
main_builder.add_node("generate_report", report_skill)
Skill 的设计原则
好的 Skill 应该遵循以下原则:
单一职责:一个 Skill 只做一件事,团伙识别 Skill 不应该同时包含特征生成逻辑。
有清晰的接口说明:工具 Skill 的 docstring 是 LLM 决定是否调用这个工具的唯一依据,写得越清楚,LLM 的决策越准确。
幂等设计:同样的输入多次调用,结果一致。Agent 在重试时会重新调用 Skill,幂等设计避免副作用。
可单独测试:Skill 是纯函数或接近纯函数,可以脱离 Agent 框架独立测试。
python
# Skill 的单元测试非常简单
def test_gang_detection_skill():
uids = ["uid_001", "uid_002", "uid_003"]
result = gang_detection_skill(uids, "2026-06-11 08:00:00")
assert "gang_count" in result
assert result["total_uids"] <= len(uids)
四、三者的本质区别
回到开头的定义,用一张表格总结:
| 维度 | CLI | MCP | Skill |
|---|---|---|---|
| 解决的问题 | 怎么运行 | 怎么连接 | 怎么复用 |
| 所在层次 | 执行层 | 协议层 | 能力层 |
| 标准化程度 | 无统一标准 | 有开放协议规范 | 无统一标准 |
| 主要使用者 | 开发者/运维 | 工具开发者 | Agent 架构师 |
| 典型形态 | shell 命令、argparse | MCP Server/Client | Tool、子图、Prompt模板 |
| 替换成本 | 低 | 高(需双端适配) | 中 |
五、三者如何协同工作
以一个完整的风控 Agent 系统为例,三者是这样配合的:
objectivec
【CLI 层】定时调度脚本
python risk_agent.py --biz_hour "2026-06-11 08:00:00"
│
▼
【Agent 核心】LangGraph 图执行引擎
│
├── 特征生成节点 ──── 调用 Skill(特征工程 Skill)
│ │
│ └── 通过 MCP 查询 DWS 数据库
│
├── 预测节点 ──────── 调用 Skill(XGBoost 预测 Skill)
│
├── 团伙识别节点 ───── 调用 Skill(团伙识别子图 Skill)
│ │
│ └── 通过 MCP 查询关联边数据
│
└── 结果写回节点 ───── 通过 MCP 写回 DWS
通过 MCP 发送 Notion 报告
CLI 负责触发和参数传递,是外部系统和 Agent 的边界。
MCP 负责 Agent 和外部数据源的通信,Agent 不需要关心数据库连接细节,只需要调用 MCP 工具。
Skill 负责 Agent 内部的能力复用,把经过验证的处理逻辑封装成稳定的模块,新的 Agent 可以直接引用。
六、常见误区
误区一:MCP 就是 Function Calling
不完全对。Function Calling 是 LLM 层面的能力,让模型可以输出结构化的工具调用请求。MCP 是协议层面的标准,定义了工具的发现、调用、返回的完整规范。两者是不同层次的东西,MCP 的工具调用底层可以用 Function Calling 实现,但 MCP 还包括资源管理、提示词模板等 Function Calling 没有的概念。
误区二:Skill 只是 Tool
Skill 是比 Tool 更广泛的概念。Tool 是 Skill 的一种形态(工具 Skill),但 Skill 还包括提示词模板 Skill 和子图 Skill。一个团伙识别的完整流程(建图、联通分量、评分),用一个 Tool 表达太复杂,封装成子图 Skill 才是正确的做法。
误区三:这三个用一个就够了
实际上它们解决的是不同层次的问题,缺任何一个都会有明显的短板。没有 CLI,Agent 很难在生产环境调度;没有 MCP,Agent 和外部系统的连接会变成一堆自定义适配代码;没有 Skill,随着业务增长 Agent 代码会变成一团乱麻。
七、总结
CLI、MCP、Skill 三者构成了 Agent 系统的基础设施:
CLI 是基础,让 Agent 能够被外部系统可靠地触发和调度,是 Agent 走向生产环境的必要条件。MCP 是管道,解决了 Agent 和外部世界的连接标准化问题,是 AI 生态互联互通的基石。Skill 是积木,让 Agent 的能力可以被沉淀、复用和组合,是 Agent 系统保持可维护性的关键。
三者之间没有高低之分,只有职责的不同。真正生产级的 Agent 系统,一定是三者协同工作的结果。
参考资料