最新资讯
dev.to 如何在专用 GPU 服务器上用 OpenAI 兼容 API 部署 LLM dev.to 审计 153 份 Claude Code 与 Codex 会话记录:User-Agent 与 URL 中的邮箱泄露 dev.to 你的 Agent Harness 应具备的 17 项能力 dev.to 离线 AI 记忆中 0.8 余弦阈值为何失效 dev.to Kimi K3.1 Pro 开放权重:自托管 2.8T 模型前的开发者清单 dev.to 如何通过工具调用引导模型以提升 Harness 质量 dev.to AI Agent 审计轨迹不等于对话记录 dev.to 精简 MCP server 工具数量:更少工具、更小影响面,双重收益 dev.to 为什么 git checkout 无法撤销 AI 编码 agent 的改动? wechat AI短剧门槛降降降!实测即梦短剧工作室:剧本分镜预演一条龙,伙伴计划长期护航 dev.to 让模型改写文档前,先量化事实保真度 dev.to 回放 153 个 Claude Code 与 Codex 会话,审计 Agent 的生产影响范围
多元动态
登录 注册
智能体 dev.to · @Once

为什么 AI Agent 会把同一个动作执行两次

原文 我的收藏

AI Agent 正从问答系统变为执行系统,会发消息、建工单、退款、下单、更新记录、触发部署和调用改变外部状态的工具。这带来分布式系统工程师熟悉的失败模式:工具调用可能已成功,但响应丢失、延迟或超时,agent 看到错误后由框架重试,于是同一动作被执行两次。文章强调超时只描述调用方的观察结果,不能证明外部提供方未执行操作,因此普通重试逻辑在 agent 循环中可能变得危险。

AI推荐理由 聚焦 agent 执行外部副作用时的重复执行问题:工具调用已成功但响应丢失或超时,agent 误判失败并重试,导致退款等操作被执行两次。文章把该问题与分布式系统的幂等性/重试语义联系起来,指出超时只说明调用方观察结果、不能证明外部操作未发生,对构建可执行 agent 的开发者有实际价值。属分析性文章,未给出具体实现方案或实测数据。

78

正文

AI agents are becoming execution systems. They no longer just answer questions. They send messages, create tickets, issue refunds, make bookings, update customer records, trigger deployments, provision resources, and call tools that change external state. That creates a failure mode distributed-systems engineers already know well — but agent loops make it unusually easy to trigger: a tool call can succeed and still look like a failure to the agent. Consider a refund: An agent decides to issue the refund. The request reaches the payment provider. The provider commits the refund. The response is lost, delayed, or times out. The agent sees an error. The framework retries the tool. At step 6, the important question is no longer: Did the request fail? It is: Did the external effect already happen? That distinction is where ordinary retry logic can become dangerous. A timeout is not proof of failure A timeout describes what the caller observed. It does not prove what the external provider did. After a lost acknowledgement, at least two realities may be consistent with the evidence the agent has: the refund did not happen, so retrying is necessary; the refund did happen, so retrying may create a duplicate. This is an ambiguous outcome. If the agent cannot distinguish those realities, blind retry is not merely a reliability mechanism. It can create a second real-world action. The same pattern applies far beyond payments: sending the same email twice; creating the same booking twice; submitting the same order twice; provisioning the same paid resource twice; firing the same deployment twice; updating an account more than once; triggering the same webhook-backed action twice. The underlying problem is not "AI hallucination." It is distributed-systems uncertainty at the boundary between intent and external effect. Why agent systems amplify the problem Traditional applications already retry failed network operations. Agent systems add more ways for repetition to occur. A tool may be repeated because: the model decides to retry after an error; the framework has retry logic; a workflow resumes from a checkpoint; a process crashes and restarts; a supervisor redispatches work; a sub-agent is re-run; an MCP tool call is attempted again; a user asks the agent to "try that again." These mechanisms can all be individually reasonable. The danger appears when they cross a side-effecting boundary without preserving the identity and outcome of the logical action. Tool-call IDs are usually the wrong identity A request ID, tool-call ID, trace ID, retry counter, or timestamp usually identifies an attempt. But a retry of the same refund is not a new business intention just because it has a new tool-call ID. For safe retry handling, we need a stable logical operation identity. For example: refund / order_123 Enter fullscreen mode Exit fullscreen mode should identify the same intended refund across all retries of that action. Attempt 1 might have one request ID. Attempt 2 might have another. But if both represent the same intended refund, the logical operation identity should remain stable. This gives us an important distinction: transport identity -> which attempt is this? logical identity -> which real-world action is this? Enter fullscreen mode Exit fullscreen mode Those are not the same question. Identity alone is not enough There is another failure mode. Suppose an application reuses the same logical operation ID but changes a value that affects the real-world action. For example: operation: send_invoice_4821 attempt 1 destination: alice@example.com attempt 2 destination: bob@example.com Enter fullscreen mode Exit fullscreen mode Those should not be treated as equivalent retries. The operation identity therefore needs to be bound to the effect-bearing payload. If a field can change the external effect — amount, destination, message body, booking details, resource configuration, recipient, etc. — changing it should produce a conflict or a new intentional operation. Otherwise a deduplication mechanism can become a different kind of bug: incorrectly collapsing two distinct actions into one. The state many systems are missing: UNKNOWN A useful execution model has at least three outcome states: State Meaning Safe default CONFIRMED Authoritative evidence says the effect happened Return/replay the known result; do not execute again ABSENT Authoritative evidence says the effect did not happen Execution may proceed UNKNOWN The effect may have happened, but available evidence cannot prove which state is true Reconcile or block The critical rule is: UNKNOWN is not permission to execute again. This sounds conservative because it is. If duplicate execution could be expensive or irreversible, safety sometimes requires giving up immediate progress. That is the classic tradeoff between safety and liveness: safety: do not accidentally create the duplicate effect; liveness: eventually complete the requested action. If provider truth is unavailable, a high-impact operation may have to remain blocked until a human or a trusted system can resolve it. Reconciliation: ask reality before repeating it When an outcome is ambiguous, the strongest recovery path is often reconciliation. Instead of retrying the mutation, perform a read-only check against an authoritative system. For a refund, that could mean asking the provider whether the refund exists. For a booking, check whether the reservation was created. For a message, query the provider-side message ledger if such a facility exists. The flow becomes: external effect may have committed | v UNKNOWN | v authoritative lookup / \ / \ CONFIRMED ABSENT | | v v do not repeat execution may proceed Enter fullscreen mode Exit fullscreen mode The phrase authoritative matters. A missing local database row is not automatically proof that the external effect did not happen. Neither is a timeout. Neither is an empty cache. ABSENT should require evidence strong enough to justify repeating the action. Not every agent tool needs this There is an obvious counterargument: Do we really want every search, calculation, and read operation going through durable execution coordination? No. That would add latency and complexity where there is little duplicate-effect risk. A better model is selective routing. For example: Route Meaning DIRECT No consequential external mutation identified PROTECT Duplicate execution could create an undesirable external effect BLOCK The system cannot establish that execution is safe A web search is usually DIRECT. A local calculation is usually DIRECT. A refund, message send, booking, order creation, or deployment trigger may be PROTECT. A tool with conflicting or insufficient safety information may be BLOCK. The asymmetry matters: a false positive mostly costs latency or integration friction; a false negative can permit an unintended duplicate real-world action. For consequential tools, conservative classification is often the rational choice. This is not a universal "exactly once" claim "Exactly once" sounds attractive, but it is easy to overstate when independent systems are involved. A client generally cannot atomically commit both: an arbitrary external provider's state; and its own local acknowledgement state unless the systems share an appropriate transaction, deduplication, or reconciliation contract. So the defensible target is narrower: One intended consequential operation should produce at most one corresponding external effect across retries — under explicit assumptions — or the system should block rather than guess. Those assumptions include: stable logical operation identity; complete effect binding; durable safety state; controlled execution concurrency; an execution boundary that cannot simply be bypassed; authoritative reconciliation where ambiguity cannot otherwise be resolved. That is a safety property, not a promise that every operation will eventually succeed. Where Once fits We have been building Once, an open-source execution-safety layer for AI agent tools and MCP integrations, around this model. The project separates attempt identity from logical action identity, preserves ambiguous outcomes, binds effect-bearing input to protected operations, and increasingly classifies toolsets so harmless calls can remain direct while consequential calls receive stronger protection. The current public implementation includes: TypeScript and Python SDKs; MCP support; deterministic cross-language operation identity; local durable protection; tool discovery and classification; selective DIRECT / PROTECT / BLOCK routing; framework integrations; hostile-retry evidence across multiple agent frameworks. The important part is the boundary of the claim. Once does not claim universal exactly-once execution across arbitrary providers and arbitrary deployments. If authoritative truth is unavailable, the correct state may remain UNKNOWN. That limitation is part of the design rather than something to hide. We published the full systems model I have now published the deeper technical treatment as a citable technical paper: Reliable Execution of Consequential AI Agent Actions Under Retries and Ambiguous Outcomes Jamie Oswald — Once Research Published: 26 September 2026 DOI: 10.5281/zenodo.22969881 The paper covers: the formal one-effect safety property; trust assumptions; ambiguous-outcome failure states; logical identity versus attempt identity; effect binding and payload drift; CONFIRMED / ABSENT / UNKNOWN; reconciliation; selective tool protection; related techniques including idempotency keys and durable workflow systems; hostile-retry evidence; threats to validity; falsifiable failure criteria. If you are building agents that can change external state, the question I would ask is simple: If this tool times out after the external effect commits, what prevents the retry from doing it again? If the answer is only "the framework retries carefully," there is probably another reliability boundary worth examining. Links Technical paper: https://doi.org/10.5281/zenodo.22969881 Once research page: https://onceexec.com/research/ Once: https://onceexec.com/ GitHub: https://github.com/stringsofthemind-oss/once

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容