mcpField
F
forge-cost-optimizer

forge-cost-optimizer

github.com/atlassian云与 DevOps27381 次安装1 周前更新
代码仓库

关于 forge-cost-optimizer

一项用于审计和优化 Atlassian Forge 应用的 Agent 技能,旨在降低平台消耗并保持正确性、安全性和可维护性。它优先查找可避免的调用及数据处理,并默认先审计、征求同意后再修改。

主要功能

  1. 01审计 Forge 应用的成本驱动因素
  2. 02查找避免调用的机会
  3. 03减少 API、存储和日志处理
  4. 04检查触发器与函数内存
  5. 05维护授权边界与数据安全
  6. 06提供优先级排序的审计建议

适用场景

  1. 01在修改前评估 Forge 应用
  2. 02减少不必要的 resolver 或触发器活动
  3. 03发现过大的 API 请求和存储操作
  4. 04检查计算与日志成本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/atlassian/forge-skills --skill forge-cost-optimizer

安装后在 Claude Code 中输入/forge-cost-optimizer确认已加载。

附带文件README.md

详细介绍

Forge 成本优化器

在保持正确性、安全性和可维护性的同时,优化 Forge 应用以降低平台用量。本技能将 Atlassian 的 Forge 成本优化指南转化为可执行的 Agent 工作流。

指南来源

建议应以 Atlassian 官方指南为依据:https://developer.atlassian.com/platform/forge/optimise-forge-costs/

如果可以使用实时 Forge 文档工具,在更改依赖当前清单语法、桥接 API、存储 API、触发器筛选条件或 Forge Remote 行为的代码之前,请先在 Forge 文档中搜索相应模块或 API。

核心原则

优先采取能减少不必要工作的更改:

  1. 彻底避免调用 — 将安全的工作移至 UI Kit / Custom UI 前端,使用桥接中的上下文,以事件替代轮询,并添加触发器筛选条件。
  2. 减少每次调用的工作量 — 批量调用 API、选择字段、在数据源端筛选、分页、尽早退出、限制并发。
  3. 减少计费数据量 — 精简 resolver 负载、减少 KVS 读写、避免记录大型负载,并在适当情况下使用实体属性。
  4. 优化计算成本 — 合理设置 memoryMiB,缩短执行时长;只有在运维权衡合理时才卸载计算。

切勿通过削弱授权、向前端暴露机密、跳过必要验证、删除必要的错误处理,或使数据过时程度超出用户业务需求来降低成本。

触发时

当用户要求优化现有 Forge 应用时,除非目标应用目录不明确,否则应立即检查应用,不要先提问。

默认采用先审计的方式: 完成成本优化审计,给出按优先级排序的建议,并询问用户是否希望 Agent 实施建议。除非用户在同一条提示中明确要求实施,例如“进行这些更改”“应用这些优化”“修复这些问题”或“更新代码”,否则在初始审计期间不要修改文件。

按顺序阅读:

  1. manifest.yml / manifest.yaml — 函数、模块、触发器、定时触发器、远程服务、资源、权限、端点映射、memoryMiB。
  2. package.json — 依赖项、脚本、Forge 软件包版本。
  3. 后端/resolver 代码 — src/**、清单中引用的处理程序、存储用法、API 调用、日志记录、异步控制流。
  4. 前端代码 — UI Kit 或 Custom UI 资源、桥接用法、invoke() 模式、渲染生命周期、缓存、负载需求。
  5. 描述需要保留的行为的测试或测试夹具。

审计完成后,提供明确的后续选项,例如实施所有快速改进、实施选定的高影响改动,或先收集用量数据。如果用户一开始就明确要求实施,则在了解审计结果后进行安全且局部的改进,并说明权衡。

优化工作流

步骤 1:确定成本概况

识别应用可能涉及的成本驱动因素:

驱动因素检查内容常见信号
函数 GB 秒数manifest.yml、处理程序resolver 调用过多、API 调用按顺序执行且速度慢、memoryMiB 过高、转换开销大
调用次数前端 invoke()、触发器渲染时发起调用、UI 调用频繁、定时轮询、事件订阅范围过广
KVS / 自定义实体storage.* 用法每次请求都写入、遍历键、低 TTL 缓存频繁失效、值过大
日志console.*记录完整事件/API 负载、热路径中存在调试日志
Forge SQLSQL 客户端用法频繁请求计算、查询时间长、存储数据过大
远程服务 / 出站流量remotes、fetch 调用外部轮询、可卸载计算的候选项、对 Runs on Atlassian 的影响

如果无法获取用量指标,请用定性等级标注估算:High、Medium、Low 或 Unknown。

步骤 2:寻找可以避免调用的机会

优先移除函数调用,而不是降低调用成本。

检查以下内容:

  • 仅用于获取产品上下文的解析器调用。替换为:
    • UI Kit:来自 @forge/react 的 useProductContext()
    • UI Kit 或 Custom UI:来自 @forge/bridge 的 view.getContext()
  • 通过解析器发起的只读 Jira/Confluence API 调用,即使可以接受以用户上下文访问。考虑使用来自 @forge/bridge 的 requestJira() / requestConfluence()。
  • 解析器中的格式化、排序、分组、客户端安全验证或仅用于 UI 的转换。如果数据已获授权,可在前端处理。
  • 渲染主体中的 invoke() 调用、无界副作用、重复的事件处理程序,或页面加载时可缓存或批处理的多个调用。

当逻辑需要 asApp()、Forge 存储、机密信息、外部凭据、跨用户授权检查或敏感业务规则时,应保留在后端。

步骤 3:优化触发器和调度

检查 scheduledTrigger、trigger 和 webtrigger 模块。

建议的更改:

  • 在业务需求允许时,延长定时触发器的间隔(fiveMinutes → hour → day → week)。
  • 将定时轮询 Atlassian 产品变更替换为产品事件。
  • 如果外部服务支持 Webhook,则将定时轮询外部服务替换为通过 Forge Web 触发器接收的入站 Webhook。
  • 添加 manifest filter.expression,在调用前过滤掉无关的产品事件。
  • 对于可能处理应用自身所触发事件的 Jira 触发器,添加 filter.ignoreSelf: true。
  • 在处理程序开头添加低成本的提前退出逻辑,避免 API 调用、存储读取或耗时转换。
  • 使用 Forge Realtime 替代前端轮询循环,避免反复调用解析器等待后端状态变化。
步骤 4:优化 API 和数据获取

函数中的每个 API 请求都会增加执行时长。请检查以下内容:

  • N+1 调用。将逐项获取替换为批量端点或可返回所需字段的搜索 API。
  • 缺少 fields、expand、limit 或 maxResults 限制。仅请求应用会用到的数据。
  • 获取全部数据后再过滤。将筛选条件下推到 JQL、CQL、REST 查询参数或存储索引中。
  • 相互独立的顺序调用。使用 Promise.all 或有界并发。
  • 无界并发。批处理大型工作负载以避免触发速率限制;除非文档或测试有充分依据,否则并发请求数控制在约 5–10 个。
  • 解析器响应过大。仅返回 UI 使用的字段。
步骤 5:优化存储

KVS 和 Custom Entity 的读写量超过免费额度后会产生费用;写入的成本远高于读取。

请检查以下内容:

  • 每次调用都写入,即使值没有变化。写入前比较值,或对写入进行防抖。
  • 对很少变化的数据使用过短的缓存 TTL。只要能接受数据过时,就优先使用较长的 TTL。
  • 在循环中读写存储。批处理、调整键结构,或使用 Custom Entities 查询。
  • 使用 storage.query().getMany() 后再在内存中过滤。改用 .index(...)、.where(...)、.limit(...) 和游标分页。
  • 需要的数据只有一小部分,却存储了较大的值。存储经过规范化或裁剪的值。
  • 将非敏感的小型单问题/页面元数据存储在 KVS 中。可以考虑改用 Jira 实体属性或 Confluence 内容属性,同时注意其可见性和 32 KB 的大小限制。

请勿将敏感或机密数据移至实体/内容属性,因为它们可能会通过产品 REST API 暴露。

第 6 步:优化日志记录

查找 console.log、console.info、console.warn、console.error 和结构化日志记录器调用。

建议的更改:

  • 在生产环境的热点路径中移除调试日志,或为其添加开关。
  • 切勿记录完整的事件负载、API 响应、存储值、机密、令牌、个人数据或大型 JSON 字符串。
  • 保留简洁的错误日志和有意义的状态变更日志。
  • 仅在有用时添加由环境变量控制的调试日志,例如 process.env.DEBUG_LOGGING === 'true'。
第 7 步:调整函数内存

检查 manifest.yml 中的函数条目。

  • 成本模型为 GB 秒:(memoryMiB / 1024) × durationSeconds。
  • 只有在考虑性能和测试覆盖率后,才降低轻量解析器的内存。
  • 如果降低内存会延长运行时间或导致故障,则应为大型负载处理保留或增加内存。
  • 优先依据证据:日志、性能分析、基准测试结果或真实的本地测试。
  • 如果缺少证据,应建议进行测量,而不是猜测并激进地减少内存。
第 8 步:谨慎评估 Forge Remote

对于合适的工作负载,Forge Remote 可以免去 Forge 函数执行,但这会将责任转移给外部运营的基础设施。

仅在符合以下一项或多项条件时,才建议使用 Forge Remote:

  • 长时间运行的工作超出标准 Forge 函数限制。
  • 计算密集型处理在成本或运行时间中占主导地位。
  • 团队已运营安全的后端,且该后端应负责处理相关逻辑。
  • 存储或查询需求确实超出 Forge 平台的能力范围。

务必说明其中的权衡:

  • 团队必须保护、扩展、监控、修补并运营远程后端。
  • 远程架构可能会影响 Runs on Atlassian 资格。
  • 外部基础设施会产生自身的成本和合规义务。

安全的实现模式

修改代码时:

  1. 保留原有行为和授权边界。
  2. 尽量将更改控制在小规模、易于审查的提交中。
  3. 如果逻辑发生变化,请添加或更新测试。
  4. 使用项目现有的风格和依赖项;简单实用工具不要添加依赖项。
  5. 除非用户明确要求,否则避免大规模重写。
  6. 使用范围最窄且相关的测试或构建命令进行验证。

快速查找模式

搜索以下模式:

invoke(
useAction(
useEffect(
requestJira(
requestConfluence(
asApp().requestJira
asUser().requestJira
storage.get
storage.set
storage.query
console.log
console.info
scheduledTrigger
ignoreSelf
memoryMiB
Promise.all
for await
for (

仔细解读结果;匹配到某个模式并不意味着它一定有问题。

输出格式

对于默认采用先审计再处理的请求,返回审计结果,并在结尾提出可以落实建议的更改:

# Forge Cost Optimization Audit

## Summary
- Overall opportunity: High | Medium | Low
- Highest-impact lever: <invocations | duration | storage | logs | memory | remote>
- Files inspected: <list>

## Prioritized Opportunities
1. [High] <title>
   - Evidence: `<file:line>` and observed pattern
   - Why it costs money: <cost driver>
   - Recommended change: <specific fix>
   - Safety notes: <authorization/data freshness/trade-offs>

## Quick Wins
- <low-risk change>

## Needs Measurement
- <changes that require usage metrics or profiling>

## Recommended Next Step
Would you like me to implement the quick wins, implement selected high-impact changes, or collect usage measurements first?

对于用户明确要求实现的请求,返回:

# Forge Cost Optimization Complete

## Changes Made
- <file>: <change and cost driver reduced>

## Validation
- <commands run and results>

## Expected Impact
- <qualitative or measured impact>

## Follow-ups
- <optional deeper optimizations or metrics to collect>

应避免的反模式

  • 不要将特权 asApp() 操作移到前端。
  • 不要在浏览器代码中暴露机密、应用凭证或仅管理员可访问的数据。
  • 不要使用实体属性存储敏感数据。
  • 不要移除生产事故诊断所需的日志;应降低日志详细程度。
  • 不要将缓存 TTL 增加到超出产品可接受的新鲜度要求。
  • 不要默认建议使用 Forge Remote;这是架构权衡,而非简单的成本开关。
  • 没有实际使用指标时,不要声称能够精确节省多少成本。

评论

支持 Markdown