mcpField
T
tres-rollup-rules

tres-rollup-rules

github.com/anthropics数据与数据库4.8k50 次安装2 周前更新
代码仓库

关于 tres-rollup-rules

用于分析组织子交易并提出汇总规则的 Tres Finance Agent 技能,面向需要整理 ERP 交易数据的团队。它依据钱包、资产、平台和方向发现候选项,并要求逐条预览验证。

主要功能

  1. 01统计子交易并发现重复模式
  2. 02按钱包、资产、平台和方向分组
  3. 03检查现有规则以避免重复覆盖
  4. 04逐条预览并验证候选规则
  5. 05列出、创建或删除汇总规则

适用场景

  1. 01为高频交易提出按日或按月汇总规则
  2. 02发现并筛除零匹配或配置有误的规则
  3. 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 规则时才有用。

分析策略

思考哪些组合能构成最佳规则:

  1. 覆盖率 — 每条规则都应覆盖其所属组中有意义的一部分。
  2. 区分性筛选条件(有用时使用,并非必需) — 四个关键字段(wallet + assetKey + platform + direction)加上 fees 已足以完整定义大多数规则。只有在 能细化异质组时,才添加可选的收窄筛选条件(methodIds、金额上下限、对手方或 subtxType)——许多优质规则一个筛选条件也不用。尤其是 subtxType,它是可选的; 不要不加思考就添加。
  3. 时间间隔 — 高频组(>~500 个子交易)使用 DAY,其他情况使用 MONTH。
  4. 现有规则 — 跳过已被 Active/Pending 规则覆盖的(account、assetKey、direction) 元组。绝不要仅根据现有规则当前的匹配数来判断其效果:运行中的规则已经汇总了 自己的交易池,因此剩下的实时(非汇总)子交易只是最近尚未处理的少数几笔——一条 高效运行的规则看起来可能无事可做。要了解规则实际处理了多少笔,请统计其生成的汇总: subTransaction(type_In: ["rollup","rollup_fee"], typeId: "<rule_id>")。只有当一条规则 几乎没有生成汇总且当前几乎没有匹配项时,才将其视为无效。
  5. 重叠(宽松处理) — 同一 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。按以下方式决定:

  1. 优先遵循组织现有的命名惯例。 根据你在步骤 1b 中获取的 Active/Pending 规则名称,推断组织的命名模式——分隔符、字段顺序、大小写,以及方向/费用/间隔的表示方式——并以相同方式命名新规则,使其自然融入现有规则。
  2. 如果没有明确的现有模式,默认使用: <wallet name> - <asset symbol> - <direction> <fees label>,并追加 (<interval>),其中费用标签对应关系如下:
    • fees: ONLY → fees(例如,“gas fees”)
    • fees: INCLUDE → include fees
    • fees: 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 或 MONTH
  • platform:大写 — 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。
  • 组织中不得已存在完全相同的规则(rule JSON 相同)。

该变更还会重新检查匹配的交易和重叠情况,并将结果作为 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 不支持

  1. 编辑 Active 规则——无法编辑 Active 规则;需要重新创建(PENDING 规则可通过 ruleId 编辑,也可删除后重新创建)。
  2. 激活/停用规则——由后端处理流水线管理,无法通过 API 直接控制。
  3. 查看汇总明细——被聚合的原始交易明细可在 TRES 控制面板的 Rollup Breakdown 报告中查看。
  4. 删除 Active 规则——只能通过 API 删除 PENDING 规则;如需删除 Active 规则,请联系 TRES 支持。

评论

支持 Markdown