【AI开发】Skill 介绍与实践 —— 用 C++ 实现简易 skill 并接入 TaoToken
1. 从 echo_upper 到文件级 Skill为什么最小 MCP 工具不够用如果你已经跟着上一篇把 C 版 MCP 服务跑起来手里大概率有一个能用的echo_upper客户端发一段文本服务端把 ASCII 小写字母转成大写再返回。这个工具很适合理解 JSON-RPC 消息流但一旦把它放进真实开发流程问题立刻暴露出来。用户不会说“把 hello 变成大写”用户会说“把这个 txt 文件里的英文字母都转成大写生成一个新文件非字母不要动”。这两句话的差距就是 MCP 工具和 Skill 之间的差距。MCP 工具解决的是“服务端能做什么、参数怎么传、结果怎么返回”Skill 解决的是“什么场景触发、按什么步骤做、边界条件是什么、成功后回报什么”。前者是能力接口后者是流程编排。我这次要做的是在原有 C MCP 服务上新增一个真正适合文件处理的工具uppercase_txt_file再配一个最小 Skilltxt-uppercase-file最后通过 TaoToken 的统一 Key/API 通道把整条链路跑通。整篇文章会给出可复制的 CMake 工程结构、skill 注册配置、端到端调用验证动作以及我实际踩过的几个报错。适合谁看已经写过或跑通过一个最小 MCP 服务、想进一步理解 Skill 与 MCP 分工的 C 开发者正在用 Codex CLI 或类似客户端做 AI 开发流程、想把自研能力接进统一通道的人以及被std::filesystem链接错误、local proxy failed、reading choices这类报错卡住的同学。核心检索词先明确C 实现简易 skill 并接入 TaoToken本质是把一个文件级 MCP 工具包装成 SKILL.md 描述的可复用流程再通过统一 API 通道调用。下面从工程结构开始一步步落地。2. TaoToken 前置准备统一 Key 与 API 通道配置在写 Skill 之前先把调用通道准备好。TaoToken 在这里扮演的角色是统一入口你不需要为每个模型或每个工具单独维护一套鉴权和地址而是用同一个 Key 走同一个 API 前缀。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个地址不加 UTM 参数直接用于配置。你需要准备三样东西我把它称为“三件套”后面无论配 Codex、Cline 还是 Claude Code都绕不开配置项值说明Base URLhttps://taotoken.net/api所有请求的统一前缀API Key在控制台创建形如sk-...只显示一次Model ID按需选择例如claude-sonnet-4-5等获取 Key 的路径是控制台里的 API Keys 页面创建后立刻复制保存页面刷新后不再完整显示。如果你还没决定用哪个模型可以先去模型对话页面做一次最小验证确认 Key 和通道都正常再回来配本地工程。这里要强调一个容易踩的坑Base URL 和具体路径的拼接方式。很多客户端要求你填的是“到/api为止”的基址然后由客户端自己拼/v1/messages或/v1/chat/completions也有客户端要求你填完整路径。TaoToken 的 API 基址是https://taotoken.net/api在 Codex 的config.toml里通常写成base_url https://taotoken.net/api由客户端补全后续路径。如果你填成https://taotoken.net/api/v1很可能出现 404 或路径重复。另外Key 不要硬编码进源码或提交到 Git。本地测试用环境变量工程里用配置文件这是基本纪律。我见过有人把 Key 写进mcp_cpp_demo.cpp里图省事结果一提交就泄露只能作废重建。准备阶段做完你应该能回答三个问题Base URL 是什么、Key 存在哪、用哪个 Model ID。这三个答案会在第 3 节的配置片段里反复出现。如果你更偏向长期编码和 Agent 场景可以顺带了解 Coding Plan它适合把这类自研 Skill 纳入日常开发流如果只是先验证模型通不通模型对话页面就够了。3. 可复制配置CMake 工程结构、MCP 注册与 SKILL.md这一节是全文的技术核心给出可以直接抄的工程结构、配置片段和 SKILL.md。先看目录布局我把它整理成 CMake 友好的形式而不是依赖 VS 工程文件mcp_example/ ├── CMakeLists.txt ├── mcp_cpp_demo/ │ ├── CMakeLists.txt │ └── mcp_cpp_demo.cpp ├── skill_examples/ │ └── txt-uppercase-file/ │ └── SKILL.md └── sample.txt顶层CMakeLists.txt只做工程声明和子目录引入cmake_minimum_required(VERSION 3.16) project(mcp_example LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_subdirectory(mcp_cpp_demo)子目录mcp_cpp_demo/CMakeLists.txt负责可执行文件和依赖。这里用FetchContent拉取nlohmann/json避免手动拷贝头文件include(FetchContent) FetchContent_Declare( nlohmann_json GIT_REPOSITORY https://github.com/nlohmann/json.git GIT_TAG v3.11.3 ) FetchContent_MakeAvailable(nlohmann_json) add_executable(mcp_cpp_demo mcp_cpp_demo.cpp) target_link_libraries(mcp_cpp_demo PRIVATE nlohmann_json::nlohmann_json)注意CMAKE_CXX_STANDARD 17这一行std::filesystem需要 C17。如果你沿用 VS 工程对应的是在.vcxproj里加LanguageStandardstdcpp17/LanguageStandard否则会报std::filesystem未定义或链接错误。源码部分核心改动是在原有echo_upper之外新增uppercase_txt_file。工具声明放在tools/list的返回里参数 schema 如下{ {name, uppercase_txt_file}, {description, Read a UTF-8 txt file, convert ASCII lowercase letters to uppercase, keep non-letters unchanged, and write the result to a txt file}, {inputSchema, { {type, object}, {properties, { {inputPath, {{type, string}, {description, Path to the source .txt file}}}, {outputPath, {{type, string}, {description, Optional output .txt path. Defaults to input_upper.txt}}}, {overwrite, {{type, boolean}, {description, Whether to overwrite an existing output file}, {default, false}}} }}, {required, json::array({inputPath})} }} }处理逻辑的关键点只处理 ASCII 的a-z不要用全局 locale 的大小写转换否则会误伤 UTF-8 中文字节。转换函数保持逐字节判断static std::string to_upper_copy_ascii(std::string s) { for (char ch : s) { if (ch a ch z) { ch static_castchar(ch - a A); } } return s; }handle_uppercase_txt_file负责校验参数、校验.txt扩展名、读取输入、转换、写入输出、返回摘要。默认输出路径用make_default_output_path生成原文件名_upper.txt已存在且未允许覆盖时直接报错。接下来是 Skill 侧。SKILL.md放在skill_examples/txt-uppercase-file/下内容如下--- name: txt-uppercase-file description: Convert the contents of a UTF-8 .txt file so that ASCII lowercase letters become uppercase while non-letters stay unchanged. Use when the user wants to uppercase a txt file, batch-convert simple text content, or write the transformed result to a new txt file by calling the MCP tool uppercase_txt_file. --- # TXT 文件大写转换 接收用户传入的 .txt 文件路径。 优先调用 MCP 工具 uppercase_txt_file参数如下 - inputPath输入文件路径 - outputPath用户指定输出路径时填写 - overwrite仅当用户明确允许覆盖现有文件时填写 遵循规则 - 将文件按 UTF-8 文本处理 - 仅将 ASCII 小写字母 a-z 转为大写 A-Z - 汉字、数字、空格、标点符号保持不变 - 默认创建新文件不覆盖源文件 如果输出路径已存在且未请求覆盖停止执行并清晰提示文件冲突。 工具执行成功后返回信息 - 源文件路径 - 输出文件路径 - 原文件是否被保留这份 SKILL.md 没有重新实现任何转换逻辑它只做三件事声明触发场景、指定优先调用的 MCP 工具、约束边界条件。这就是 Skill 与 MCP 的标准分工。最后是 Codex CLI 的 MCP 注册配置写在~/.codex/config.tomlWindows 下是C:\Users\你\.codex\config.toml[mcp_servers.cpp_demo] type stdio command D:\\mcp_example\\build\\mcp_cpp_demo\\Debug\\mcp_cpp_demo.exe cwd D:\\mcp_example startup_timeout_sec 120如果你同时要接 TaoToken 的模型通道在同一个config.toml里补上模型配置三件套齐全model claude-sonnet-4-5 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEYenv_key指向环境变量名Key 本身放在系统环境变量里不写进文件。Skill 文件放到 Codex 可发现的位置例如C:\Users\你\.codex\skills\txt-uppercase-file\SKILL.md。配置完成后输入/skills应该能看到txt-uppercase-file出现在列表里。4. 验证请求与成功结果从编译到端到端调用配置写完必须验证否则你永远不知道是工具没注册、Skill 没被发现还是通道没通。我按“编译 → 手动 MCP 调用 → Skill 触发”三步走。第一步编译。用 CMake 的话cmake -S . -B build -DCMAKE_BUILD_TYPEDebug cmake --build build --config DebugWindows 上如果生成的是 VS 工程也可以用 MSBuild D:\Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe D:\mcp_example\build\mcp_cpp_demo.sln /t:Build /p:ConfigurationDebug /p:Platformx64编译成功后可执行文件在build/mcp_cpp_demo/Debug/mcp_cpp_demo.exe或你 VS 工程对应的x64\Debug\下。第二步手动发 MCP 消息验证工具注册。启动程序后先发初始化{jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:manual-test,version:0.1.0}}}再查工具列表{jsonrpc:2.0,id:2,method:tools/list}返回里应该同时出现echo_upper和uppercase_txt_file。如果只有前者说明tools/list的数组没改对回去检查 JSON 结构。准备一个测试文件D:\mcp_example\sample.txt内容写成hello, World! 123 今天abc然后调用文件工具{jsonrpc:2.0,id:3,method:tools/call,params:{name:uppercase_txt_file,arguments:{inputPath:D:\\mcp_example\\sample.txt}}}成功时返回类似{ jsonrpc: 2.0, id: 3, result: { content: [ { type: text, text: Converted file to uppercase.\nInput: D:\\mcp_example\\sample.txt\nOutput: D:\\mcp_example\\sample_upper.txt } ], isError: false } }同时sample_upper.txt生成内容应为HELLO, WORLD! 123 今天ABC。注意中文“今天”没变数字和标点也没变只有 ASCII 小写字母被转换这说明逐字节判断生效了。第三步Skill 触发。在 Codex CLI 里输入/skills确认txt-uppercase-file在列表然后用自然语言触发用 txt-uppercase-file skill 处理 D:\mcp_example\sample.txt把这个 txt 文件转成大写不要覆盖原文件预期行为是模型优先调用uppercase_txt_file传入inputPath不传overwrite返回源文件路径、输出文件路径和原文件保留状态。如果模型绕开工具自己读文件再写回说明 SKILL.md 的 description 不够明确或者 Skill 没被正确加载。到这里整条链路就通了C MCP 工具提供能力SKILL.md 提供流程约束TaoToken 提供统一模型通道。三者各司其职没有互相替代。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节对照真实报错给出定位思路。这些错我在不同阶段都遇到过按出现频率排序。401 Unauthorized。最常见的原因是 Key 没生效或 Base URL 拼错。先确认环境变量TAOTOKEN_API_KEY在当前终端可见Windows 下改完环境变量要重开终端。再确认base_url是https://taotoken.net/api没有多写/v1。如果 Key 是从控制台复制的检查有没有带多余空格或换行。401 基本是鉴权层问题和 MCP 工具本身无关。local proxy failed。这个报错通常出现在客户端尝试走本地代理但代理没启动或端口不对。检查你的客户端配置里有没有残留的代理设置把代理相关字段清掉直连https://taotoken.net/api。如果你在config.toml里同时配了model_provider和旧的代理项两者会冲突删掉不用的那个。reading choices 相关报错。这类错误一般出现在响应解析阶段客户端期望的返回结构和实际返回不匹配。常见诱因是 Base URL 指向了错误的路径导致返回的是 HTML 错误页而不是 JSON。用curl直接打一次接口确认返回体是 JSONcurl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H content-type: application/json \ -d {model:claude-sonnet-4-5,max_tokens:64,messages:[{role:user,content:ping}]}如果返回 HTML 或 404说明路径不对如果返回 JSON 但客户端仍报 reading choices检查客户端版本是否支持当前响应格式。OAuth 相关报错。有些客户端默认走 OAuth 流程而 TaoToken 用的是 API Key 鉴权。如果你看到 OAuth token 获取失败说明客户端在尝试它自己的登录流程而不是用你配的 Key。检查配置里是否误开了 OAuth 模式改成 API Key 模式把env_key指向正确的环境变量。MCP 工具调用返回 -32602。这是参数校验失败常见于inputPath传了非字符串、overwrite传了非布尔值或者输入文件不是.txt。对照handle_uppercase_txt_file里的校验顺序逐条排查先看扩展名再看文件是否存在再看是否普通文件最后看输出是否冲突。Skill 不触发。先确认/skills列表里有它再确认 SKILL.md 的 frontmatter 格式正确---包裹name和description都在。description 里要包含触发关键词比如“uppercase a txt file”否则模型匹配不到。排障时如果怀疑是通道问题去 API Keys 页面重新确认 Key 状态或对照接入文档检查路径拼接。如果只是想验证模型本身通不通用模型对话页面发一句话最快。长期做编码和 Agent 的话Coding Plan 能省掉不少重复配置。6. 把自研 Skill 接进统一通道下一步怎么走走到这里你已经有了一个可被 AI 开发流程调用的最小 SkillC 写的 MCP 工具负责文件级大写转换SKILL.md 负责触发条件和边界约束TaoToken 负责统一模型通道。这套结构可以复制到任何“读文件 → 处理 → 写文件”的场景比如批量重命名、格式转换、日志提取。下一步我建议做两件事。第一把uppercase_txt_file的参数再扩一层比如支持encoding或dryRun让工具边界更清晰Skill 的 description 也能写得更具体。第二把 Skill 目录纳入版本管理和 MCP 源码放在同一个仓库这样工具和流程说明不会脱节。如果你还没拿到 Key先去控制台创建如果通道已经通了直接去接入文档对照一遍路径拼接确认没有多余后缀。需要长期跑编码和 Agent 任务的话Coding Plan 比按次调用更省心。整条链路的关键不是某个单点配置而是“能力用 MCP 暴露、流程用 Skill 约束、通道用统一 Key 收口”这个分工记住这一点后面接什么工具都不会乱。

相关新闻

Java城堡游戏项目实战:从面向对象设计到命令模式扩展

Java城堡游戏项目实战:从面向对象设计到命令模式扩展

简介:java 城堡游戏项目.zip 是一份基于 Java 开发的城堡冒险小游戏源码包,适合 Java 初学者和想了解游戏开发流程的开发者用作练手与课程设计参考,是一款寓教于乐的小型游戏项目。项目围绕角色在城堡场景中的探索与互动展开,涵盖…

2026/10/18 4:57:36 阅读更多 →
Linux启动过程全解析:从GRUB到systemd的排障实战

Linux启动过程全解析:从GRUB到systemd的排障实战

又到了RH134的知识点整理时间。第10章"控制启动过程"这节,很多人嫌杂:一会儿systemd,一会儿GRUB,一会儿又是target,背完就忘。但说句实在话,想搞懂Linux系统到底是怎么从按下电源键走到登录界面的…

2026/10/18 4:57:36 阅读更多 →
DASCTF 2021 MISC赛题复盘:文件体检、流量分析与编码还原实战

DASCTF 2021 MISC赛题复盘:文件体检、流量分析与编码还原实战

1. 赛题背景与整体复盘思路DASCTF 2021 那场 MISC 方向的题目,当时在圈子里讨论度相当高。我是在赛后隔了几天才拿到题目包,花了大概两个晚上把几道有代表性的题从头到尾复现了一遍。写这篇复盘,主要是给当时卡住没做出来、或者想系统补一下 …

2026/10/18 4:56:36 阅读更多 →

最新新闻

C# IOCP高性能Socket服务:池化设计与5000+并发实战

C# IOCP高性能Socket服务:池化设计与5000+并发实战

简介:这是一份面向C#中高级开发者与网络编程学习者的Socket高性能异步通信实战示例,聚焦.NET Framework下SocketAsyncEventArgs核心机制的应用落地,解决传统Begin/End模式性能瓶颈与高并发连接管理难题。资源包含20个文件,以6个核…

2026/10/18 9:47:34 阅读更多 →
VS2019无法定位程序输入点到IPHLPAPI.DLL?排查与修复全指南

VS2019无法定位程序输入点到IPHLPAPI.DLL?排查与修复全指南

前阵子接手一台旧开发机,双击 Visual Studio 2019 的图标,启动画面刚出来,屏幕上就弹了一个对话框,标题栏写着“无法找到入口点”:无法定位程序输入点 RtlGetPersistedStateLocation 于动态链接库 IPHLPAPI.DLL 上。点…

2026/10/18 9:47:34 阅读更多 →
基于Java Swing和MySQL的学生选课管理系统全解析

基于Java Swing和MySQL的学生选课管理系统全解析

简介:一套基于Java Swing与MySQL的学生选课管理系统项目,适配IntelliJ IDEA,面向Java初学者及需要完成课程设计、毕业设计的学生。系统划分为系统管理、数据管理和数据查询三大部分:系统管理实现密码设置、用户登录和退出&#xf…

2026/10/18 9:47:34 阅读更多 →
青少年开源参与指南:从零开始第一次PR到开源社区成长路径

青少年开源参与指南:从零开始第一次PR到开源社区成长路径

1. 先从背景说起:为什么会有“青少年开源”这个议题1.1 社区里那些让我意外的年轻人这几年混迹各种开源社区和线下技术活动,有个现象越来越明显:出现在贡献者列表里的年轻面孔越来越多了。以前遇到一个高中生PR(Pull Request&…

2026/10/18 9:47:34 阅读更多 →
李雅普诺夫指数与沃夫算法:从混沌判据到MATLAB实操

李雅普诺夫指数与沃夫算法:从混沌判据到MATLAB实操

简介:本资源是一份面向动力系统与混沌理论研究者的MATLAB实践工具包,聚焦李雅普诺夫指数的数值计算与稳定性判别,特别适合控制工程、非线性科学及时间序列分析方向的研究生与科研人员。压缩包内含1个核心MATLAB脚本文件(lyapunov_…

2026/10/18 9:47:34 阅读更多 →
基于计算机视觉的寄生虫卵自动识别:从数据到部署的实战经验

基于计算机视觉的寄生虫卵自动识别:从数据到部署的实战经验

寄生虫卵的人工镜检,做过的都知道有多费眼睛。我接触过不少基层检验科和疾控实验室的老师,他们每天要看几十上百张涂片,在显微镜下一帧一帧地找虫卵,不仅效率低,而且极度依赖个人经验——同一个视野,老专家…

2026/10/18 9:46:34 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →