> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent

> 当参与者不是人时，架构的每一层各自要做什么——协议之外的 runtime、agent 负载下的准入、作为一笔交易的授权，以及一个可重放的环境。

这套东西面向的方向是：**一个人由好几个 agent 代表，每个 agent 执行他意图中的一部分**。不是一个人加一件工具，也不是一个跑固定脚本的机器人——而是市场上的好几个对手方，全都对同一个账户负责。

参与者变了，市场微观结构就跟着变。单笔规模下降、消息速率上升，撤单相对成交的比例比现在更高，而且流量会呈现出人类流量没有的相关性：读同一个信号的 agent 会在同一刻得出同一个结论。这些都不是靠加一个功能能解决的，只能一层一层走过整个架构，问每一层各自要做什么不一样的事。

这一页就是那一遍，按顺序走，并写明每一层实际走到了哪。

<div className="dg" data-dg="agent-layers">
  <div className="dg-c" style={{aspectRatio:"720 / 500"}}>
    <svg className="dg-w" viewBox="0 0 720 500" aria-hidden="true" />

    <div className="dg-band" style={{left:"0.0000%",top:"3.6000%",width:"100.0000%",height:"19.6000%"}}><span className="dg-cap">1 · 应用层</span></div>
    <div className="dg-band" style={{left:"0.0000%",top:"26.0000%",width:"100.0000%",height:"19.6000%"}}><span className="dg-cap">2 · 网络层</span></div>
    <div className="dg-band" style={{left:"0.0000%",top:"48.4000%",width:"100.0000%",height:"19.6000%"}}><span className="dg-cap">3 · 执行层</span></div>
    <div className="dg-band" style={{left:"0.0000%",top:"70.8000%",width:"100.0000%",height:"19.6000%"}}><span className="dg-cap">4 · 状态层</span></div>
    <div className="dg-b dg-left" style={{left:"2.2222%",top:"8.0000%",width:"95.5556%",height:"12.0000%"}}><span className="dg-t">runtime 在协议之外</span><span className="dg-s">而且不带任何特权——没有更低延迟、没有更早的数据、没有第三方够不到的接口</span></div>
    <div className="dg-b dg--blue dg-left" style={{left:"2.2222%",top:"30.4000%",width:"95.5556%",height:"12.0000%"}}><span className="dg-t">当发送方是 agent 时的准入</span><span className="dg-s">撤单迟到比下单迟到更糟；公平按最近一段历史来记，不是逐条消息来限</span></div>
    <div className="dg-b dg--sky dg-left" style={{left:"2.2222%",top:"52.8000%",width:"95.5556%",height:"12.0000%"}}><span className="dg-t">授权是一笔交易</span><span className="dg-s">它有区块高度，在封闭指令集里——而撤销它会在同一个区块里撤掉该 agent 的挂单</span></div>
    <div className="dg-b dg--green dg-left" style={{left:"2.2222%",top:"75.2000%",width:"95.5556%",height:"12.0000%"}}><span className="dg-t">一个可重放、按区块定版的环境</span><span className="dg-s">point-in-time 是构造出来的，不是靠纪律维持的</span></div>
    <div className="dg-free dg-mid" style={{left:"0.0000%",top:"92.0000%",width:"100.0000%"}}><div className="dg-n">和架构总览是同样的四层。只有问题不同：当参与者不是人时，每一层各自要做什么？</div></div>
  </div>
</div>

| 层       | 变的是什么                        | 状态               |
| ------- | ---------------------------- | ---------------- |
| **应用层** | runtime——研究加执行——在协议之外，不带任何特权 | 已承诺              |
| **网络层** | 突发的、相关的、撤单密集的流量下的准入          | 已交付，两个问题待定       |
| **执行层** | 授权变成一笔带条款的交易                 | 全有或全无部分已交付；条款已承诺 |
| **状态层** | 链就是 agent 被评估的那个环境           | 已交付              |

<h2 id="1-application-the-runtime-sits-outside-and-has-to">
  1 · 应用层 —— runtime 在协议之外，而且必须在
</h2>

agent runtime 是一个研究加执行的框架：它形成判断，把判断变成可执行的东西，再送到场所面前。它跑在应用层，和前端、API 客户端同一层，**不是协议的一部分**。

这个位置首先是物理约束，其次才是设计取舍。模型以秒为单位推理，市场以毫秒为单位移动。任何需要调用模型的东西，都不能待在订单实际经过的那条路上——也就是说，**协议里根本没有模型**。这不是遗漏：结算路径上放一个模型，会毁掉这里其他一切所依赖的那条性质。执行路径必须在每个节点上产出相同的字节，而推理做不到。

所以 runtime 待在外面，诚实的问题就变成了：协议欠它什么。五样，而且都是已承诺而非已交付：

|            | 它给 agent 的                         |
| ---------- | ---------------------------------- |
| **预执行模拟**  | 在提交之前，对着已提交状态评估一笔订单会做什么            |
| **幂等提交**   | 对一次结果不明的提交重试，而不担心重复暴露              |
| **有名字的终态** | 不存在结果未知的结局——每个动作都终结在一个有名字的状态上      |
| **可恢复**    | 一个重启的 agent 知道自己刚才到哪了、下一步该做什么      |
| **带归属的回执** | 这个 agent 做了什么、在谁的授权之下、花了多少——作为协议输出 |

状态见[后续规划](/zh/protocol/roadmap/whats-next)。

<Note>
  runtime 不持有任何特权路径。没有更低的延迟，没有更早的数据，也没有第三方 runtime 够不到的接口。这句话值得写出来而不是默认，因为这套架构在别处的主张是「交易者和清算所之间没有任何人」——而一个自家工具外加一条专用通道，恰恰就是那个「任何人」。
</Note>

<h2 id="2-network-admission-when-the-senders-are-agents">
  2 · 网络层 —— 当发送方是 agent 时的准入
</h2>

mempool 决定什么值得留着、某个发送方的哪一笔排在下一个、哪些对等节点会听说它、以及需求超过容量时丢掉什么。agent 流量对这四件事全都是压力，而其中两条吸收它的性质早就在了，理由跟 agent 无关。

**撤单迟到比下单迟到更糟。** [mempool](/zh/protocol/architecture/mempool)在设计上就把下单和撤单当作不对称的两类。agent 会把这个不对称拉得更极端，因为它的撤单/成交比高于人；但问题的形状，正是这一层当初围着建的那个。

**公平按最近一段历史来记，不是逐条消息来限。** mempool 保有一份滚动记录：最近哪些发送方、哪类流量吃掉了容量，据此塑形下一步先服务谁。**这一条对相关性突发才是关键**：四十个 agent 对同一个信号同时撤单，不是把平均负载乘四十再摊平，而是一根尖峰。逐条消息的限流看不见它，「谁最近很吵」的记忆看得见。

**共识不随吞吐增长。** 交易以批的形式到达验证者，而且提案引用它之前必须先证明可得性，所以区块提案携带的是摘要不是交易体。一个把消息速率抬高一个数量级的 agent 群体，完全不会抬高共识消息的大小。

<Warning>
  区块消灭的是**块内**的竞速：同一区块里的两笔交易有一个每个节点都算得出的先后。**但这条保证从区块边界才开始。** 进块之前仍然是竞速，它被发送方级公平塑形，不是被它消除。准入不等于入块。
</Warning>

这一层有两个问题是开放的，而且都是在 agent 的量级上才成为实际问题，人的量级上不是。

**一次撤单该花多少。** 执行层已经把撤单排在最前——它们跑在任何可能吃流动性的东西之前。网络层的同一个问题还没定：便宜且优先的撤单正是「挂单可防御」的来源，同时也是灌满一个 mempool 最便宜的方式。撤单该不该有独立于下单的容量账户，尚未决定。

**幂等该归哪一层。** 一个收不到答复的 agent 会重发。幂等提交在执行层是已承诺的，它了结了真正要紧的后果——不会重复暴露。但它没有了结网络层的那个版本：mempool 该不该认出一次重发是同一个意图，还是两条都留着、交给执行层去重。这两种做法在重试风暴下的行为不一样。

<Note>
  有一件事是刻意不做的：给 agent 单独开一条准入通道。优先接入是每一家中心化场所最终都会卖的东西，而它会跟「交易者和清算所之间没有任何人」这句话直接冲突。agent 流量走同一扇门。
</Note>

<h2 id="3-execution-authorization-is-a-transaction">
  3 · 执行层 —— 授权是一笔交易
</h2>

这一层是账户模型真正改变的地方，而整个改变都从一个事实推出来。

**把一个账户交给 agent，是链上的一笔交易。** 不是一次表单提交，不是设置页里签出的一个 API key，也不是运营方数据库里的一行。是一笔交易，在一个区块里，有高度，由授予它的那个账户签名——因此任何第三方都能找到它、读它、核对它，不必问任何人。

由此有三个结果，每一个都是 API key 做不到的事。

**它在封闭指令集里。** agent 授权是[内核](/zh/protocol/architecture/kernel)枚举好的操作之一。通用链表达不了它——那次调用的含义对它是不透明的字节码。中心化场所是在你看不到的软件里强制它。而在这里，权限和它的边界**就是那条指令**，所以边界是可核对的，而不是被承诺的。

**它带得了这个 agent 能做什么，带不了它不能做什么。** 一份授权可以说明：这个 agent 能持有多少、能亏多少、能碰哪些市场、能不能改保证金模式。它**说不出**「提现」。这不是一个默认关着的开关——根本没有那个词可写。一个操作账户的 agent，没有任何可表达的路径把资金移出去。

**撤销它，会连带撤掉这个 agent 的挂单。** 撤销也是一笔交易，它落在一个[排序](/zh/trading/tx-sequencing)已经规定「撤单跑在任何可能吃流动性的东西之前」的区块里。所以这个 agent 留在簿上的单，和那份权限在同一个区块里一起走。在撤销只是一次数据库写入的场所，key 停止工作，而挂单处在未定义状态。在这里，这个停止是可证明的，而且任何人都能找到它发生在哪个高度。

<div className="dg" data-dg="agent-authority">
  <div className="dg-c" style={{aspectRatio:"720 / 214"}}>
    <svg className="dg-w" viewBox="0 0 720 214" aria-hidden="true">
      <path className="dg-wire" d="M 213.33 88.00 L 244.93 88.00" />

      <path className="dg-head" d="M 251.33 88.00 L 244.93 92.40 L 244.93 83.60 Z" />

      <path className="dg-wire" d="M 468.67 88.00 L 500.27 88.00" />

      <path className="dg-head" d="M 506.67 88.00 L 500.27 92.40 L 500.27 83.60 Z" />
    </svg>

    <div className="dg-b dg--blue" style={{left:"0.0000%",top:"14.0187%",width:"29.0741%",height:"54.2056%"}}><span className="dg-t">授予</span><span className="dg-s">第 N 个区块里的一笔交易</span><span className="dg-n">它带着边界：这个 agent 能持有什么、能亏多少、能交易什么。它带不了提现——那个词根本不存在</span></div>
    <div className="dg-b dg--sky" style={{left:"35.4630%",top:"14.0187%",width:"29.0741%",height:"54.2056%"}}><span className="dg-t">行动</span><span className="dg-s">每一次动作都写明授权来自谁</span><span className="dg-n">归属到授予它的那个账户，不只是归属到提交它的那个 agent</span></div>
    <div className="dg-b dg--orange" style={{left:"70.9259%",top:"14.0187%",width:"29.0741%",height:"54.2056%"}}><span className="dg-t">撤销</span><span className="dg-s">第 M 个区块里的一笔交易</span><span className="dg-n">该 agent 的挂单在同一个区块里被撤掉，在任何可能吃流动性的东西运行之前</span></div>
    <div className="dg-free dg-mid" style={{left:"0.0000%",top:"76.6355%",width:"100.0000%"}}><div className="dg-n">这三件没有一件是「等着别人告诉你」的数据库写入。每一件都是一笔任何人都能按高度找到的交易。</div></div>
  </div>
</div>

今天这份授予是全有或全无外加一个过期时间。上面那些更丰富的条款——能持有什么、能亏多少、下一步能做什么——是已承诺而非已交付，见[后续规划](/zh/protocol/roadmap/whats-next)。**已经成立的是事后补不回来的那部分**：权限是一个协议对象，而不是运营方对某个权限的记录。

<h3 id="what-the-venue-already-carries-for-the-runtime">
  场所已经替 runtime 扛下的部分
</h3>

一个必须在普通场所上保护用户的交易 runtime，最后总会给自己造一个特权内核：一份它自己维护、自己对账的持仓账本；一次它自己算、然后祈祷场所也这么算的事前风控；一份它自己写、又无法证明没被改过的审计日志。**这三件都是在替一个不肯出示账本的场所做冗余。**

这三件在这里是协议性质。[清算所](/zh/protocol/architecture/clearinghouse)是账本唯一的写入方。风险阶段跑在撮合之前，同一个区块里。审计日志就是链，而且每一次状态变更都带着引起它的那笔交易。剩给 runtime 的是第四件——幂等的订单网关——而那是接口问题，不是信任问题。

<h3 id="matching-the-block-is-already-the-batch">
  撮合：区块本身就是批
</h3>

agent 流量抬高频次、压低单笔规模，而这正是最常被用来论证批量拍卖的那种微观结构：离散区间、一起清算、早到一微秒也没有优势。

这条性质在这里**已经成立**，而且不是因为加了一个批量拍卖。区块内的时间是共识提交的位次而不是本地时钟，所以**区块内不存在亚毫秒级的优势**；而撤单跑在任何主动订单之前，所以一个过时的报价可以被撤掉，不会被同它一起到达的订单吃掉。区块就是一个一起清算的离散区间。它是执行一份已提交定序的**后果**，不是市场设计的外挂。

在这之上还要不要做更多——而且连续的价格-时间优先和频繁批量拍卖是**互斥选项而不是叠加项**，因为一次批量拍卖是刻意在批内取消时间优先的——正在探索，没有在建。

<h2 id="4-state-the-chain-is-the-environment">
  4 · 状态层 —— 链就是那个环境
</h2>

一个 agent 的好坏，取决于它是对着什么被评估的，而绝大部分失败恰恰发生在评估这一环。一个在模拟器里赚钱、上生产就不行的策略，通常并不是遇上了一个新市场，而是遇上了一个不是场所的模拟器。

[状态层](/zh/protocol/architecture/state/model)靠**构造**而不是靠纪律消掉这个落差。状态按区块定版，每一次变更都归属到引起它的那笔交易，所以重放一个区块重放的是**环境本身**而不是环境的一个模型——同一台将要执行这个 agent 的状态机，跑在网络已经提交的输入上。这正是[自己验一遍](/zh/developers/verify)里的第五项检查，也是这里的回测和对着交易所历史 API 做的回测**不是同一类东西**的原因。

更微妙的一条是：这里的 **point-in-time 是构造出来的**。从交易所 API 拼出来的数据集，只有在拼的人足够小心时才是 point-in-time 的，而前视偏差会从没人注意的缝里漏进来——某个字段事后被回填、某次修正被应用到历史上、某个参考价被修订。在这里这个问题不成立：一个区块的状态就是那个区块当时为真的东西，因为状态从来就只有这一种形态。

<h2 id="what-gets-harder">
  会变得更难的部分
</h2>

为 agent 建设，不只是一串变好的事情。

**确定性是双刃的。** 一个 agent 能在提交前预测自己的订单会做什么，因为同样的输入在每个节点产出同样的结果。**别人的 agent 对你的订单也能。** 可复现性同时抬高了你的可规划性和你的可预测性，而第二样不是免费的。

**agent 的流动性是相关的流动性。** 人类做市商在不同时刻撤走，因为他们在不同时刻注意到。读同一份公开状态的 agent 会一起得出同一个结论。由 agent 支撑的订单簿在平常的日子更深，而在要紧的那一天可能更快变薄——这是协议的承接层被设计来应对的市场结构风险，不是它们能消除的风险。

**预言机读的那些场所，agent 也在里面交易。** 认证把价格绑定到消费它的那个区块；它并不让底层市场变得不可操纵，而一群依据相关信号行动的 agent，正是底层可以一起移动的又一种方式。见[预言机保证什么、不保证什么](/zh/protocol/architecture/oracle)。

**agent 对自己的评估不构成证据。** 交易的反馈是有噪声且非平稳的，代码的反馈不是——编译器会告诉你你错了，而一个赚钱的星期不会告诉你你对了。任何为 agent 建设的场所，都必须把 agent 自己对自己表现的陈述当作**对抗性输入**而不是一次测量。这也是[自己验一遍](/zh/developers/verify)那些检查全都围绕「能被重算的东西」而不是「能被报告的东西」来写的原因之一。

<h2 id="where-to-go-next">
  后续阅读
</h2>

<CardGroup cols={2}>
  <Card title="AI 交易：现在与下一步" href="/zh/protocol/ai-trading">
    四个阶段，以及为什么必须改变的是账户。
  </Card>

  <Card title="自己验一遍" href="/zh/developers/verify">
    那些让 agent 的评估不只是一句声称的检查。
  </Card>

  <Card title="信任假设" href="/zh/protocol/architecture/trust">
    能查的都查完之后，还剩下什么要信任。
  </Card>

  <Card title="后续规划" href="/zh/protocol/roadmap/whats-next">
    agent runtime 与授权条款的状态。
  </Card>
</CardGroup>
