ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenClaw Skill 开发实战:从零写一个 AWS 成本监控技能(附完整代码与配置骨架)

OpenClaw Skill 开发实战:从零写一个 AWS 成本监控技能(附完整代码与配置骨架) 1. 为什么我要给 OpenClaw 写一个 AWS 成本监控 SkillOpenClaw 装好之后天气查询、网页摘要、文件整理这些通用能力都能跑但一碰到我这个月 AWS 花了多少钱这种问题就卡住了。原因很简单Agent 本身不知道你的云账号长什么样也没有内置调用 Cost Explorer 的能力。它需要一个明确的操作手册告诉它遇到这类请求时该执行什么命令、读哪个文件、按什么格式输出。这就是 Skill 存在的意义。Skill 是 OpenClaw 的能力扩展单元核心是一个 SKILL.md 文件——写给 AI Agent 看的操作手册。Agent 收到请求后先扫描所有 Skill 的描述信息匹配上了才加载正文按里面的指令执行。门槛低、即时生效、按需加载不用编译、不用重启。我这次要落地的场景很具体让 OpenClaw 能回答AWS 这个月花了多少哪个服务最烧钱月底预计总费用是多少。交付物包括一份可复制的 SKILL.md 模板、一个 config.toml 配置骨架、一个 Python 辅助脚本以及本地验证动作。适合已经在用 OpenClaw、想让 Agent 干点定制活的开发者也适合刚接触 Skill 机制、想找一个完整案例跟做的人。下面按目录结构 → SKILL.md 编写 → 配置骨架 → 脚本实现 → 本地验证 → 排障的顺序走一遍每一步都能直接复制。2. TaoToken 前置给 Skill 里的模型调用准备一个稳定入口AWS 成本监控 Skill 本身不依赖大模型但如果你想让 Agent 在拿到成本数据后自动生成分析结论比如EC2 比上月涨了 30%建议检查闲置实例就需要在 Skill 的 Steps 里调用模型。这时候一个稳定的 API 入口就很重要。TaoToken 提供的就是这样一个入口。它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的调用方式你可以在 Skill 的脚本里直接用它做成本数据的二次分析。官网在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content注册后到控制台创建 API Key 即可。具体操作路径打开控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建一个 API Key到 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite复制密钥想先验证模型是否可用去模型对话页https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite发一条测试消息接入细节看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite如果你打算长期跑编码类或 Agent 类任务Coding Plan 页面https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite有更划算的套餐。Claude Code 用户可以直接参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite的接入说明。把 Key 拿到手后写进下面第 4 节的 config.toml 里Skill 脚本就能在生成报告时调用模型做趋势分析。3. 技能目录结构与 SKILL.md 编写3.1 目录结构OpenClaw 的 Skill 放在工作区的 skills 目录下每个技能一个文件夹。推荐结构如下~/.openclaw/workspace/skills/aws-cost-monitor/ ├── SKILL.md # 必须有技能定义 ├── config.toml # 配置骨架存放阈值、区域等 ├── scripts/ │ └── check_cost.py # 辅助脚本查询成本数据 └── references/ └── cost-explorer-notes.md # 可选参考文档原则是 SKILL.md 保持精简大段内容拆到子目录。Agent 只读 SKILL.md 的正文脚本和参考文档按需加载。3.2 SKILL.md 模板SKILL.md 用 Markdown 写结构固定。下面是我实测可用的模板# AWS Cost Monitor ## Description 查询 AWS 账户费用生成成本报告按服务拆分超预算告警。 ## Triggers - 用户说查一下我的 AWS 账单 - 用户说这个月花了多少钱 - 用户说AWS 成本报告 - 用户说看看云资源开销 - 用户说账单超了没 - 用户说成本分析 - 用户说哪个服务花钱多 ## Steps 1. 执行 scripts/check_cost.py 获取成本数据 2. 解析 JSON 输出 3. 生成报告 AWS 成本报告 | YYYY-MM-DD 统计周期YYYY-MM-01 ~ YYYY-MM-DD 本月累计费用$XXX.XX 按服务拆分Top 5 日均费用 / 预估月底总费用 4. 预估超 $500 则追加告警 5. 用户指定阈值则替代默认值 ## Notes - 需要 AWS CLI 凭证和 ce:GetCostAndUsage 权限 - 数据有 24-48 小时延迟 - Cost Explorer API 只能通过 us-east-1 调用Triggers 是匹配的关键。我踩过的坑是只写了书面语用户口语提问就匹配不上。经验是把各种说法都列进去先上线再迭代补充。3.3 config.toml 配置骨架把可变参数抽到配置文件里改阈值不用动脚本[aws] region us-east-1 profile default [monitor] # 月度预算阈值超过则告警 budget_threshold 500.0 # 报告里展示的服务数量 top_services 5 # 是否启用模型分析 enable_ai_analysis false [taotoken] # 启用模型分析时填写 api_base https://taotoken.net/api api_key model gpt-4o-mini [report] # 报告语言 language zh # 日期格式 date_format %Y-%m-%denable_ai_analysis打开后脚本会把成本数据发给 TaoToken 的 API让模型生成趋势分析和优化建议。api_key 从第 2 节的控制台获取。4. 脚本实现与本地验证4.1 check_cost.py 完整代码脚本依赖 boto3负责查询总费用、按服务拆分、预估月底总额#!/usr/bin/env python3 AWS Cost Monitor — 查询 AWS 账户成本数据 依赖boto3 权限ce:GetCostAndUsage import json import sys from datetime import datetime, timedelta import boto3 def get_month_range(year: int 0, month: int 0) - tuple: 获取指定月份的起止日期。 today datetime.utcnow() if year 0 or month 0: year today.year month today.month start f{year:04d}-{month:02d}-01 if month 12: end_date datetime(year 1, 1, 1) else: end_date datetime(year, month 1, 1) # 当前月 End 用明天排他的 if year today.year and month today.month: end_date today timedelta(days1) return start, end_date.strftime(%Y-%m-%d) def query_total_cost(client, start: str, end: str) - float: 查询总费用。 resp client.get_cost_and_usage( TimePeriod{Start: start, End: end}, GranularityMONTHLY, Metrics[UnblendedCost], ) total 0.0 for result in resp[ResultsByTime]: total float(result[Total][UnblendedCost][Amount]) return round(total, 2) def query_cost_by_service(client, start: str, end: str) - list: 按服务维度查询费用。 resp client.get_cost_and_usage( TimePeriod{Start: start, End: end}, GranularityMONTHLY, Metrics[UnblendedCost], GroupBy[{Type: DIMENSION, Key: SERVICE}], ) services {} for result in resp[ResultsByTime]: for group in result[Groups]: name group[Keys][0] amount float(group[Metrics][UnblendedCost][Amount]) services[name] services.get(name, 0.0) amount sorted_list sorted(services.items(), keylambda x: x[1], reverseTrue) return [ {service: n, amount: round(a, 2)} for n, a in sorted_list if a 0.01 ] def estimate_monthly_total(total_so_far: float, start: str) - float: 预估月底总费用。 today datetime.utcnow() start_date datetime.strptime(start, %Y-%m-%d) days_passed (today - start_date).days if days_passed 0: return total_so_far if start_date.month 12: next_month datetime(start_date.year 1, 1, 1) else: next_month datetime(start_date.year, start_date.month 1, 1) total_days (next_month - start_date).days return round(total_so_far / days_passed * total_days, 2) def main(): year, month 0, 0 if len(sys.argv) 3: year, month int(sys.argv[1]), int(sys.argv[2]) start, end get_month_range(year, month) client boto3.client(ce, region_nameus-east-1) total query_total_cost(client, start, end) services query_cost_by_service(client, start, end) today datetime.utcnow() days_passed (today - datetime.strptime(start, %Y-%m-%d)).days result { period: {start: start, end: end}, total_cost: total, daily_average: round(total / max(days_passed, 1), 2), estimated_monthly_total: estimate_monthly_total(total, start), days_passed: days_passed, top_services: services[:10], query_time: today.strftime(%Y-%m-%d %H:%M:%S UTC), } print(json.dumps(result, indent2, ensure_asciiFalse)) if __name__ __main__: main()4.2 放置文件与赋权mkdir -p ~/.openclaw/workspace/skills/aws-cost-monitor/scripts mkdir -p ~/.openclaw/workspace/skills/aws-cost-monitor/references chmod x ~/.openclaw/workspace/skills/aws-cost-monitor/scripts/check_cost.py4.3 验证依赖与凭证pip install boto3 aws sts get-caller-identity第二条命令返回你的账号 ID 和 ARN说明凭证正常。如果报Unable to locate credentials先配置aws configure。4.4 手动测试脚本python3 ~/.openclaw/workspace/skills/aws-cost-monitor/scripts/check_cost.py正常输出一段 JSON包含total_cost、top_services、estimated_monthly_total等字段。看到这些字段就说明脚本通了。4.5 在 OpenClaw 中触发文件放好后不用重启。直接在对话里说查一下我的 AWS 账单Agent 会匹配 Triggers加载 SKILL.md执行脚本按 Steps 里的格式生成报告。如果没触发检查 Triggers 里有没有覆盖你用的说法。5. 本篇常见错排查5.1 Cost Explorer 只认 us-east-1不管你的资源在哪个区域Cost Explorer API 都必须走 us-east-1。脚本里boto3.client(ce, region_nameus-east-1)这行不能改。我一开始按资源区域传了 ap-northeast-1直接报InvalidParameterValue查了二十分钟才反应过来。5.2 End 日期是排他的查今天的数据End 得写明天。比如查 3 月 1 日到 3 月 15 日End 要写2024-03-16。脚本里已经处理了当前月的情况但如果你手动传月份参数注意这个规则。5.3 数据延迟 24-48 小时新账号或刚产生的费用查出来可能是零。别慌等一两天再看。这是 Cost Explorer 的数据同步机制不是脚本问题。5.4 Triggers 覆盖不全只写了查 AWS 账单用户说这个月云上花了多少就匹配不上。解决办法是把各种口语变体都列进去上线后根据实际对话补充。我后来加了成本分析哪个服务花钱多账单超了没才稳定。5.5 权限不足报AccessDeniedException说明 IAM 用户没有ce:GetCostAndUsage权限。到 IAM 控制台给对应用户附加AWSBillingReadOnlyAccess策略或者自定义一条只含ce:GetCostAndUsage的策略。5.6 config.toml 没被读取脚本默认不读 config.toml需要你在脚本里加解析逻辑。如果只是跑通基础功能可以先硬编码阈值要改阈值时再补上 tomllib 解析。Python 3.11 自带 tomllib低版本用 tomli。6. 进阶技巧与后续动作6.1 定时巡检在HEARTBEAT.md里加一行Agent 心跳时会主动触发- [ ] 每天早上 9:00UTC8执行 AWS 成本监控6.2 Skill 嵌套Steps 里可以引用其他 Skill6. 费用超阈值时使用飞书通知Skill 发送告警6.3 接入模型做趋势分析把成本数据丢给 TaoToken 的 API 做分析在 config.toml 里打开enable_ai_analysis并填好 api_key。脚本会把 JSON 数据发给模型拿回EC2 比上月涨了 30%建议检查闲置实例这类结论。模型对话入口在https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite可以先在那里试一下提示词效果。6.4 条件触发- 每月 1-15 日简要报告 - 每月 16-31 日完整报告含趋势分析 - 月底月度总结对比上月6.5 发布到 ClawHubSkill 调好后可以打包发布SKILL.md 描述写完整脚本不要硬编码敏感信息打包成.skill文件提交。别人也能用你的成本监控技能。从动手到跑通大概 40 分钟。不需要改环境不需要编译写好 Markdown 和 Python 脚本放到目录下就生效。现在每天在对话里说一句查一下账单几秒钟拿到完整报告比手动翻控制台高效太多。如果你也在用 AWS也嫌查账单麻烦可以试试这个方案。有报错先对照第 5 节排查权限和区域这两项最容易出问题。
返回列表