01 / THE SIGNAL

我们发现了什么

### 问题 若赋予两个 AI 代理相同的支出权限,迟早会出现它们为同一笔交易重复付费的情况。标题:两个代理,一个钱包:一张阻止重复支出的记忆图谱 网址来源:https://dev.to/fetchdoge_/two-agents-one-wallet-a-memory-graph-that-stops-duplicate-spends-23hb 发布时间:2026-10-17T23:39:20Z

  • 来源:DEV Community(发现于 2026-10-18)
  • 证据等级:D · 发现产品或需求信号,暂未获得可核验的商业证据。
  • 商业模式:待核验
  • 主题:AI Agent
  • 初筛评分:14.9/100 · 收录 1 次
#工作流自动化#待验证#产品发现
02 / SOURCE & EVIDENCE

证据,比故事更重要。

发现产品或需求信号,暂未获得可核验的商业证据。

规则清洗与初筛,未经人工商业核验。原文语境、实际客户和付费情况仍需自行验证。

引用与数字披露

来源类型(原作者自述/第三方测算/媒体转引)需采集端标注,本版尚未落字段。

短句引用
作者
未标注
抓取日期
来源类型
未标注
数字口径
币种
未标注
口径
未标注
披露主体
未标注
披露日期
未标注

中文辅助译文(全文)

问题

给两个 AI 代理同样的支出权限,它们迟早会为同一笔东西付两次款。不是因为它们粗心——而是因为它们谁都看不到对方刚刚做了什么。每个代理的记忆都止于各自的上下文窗口。

Permit 是我为代理构建的支付授权层:在限定范围内、可撤销的支出权限,每次结果都附带收据。为了 Graph Hacks,我提出了一个更窄的问题:如果代理之间的协调存在于一张图中,让它们在行动前去查询这张图,会怎样?

我构建的内容

Permit Memory Graph。FalkorDB 持有共享状态:

  • 节点: 代理、permit、claim、商家、收据
  • 边: 谁持有哪个 permit、谁声明了哪个作用域、决定了什么以及为什么

在任何支出之前,代理会向图查询三个问题:这个作用域是否已被声明?此权限是否仍然有效?上一个代理从这个商家学到了什么?

演示,分三拍

  1. 代理 A 在共享的 500 美元 permit 池中花费 120 美元用于 cloud-gpu。图中记录了这次 claim。
  2. 代理 B 尝试同一笔支出——并先询问图。它发现了 A 的 claim 并拒绝:重复作用域,已被声明,并以该 claim 的 ID 作为出处(provenance)。
  3. 撤销 permit 节点,两个代理都安全失败(fail closed)。没有有效的权限,就没有支出,没有例外。

在真实的 FalkorDB 后端上,演示图最终为 9 个节点 / 11 条边;最终审计套件通过 17/17 个切片测试和 5/5 个 Falkor 后端测试。一条用诚实的方式学到的运维经验:每次运行前清空图。在脏图上再次运行仍然能通过,但计数会漂移(13 个节点 / 19 条边)——陈旧状态会悄然撒谎,所以运行手册每次都先清空。

这张图给你带来什么

带着收据的拒绝胜过带着耸肩的拒绝。当代理 B 拒绝时,它可以指向那个让它说"不"的精确 claim 节点。这种出处——决策、证据、边——就是我 Permit 工作的整个论点,而这张图把它从一个日志文件变成了一次查询。

基准测试:以我已修复的 bug 为衡量对象

演示只能证明演示能跑。所以我在运行之前就冻结了一项更难的测试:来自 Permit 自身历史的七个事件——真实的问题和修复,每个都对应一份已合并的 PR——在图中重建为场景。我预先写下了每个事件中第二个代理会向图询问的问题,以及 Permit 的修复所保证的答案。然后我在真实的 FalkorDB 后端上运行它们,让图来回答。

首次运行:7 个中通过 4 个。 然后我修复了三个未通过的,再用同一套冻结用例重新运行:7/7 通过。 两次运行都记录在日志中;下面是每次所展示的内容。

四个通过的是协调的核心:一次支出在飞行途中其 permit 被撤销后会安全失败;图指明哪个代理首先声明了一笔支出,第二个代理的拒绝引用了那个精确的 claim ID;拒绝本身记录在案,并附上理由;撤销 permit 会使其飞行中的 claim 作废,而不是让它保持"活跃"。

三次首次运行的未通过同样具体,我也不打算淡化它们:

  • 累计上限(cumulative caps)。 两个代理各自在一家商家的 500 美元上限下各声明了 300 美元——总共 600 美元的 claim,而图放行了两个。它只检查了单个 claim 对照上限,从未汇总已被声明的总额。Permit 本身会拒绝这种情况(原子并发上限,PR #20);图的切片没有这个保证。
  • 过期。 一份过期时间已经过去的 permit 仍然成功支出。切片从未读取过期时间戳。Permit 在发布时收紧了过期检查(PR #29);图并未强制执行。
  • 崩溃存活。 我杀掉了服务器并重启。图回来时空空如也——每一条 claim 的出处都消失了。演示配置下,存储是易失性的;Permit 的崩溃恢复持久性(PR #26)并未传递过来。

于是我精确修复了这三点——admission 现在将活跃 claim 汇总后与上限比对,permit 带有 admission 真正会读取的过期时间,服务器以持久化的仅追加存储运行——每个修复增加一个测试(套件现在为 9/9),并用相同的预期答案重新运行同一组七个用例,测试集在所有这一切之前就已经冻结。第二次运行:7/7——第二笔 300 美元的 claim 被累计上限拒绝,过期的 permit 被拒绝,而在杀掉重启之后图仍然知道谁声明了什么。

这就是这件事诚实的样貌:它回答了每个被构建来回答的问题——谁声明了什么、决定了什么、什么被撤销——基准测试发现了切片尚未长出来的三条 Permit 保证。针对不变的测试集进行修复并重新衡量,这正是拥有一份基准测试的意义所在。一份只包含你已经通过的事的基准测试,就不是基准测试。(冻结测试集和完整的测量日志随项目一同发布。)

我接下来要做的事

跨会话持久化商家声誉,让"上一个代理从这个商家学到了什么?"拥有比一次演示运行更长的记忆——并将图查询接入 Permit 的实时闸门,让重复声明的拒绝背后带上真正的收据链。

译文由上游机器翻译生成,可能有误;判断请以英文原文为准。

英文原文(来源本站未改写)

The problem

Give two AI agents the same spending authority and they will, sooner or later, pay for the same thing twice. Not because they're careless — because neither one can see what the other just did. Each agent's memory ends at its own context window.

Permit is my payment-authority layer for agents: scoped, revocable permission to spend, with every outcome receipted. For Graph Hacks I asked a narrower question: what if the coordination between agents lived in a graph they both query before acting?

What I built

Permit Memory Graph. FalkorDB holds the shared state:

  • Nodes: agents, permits, claims, merchants, receipts
  • Edges: who holds which permit, who claimed which scope, what was decided and why

Before any spend, an agent asks the graph three questions: Has this scope already been claimed? Is this authority still live? What did the last agent learn about this merchant?

The demo, in three beats

  1. Agent A spends $120 on cloud-gpu against a shared $500 permit pool. The graph records the claim.
  2. Agent B tries the same spend — and asks the graph first. It finds A's claim and refuses: duplicate scope, already claimed, citing the claim's ID as provenance.
  3. Revoke the permit node, and both agents fail closed. No live authority, no spend, no exceptions.

On the real FalkorDB backend the demo graph ends at 9 nodes / 11 edges; the final audited suite passes 17/17 slice tests and 5/5 Falkor-backed tests. One operational lesson, learned the honest way: clear the graph before every run. A second run on a dirty graph still passes but the counts drift (13 nodes / 19 edges) — stale state lies quietly, so the runbook wipes first, every time.

What the graph buys you

A refusal with a receipt beats a refusal with a shrug. When Agent B says no, it can point at the exact claim node that made it say no. That provenance — decision, evidence, edge — is the whole thesis of my Permit work, and the graph makes it a query instead of a log file.

The benchmark: measured against bugs I already fixed

A demo proves a demo works. So I froze a harder test before running it: seven incidents from Permit's own history — real issues and fixes, each with its merged PR on the record — rebuilt as scenarios in the graph. For each one I wrote down, in advance, the question a second agent would ask the graph and the answer Permit's fix guarantees. Then I ran them on the real FalkorDB backend and let the graph answer.

First run: 4 of 7. Then I fixed the three misses and ran the identical frozen set again: 7 of 7. Both runs are in the log; here's what each one showed.

The four passes are the coordination core: a spend attempted after its permit was revoked mid-flight fails closed; the graph names which agent claimed a spend first, and the second agent's refusal cites that exact claim ID; the refusal itself is on the record, reason included; and revoking a permit voids its in-flight claim instead of leaving it "active."

The three first-run misses were just as specific, and I'm not going to soften them:

  • Cumulative caps. Two agents each claimed $300 against one $500 cap, at different merchants — $600 in total claims, and the graph allowed both.It checked a single claim against the cap and never summed what was already claimed.Permit itself refuses this (atomic concurrent cap, PR #20);the graph slice didn't have that guarantee.
  • Expiry. A permit whose expiry had already passed still spent successfully.The slice never read an expiry timestamp.Permit tightened expiry at release time (PR #29);the graph didn't enforce it.
  • Crash survival. I killed the server and restarted it.The graph came back empty — every claim's provenance, gone.

As configured for the demo, the store was volatile;Permit's crash-resume durability (PR #26) didn't carry over.

So I fixed exactly those three things — admission now sums active claims against the cap, permits carry an expiry that admission actually reads, and the server runs with durable append-only storage — added one test per fix (suite now 9/9), and re-ran the same seven cases with the same expected answers, the set frozen before any of it. Second run: 7 of 7 — the second $300 claim refused against the cumulative cap, the expired permit refused, and after the kill and restart the graph still knew who had claimed what.

That's the honest shape of the thing: the graph answered every question it was built to answer — who claimed what, what was decided, what got revoked — and the benchmark found the three Permit guarantees the slice hadn't grown yet. Fixing them and re-measuring against the unchanged set is the whole point of having one. A benchmark that only contains things you already pass isn't a benchmark. (The frozen set and the full measurement log ship with the project.)

What I'd do next

Persist merchant reputation across sessions, so "what did the last agent learn about this merchant?" has a longer memory than one demo run — and wire the graph check into Permit's live gate, where a duplicate claim refusal would carry a real receipt chain behind it.

出处https://dev.to/fetchdoge_/two-agents-one-wallet-a-memory-graph-that-stops-duplicate-spends-23hb抓取日期 · 采集源 DEV Community

03 / EVIDENCE GAPS

这条还缺什么证据?

下面每条都由本条已有字段推出(等级、理由、商业模式、来源次数、是否演示), 本站不生成推测性结论;通用验证方法放在方法论页。

  • 可核验的收入或付费证据查官网定价页与付费口径;第三方数据源(如 GetLatka)只作旁证,需标注来源与时点。
  • 商业模式未定确认按席位/按用量/授权还是开源托管版收费;开源项目另查 LICENSE 与是否存在付费版。
  • 只有单一来源找一手站点或其他渠道是否重复出现同一产品;社区热帖数量不等于商业进展。

通用验证清单(谁有这个问题/谁愿意付费/一个人能交付哪一小步)见我们的筛选方法。

04 / SIGNAL HISTORY

发现时间线