前阵子在给团队做 AI Agent 能力扩展方案调研时我一直在想一个问题大模型本身只会“对话”它究竟靠什么去查数据库、操作浏览器、调用设计稿、执行本地脚本网上资料大多把“MCP 配置一下就能用”说得特别简单但真正落地时协议结构、Skill 组织方式、客户端配置、鉴权边界每一步都有坑。这篇文章我会把 AI Agent 的两大扩展手段讲透并给出可以直接复用的实战代码覆盖概念、原理、搭建过程和排错思路适合正在做 Agent 应用开发、也想了解 MCP 与 Skill 到底是什么的读者。1. AI Agent 为什么需要能力扩展从“会聊天”到“能干活”1.1 AI Agent 的核心组成AI Agent智能体并不是一个神秘的概念。从工程视角来看一个完整可用的 Agent 至少包含四个核心模块大模型负责理解用户意图、规划任务、生成文本或工具调用参数上下文管理器负责承载多轮对话、记忆、检索结果和工具返回内容工具层负责把模型“想做”的动作真正执行到外部系统执行与反馈回路负责把执行结果重新喂给模型形成“规划—执行—观察—再规划”的循环。只有一个大模型的程序不能叫 Agent它只是聊天机器人。真正的 Agent 必须有“行动能力”而行动能力几乎全部来自工具层。在我实际做的项目里纯粹让模型自己推理、自己写答案的应用只占少数绝大多数业务需求最后都落在“帮我查一下订单”“把这份报表发到群里”“根据设计稿生成前端页面”这类需要对接真实资源的任务上。所以工具层怎么设计基本决定了 Agent 能干什么活。1.2 模型能力边界为什么单靠 Prompt 不够我们在项目初期也走过一段“靠 Prompt 打天下”的弯路。当时为了控制模型输出格式把工具描述、字段说明、调用约束全部写进系统提示词结果模型动不动就把参数编错或者触发了根本不存在的工具。这里面的问题在于大模型本质上是概率推理器它只能“按照文字描述猜测”工具的调用方式并没有办法保证它与真实接口永远一致。一旦工具数量增加系统提示词会迅速膨胀模型对每个工具的关注度会被稀释出现工具名混淆、参数类型错误、应答格式不稳定等一连串问题。而且工程上还有一个更现实的问题很多能力不在模型的知识范围内比如某个内部数据库的 schema、某套设计稿的节点结构、某个浏览器的真实 DOM 状态模型根本没有训练数据。这时候再好的 Prompt 也无济于事必须通过机制化的方式把“外部世界”接入进来。这也是我为什么强烈建议做 AI Agent 开发的同学认真研究 MCP 和 Skill 的原因。它们不是同一层的事物但都在解决“模型如何安全、规范、可复用地下达和执行动作”的问题。1.3 MCP 与 Skill 的能力扩展定位先给一个整体结论方便后面理解MCP 解决的是“Agent 如何连接外部工具和数据源”的协议问题它把各种服务能力抽象成统一接口让 Agent 可以像“即插即用”一样接入数据库、浏览器、设计工具、文件系统等。Skill 解决的是“Agent 如何复用一套成熟的行为流程”的知识问题它把完成一类任务所需的指令、经验、脚本和参考资料打包成一个可复用的技能包Agent 遇到对应场景时可以直接加载执行。可以这样类比MCP 是 Agent 的“手”帮助 Agent 碰到真实系统和数据Skill 是 Agent 的“操作手册”告诉 Agent 在某个场景里应该按什么步骤把活干完。两者经常配合使用——Skill 负责描述流程和策略MCP 负责具体执行动作。理解了这层关系再去读后面的架构和代码就不会觉得混乱。2. 环境准备与工具链选型2.1 基础运行环境本文的实战部分会同时用到 Python 和 Node.js原因很简单目前 MCP SDK 对这两种语言支持最成熟。版本需要根据实际项目情况调整本文示例以常见环境为例重点演示配置思路操作系统macOS / Linux / WindowsWindows 建议使用 PowerShell 或 WSL 2Python 3.10 及以上Node.js 18 及以上一个支持 MCP 的 Agent 客户端常见的有 Claude Desktop、Claude Code、Cursor、Cline、Windsurf 等示例中会以 JSON 配置文件的方式演示基本兼容大多数客户端编辑器推荐 VS Code 或 Cursor主要为了方便查看 JSON 配置和 Python 日志。2.2 核心工具链清单MCP Python SDK包名为mcpMCP TypeScript SDK包名为modelcontextprotocol/sdkAgent 客户端各自的 Skill 目录约定不同产品命名可能不同若干参考类 MCP Server例如官方仓库中提供的 PostgreSQL、Git、Selenium、文件系统等示例实现。工具链版本变化较快我没有在本文写死某个小版本号。如果你的环境安装报错优先去对应官方仓库看 README 和 release note不要盲目把网上别人用的版本号复制到生产环境。2.3 概念辨析MCP、Skill、Function Calling、Computer Use很多读者会把 MCP、Skill、Function Calling、Computer Use 混为一谈这里我用尽量直白的方式区分Function Calling 是模型厂商提供的一种结构化输出能力它让模型按 JSON 格式输出“要调用哪个函数、参数是什么”。它是一套模型侧的约定不是一个跨系统协议。MCP 是统一的工具接入协议。它不仅有“模型输出函数调用参数”这一层还解决了工具的发现、连接、鉴权、生命周期管理、资源访问等更完整的工程问题。可以把 MCP 理解成“工具层的 USB-C 接口”。Skill 是面向场景的行为封装。它把“什么时候用、按什么步骤做、需要什么脚本、有哪些经验注意点”写成一个包让 Agent 遇到适配场景时自动加载。Computer Use 是让模型直接操作图形界面看屏幕、模拟鼠标键盘的一类能力可以理解为一种特殊的工具但与 MCP 的定位不同两者可以共存也可以单独使用。把这几个概念区分清楚能避免很多入职面试和方案评审时的尴尬问题。3. MCP 核心原理拆解3.1 MCP 协议是什么MCP 全称 Model Context Protocol是一个开放协议目标是为“大模型应用接入外部工具与数据源”建立一套统一规范。它由 Anthropic 在 2024 年底提出随后迅速被各类 Agent 客户端和工具厂商支持。从传输角度看MCP 支持多种传输方式开发中最常用的是 stdio标准输入输出也就是 Agent 客户端启动一个本地子进程通过标准输入和标准输出与 MCP Server 通信。另一种常见方式是 SSEServer-Sent Events或 HTTP 流式传输用于连接远程服务。协议本身定义了三类核心原语Tools工具、Resources资源、Prompts提示模板。Tools 是绝大多数人最先接触的它让模型可以调用一个具体动作Resources 让模型可以读取一段数据内容Prompts 则是可供复用的提示词模板。在实际业务中我们通常先从一个 Tools 类型的 Server 入手。3.2 Host、Client、Server 三层架构MCP 的架构可以清晰地分为三层Host宿主用户直接面对的 Agent 程序例如 Claude Desktop、Cursor 等。它负责收集用户意图调度模型并管理多个 Client。Client客户端Host 进程内与某个 MCP Server 建立一对一连接的组件。它的职责是维护连接状态、转发工具调用请求、把 Server 返回结果交给模型。Server服务端独立的进程可能是本地脚本也可能是远程服务负责暴露工具、资源和提示模板。它可以封装数据库、浏览器、设计稿工具、内部 API 等各种能力。这套架构的好处是解耦。开发者只需要按协议实现一个 Server任何支持 MCP 的客户端都能直接使用不需要为每个 Agent 产品单独开发插件。3.3 一次完整的 MCP 调用流程我们以“模型查询订单状态”为例梳理一次完整调用Host 收到用户问题“订单 10086 现在什么状态”Host 将问题交给大模型模型根据 Server 暴露的工具描述决定调用query_order工具并生成参数{order_id: 10086}。Client 通过协议把工具调用请求发送给 MCP Server。Server 执行真实查询逻辑从数据库或 API 获取数据。Server 把结果返回给 Client再被拼接到模型上下文。模型阅读结果生成最终回答“订单 10086 已发货物流单号是 JD00123456。”这个流程里MCP 的价值在于第 2 步到第 5 步的“标准化通信”。工具描述如何暴露、参数如何解析、结果如何返回都有约定开发者不用关心客户端是哪一家只要协议对得上就能跑通。3.4 常见 MCP Server 应用场景我在选题调研时梳理了一下社区里比较热的 MCP 应用方向几乎覆盖了日常开发的所有高频操作数据库 MCP让 Agent 直接查询 PostgreSQL、MySQL、SQLite。浏览器自动化 MCP例如 Playwright MCP让 Agent 打开网页、点击按钮、抓取数据。设计工具 MCPFigma、MasterGo、蓝湖的 MCP 插件可以让 Agent 读取设计稿结构辅助生成前端代码。3D 与游戏引擎 MCPBlender、Unity、Cocos Creator 等让 Agent 操作场景、生成资源。版本库 MCP封装 Git 操作让 Agent 读取代码、创建分支、提交变更。日常效率工具 MCP日历、邮件、飞书/钉钉机器人、任务管理工具等。这些案例说明MCP 已经从“尝鲜”走向了“基础设施”。接下来我直接带大家搭建一个自己的 Server。4. Skill 核心原理拆解4.1 Skill 的本质Skill 在中文里常被翻译成“技能”但它并不是指某个单一的工具函数而是一整套“完成某类任务的经验包”。一个典型的 Skill 可以包含任务说明、使用步骤、输入输出约定、辅助脚本、数据文件和注意事项。它解决的核心问题是让 Agent 不再依赖用户每次手写详细指令而是遇到某个场景时自动从技能库中加载对应的行为规范。比如团队内部经常要做数据周报那我们可以把“取数—清洗—统计—生成图表—写成周报”的完整流程封装成一个周报 Skill。以后任何成员只要说一句“生成本周数据周报”Agent 就会加载这个 Skill按步骤执行。Skill 的出现本质上是为了让 Agent 的行为可编排、可复用、可沉淀。这是从“写 Prompt”升级到“建设 Agent 能力资产”的关键一步。4.2 Skill 与 Prompt、Function Calling 的关系这个问题很容易被面试官追问Skill 和 Prompt 有什么区别我的理解是Prompt 是一次性或嵌入在系统提示中的文字指令它没有独立的生命周期改起来需要动整个系统配置而 Skill 是一个结构化、可独立版本管理的单元它不仅有描述文本还能带脚本和资源。Skill 最终确实是靠“加载后变成 Prompt 或指导上下文”起作用的但从工程管理角度看资产边界完全不同。Skill 也和 Function Calling 不同。Function Calling 是“模型决定调用哪个函数”Skill 是“模型决定按哪套流程处理问题”。Skill 内部完全可以包含多个 Function Calling 动作甚至包含多个 MCP 工具调用。可以理解为Skill 是更高阶的行为封装Function Calling 和 MCP 是底层的执行能力。4.3 Skill 的通用结构与加载机制虽然不同客户端的 Skill 实现有差异但大体遵循一种通用结构。下面是我在项目中比较常用的一种组织方式skills/ weekly-report/ SKILL.md scripts/ generate_report.py references/ template.md assets/ logo.png其中SKILL.md是入口文件通常包含两大部分头部元信息技能名称、描述、适用场景和正文任务步骤、规则、示例、注意事项。加载机制一般是Agent 根据当前用户意图与所有 Skill 的 description 做匹配当匹配度足够高时将对应 Skill 的内容注入上下文必要时执行其中的辅助脚本。这种设计让 Agent 的“知识”和“能力”可以像积木一样叠加而不是每次都在一个巨大的 Prompt 里手写所有规则。5. 实战用 Python 快速搭建 MCP Server5.1 安装依赖我们使用 Python 版本搭建一个“订单查询 销售统计”的 MCP Server。首先创建项目目录并安装依赖。mkdir mcp-demo cd mcp-demo python -m venv .venv source .venv/bin/activate # Windows 使用 .venv\Scripts\activate pip install mcp如果你的网络环境安装较慢可以切换为镜像源。安装完成后可以用下面的命令确认 SDK 是否可用python -c import mcp; print(mcp ok)5.2 编写核心 Server 代码新建文件order_server.py。我们使用mcp.server.fastmcp.FastMCP来快速创建一个 Server。为了演示方便这里先使用内存数据代替真实数据库。# mcp-demo/order_server.py from mcp.server.fastmcp import FastMCP # 创建 MCP Server名字会显示在客户端配置中 mcp FastMCP(order-demo) # 模拟的订单数据 ORDERS { 10086: {status: 已发货, carrier: 顺丰, tracking_no: SF1234567890}, 10087: {status: 待付款, carrier: , tracking_no: }, 10088: {status: 已完成, carrier: 中通, tracking_no: ZT987654321}, } mcp.tool() def query_order(order_id: str) - str: 根据订单号查询订单状态、物流公司和运单号。 Args: order_id: 订单号例如 10086。 info ORDERS.get(order_id) if not info: return f未找到订单 {order_id} return ( f订单 {order_id} 当前状态{info[status]} f物流公司{info[carrier] or 暂无} f运单号{info[tracking_no] or 暂无} ) mcp.tool() def count_orders() - str: 统计当前订单总数以及各状态订单数量。 total len(ORDERS) status_count {} for info in ORDERS.values(): status_count[info[status]] status_count.get(info[status], 0) 1 return f订单总数{total}状态分布{status_count} if __name__ __main__: # 启动 Server默认使用 stdio 传输 mcp.run()这段代码里有两个关键点mcp.tool()装饰器把函数注册成一个可供模型调用的工具函数的 docstring 会被当作工具描述模型就是靠这段描述决定何时调用以及传什么参数的所以描述要写得尽量清晰。mcp.run()默认以 stdio 方式启动适合作为本地子进程被 Agent 客户端拉起。5.3 运行方式验证在终端运行python order_server.py如果 SDK 安装正常你会发现终端看起来“卡住”了没有任何输出。这是正常的因为程序正在等待从标准输入读取协议消息。你可以按CtrlC结束。如果想快速验证工具函数本身的逻辑可以加一行测试代码临时运行但更推荐直接在后续的客户端配置中验证因为那样能验证完整的 MCP 通信链路。5.4 在客户端中配置 MCP大部分支持 MCP 的客户端都支持通过 JSON 文件声明 MCP Server。下面是一个通用的配置片段文件名可能是.mcp.json或客户端偏好设置中的 MCP Servers 区域具体入口因产品而异。{ mcpServers: { order-demo: { command: python, args: [/absolute/path/to/mcp-demo/order_server.py] } } }配置完成后重启客户端。然后向 Agent 提问“订单 10086 现在什么状态” 模型应该会自动调用query_order工具并返回如下结果订单 10086 当前状态已发货物流公司顺丰运单号SF1234567890如果客户端有“工具列表”或“MCP 资源”面板你也能看到query_order和count_orders两个工具已经注册成功。此时第一个 MCP 服务就算跑通了。5.5 补充连接真实数据库时的注意事项热词里经常看到“claude code 安装 mcp 读取数据库”说明很多人希望让 Agent 直接读库。这里补充一条重要经验不要把生产库的写权限直接暴露给 Agent应先为 Agent 创建只读账号并限定 schema 和表查询语句要走参数绑定避免让模型生成的字符串直接拼接 SQL在测试环境验证所有工具的行为再考虑发布到生产。连接 MySQL 时需要在 Server 端引入数据库驱动并在工具函数内部完成连接创建、查询、关闭。数据库密码不要写死在代码里建议通过环境变量或密钥管理服务注入。6. 实战创建并调试一个 Agent Skill6.1 Skill 设计目标先规划一个技能运营数据周报分析 Skill。当用户说“生成这周运营周报”时Agent 能按固定流程做四件事从数据源加载本周订单数据清洗并统计核心指标生成趋势图表按固定模板输出周报内容。这套流程如果每次都用对话方式临时指挥既容易遗漏环节结果格式也会不稳定。封装成 Skill 后Agent 会稳定地按步骤执行。6.2 目录结构与 SKILL.md在 Agent 的 skills 目录下新建weekly-report技能包。先看目录结构skills/ weekly-report/ SKILL.md scripts/ build_report.py references/ report_template.md编写SKILL.md作为技能入口。这里采用比较通用的 Markdown 头信息格式不同客户端字段略有差异请以你的客户端文档为准。--- name: weekly-report description: 当用户需要生成运营数据周报、统计本周订单、分析销售趋势时使用该技能可以自动完成数据统计、图表生成和报告输出。 --- # 运营数据周报 Skill ## 适用场景 - 用户要求“生成本周周报”“汇总本周数据”“分析订单趋势”。 ## 执行步骤 1. 调用订单统计工具获取本周订单量、销售额、退款率等基础指标。 2. 调用趋势分析脚本计算环比变化。 3. 调用图表生成脚本输出 PNG 趋势图。 4. 按照 references/report_template.md 的模板填充内容。 ## 注意事项 - 数据时间范围默认是本周一至今天用户另有说明时以用户为准。 - 如果某项指标无法获取不要猜测明确标注“数据缺失”。 - 输出报告时保留两位小数。这里的关键是把任务步骤写得足够具体让模型能稳定地按流程执行同时留下处理异常的规则。6.3 编写辅助脚本build_report.py是一个辅助脚本负责把原始数据转成 Markdown 报告片段。这里不连接真实数据库用模拟数据演示处理逻辑。# skills/weekly-report/scripts/build_report.py import json import sys def compute_metrics(orders_data: list[dict]) - dict: 根据订单列表计算核心运营指标。 Args: orders_data: 订单列表每个订单包含 amount、status 等字段。 total_amount sum(float(o.get(amount, 0)) for o in orders_data) total_orders len(orders_data) success_orders [o for o in orders_data if o.get(status) success] return { total_orders: total_orders, total_amount: round(total_amount, 2), success_orders: len(success_orders), success_rate: round(len(success_orders) / total_orders, 4) if total_orders else 0, } def format_report(metrics: dict) - str: 把指标格式化成周报 Markdown 片段。 return ( ## 本周核心指标\n\n f- 订单总量{metrics[total_orders]}\n f- 成交金额{metrics[total_amount]}\n f- 成交订单数{metrics[success_orders]}\n f- 订单成功率{metrics[success_rate] * 100:.2f}%\n ) if __name__ __main__: # 从命令行接收 JSON 字符串方便 Agent 调用 raw sys.argv[1] data json.loads(raw) result compute_metrics(data) print(format_report(result))这个脚本体现了 Skill 的一个重要设计原则复杂计算不要依赖模型心算而是尽量放进脚本里执行模型只负责调度和解读结果。这样能大幅提升结果准确率。6.4 让 Agent 按 Skill 执行当 Skill 包被正确放入目录后重启 Agent 客户端然后输入生成这一周运营数据周报数据文件在 data/weekly_orders.jsonAgent 应当自动加载weekly-reportSkill按SKILL.md里的步骤执行最终输出包含「本周核心指标」的报告。如果你的客户端支持显示“加载了某个 Skill”你应该能看到技能名称出现在调用信息里。如果你在验证时发现 Agent 没有自动加载该 Skill可以检查Skill 目录是否放在客户端约定的根目录下description是否写清楚适用场景模型匹配能力有限时可以主动提示“使用 weekly-report 技能生成本周周报”脚本是否有执行权限Windows 系统下要注意 Python 命令的可执行路径。7. 开发中常见问题与排查思路下面整理一份高频问题清单覆盖我实践和社区反馈中常见的坑。问题现象常见原因解决思路配置 MCP 后客户端未识别 Server命令路径或参数写错或 Server 启动即崩溃先在终端手动运行命令确认能进入等待状态检查 JSON 中command和args是否为绝对路径模型总是编造工具名工具说明不清晰或工具数量过多精简工具数量docstring 写清楚“何时调用”必要时为每组工具增加命名前缀调用 MCP 工具后返回值格式异常Server 返回了非文本内容或模型未按结构解析先保证 Server 返回纯文本 Markdown生产环境可以统一 JSON 结构返回并让模型按 JSON 读取Skill 没有被自动加载description 匹配不上或者目录结构不对检查 Skill 目录层级、文件名是否为SKILL.md在对话中显式指定技能名验证脚本执行报编码错误Windows 下默认编码不是 UTF-8在脚本入口处加# -*- coding: utf-8 -*-或设置环境变量PYTHONUTF81数据库 MCP 查询超时查询未加 LIMIT或连接池失效在工具函数内强制加 LIMIT设置连接超时生产环境建议使用只读账号修改 Server 代码后客户端仍走旧逻辑客户端缓存了 Server 进程重启客户端或先杀死残留的 MCP 子进程再测试排查问题的基础方法论是“分层定位”先确认 Server 端能独立运行再确认配置能被客户端读到最后确认模型是否真的发起了正确的工具调用。这个顺序能过滤掉大部分低级错误。安全提醒如果你在 MCP Server 里实现了数据库删除、更新、文件写入等操作务必先做好备份和最小授权。不要在未确认数据影响范围的情况下把高风险操作直接暴露给模型更不要在生产环境用管理员账号直接连接 MCP Server。8. 最佳实践与工程建议8.1 安全与权限边界Agent 的能力越强安全风险越高。基于我踩过的坑建议所有人在上线前都做一次安全审查最小权限原则MCP Server 连接的数据库、文件目录、API 都要限制到“完成任务所需的最小范围”。危险操作确认机制删除、覆盖、转账、发送消息等高危动作不要由模型单独决定至少在客户端侧增加人工确认步骤。输入校验模型生成的参数不一定安全Server 端必须对长度、格式、枚举范围做校验防止注入和异常输入。密钥管理所有密码、Token 通过环境变量或密钥服务注入严禁硬编码到代码和配置里。审计日志记录每次工具调用的发起人、参数、返回结果和时间方便事后追溯。8.2 配置与版本管理MCP Server 和 Skill 本质上都是代码资产要像业务代码一样管理。用 Git 管理 MCP Server 代码和 Skill 目录每个技能一个独立目录提交信息写清楚变更原因。Server 和 Skill 的配置尽量做到环境隔离开发、测试、生产使用不同的配置文件和鉴权信息。为 MCP Server 固定依赖版本使用requirements.txt或package.json锁定版本避免协议升级导致不兼容。Skill 的SKILL.md也建议带版本号字段方便比较不同版本的执行效果。8.3 稳定性与可观测性MCP Server 是独立进程稳定性问题通常比较隐蔽。建议从三方面入手日志在工具函数入口和出口分别打印日志记录参数和耗时心跳与超时远程 MCP Server 要设置连接超时和请求超时避免模型等待过久回归测试为每个工具准备一组测试用例定期运行防止工具行为被无意修改。下面是一个简单的日志装饰器示例可以直接用到你的 Server 里。import functools import logging logging.basicConfig(levellogging.INFO, format%(asctime)s %(levelname)s %(message)s) logger logging.getLogger(mcp-server) def log_tool(func): functools.wraps(func) def wrapper(*args, **kwargs): logger.info(call %s args%s kwargs%s, func.__name__, args, kwargs) result func(*args, **kwargs) logger.info(done %s result%s, func.__name__, result) return result return wrapper然后把装饰器加到工具函数上mcp.tool() log_tool def query_order(order_id: str) - str: ...8.4 测试与迭代方法Agent 应用的测试与普通后端不同它包含两层不确定性模型调不准参数工具执行出错两层需要分开验证。建议建立“三层测试”体系单元层直接调用工具函数传合法和非法参数确保函数本身逻辑正确。协议层模拟 MCP 客户端发起工具调用校验协议消息往返是否正常。模型层用典型用户问题驱动完整 Agent 流程记录成功率、错误类型和模型决策原因分析失败样本后持续优化工具描述和 Skill 步骤。每次迭代只改一个变量要么改工具描述要么改 Skill 步骤要么改脚本逻辑避免多个改动混合在一起导致无法定位是哪个变化影响了效果。9. 总结与学习路线这篇文章从概念上讲清楚了 AI Agent 能力扩展的两条主线MCP 负责统一接入外部工具与数据源Skill 负责沉淀可复用的任务流程。实战部分我们亲手搭建了一个 Python MCP Server并创建了一个带脚本的 Skill 包也整理了开发中最高频的排错问题和工程落地的安全、稳定性建议。下一步建议按下面的顺序继续深入先把你常用的内部服务数据库、文件系统、内部 API封装成自己的 MCP Server跑通“配置—调用—结果回流”的完整链路再从高频重复任务中提炼 3 到 5 个 Skill让 Agent 从“会调用工具”升级为“会按规范完成业务”然后关注客户端产品对 MCP 的差异化支持结合你实际使用的编辑器或平台做配置优化最后建立一套针对工具调用和 Skill 效果的评估集用数据驱动 Agent 持续迭代。AI Agent 的能力边界本质上是由你能安全、规范接入多少真实能力决定的。与其反复在 Prompt 里堆砌规则不如把工具协议做好、把技能包做厚。这个方向值得深挖欢迎在实践中多踩坑、多总结也欢迎在评论区交流你的 MCP 与 Skill 落地经验。