资讯动态

agent-skills:原子化AI能力单元的CLI-first设计与工程实践

发布时间:2026/10/26 9:41:07 来源:尧图企业网站定制
1. 项目概述从“agent-skills”这个词组看懂现代开发者工具链的底层演进“agent-skills”不是某个具体软件的名字也不是某家公司的产品代号而是一个正在快速凝聚共识的技术概念——它代表一类新型可插拔、可组合、可验证的原子化能力单元专为AI代理Agent系统设计。我第一次在GitHub上看到这个仓库名时下意识点开README发现里面没有传统意义上的“安装教程”只有一行命令npx skills/cli init。那一刻我就意识到这背后不是又一个CLI工具的简单迭代而是前端工程化、AI应用开发和命令行交互范式三股力量交汇后催生的新物种。核心关键词“agent-skills”必须放在这个语境里理解它不是“给Agent加技能”的通俗说法而是指以标准化协议封装、通过CLI统一调度、支持跨平台复用的最小功能契约。你可以在本地用npx直接调用也可以把它嵌入Next.js App的API Route里还能作为Playwright测试脚本里的一个步骤被自动触发。它不绑定框架不强依赖运行时甚至不强制要求Node.js——只要能执行HTTP请求或标准输入输出就能消费一个skill。这种设计哲学直接绕开了过去十年里反复出现的“SDK地狱”每个服务都配一套SDK每个SDK都带一堆peerDependencies每次升级都像拆炸弹。为什么现在突然冒出这么多相关热词你看热搜列表里高频出现的cli、npx、slash commands、codex cli、zcode cli其实都在指向同一个趋势开发者正在放弃“下载安装完整IDE/平台”的重模式转向“按需加载能力模块”的轻模式。比如你在VS Code里敲/test背后可能调用的是一个托管在GitHub Pages上的skills/test-runner你在终端输入skills deploy --envstaging实际执行的是一个用Zod校验参数、用Oclif构建交互、用Vercel Serverless Functions跑逻辑的独立服务。这不是“命令行复兴”而是能力交付方式的静默革命——把功能从“打包进二进制”变成“发布为可寻址端点”。适合谁来关注这个方向如果你是前端工程师正被“又要写React组件又要搭CI又要维护Dockerfile”压得喘不过气如果你是SRE每天花3小时处理不同团队提交的“请帮我们部署这个新工具”工单如果你是AI产品经理发现模型能力再强落地时卡在“怎么让销售同事一键生成客户报告”这种具体动作上——那么“agent-skills”就是你现在最该盯住的接口层。它不解决模型训练问题但能让你把Claude、Qwen、甚至本地Ollama模型的能力像调用fs.readFile()一样自然地编排进业务流程。我上周用5个skills拼出一个自动周报生成器git-changes抓本周提交 →jira-issues查关联任务 →claude-summarize生成摘要 →notion-sync写入文档 →slack-notify发提醒。全程没写一行HTTP请求代码所有错误重试、超时控制、凭证管理都由skills runtime自动处理。这背后真正的技术支点其实是三个被长期低估的基础设施一是npx作为零配置执行引擎的成熟度它早已不是“临时跑个脚本”的玩具而是具备缓存、沙箱、版本解析能力的轻量级包管理器二是Slash Commands协议的事实标准化Slack/Discord/Notion都采用类似/command arg1 arg2的语法skills CLI正是以此为交互锚点三是前端构建工具链对ESM Top-Level Await Conditional Exports的全面支持使得一个skill既能当Node.js模块用也能当浏览器ESM导入还能被Deno直接执行。这三者叠加才让“写一次到处调用”从口号变成日常操作。接下来我会一层层拆解这个看似简单的词组到底如何在真实项目中落地、调试、扩展和维护。2. 核心设计逻辑为什么“agent-skills”必须是CLI-first、协议驱动、零依赖的架构2.1 CLI-first不是妥协而是对开发者心智模型的精准适配很多人看到npx skills/cli init第一反应是“又要学新CLI我连npm run script都记不全。” 这种抵触非常合理——过去十年我们被Webpack CLI、Create React App、Vite CLI、Turborepo CLI轮番教育每个都宣称“开箱即用”结果打开node_modules一看依赖树深达27层。但“agent-skills”的CLI设计哲学完全不同它不提供任何内置功能只做三件事——解析命令、匹配skill、转发参数、捕获输出。你可以把它理解成一个智能的xargs增强版而不是一个功能集合体。为什么必须CLI-first因为这是唯一能同时满足三类用户的交互界面终端用户如运维、数据分析师需要skills db-backup --hostprod --retention7d这种直白指令拒绝打开GUI或写JSON配置开发者如前端、后端需要skills dev --watch实时监听文件变化并热重载skill同时支持skills test --coverage生成测试报告平台方如内部工具平台、低代码平台需要skills list --formatjson输出结构化数据用于动态渲染UI按钮或生成API文档。我实测过三种替代方案Web UI驱动需要维护登录态、权限系统、前端路由一个简单数据库备份功能就得搭整套ReactExpress栈SDK集成每个语言都要写bindingPython用户抱怨“为什么我要装Node.js才能用这个backup工具”HTTP API直调用户得自己处理认证头、重试逻辑、错误码映射curl -X POST https://api.skills.dev/v1/db-backup -H Authorization: Bearer $TOKEN -d {host:prod}的学习成本远高于skills db-backup --hostprod。CLI成为事实标准本质是回归Unix哲学——“每个程序只做一件事并做好”。skills CLI本身代码不到800行我fork后统计过核心逻辑就一个函数# 伪代码示意 parseCommand($argv) → { skillName, args, flags } resolveSkill(skillName) → /path/to/skill/bin/index.js execa(resolveSkill(), [...args, ...flags]) → { stdout, stderr, code }所有复杂性都被推给skill本身参数校验用Zod、日志输出用Pino、错误处理用自定义Error Class。CLI只负责“搬运工”角色。这种分离让skill开发者可以专注业务逻辑CLI维护者只需保证调度层稳定——这才是可持续协作的基础。2.2 协议驱动Slash Commands不是UI糖衣而是能力发现与编排的通用语言热搜词里反复出现的slash commands常被误解为“Slack里打斜杠的功能”。但在agent-skills体系里它是一个能力注册与调用的元协议。每个skill必须声明自己的manifest.json其中关键字段是{ name: db-backup, description: Create encrypted backup of PostgreSQL database, command: /db-backup, parameters: [ { name: host, type: string, required: true }, { name: retention, type: number, default: 30 } ], platforms: [cli, slack, notion] }这个manifest不是装饰品而是runtime的执行契约。当你在终端执行skills db-backup --hostprodCLI会查找db-backup对应的manifest用Zod Schema校验--hostprod是否符合parameters[0]定义将参数转换为标准格式如{ host: prod, retention: 30 }调用skill的execute(input)函数传入此对象捕获返回值按outputFormat字段决定是打印JSON还是纯文本。更关键的是同一份manifest能被不同平台消费Slack Bot收到/db-backup hostprod消息自动解析参数并调用skillNotion Database的Button Property配置/db-backup点击即触发内部Dashboard的React组件用useSkill(db-backup)Hook传入参数获得Promise。我去年在客户现场部署时发现他们销售团队用Notion Button一键生成客户分析报告而运维团队用CLI定时执行同样逻辑。两者调用的是完全相同的skill代码只是入口不同。这种一致性消除了“功能在A平台可用B平台要重写”的经典痛点。协议驱动的价值在于把“能力”从“渠道”中解耦——就像USB-C接口不关心插的是手机还是显示器skills协议也不关心调用方是终端还是网页。2.3 零依赖原则一个skill包为何能小到27KB且无需install你可能会问既然叫skills/cli那是不是所有skill都得装一堆依赖答案是否定的。真正体现设计功力的是skills的发布形态——它必须是一个自包含的、无peerDependencies的ESM包。我解压过官方推荐的skills/git-changes包结构如下node_modules/skills/git-changes/ ├── package.json # {type: module, exports: ./dist/index.js} ├── dist/ │ ├── index.js # 6.2KB含所有逻辑内联ZodPino精简版 │ └── index.d.ts # 类型定义 └── src/ # 源码开发用关键点在于所有依赖都被rollup打包进dist/index.js包括Zod仅用到的z.string().min(1)部分、Pino仅用到pino({ level: info })、甚至child_process的polyfill为浏览器环境准备package.json明确声明exports禁止Node.js加载src/目录强制走预构建路径零peerDependencies不声明zod: ^3.0.0因为Zod已被打包不声明pg: *因为数据库操作被抽象为execute()函数的输入参数具体driver由调用方注入见下文“运行时注入”部分。这种设计带来三个硬性好处安装极速npm install skills/db-backup实际只下载一个27KB的tgz包比npm install pg1.2MB快15倍版本安全你的App用Zod 4.xskill用Zod 3.x互不干扰因为skill的Zod已固化在dist里跨环境一致同一份dist文件既能在Node.js 18里运行也能通过import { execute } from https://cdn.skypack.dev/skills/db-backup1.2.0在浏览器里执行需配合fetch替代child_process。我曾用这个特性救急客户生产环境禁止npm install但允许curl下载文件。我把skill dist包上传到内部OSS用npx -p https://internal.oss/skills/db-backup-1.2.0.tgz skills db-backup --hostprod直接运行——整个过程3秒完成没有依赖冲突没有权限问题。零依赖不是教条而是为极端部署场景预留的逃生通道。3. 实操全流程从初始化到发布手把手构建一个可商用的agent-skill3.1 初始化用官方CLI创建骨架但立刻删掉90%的模板代码第一步永远是npx skills/cli init my-first-skill。这会生成一个标准目录结构my-first-skill/ ├── package.json ├── manifest.json ├── src/ │ ├── index.ts # 主入口 │ └── types.ts # 类型定义 ├── tests/ │ └── index.test.ts └── README.md但这里有个关键陷阱官方模板为了“开箱即用”默认集成了Jest测试、TypeScript配置、ESLint规则——这些对一个skill来说全是噪音。我建议初始化后立即执行三步清理删除tests/目录和jest.config.jsskill的测试应该聚焦在execute()函数的输入输出而非CLI交互。用Vitest更快替代Jest单文件测试足够简化package.json移除devDependencies里所有非必要项只保留typescript: ^5.0.0,vite: ^4.0.0用于构建skills/cli: ^1.0.0仅用于本地开发重写src/index.ts模板里充斥着import { Command } from oclif/core等CLI框架代码但skill的核心是execute()函数其他都是可选装饰。清理后的src/index.ts应长这样import { z } from zod; // 定义输入Schema —— 这是skill的契约 const InputSchema z.object({ url: z.string().url(), timeout: z.number().min(1000).max(30000).default(5000), }); // 定义输出类型 —— 这是skill的承诺 export type Output { status: success | error; data?: string; // 原始HTML内容 error?: string; }; // 核心逻辑只做一件事 —— 抓取网页标题 export async function execute(input: z.infertypeof InputSchema): PromiseOutput { try { const controller new AbortController(); const timeoutId setTimeout(() controller.abort(), input.timeout); const res await fetch(input.url, { signal: controller.signal }); clearTimeout(timeoutId); if (!res.ok) { return { status: error, error: HTTP ${res.status} }; } const html await res.text(); const titleMatch html.match(/title(.*?)\/title/i); const title titleMatch ? titleMatch[1].trim() : No title found; return { status: success, data: title }; } catch (err) { return { status: error, error: err instanceof Error ? err.message : Unknown error }; } } // CLI入口仅用于本地调试生产环境不使用 if (process.argv[1]?.includes(index.ts)) { const input InputSchema.parse({ url: process.argv[2], timeout: parseInt(process.argv[3] || 5000), }); execute(input).then(console.log).catch(console.error); }注意这个设计的精妙之处execute()函数完全独立于任何框架可直接import { execute } from ./src在任何JS环境调用CLI入口用process.argv判断避免污染主逻辑输入校验用Zod错误处理用标准try/catch输出结构清晰可预测。这种极简主义让skill的可维护性大幅提升。我见过太多项目因为过度依赖Oclif或Commander导致升级CLI框架时整个skill崩溃。而这里你升级Zod或Fetch API只需改execute()内部实现manifest和调用方式完全不变。3.2 构建与打包Rollup配置的5个必调参数避开90%的体积陷阱skills的发布包必须小而精因此构建环节至关重要。我用Rollup而非Webpack因其配置更透明、tree-shaking更激进。以下是rollup.config.js的核心配置已实测压缩至12KBimport { nodeResolve } from rollup/plugin-node-resolve; import terser from rollup/plugin-terser; import typescript from rollup/plugin-typescript; export default { input: src/index.ts, output: { file: dist/index.js, format: es, // 必须ESM兼容Node.js和浏览器 exports: named, sourcemap: false, // 生产环境禁用source map }, plugins: [ // 关键1只解析node_modules不打包polyfill nodeResolve({ browser: true, preferBuiltins: false }), // 关键2TypeScript编译禁用declaration.d.ts由tsc单独生成 typescript({ tsconfig: ./tsconfig.build.json, include: [src/**/*], exclude: [node_modules, tests], noEmit: false, emitDeclarationOnly: false, }), // 关键3Terser压缩启用mangle但禁用compress避免破坏Zod校验逻辑 terser({ mangle: { reserved: [z, zod] // 保留Zod全局变量名防止校验失效 }, compress: false, // Zod的链式调用z.string().min(1)经compress后可能出错 format: { comments: false } }), // 关键4手动排除大型依赖如axios改用原生fetch { resolveId: (id) { if (id axios) return /dev/null; // 模拟不存在 return null; } }, // 关键5内联小依赖zod/pino但排除大依赖 { transform: (code, id) { if (id.includes(zod) code.length 50000) { return code.replace(/export \* from/g, export); // 简化导出 } return null; } } ], external: [node:fs, node:path], // 明确标记Node.js内置模块为external };这5个参数背后是我踩过的坑preferBuiltins: false早期版本默认true导致require(fs)被替换成browserify的fs polyfill体积暴增300KBcompress: false开启compress后Zod的.optional().default()会被压缩成.o().d()运行时报TypeError: Cannot read properties of undefinedmangle reservedZod依赖z全局变量若mangle成az.string()就失效external显式声明不声明时Rollup会尝试打包fs结果引入整个Node.js fs polyfill手动resolveId排除axios很多模板默认用axios但skills规范要求用fetch必须主动拦截。构建后执行npm pack生成tgz包用npx size-limit检测$ npx size-limit ✅ skills/web-title: max size is 12 KB with current dependencies超过15KB的skill会被CI拒绝合并——这是团队约定的硬性红线。体积控制不是优化项而是能力可组合性的前提10个12KB的skill总加载时间远低于1个120KB的SDK。3.3 发布与验证四步发布法确保skill在任意环境可靠运行发布一个skill不是npm publish就完事。我总结的四步法每一步都有自动化检查第一步本地CLI验证开发机# 1. 全局安装CLI npm install -g skills/cli # 2. 在skill目录执行 skills dev --watch # 启动监听修改src后自动重建 # 3. 测试命令 skills web-title --urlhttps://example.com --timeout3000 # 预期输出{ status: success, data: Example Domain }提示skills dev会启动一个轻量Watcher用chokidar监听src/变化触发rollup -c重建dist然后自动重启CLI进程。比npm run build skills ...快5倍。第二步npx沙箱验证干净环境# 创建空目录模拟新用户首次使用 mkdir /tmp/sandbox cd /tmp/sandbox npx skills/clilatest web-title --urlhttps://example.com # ✅ 成功证明skill不依赖本地node_modulesnpx能正确解析dist # ❌ 失败常见原因是manifest里main指向了src/index.ts而非dist/index.js第三步跨平台验证Windows/macOS/Linux用GitHub Actions跑矩阵测试jobs: test-cross-platform: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkoutv3 - name: Setup Node uses: actions/setup-nodev3 with: node-version: 18 - name: Test skill run: | npm install -g skills/cli skills web-title --urlhttps://example.com | grep Example Domain注意Windows上child_process.execSync行为不同但我们的skill用fetch天然跨平台。第四步平台集成验证Slack/Notion在Slack App管理后台添加Slash Command/web-titleEndpoint URL设为https://your-api.com/skills/web-title在Notion Developer Portal创建Internal Integration添加Button PropertyAction设为/web-title实际点击测试确认返回结果被正确解析Slack显示卡片Notion更新属性。只有四步全部通过才能执行npm publish --access public。我坚持这个流程是因为曾有一个skill在本地完美但npx时因exports配置错误加载了未构建的TS源码导致SyntaxError。四步法把问题拦截在发布前避免影响下游用户。4. 深度避坑指南12个真实故障场景与我的应急响应手册4.1 “npx playwright install失败”背后的真相不是网络问题而是skills的依赖策略冲突热搜词里高频出现的npx playwright install失败表面看是Playwright安装问题实则是skills生态里一个经典误用。很多开发者想用skills封装Playwright自动化于是写// ❌ 错误示范在skill里直接import playwright import { chromium } from playwright; export async function execute(input: any) { const browser await chromium.launch(); // 这里就会失败 // ... }问题根源在于Playwright的chromium.launch()需要下载二进制浏览器而skills的零依赖原则禁止在dist/里打包二进制。npx playwright install失败是因为skills CLI执行时工作目录是node_modules/skills/xxx/dist/而Playwright试图在此目录下创建./browsers/但dist/通常是只读的尤其在CI环境。正确解法运行时注入Runtime Injectionskills规范允许将重型依赖作为“运行时参数”传入// ✅ 正确skill只定义接口不加载依赖 export interface PlaywrightContext { launch: (opts?: any) Promiseany; } export async function execute( input: z.infertypeof InputSchema, context: PlaywrightContext // 运行时注入 ): PromiseOutput { const browser await context.launch(); // ... 使用browser }调用方负责准备context# 终端调用 npx skills/cli web-scrape \ --urlhttps://example.com \ --injectplaywright1.30.0 # CLI自动安装playwright并注入或在Node.js中import { execute } from skills/web-scrape; import { chromium } from playwright; const context { launch: () chromium.launch() }; execute({ url: https:// }, context);这个模式把“下载浏览器”的责任交给调用方skills保持纯净。我用此法成功部署了23个Playwright-based skills零安装失败。4.2 “codex cli安装慢”与“node安装codex cli很慢”的根因registry镜像与pnpm的协同优化codex cli安装慢本质是npm install默认从registry.npmjs.org下载而skills生态大量使用skills/xxx包这些包虽小但数量多一个项目常引用10 skills逐个HTTP请求累积延迟显著。三步提速法实测从6分钟→22秒切换registry镜像npm config set registry https://registry.npmmirror.com # 或使用pnpm更优 pnpm add -g skills/clipnpm的硬链接机制使重复包如多个skills都用Zod只下载一次。预构建依赖缓存在CI中pnpm store add提前缓存常用skills- name: Cache skills run: | pnpm store add skills/git-changes1.0.0 \ skills/jira-issues2.1.0 \ skills/claude-summarize0.8.0本地CLI懒加载不全局安装skills/cli改用npx指定版本# ❌ 慢每次npx都解析最新版 npx skills/cli web-title # ✅ 快锁定版本npx直接从缓存取 npx skills/cli1.2.0 web-title我帮客户优化CI流水线时应用此法后skills install步骤从平均412秒降至19秒提速21倍。4.3 Slash Commands在Slack/Notion中“找不到命令”的7种排查路径当/my-skill在Slack里提示“Command not found”别急着重装App按此顺序排查排查项检查方法修复方案1. Manifest未注册访问https://api.skills.dev/v1/manifests/my-skill确保skill已npm publish且package.json中name与URL匹配2. Slack App未启用Slack Admin Console → Manage Apps → 找到App → Permissions → 检查commandsscope添加commands权限并重新授权3. Endpoint URL错误Slack App → Interactive Components → Request URL必须是HTTPS且域名在manifest.json的platforms中声明4. 签名验证失败查看Slack回调日志是否有401 Unauthorized在skills backend中用Slack提供的signing_secret验证X-Slack-Signature头5. 参数解析错误Slack日志中text: hostprod timeout3000确保manifest中parameters定义与/my-skill hostprod语法匹配6. Timeout超时Slack要求响应3秒查看backend耗时在execute()开头加console.time(execute)确保逻辑2.5秒7. CORS问题Notion浏览器Console报CORS policyNotion要求endpoint返回Access-Control-Allow-Origin: *我整理了一个速查表贴在团队共享文档首页。最常犯的错误是第4项——Slack签名验证。很多开发者直接转发请求到skill忘了验证签名导致Slack认为请求被篡改而拒绝。解决方案是用官方slack/interactive-messages库import { createSignatureVerifier } from slack/interactive-messages; const verifier createSignatureVerifier(process.env.SLACK_SIGNING_SECRET!); app.post(/slack/actions, async (req, res) { if (!verifier.isValidRequest(req.rawBody, req.headers)) { return res.status(401).send(Invalid signature); } // 继续处理 });4.4 “skills测试”失败的3个隐藏雷区与我的断点调试法skills测试失败往往不是逻辑错而是环境假设错。我用VS Code的Debugger设置以下断点雷区1fetch在Node.js 18默认启用但旧版需polyfill现象ReferenceError: fetch is not defined断点位置src/index.ts第一行解决在package.json中添加engines: { node: 18.0.0 }CI中强制Node 18雷区2Zod Schema在strict mode下对undefined敏感现象execute({})抛ZodError但CLI调用时--flag未传值input为{}断点位置InputSchema.parse(input)调用处解决用.optional().default(null)而非.optional()确保未传参时有默认值雷区3异步资源未清理导致测试hang住现象Vitest测试卡住不退出断点位置afterAll(() { /* 清理逻辑 */ })解决skills中所有setTimeout/setInterval必须在execute()结束时clear或用AbortController我写了一个测试基类强制所有skills继承import { afterEach, beforeEach } from vitest; export class SkillTestHelper { private timers: NodeJS.Timeout[] []; protected setTimeout(fn: () void, ms: number) { const timer setTimeout(fn, ms); this.timers.push(timer); return timer; } protected afterAllCleanup() { afterEach(() { this.timers.forEach(clearTimeout); this.timers []; }); } }在测试文件中import { SkillTestHelper } from skills/test-utils; const helper new SkillTestHelper(); helper.afterAllCleanup(); test(should fetch title, async () { const result await execute({ url: https://example.com }); expect(result.status).toBe(success); });这套方法让我团队的skills测试通过率从83%提升至100%且平均执行时间缩短40%。5. 生产级扩展如何用skills构建企业级AI工作流避开“玩具项目”陷阱5.1 从单个skill到skills orchestration用YAML编排复杂流程单个skill解决原子问题但真实业务需要组合。skills生态提供了skills flow命令用YAML定义工作流# workflow.yaml name: weekly-report steps: - name: get-changes skill: git-changes input: repo: https://github.com/company/app since: 7d - name: get-issues skill: jira-issues input: jql: project APP AND updated -7d dependsOn: get-changes # 上一步输出作为本步输入 - name: summarize skill: claude-summarize input: text: {{ get-changes.output }}\n{{ get-issues.output }} dependsOn: [get-changes, get-issues] - name: publish skill: notion-sync input: pageId: abc123 content: {{ summarize.output }}执行skills flow --file workflow.yaml关键设计点dependsOn声明依赖关系skills CLI自动拓扑排序支持并行无依赖的steps并发执行{{ step.output }}语法自动提取上一步的data字段避免手动JSON.parse失败自动回滚若notion-sync失败CLI会调用git-changes的rollback()函数如果定义。我用此法重构了客户的数据ETL流程原来用Airflow调度5个Python脚本现在用3个skills 1个YAML维护成本降低70%。YAML不是配置文件而是可版本控制、可Code Review、可Git Diff的业务逻辑。5.2 权限与安全skills的RBAC模型与凭证隔离实践skills执行常涉及敏感操作如数据库备份、API调用必须隔离凭证。skills CLI内置RBAC# 为不同环境创建profile skills profile create prod --envproduction skills profile create staging --envstaging # 为profile绑定凭证加密存储 skills profile set prod DB_URLpostgres://user:passprod/db skills profile set staging DB_URLpostgres://user:passstaging/db # 执行时指定profile skills db-backup --profileprod --hostprod底层原理CLI用node:crypto的scrypt算法以profile name为salt加密存储凭证到~/.skills/profiles/。即使磁盘泄露无salt无法解密。更进一步我实现了“凭证注入”模式skills不直接读取DB_URL而是接收一个DatabaseClient实例export interface DatabaseClient { query: (sql: string) Promiseany; } export async function execute( input: any, client: DatabaseClient // 运行时注入 ) { return client.query(BACKUP DATABASE ${input.db}); }这样credential management完全由调用方控制skills只专注逻辑。我们在Kubernetes中用Secrets挂载凭证Pod启动时注入clientskills代码零改动。5.3 监控与可观测性skills的OpenTelemetry集成与告警阈值设定skills生产环境必须可观测。我在每个skill的execute()开头加入OTel追踪import { trace } from opentelemetry/api; export async function execute(input: any) { const tracer trace.getTracer(skills/web-title

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑