---
title: "智能体钱包：AI 智能体的会话与权限模型"
description: "AI 智能体如何在不持有私钥的情况下获得受限且可撤销的钱包访问权限：会话、委托签名与即时撤销。"
---

# 智能体钱包：AI 智能体的会话与权限模型

<ImageBlock
  src="https://media.alchemy.com/agent-wallets-1.png"
  alt="Agent 钱包：面向 AI Agent 的会话与权限模型"
  width={3840}
  height={1800}
  priority
/>

一个在链上交易的 AI agent,离转移真实资金只差一个签名。它已经读取了市场行情,选好了通过某个 DEX 的路径,准备执行。要安全地完成这件事,归结为一个问题:如果这个 agent 出错、被劫持,或者干脆有 bug,会发生什么?它能不能把钱包提空,你能不能在损失发生前把它拦下来?

## 什么是 agent 钱包,它和普通加密钱包有什么区别?

普通钱包假设有一个人来审查并签署每一笔交易,私钥只有这个人持有。agent 钱包的假设正好相反:由一个 AI agent 或自动化程序持续签名,没有人每次点击批准,而资金的实际所有者(个人或公司)仍然保有最终控制权。

两者的区别在于围绕签名密钥的权限模型,而不是钱包里的余额或地址:agent 被允许做什么(受限的能力范围)、允许做多久(有时限的 session)、以及出问题时你能多快切断它。

[Agent Wallets](https://www.alchemy.com/docs/agent-wallets) 直接处理了这三点:

- 受限的能力范围:一个 CLI session 只包含你授予它的特定签名方法,比如转账、swap、跨链桥,或合约调用。把密钥限制到某个合约的具体函数,属于 [Wallet API 的 session-key 权限](https://www.alchemy.com/docs/wallets/smart-contracts/modular-account-v2/session-keys/session-key-permissions),不是 CLI 的能力范围。
- 有时限的 session:每次授权都带有过期时间,即使没有人手动撤销,访问权限也会自行失效。
- 快速关闭:从 Alchemy dashboard 或用 `alchemy wallet disconnect` 撤销一个 CLI session,会立即在验证层生效,不需要交易。

无论你是直接使用 Agent Wallets CLI 产品(覆盖 EVM 和 Solana),还是基于底层的 Wallet APIs session-key 原语为自己的用户构建功能,受限的能力范围和过期时间都会出现。无需上链交易即可立即关闭是 CLI 路径的特点。移除一个 Wallet API session key 则是链上卸载操作。

## agent 钱包如何让私钥远离 agent?

为 agent 设计安全的交易,意味着把普通钱包捆绑在一起的东西拆分开:托管(谁持有私钥)、授权(允许做什么)、控制(谁能批准或关闭它)。

- [Turnkey](https://docs.turnkey.com/features/policies/delegated-access/agentic-wallets) 把托管放在硬件安全飞地(enclave)内,策略引擎也运行在同一个飞地中,所以只有请求通过规则检查后才会产生签名,agent 从未接触到密钥。
- [Crossmint](https://docs.crossmint.com/wallets/concepts/signers) 和 [Cobo](https://www.cobo.com/products/agentic-wallet/manual/developer/technical-architecture) 则把钱包拆分为所有者密钥和 agent 密钥(Cobo 使用跨多个独立方的 MPC,而非单一密钥),这样 agent 的密钥只在所有者设定的限制内起作用。
- Alchemy [把同样的分离机制内置在了 CLI 中](https://www.alchemy.com/blog/agent-wallets-alchemy-cli):一个本地生成的 session signer 用于验证 agent 身份,而一个独立的托管方持有实际的私钥,agent 只需完成身份验证和签名,从不接触私钥本身。

具体运作方式如下。

- 运行 `alchemy wallet connect`,CLI 会在本地生成一个 P-256 密钥对,该密钥对永远不会离开你的机器。
- 你在 Alchemy dashboard 中批准该 session,这会把这个公钥作为签名者附加上去,并限定特定能力和你设置的过期时间。
- 钱包实际的私钥由一个嵌入式钱包合作方持有,默认是 Privy。
- 每次签名调用都要经过两步检查:Alchemy 的后端构建托管方所需的确切负载,你的 CLI 在本地对其签名,只有当 session 仍然有效时,请求才会到达托管方。agent 从未接收或处理过私钥。

## 应该用什么基础设施来进行权限的开通和控制?

有两条路径,取决于你在为谁开发。

如果你要给一个编程 agent 或内部自动化流程配置钱包,[Alchemy CLI 中的 Agent Wallets](https://www.alchemy.com/docs/agent-wallets) 是最快的路径,它也是取代[把私钥直接粘贴进 Cursor](https://www.alchemy.com/overviews/stop-pasting-private-keys-into-cursor) 这种做法的方案,能让 agent 真正安全地使用钱包。

在 dashboard 中创建一个钱包,运行 `alchemy wallet connect --mode session`,批准该 session 的能力范围和过期时间,agent 就能立即获得一个受限 session,可用于转账和合约调用,以及 EVM 主网上的 swap 和跨链桥操作。无需 SDK 集成,而且 CLI 的 `agent-prompt` 命令会给 agent 提供一份完整的命令、参数和错误码清单,agent 不需要去读文档就能正确使用整个接口。

如果你在构建一个产品,让你自己的用户把签名权委托给某个 agent,请使用 [Wallet APIs session keys](https://www.alchemy.com/docs/wallets/reference/wallet-apis-session-keys/api)。用户的智能账户会通过 [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) 在链上完成委托,你调用 `wallet_createSession`(或 SDK 中的 `client.grantPermissions()`),传入一个 session key 和一个权限数组,用户签署一次 EIP-712 授权,此后 agent 用这个 session key 签署每一笔操作,永远不用所有者的密钥。

## 可以委托哪些操作,权限的粒度有多细?

委托在这里分两层:第一层是某个 session 完全允许调用哪些操作,再深一层,是这些调用能触及多少额度或哪些具体合约。

在 CLI session 这一层,第一层就是一份允许调用的方法列表。

- 一个 session 可以包含 `evm.signMessage`、`evm.signTypedData`、`evm.signAuthorization`、`evm.prepareCalls`、`evm.sendCalls` 和 `solana.signTransaction`。
- 所有操作都经由 Alchemy 的钱包调用(`wallet_prepareCalls` 和 `wallet_sendCalls`)完成,交易逻辑(比如排序和打包)以及 gas 赞助都由此处理好。

代价是,session 不能像独立私钥那样签署任意的原始 EVM 交易,所以如果你的 agent 需要接入某个第三方 SDK 或协议,而该协议要求把原始 EVM 交易交给它签名,这种流程目前无法通过 CLI session 实现。如果这是你需要的用例,请[联系我们](https://www.alchemy.com/contact-sales)。

在 Wallet APIs 这一层,[session-key 权限](https://www.alchemy.com/docs/wallets/smart-contracts/modular-account-v2/session-keys/session-key-permissions)的可配置性更强。CLI 的能力列表只能回答是或否:这个 session 到底能不能调用 `sendCalls`?Wallet API 权限在此基础上增加了限额:不只是某种转账是否被允许,还包括能转移多少、用哪种代币、通过哪个具体合约。如果 agent 需要真正的花费上限,比如某个代币在 24 小时窗口内 100 USDC 的上限,而不只是某个操作开关的启用与否,请使用 Wallet APIs:

<EmbeddedTable
  table={{
    columns: [
      { key: "1", width: 240, title: "Permission type", dataType: "object" },
      { key: "2", width: 400, title: "What it restricts", dataType: "object" },
    ],
    data: [
      {
        "1": {
          title: "<p><code>native-token-transfer</code></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>Caps how much native token (ETH, say) the key can move, via a fixed allowance</p>",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        "1": {
          title: "<p><code>erc20-token-transfer</code></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>Caps cumulative ERC-20 transfers and approvals for one token contract to a set allowance</p>",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        "1": { title: "<p><code>gas-limit</code></p>", tooltip: "", icon: "" },
        "2": {
          title: "<p>Caps how much gas the key can spend across transactions</p>",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        "1": {
          title: "<p><code>contract-access</code></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>Allows every function on one named contract, nothing else</p>",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
      {
        "1": {
          title:
            "<p><code>functions-on-contract</code> / <code>account-functions</code> / <code>functions-on-all-contracts</code></p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>Allows only specific function selectors, on one contract, on the account itself, or everywhere</p>",
          tooltip: "",
          icon: "",
        },
        id: 4,
      },
      {
        "1": { title: "<p><code>root</code></p>", tooltip: "", icon: "" },
        "2": {
          title:
            "<p>Full access to everything, a very dangerous permission to grant. Use judiciously.</p>",
          tooltip: "",
          icon: "",
        },
        id: 5,
      },
    ],
  }}
/>

每个权限还带有一个 `expirySec`,所以一次授权可以同时把某个 session key 限定到,比如说,某个质押合约、100 USDC 的上限,以及一个 24 小时的窗口。

## 如何批准、验证并撤销一个 agent 的钱包 session

批准操作只由人来执行一次。在 CLI 流程中,这是你连接 session 时的 dashboard 批准步骤。在 Wallet APIs 流程中,这是所有者签署授权该 session key 权限的 EIP-712 类型化数据。

验证应该在每一次改变状态的操作之前进行,而不只是在初始设置时。在 agent 执行任何不可逆操作之前,运行 `alchemy --json --no-interactive wallet status --verify`。它会返回当前有效的签名者、session 过期时间,以及已启用的能力,这样 agent(或你的编排代码)就能在继续之前确认 session 仍然有效。

撤销有两种机制:

- 从 dashboard 或用 `alchemy wallet disconnect` 撤销时,session 会在验证层被撤销。下一次签名尝试会在到达托管方之前就被拒绝,立即生效,不需要交易。
- 如果你是直接在智能账户层面管理 session key(在 CLI 产品之外),[移除一个 session key](https://www.alchemy.com/docs/wallets/smart-contracts/modular-account-v2/session-keys/removing-session-keys) 意味着通过一次 user operation 卸载其验证器,这个操作必须像其他链上操作一样被发送并打包上链。

## 如何确保撤销 agent 访问权限是即时的

假设你发现 agent 做了错事,于是你点击撤销。如果你的应急开关是通过修改一条存储在链上的规则来实现的,这个改动仍然需要作为一笔交易发送并打包上链才能生效,所以会存在一个窗口期,可能是一个区块时间,也可能更长,在这个窗口期内,即使你已经告诉系统要停止 agent,它仍然可以继续行动。问题在于如何设计撤销机制,让它不存在这个空档。

关键在于执行(enforcement)发生在哪里。如果阻挡在 agent 和链之间的唯一屏障是存储在智能合约内的一条规则,关闭这条规则就意味着发送一笔交易来改变合约状态,这笔交易必须先被打包才能生效。如果执行发生在另一个层面,即在请求被签名或广播之前就先检查,那么撤销只是删除或使那次检查失效,你一执行就立即生效。

Alchemy 的 Agent Wallets、Turnkey 的策略引擎,以及 Cobo 的 pact 系统,用的都是后一种模式。

- Turnkey 删除非 root 的 agent 用户,该凭证之后的每一次请求都会在飞地(enclave)处失败。
- Cobo 在服务端撤销一个 pact 及其 API key,并明确说明 agent 下一次的 API 调用会被拒绝。
- Alchemy 在后端验证层撤销 session,下一次签名尝试会在离开 Alchemy 基础设施之前就被拒绝,也就是在到达托管方之前。

Crossmint 采用了不同的做法:它的权限存放在智能合约钱包本身内,所以移除一个 agent 的签名者是对该合约链上状态的一次修改。虽然由链本身而非服务器来强制执行规则,这[让被攻破的 agent 更难绕过](https://www.crossmint.com/learn/agent-wallets-compared),但代价是速度:修改一个链上权限意味着要发送一笔交易,所以撤销操作要承受链本身的结算时间,而后端检查的方式完全不需要这个等待。

## Agent Wallets 与 Wallet API session keys 的对比

无论是 Agent Wallets,还是通过 Wallet APIs 使用 session keys,都能让私钥远离 agent。区别在于你需要多细的控制粒度、真正是谁在向 agent 委托权限,以及撤销机制如何运作。CLI session 在验证层被切断,不需要交易。卸载一个 Wallet API session key 则要等待一次被打包的 user operation。

<EmbeddedTable
  table={{
    columns: [
      {
        key: "1",
        width: 280,
        title: "Use Agent Wallets (the CLI)",
        dataType: "object",
      },
      {
        key: "2",
        width: 320,
        title: "Use Wallet APIs session keys",
        dataType: "object",
      },
    ],
    data: [
      {
        "1": {
          title:
            "<p>You're wiring up a coding agent or an internal script and want it signing in minutes, no SDK integration required.</p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>You're building a product where your own end users delegate signing to an agent on their own smart account.</p>",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        "1": {
          title:
            "<p>A yes/no capability list, can this session send, swap, bridge, or make contract calls, is enough scoping for what the agent does.</p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>You need an actual spend cap, like a fixed allowance on native token or one ERC-20, enforced by the permission itself.</p>",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        "1": {
          title:
            "<p>The Alchemy dashboard is a fine place to create the wallet and approve sessions by hand.</p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            "<p>You need contract- or function-level allowlists as the real enforcement boundary, not just a capability flag.</p>",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        "1": {
          title:
            "<p>The CLI already handles what the agent needs to do: sending, batching calls, and getting its gas sponsored across EVM and Solana, plus swapping and bridging on EVM mainnet.</p>",
          tooltip: "",
          icon: "",
        },
        "2": {
          title:
            '<p>You need to grant session keys from your own app. Neither path signs an arbitrary raw EVM transaction for a third-party SDK today. <a href="https://www.alchemy.com/contact-sales">Reach out to us</a> if that\'s the use case.</p>',
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
    ],
  }}
/>

## Alchemy 与 Turnkey、Crossmint、Cobo 的对比

<EmbeddedTable
  table={{
    columns: [
      { key: "1", width: 180, title: "Provider", dataType: "object" },
      { key: "2", width: 240, title: "Where custody lives", dataType: "object" },
      {
        key: "3",
        width: 260,
        title: "Where policy is enforced",
        dataType: "object",
      },
      {
        key: "4",
        width: 280,
        title: "Instant revoke without a mined transaction",
        dataType: "object",
      },
    ],
    data: [
      {
        "1": { title: "<p>Alchemy Agent Wallets</p>", tooltip: "", icon: "" },
        "2": {
          title:
            "<p>Embedded wallet partner (Privy by default) for CLI sessions, or any signer you choose via Wallet APIs</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Backend session-verification layer for CLI sessions; onchain session-key permissions on the smart account for custom Wallet APIs integrations</p>",
          tooltip: "",
          icon: "",
        },
        "4": {
          title:
            "<p>Yes for CLI sessions, via dashboard or <code>wallet disconnect</code>. Wallet API session keys: no, uninstalling the validator is a mined user operation</p>",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        "1": { title: "<p>Turnkey</p>", tooltip: "", icon: "" },
        "2": {
          title: "<p>AWS Nitro secure enclave (TEE)</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Policy engine running inside the same enclave, evaluated before every signature</p>",
          tooltip: "",
          icon: "",
        },
        "4": {
          title:
            "<p>Yes, delete the non-root agent user or toggle a DENY policy</p>",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        "1": { title: "<p>Cobo Agentic Wallet</p>", tooltip: "", icon: "" },
        "2": {
          title:
            "<p>MPC across independent parties, no single key</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Three-stage server-side policy engine (permission, rule, counter), evaluated on every request</p>",
          tooltip: "",
          icon: "",
        },
        "4": {
          title:
            "<p>Yes, freeze or revoke a pact; the API key gets invalidated server-side</p>",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        "1": { title: "<p>Crossmint</p>", tooltip: "", icon: "" },
        "2": {
          title:
            "<p>Dual-key smart contract wallet: owner key plus an agent key sealed in a TEE</p>",
          tooltip: "",
          icon: "",
        },
        "3": {
          title:
            "<p>Onchain, inside the smart contract itself (per-transaction limits, allowlists, time windows checked at execution)</p>",
          tooltip: "",
          icon: "",
        },
        "4": {
          title:
            "<p>By design, no. Removing a signer changes the wallet contract's onchain signer set, so it settles like any other onchain operation rather than a synchronous backend check</p>",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
    ],
  }}
/>

简而言之:Alchemy CLI session、Turnkey 和 Cobo 都在链下执行并即时撤销。Crossmint 和 Wallet API session keys 在链上执行,所以撤销要承受结算时间。

## 应避免的常见错误

- **不要把 gas 赞助当作花费上限。** 赞助策略决定的是谁支付手续费,而不是 agent 能转移多少资金。真正的花费上限要用 session-key 权限或合约层的额度限制来实现。
- **不要把链上权限变更当作你的应急开关。** 如果撤销访问权限意味着要在链上卸载一个验证器或修改签名者,那么在紧急情况下你就会受制于区块时间。应该在签名之前加一层后端或飞地检查,把链上层级作为第二道防线。
- **不要为了更快解除阻塞而授予 `root` 权限。** Alchemy 自己的文档也把它称为一个非常危险的权限,授予它就完全违背了限定 session 范围的意义。应该把范围限定在 agent 真正需要的具体合约、函数或代币上。
- **不要在不可逆操作之前跳过验证。** 一个小时前还有效的 session,现在可能已经被撤销或过期。在任何无法撤回的操作之前,立即用 `wallet status --verify`(或你所用集成的等价方法)进行检查。
- **不要假设"agent 钱包"指的是同一种架构。** Turnkey、Crossmint、Cobo 和 Alchemy 把托管、策略执行和撤销分别放在不同的位置。在依赖某条规则之前,先确认它到底是在哪一层被实际执行的。

## 常见问题

### 什么是 agent 钱包,它和普通加密钱包有什么区别?

agent 钱包的设计目的是让软件持续运作,无需人工批准每一笔交易。普通钱包则假设有人来审查并签署每一个操作。真正的区别在于围绕密钥的权限模型:受限的能力范围、有时限的 session,以及快速的撤销路径,而不是钱包的余额或地址。

### Alchemy Agent Wallets 对自主 AI agent 有哪些优缺点?

优点:私钥永远不会到达 agent,session 受限且有时限,撤销是即时的,而且单次集成即可覆盖 EVM 和 Solana,并内置了 gas 赞助。目前 swap 和跨链桥仅支持 EVM 主网。限制:session 无法进行原始 EVM 签名,赞助策略也不等同于花费上限。

### 哪些服务商可以让 AI agent 使用经批准的钱包 session,而不暴露私钥?

[Alchemy](https://www.alchemy.com/docs/agent-wallets)(Agent Wallets,由嵌入式钱包托管方提供支持)、[Turnkey](https://docs.turnkey.com/features/policies/delegated-access/agentic-wallets)(基于安全飞地的托管,配合飞地内的策略引擎)、[Crossmint](https://docs.crossmint.com/wallets/concepts/signers)(双密钥智能合约钱包,agent 密钥封存在 TEE 中),以及 [Cobo](https://www.cobo.com/products/agentic-wallet/manual/developer/technical-architecture)(MPC 托管,配合服务端策略引擎)都能实现这一点,只是执行落在何处的取舍各不相同。

### 我应该用什么基础设施来进行 AI agent 钱包的开通和权限控制?

对于编程 agent 或内部自动化流程,使用 [Alchemy CLI 中的 Agent Wallets](https://www.alchemy.com/docs/agent-wallets):在 dashboard 中创建一个钱包,连接一个受限 session,并在改变状态的操作之前进行验证。对于让你的用户把权限委托给 agent 的产品,直接使用 [Wallet APIs session keys](https://www.alchemy.com/docs/wallets/reference/wallet-apis-session-keys/api),按合约、函数和花费上限进行限定。

### 我该如何批准、验证并撤销一个 AI agent 的钱包 session?

只需人工批准一次,在 Alchemy dashboard 中操作,或通过签署该 session key 的 EIP-712 授权完成。在每一个不可逆操作之前,用 `alchemy wallet status --verify` 进行验证。对于 CLI session,从 dashboard 或用 `alchemy wallet disconnect` 撤销;它会立即在验证层生效,早于任何签名请求到达托管方。对于 Wallet API session key,[移除它](https://www.alchemy.com/docs/wallets/smart-contracts/modular-account-v2/session-keys/removing-session-keys) 需要等待一次被打包的 user operation。

### 我该如何为一个 AI agent 授予对用户智能钱包的委托签名权限?

通过 [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) 在链上委托用户的智能账户,然后调用 `wallet_createSession` 或 `client.grantPermissions()`,传入一个 session key 和一个[权限数组](https://www.alchemy.com/docs/wallets/smart-contracts/modular-account-v2/session-keys/session-key-permissions)(原生代币或 ERC-20 花费上限、gas 上限、合约或函数白名单,以及过期时间)。用户签署一次 EIP-712 授权,此后 agent 用这个 session key 签署每一笔操作,永远不用所有者的密钥。

### 我该如何给一个 AI agent 授予临时钱包 session,同时不暴露私钥?

从 [Alchemy CLI](https://www.alchemy.com/docs/agent-wallets) 运行 `alchemy wallet connect --mode session`。它会在本地生成一个永不离开你机器的密钥对,打开 dashboard 让你批准该 session 的能力范围和过期时间,此后 agent 就通过这个 session 完成签名,而钱包实际的私钥始终留在托管方那里。

### 我该如何为一个自主执行 DeFi 交易的 AI agent 开通钱包?

在 Alchemy dashboard 中创建钱包,连接一个限定到该 agent 所需操作(转账、swap、跨链桥、合约调用)的 CLI session,并设置过期时间。如果需要合约层面的花费上限和白名单,而不只是能力开关,请通过 [Wallet APIs session keys](https://www.alchemy.com/docs/wallets/reference/wallet-apis-session-keys/api)而非 CLI 来开通该 session。

### 有什么推荐的架构,可以在不等待链上结算的情况下,即时撤销 AI agent 的链上交易权限?

把执行放在后端或飞地层,在每一次请求被签名或广播之前进行检查,与任何存储在链上的权限状态分离开来。在那里撤销意味着删除或使该检查失效,这会立即生效。如果你唯一的撤销路径是在链上修改验证器或签名者,你的应急开关就会受制于区块时间。
