关于 tres-rollup-rules
用于分析组织子交易并提出汇总规则的 Tres Finance Agent 技能,面向需要整理 ERP 交易数据的团队。它依据钱包、资产、平台和方向发现候选项,并要求逐条预览验证。
主要功能
- 01统计子交易并发现重复模式
- 02按钱包、资产、平台和方向分组
- 03检查现有规则以避免重复覆盖
- 04逐条预览并验证候选规则
- 05列出、创建或删除汇总规则
适用场景
- 01为高频交易提出按日或按月汇总规则
- 02发现并筛除零匹配或配置有误的规则
- 03查看或删除已有汇总规则
MCP 相关
通过 TRES Finance MCP connector 执行 GraphQL 查询和变更;技能要求在不确定时先用 validate_query 验证查询。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ claude-plugins-community --skill tres-rollup-rules安装后在 Claude Code 中输入/tres-rollup-rules确认已加载。
附带文件references/proposal-html-template.html
详细介绍
TRES Finance — 汇总规则
分析组织的子交易模式,识别重复交易组,并提出汇总规则,将每个时间间隔内的交易合并为单条记录,以便更整洁地集成到 ERP。这是一个数据驱动的发现流程——从数据中找到候选项,根据真实交易逐一验证,然后展示并创建规则。
汇总规则由四个维度共同确定,这些维度精确界定了它所涵盖的子交易: internalAccount(钱包)+ 资产 KEY + 平台 + balanceFactor(方向)。 可选的区分筛选条件(费用、methodIds、subtxType、金额范围、交易对手)可进一步缩小范围。你发现并提出的所有内容都必须符合此结构——请参阅底部的规则字段参考。
汇总是非破坏性的:原始子交易始终会保留,并在汇总明细报告中显示。
所有 GraphQL 操作都通过 TRES Finance MCP connector(execute 工具;不确定时先用 validate_query 验证)。所有变量键和嵌套输入字段都必须使用 camelCase(例如 internalAccountId、balanceFactor),绝不能使用 snake_case。
路由
- “建议 / 创建 / 提出汇总规则”、“交易太多”、“汇总 X” → 运行完整的发现流程(下方步骤 0–6)。这是主要流程。
- “显示 / 列出我的汇总规则” → 第 A 节(列出现有规则),然后停止。
- “删除汇总规则” → 第 C 节(删除规则)。
- “审核此特定规则” / “此规则会匹配什么” → 转交给 tres-rollup-review 技能。
步骤 0 — 确认范围
与用户确认范围,但保持简洁——只有分析范围受限,规则本身通常不设限制。
分析时间范围(可选)
时间段只会缩小发现查询的范围,以便查看近期且具有代表性的活动。它不是必需项,也不是规则的日期范围。
- “Q1 2025” → 开始:
2025-01-01T00:00:00Z,结束:2025-03-31T23:59:59Z - “最近 3 个月” → 根据今天计算
如果用户没有指定时间段,则分析所有历史数据——这完全可以,也是常见做法。
规则日期范围(优先不设范围)
创建的规则通常不应设置开始 / 结束日期——默认从“时间起点开始,永久生效”,以便持续捕获之后符合条件的交易。只有用户明确要求限制规则范围时,才设置 startDate/endDate。
钱包(可选,默认:全部)
用户可以限定特定钱包。
资产类别(可选,默认:所有非垃圾资产)
用户可以限定特定资产类别(例如“仅稳定币”、“ETH”)。请注意,一个类别(例如 USDC)可能包含许多资产键 / 链,但每条规则只针对一个键——请参阅步骤 2 中的资产类别映射。
聚类指导(可选)
例如“重点关注 Gas 费”、“忽略低于 $10 的质押奖励”、“按 methodId 对 ETH 转账分组”。
简要确认范围,然后开始:
“我会检查所有钱包和所有资产中的汇总候选项(分析所有历史数据)。除非你希望限制日期范围,否则我提出的规则都将不设结束日期。 现在开始。”
步骤 1 — 清点
运行以下操作(尽可能并行)。
1a. 钱包
query Wallets { internalAccount { totalCount results { id name identifier parentPlatform platforms balancesCount status } } }
收集钱包 id(整数)——这是规则的 internalAccountId。使用 platforms(复数列表)和 parentPlatform(字符串);钱包没有单数的 platform 字段。
1b. 现有汇总规则(避免重复覆盖)
query ExistingRules { subTransactionRollupRule { totalCount results { id name interval status startDate endDate createdBy lastSuccessfulRunAt rule } } }
rule 是 JSON 配置(internal_account_id、asset_id、platform、balance_factor、fees 等)。记录已由 Active 或 Pending 规则覆盖的(账户、assetKey、方向)组合——跳过这些组合。忽略 Disabled 规则(它们是已被取代的旧版本,不属于当前生效的覆盖范围)。同时查看此处现有规则的名称,了解组织的命名惯例(见下方“命名”)。
1c. 范围内的子交易总数
query InScope($ts_Gte: DateTime, $ts_Lte: DateTime) {
subTransaction(timestamp_Gte: $ts_Gte, timestamp_Lte: $ts_Lte) { totalCount }
}
(分析所有历史记录时,完全省略时间戳参数。)
报告:“找到 X 个钱包、Y 条现有规则(其中 Z 条处于启用状态),范围内有 N 笔子交易。”
步骤 2 — 发现(核心分析)
使用聚合查询,找出重复交易量最大的(钱包、资产、方向)组,然后深入分析区分性筛选条件。
筛选条件名称参考(已验证 — 请使用这些确切名称)
- 钱包:
belongsTo_In: [ID](数组,即使只有一个 ID) - 按键筛选资产:
asset_In: [ID](资产 KEY 数组,例如["ethereum_native"]) - 资产类别:
asset_AssetClass_In: [ID] - 方向:
balanceFactor: Float(-1= OUTFLOW,1= INFLOW) - 金额:
amount_Gte/amount_Lte;法币金额:fiatValue_Gte/fiatValue_Lte - 交易对手:
sender_Identifier_In: [String]、recipient_Identifier_In: [String] - 方法:
tx_MethodId: String(单个值),或按tx__method_id分组 - 子交易类型:
type: String/type_In: [String](FinancialAction)——使用 小写值进行筛选("gas"、"reward"等);注意,这与变更中的大写subtxType枚举值正好相反。groupBy: ["type"]也可用。 - 日期:
timestamp_Gte/timestamp_Lte - 排除已汇总的子交易:
excludeRollups: true - 排除 Gas/手续费子交易:
excludeGasFees: true;排除垃圾交易:excludeSpam: true - 仅限内部转账:
internalTransfer: true
始终排除已汇总的子交易
在每个发现/计数查询中添加 excludeRollups: true。此参数会剔除 ROLLUP / ROLLUP_FEE
子交易,因此计数反映新规则实际会捕获的内容,与汇总引擎自身的筛选方式一致。如果不添加,先前规则已汇总的组会被重复计数。(onlyRollup: false 不会起到此作用——它是空操作。)若要检查现有规则的处理结果,请查询 type_In: ["rollup", "rollup_fee"], typeId: "<rule_id>"——只有与 rollup 类型搭配时,typeId 才表示汇总规则 ID。
2a. 按规则的实际键分组(钱包 ID + 资产键 + 平台 + 方向)
query GroupByKey($ts_Gte: DateTime, $ts_Lte: DateTime) {
subTransaction(
timestamp_Gte: $ts_Gte, timestamp_Lte: $ts_Lte,
excludeRollups: true,
groupBy: ["belongs_to", "asset", "platform", "balance_factor"],
aggregations: [
{ field: id, function: COUNT, alias: "count" },
{ field: fiatValue, function: AVG, alias: "avgFiat" }
]
) {
groupedAggregations { groupKey results { alias value } }
}
}
groupKey 会提供钱包 ID(→ internalAccountId)、资产 键(→
assetId)、平台和 balanceFactor——这正是规则所需的四个字段,无需猜测名称/符号。子交易少于约 50 笔的组通常不值得创建规则。
资产类别桥接
用户会按资产 类别 提出需求(“汇总我们所有的 USDC”),而规则针对的是单个资产 键。
当用户按类别限定范围时,你可以先按 asset__asset_class__symbol 分组以确定优先级,但随后必须将每个有价值的类别展开为具体资产键(步骤 2a 已返回这些键),并为每个(钱包、assetKey、平台、方向)提议一条规则。在报告中,列出同一钱包下的同类键,让用户了解每条规则涵盖和未涵盖的变体。
2b. 按 methodId 深入分析(针对每个重要组)
query DrillMethod($ts_Gte: DateTime, $ts_Lte: DateTime, $belongsTo_In: [ID], $asset_In: [ID], $balanceFactor: Float) {
subTransaction(
timestamp_Gte: $ts_Gte, timestamp_Lte: $ts_Lte,
belongsTo_In: $belongsTo_In, asset_In: $asset_In, balanceFactor: $balanceFactor,
excludeRollups: true,
groupBy: ["tx__method_id"],
aggregations: [
{ field: id, function: COUNT, alias: "count" },
{ field: amount, function: AVG, alias: "avgAmount" },
{ field: amount, function: MAX, alias: "maxAmount" }
]
) {
groupedAggregations { groupKey results { alias value } }
}
}
2c. 按子交易类型深入分析(可选)
使用 groupBy: ["type"] 重复相同的查询结构,查看特定子交易类型是否在该组中占主导地位——仅当你打算使用 subtxType 规则时才有用。
分析策略
思考哪些组合能构成最佳规则:
- 覆盖率 — 每条规则都应覆盖其所属组中有意义的一部分。
- 区分性筛选条件(有用时使用,并非必需) — 四个关键字段(wallet +
assetKey + platform + direction)加上
fees已足以完整定义大多数规则。只有在 能细化异质组时,才添加可选的收窄筛选条件(methodIds、金额上下限、对手方或subtxType)——许多优质规则一个筛选条件也不用。尤其是subtxType,它是可选的; 不要不加思考就添加。 - 时间间隔 — 高频组(>~500 个子交易)使用 DAY,其他情况使用 MONTH。
- 现有规则 — 跳过已被 Active/Pending 规则覆盖的(account、assetKey、direction)
元组。绝不要仅根据现有规则当前的匹配数来判断其效果:运行中的规则已经汇总了
自己的交易池,因此剩下的实时(非汇总)子交易只是最近尚未处理的少数几笔——一条
高效运行的规则看起来可能无事可做。要了解规则实际处理了多少笔,请统计其生成的汇总:
subTransaction(type_In: ["rollup","rollup_fee"], typeId: "<rule_id>")。只有当一条规则 几乎没有生成汇总且当前几乎没有匹配项时,才将其视为无效。 - 重叠(宽松处理) — 同一 wallet + assetKey + platform + direction 上,筛选条件 不互斥的两条规则可能会匹配到相同的子交易。这并非致命问题:引擎会按 id(PK) 确定性地处理规则,因此同一笔子交易总会由同一条规则处理。优先选择互不重叠的规则, 但重叠只需备注,不会阻止采用。
对每个候选规则,说明选择此组合的原因。
步骤 2.5 — 验证候选规则(强制质量关卡)
此时,N 个候选规则对象(来自步骤 2)已在上下文中。调用一次
tres-rollup-review 技能(通过 Skill 工具)**——这会将审查检查项加载到你自己的
上下文中(它不是单独的 Agent,且不需要参数;候选规则已在此处,无需传递)。然后按照
其中的说明,逐个检查候选规则——对每个候选规则运行审查中的检查 1(调用一次
subTransactionRollupRulePreview)、检查 2 和检查 3,并记录每个候选规则的结论:
PASS / DROP / FIX,同时记录准确的子交易数和父交易数。因此,10 个候选规则 →
10 次预览调用 → 10 个结论。
根据检查结果采取行动:
- DROP 匹配到 0 笔子交易的任何候选规则(该规则将不起作用)。
- FIX 配置问题(日期范围颠倒、最小值 > 最大值、标识符用于错误方向、 前缀互斥、cutoffTime 错误)。
- 在报告中注明与其他候选规则或 Active/Pending 规则的任何重叠情况 — 重叠仅供参考(引擎会按 id 确定性地处理),因此只有在用户希望划分更清晰时才调整; 不要仅因重叠而删除候选规则。
被 DROP 或存在尚未解决的 FIX 问题的候选规则不得进入步骤 3。此关卡能确保建议质量; 不要跳过。
命名汇总规则
每条拟议规则都需要一个清晰、一致的 name。按以下方式决定:
- 优先遵循组织现有的命名惯例。 根据你在步骤 1b 中获取的 Active/Pending 规则名称,推断组织的命名模式——分隔符、字段顺序、大小写,以及方向/费用/间隔的表示方式——并以相同方式命名新规则,使其自然融入现有规则。
- 如果没有明确的现有模式,默认使用:
<wallet name> - <asset symbol> - <direction> <fees label>,并追加(<interval>),其中费用标签对应关系如下:fees: ONLY→fees(例如,“gas fees”)fees: INCLUDE→include feesfees: EXCLUDE→exclude fees示例:EVM Exec Wallet 1 - ETH - outflow fees (monthly)。如果某个能区分规则的筛选条件定义了整条规则(例如,已知方法),将其纳入名称(例如,… - LP exits (daily))。
确保名称易于理解,并且在提案集合中唯一。在 HTML 报告、提案表格和创建变更的 name 字段中使用相同名称。
步骤 3 — 展示结果
3a. HTML 提案报告
在工作目录中写入独立的 .html 文件(例如
rollup-rules-proposal.html),并告知用户文件路径,以便他们打开。逐字使用
references/proposal-html-template.html 中的模板和模式——原样复制 CSS 和骨架,仅将 `` 注释替换为实际数据行。不要重新生成 CSS 或布局。该参考文件说明了摘要卡片、拟议规则表格、已跳过规则表格、每位候选项的 “Preview matched txs” 账本链接、影响徽章,以及哈希/地址的显示规则。保持 HTML 简洁(正文目标为 4000 个 token 以下)。
该参考文件中的以下关键内容规则在此特别说明,因为它们很重要:
- Volume 列始终为
Volume (sub-tx / tx),数值始终以~为前缀(例如,~1,240 / ~310)——这些数值是经 rollup_review 验证的 sub-tx 数量和不同 parent-tx 数量;~表示 Preview 链接的账本筛选条件无法精确表达每一项规则筛选条件。 - 影响徽章:高交易量是好结果,绝不是警报——HIGH 用绿色,MEDIUM 用靛蓝色,LOW 用灰色。红色仅用于实际问题(🟢/🟡/🔴 验证状态),绝不用作影响等级。
- 已跳过规则表格:纳入被 rollup_review 门槛筛掉的候选项(例如,“0 matching sub-txs”“overlaps rule #38211”)。
3b. 提案任务表格
在聊天中提供一个带编号的 Markdown 表格——每条拟议规则占一行——以便用户按编号批准。列:#、Rule Name、Wallet (id)、Asset / Platform、Direction、Filter、Volume (sub-tx / tx)、Interval、Validated Impact。优先级提示:超过 1000 个 sub-tx 为 HIGH,200–1000 个为 MEDIUM,少于 200 个为 LOW。
步骤 4 — 用户审核
询问用户:
“我拟议了 X 条汇总规则(均已根据真实交易验证)。请查看上方的报告和表格。你可以:
- 全部批准——我将创建所有拟议规则
- 批准指定规则——告诉我对应编号
- 提供反馈——告诉我需要调整什么,我会重新分析
- 取消——不会创建任何规则”
在继续之前等待用户回复。未经明确确认,绝不创建规则。
第 5 步 — 创建规则
对于已批准的规则,通过 MCP execute 工具调用 createSubTransactionRollupRules 变更(该工具接受批量请求,并返回逐条规则的结果及验证问题):
mutation CreateRollupRules($rules: [RollupRuleCreationRequest]!) {
createSubTransactionRollupRules(rules: $rules) {
results {
rollupRuleId
validationIssues { blocking type message }
}
}
}
$rules 中的每个条目(全部使用 camelCase):
{
"name": "ETH outflow gas — wallet-1 (daily)",
"interval": "DAY",
"createdBy": "AI",
"rule": {
"internalAccountId": 123,
"assetId": "ethereum_native",
"platform": "ETHEREUM",
"balanceFactor": "OUTFLOW",
"fees": "ONLY",
"methodIds": ["0x573ade81"]
}
}
- 始终设置
createdBy: "AI",以便在审计记录中将规则归于 AI。 - 除非用户希望限定规则的有效期限,否则省略
startDate/endDate——省略后规则将没有期限限制。 - 仅包含用户或分析实际设置的可选筛选字段——不要为未使用的可选字段发送
null,只需在rule对象中省略它们。 - 优先创建新规则。支持编辑现有的 PENDING 规则(通过顶层的
ruleId: <id>),但待处理规则可能会在延迟后自动获批,因此原位编辑可能与激活操作发生竞争——只有用户明确要求时才编辑待处理规则。
枚举值(GraphQL 枚举,在查询中不加引号):
interval:DAY或MONTHplatform:大写 —ETHEREUM、BASE、SOLANA、BITCOIN、…balanceFactor:INFLOW(流入,+1)或OUTFLOW(流出,-1)fees:INCLUDE(交易及其费用)、EXCLUDE(不含费用的交易)、ONLY(仅费用子交易——选取 GAS 和 FEE)。对于 gas/fee 汇总规则,单独使用fees: ONLY;不要同时设置subtxType: GAS/FEE——ONLY已涵盖它们,添加subtxType: GAS是多余的,而且会错误地排除 FEE 子交易。subtxType:FinancialAction枚举或 null — 例如REWARD、NATIVE_TRANSFER、TOKEN_TRANSFER。gas/fee 汇总规则留空(改用fees: ONLY)。createdBy:AI
**平台大小写:**查询筛选条件中使用小写(subTransaction(asset_In: [...])、asset(platform: "ethereum"));变更输入中使用大写枚举(rule.platform: ETHEREUM)。查询返回值也使用大写。
服务强制执行的验证规则(绝不能提出违反这些规则的规则):
senderIdentifier仅适用于 INFLOW 规则;recipientIdentifier仅适用于 OUTFLOW 规则(对于流出交易,发送方始终是你的钱包,流入交易则相反)。senderIdentifier⊥originalSenderPrefix;recipientIdentifier⊥originalRecipientPrefix(两者互斥)。startDate必须早于endDate。- 组织中不得已存在完全相同的规则(
ruleJSON 相同)。
该变更还会重新检查匹配的交易和重叠情况,并将结果作为 validationIssues 返回——rollup_review 门控步骤应已发现这些问题,但服务拥有最终决定权。
解析 assetId 和 internalAccountId
internalAccountId(整数):取自第 1 步的钱包清单。assetId是资产键 ="<platform_lowercase>_<identifier>"。原生代币:ethereum_native、base_native、solana_native。ERC-20:ethereum_0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48(USDC)。第 2a 步已在 groupKey 中返回键;否则请查询:
query AssetKeys { asset(key_In: ["ethereum_native"]) { results { key identifier platform symbol name parentPlatform } } }
第 6 步 — 报告结果
对于批量响应中的每条规则结果,使用颜色标记结果,让用户一眼看到状态——🟢 绿色 = 已创建且无问题,🟡 黄色 = 已创建,但存在非阻塞验证问题,🔴 红色 = 已阻止 / 未创建:
- 存在
rollupRuleId,且没有validationIssues→ 🟢 已创建 - 存在
rollupRuleId,且只有非阻塞validationIssues→ 🟡 已创建,已注明问题 - 存在任何
blocking: true的validationIssues(没有rollupRuleId)→ 🔴 失败,引用message
已创建的规则初始状态为 PENDING,并在下一个处理周期激活。在第 3 步报告中展示每条拟议规则的 rollup_review 验证结果时,也使用相同的 🟢/🟡/🔴 标记。
A. 列出现有汇总规则
当用户只是想查看当前规则时:
query ListRollupRules($limit: Int, $offset: Int, $status_In: [String]) {
subTransactionRollupRule(limit: $limit, offset: $offset, status_In: $status_In) {
totalCount
results { id name interval startDate endDate nextActivationDate status rule }
}
}
变量:{"limit": 50, "offset": 0}(添加 status_In: ["Active"] 等条件进行筛选;
状态值首字母大写)。以编号 Markdown 表格呈现:名称、ID、状态、间隔、
日期范围(或“无限期”)以及关键规则筛选条件(钱包、资产、方向、费用和任何
可选筛选条件)。如果 totalCount > 50,请分页。
C. 删除汇总规则
只能通过 API 删除 PENDING 规则。删除 Active 规则需要 TRES 支持。
首先列出规则(第 A 节),让用户确认要删除哪些规则,然后在删除前确认 规则 ID。
mutation DeleteRollupRules($ruleIds: [Int]!) {
deleteSubTransactionRollupRules(ruleIds: $ruleIds) {
results { deletedIds failures { ruleId reason } }
}
}
报告 deletedIds(成功删除的 ID)和 failures(包括原因——通常是因为规则
已处于 Active 状态)。
规则字段参考(RollupRule)
必填: internalAccountId(int)、assetId(资产键)、platform(枚举)、
balanceFactor(INFLOW/OUTFLOW)、fees(INCLUDE/EXCLUDE/ONLY)。
可选(有安全默认值——仅在需要时设置): senderIdentifier、
recipientIdentifier、originalSenderPrefix、originalRecipientPrefix、methodIds
(列表)、maxAmount、minAmount、excludeFiat(默认为 false)、excludeInternal(默认为
false)、subtxType(FinancialAction)、bufferInDays(默认为 0;等待迟到交易的天数)、
cutoffTime("HH:MM")、rollupInternalTransfersOnly(默认为 false;
为 true 时,仅汇总内部转账,且汇总项会与其流入项配对——系统还会设置
mergeWithInflowTx 和 runInternalTransferClassificationOnRollups)。
顶层请求字段: name(必填)、interval(必填)、rule(必填)、
startDate(可选)、endDate(可选)、ruleId(可选——编辑待处理规则)、
createdBy(设置为 AI)。
FinancialAction 枚举值(用于 subtxType): TRACE_TRANSFER、TOKEN_TRANSFER、
NATIVE_TRANSFER、DELEGATION、UNDELEGATION、VEST、UNVEST、VALIDATOR_CREATION、REWARD、
COMMISSION、GAS、FEE、EXCHANGE_WITHDRAWAL、EXCHANGE_DEPOSIT、EXCHANGE_TRANSFER、
EXCHANGE_BUY、EXCHANGE_SELL、EXCHANGE_LOAN、EXCHANGE_SETTLEMENT、REBATE、FIAT_TRANSFER、
BURNED、ROLLUP、ROLLUP_FEE、PLUG、GROUP、FUNDING、INTEREST、TRANSFER_DELEGATION_REWARD、
REEVALUATION、PAYMENT、BANK_DEPOSIT、BANK_WITHDRAWAL、MINING_REWARD。
规则
- 保持上下文精简——使用聚合查询,切勿获取完整结果集。
- 尽可能并行运行发现查询。
- 呈现结果前,务必运行第 2.5 步 rollup_review 门控。
- 分析后,务必同时生成 HTML 报告和提案表格。
- 说明每条拟议规则的理由。
- 创建前务必确认——先呈现完整提案,并等待用户明确批准,再调用创建变更操作。
- 呈现报告后,提供简短的对话式总结。
- 选择维度时,纳入用户提供的聚类指导。
限制——MCP 不支持
- 编辑 Active 规则——无法编辑 Active 规则;需要重新创建(PENDING 规则可通过
ruleId编辑,也可删除后重新创建)。 - 激活/停用规则——由后端处理流水线管理,无法通过 API 直接控制。
- 查看汇总明细——被聚合的原始交易明细可在 TRES 控制面板的 Rollup Breakdown 报告中查看。
- 删除 Active 规则——只能通过 API 删除 PENDING 规则;如需删除 Active 规则,请联系 TRES 支持。