关于 forge-cost-optimizer
一项用于审计和优化 Atlassian Forge 应用的 Agent 技能,旨在降低平台消耗并保持正确性、安全性和可维护性。它优先查找可避免的调用及数据处理,并默认先审计、征求同意后再修改。
主要功能
- 01审计 Forge 应用的成本驱动因素
- 02查找避免调用的机会
- 03减少 API、存储和日志处理
- 04检查触发器与函数内存
- 05维护授权边界与数据安全
- 06提供优先级排序的审计建议
适用场景
- 01在修改前评估 Forge 应用
- 02减少不必要的 resolver 或触发器活动
- 03发现过大的 API 请求和存储操作
- 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。
核心原则
优先采取能减少不必要工作的更改:
- 彻底避免调用 — 将安全的工作移至 UI Kit / Custom UI 前端,使用桥接中的上下文,以事件替代轮询,并添加触发器筛选条件。
- 减少每次调用的工作量 — 批量调用 API、选择字段、在数据源端筛选、分页、尽早退出、限制并发。
- 减少计费数据量 — 精简 resolver 负载、减少 KVS 读写、避免记录大型负载,并在适当情况下使用实体属性。
- 优化计算成本 — 合理设置
memoryMiB,缩短执行时长;只有在运维权衡合理时才卸载计算。
切勿通过削弱授权、向前端暴露机密、跳过必要验证、删除必要的错误处理,或使数据过时程度超出用户业务需求来降低成本。
触发时
当用户要求优化现有 Forge 应用时,除非目标应用目录不明确,否则应立即检查应用,不要先提问。
默认采用先审计的方式: 完成成本优化审计,给出按优先级排序的建议,并询问用户是否希望 Agent 实施建议。除非用户在同一条提示中明确要求实施,例如“进行这些更改”“应用这些优化”“修复这些问题”或“更新代码”,否则在初始审计期间不要修改文件。
按顺序阅读:
manifest.yml/manifest.yaml— 函数、模块、触发器、定时触发器、远程服务、资源、权限、端点映射、memoryMiB。package.json— 依赖项、脚本、Forge 软件包版本。- 后端/resolver 代码 —
src/**、清单中引用的处理程序、存储用法、API 调用、日志记录、异步控制流。 - 前端代码 — UI Kit 或 Custom UI 资源、桥接用法、
invoke()模式、渲染生命周期、缓存、负载需求。 - 描述需要保留的行为的测试或测试夹具。
审计完成后,提供明确的后续选项,例如实施所有快速改进、实施选定的高影响改动,或先收集用量数据。如果用户一开始就明确要求实施,则在了解审计结果后进行安全且局部的改进,并说明权衡。
优化工作流
步骤 1:确定成本概况
识别应用可能涉及的成本驱动因素:
| 驱动因素 | 检查内容 | 常见信号 |
|---|---|---|
| 函数 GB 秒数 | manifest.yml、处理程序 | resolver 调用过多、API 调用按顺序执行且速度慢、memoryMiB 过高、转换开销大 |
| 调用次数 | 前端 invoke()、触发器 | 渲染时发起调用、UI 调用频繁、定时轮询、事件订阅范围过广 |
| KVS / 自定义实体 | storage.* 用法 | 每次请求都写入、遍历键、低 TTL 缓存频繁失效、值过大 |
| 日志 | console.* | 记录完整事件/API 负载、热路径中存在调试日志 |
| Forge SQL | SQL 客户端用法 | 频繁请求计算、查询时间长、存储数据过大 |
| 远程服务 / 出站流量 | remotes、fetch 调用 | 外部轮询、可卸载计算的候选项、对 Runs on Atlassian 的影响 |
如果无法获取用量指标,请用定性等级标注估算:High、Medium、Low 或 Unknown。
步骤 2:寻找可以避免调用的机会
优先移除函数调用,而不是降低调用成本。
检查以下内容:
- 仅用于获取产品上下文的解析器调用。替换为:
- UI Kit:来自
@forge/react的useProductContext() - UI Kit 或 Custom UI:来自
@forge/bridge的view.getContext()
- UI Kit:来自
- 通过解析器发起的只读 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 资格。
- 外部基础设施会产生自身的成本和合规义务。
安全的实现模式
修改代码时:
- 保留原有行为和授权边界。
- 尽量将更改控制在小规模、易于审查的提交中。
- 如果逻辑发生变化,请添加或更新测试。
- 使用项目现有的风格和依赖项;简单实用工具不要添加依赖项。
- 除非用户明确要求,否则避免大规模重写。
- 使用范围最窄且相关的测试或构建命令进行验证。
快速查找模式
搜索以下模式:
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;这是架构权衡,而非简单的成本开关。
- 没有实际使用指标时,不要声称能够精确节省多少成本。